Developers & cloud

Let your chat hand the work to the coding agent that already has the repo.

The agent in your browser has your instruction. The machine under your desk — or the VM in eu-central-1 — has the checkout, the toolchain, the private registry token, the .env, the datasets and the GPU. AI Commander lets the first one start a headless coding agent on the second: claude -p "…", codex exec "…", or whatever CLI you use, spawned as a detached job that keeps working after the tool call returns and after the conversation ends. You ask how it went later — from another chat, another client, or your phone.

What actually happens

There is no agent-to-agent protocol here, and no ask_agent tool. The mechanism is deliberately boring, which is why it works with every coding agent that has a non-interactive mode:

So the cloud agent is the dispatcher and the reporter; the local agent is the one doing the engineering. The only thing crossing the relay is an instruction going in and bounded slices of log coming out.

Prerequisite on the target machine. The coding agent's CLI has to be installed and already authenticated there, the same as if you had SSH'd in and typed the command yourself. AI Commander does not install or log into anything for you — it starts the process. One short remote_exec (which claude, codex --version) is the right way to check before starting a long run.

Why not just let the cloud agent write the code

Sometimes you should. But three things fall out of running the coding agent on the machine that owns the work:

The reverse split is worth naming too: your cloud agent is still the one that talks to you, holds the context of what you actually want, and reads the result critically. It just stops being the thing that has to hold a shell open.

Why this must be a job, not an exec

remote_exec is for commands that finish in seconds or minutes. It has two caps, and they do different things — the difference matters a lot for an agent run:

remote_job_start removes both problems by keeping the output on the machine: the log goes to a file, only bounded slices ever cross the relay (each remote_job_logs reply is capped at 256 KiB, and you page forward by feeding nextOffsetBytes back as offset_bytes), and the exit code is recorded to disk. The log file itself is capped at 256 MiB, and on overflow the agent only stops recording — it never kills the job.

MCP toolDoesREST
remote_job_start(code, command, cwd?, env?, name?, gpu_index?) Spawns the coding agent, returns its jobId immediately. POST /api/v1/jobs
remote_job_list(code, status?, include_command?) Runs in flight, plus finished ones still retained. GET /api/v1/jobs
remote_job_status(code, job_id, include_command?) running, exited with the exit code, or unknown. GET /api/v1/jobs/{id}
remote_job_logs(code, job_id, tail_lines?, offset_bytes?, max_bytes?) What the coding agent printed; last 200 lines by default. GET /api/v1/jobs/{id}/logs
remote_job_cancel(code, job_id) Kills the whole process tree — the agent and everything it spawned. DELETE /api/v1/jobs/{id}

cwd must be an absolute path that already exists — point it at the repo — and env takes string values only. There is no elevated option for jobs: a job runs with exactly the rights remote_exec has on that machine, and an explicit elevated: true is refused rather than quietly downgraded. Full shapes and error codes are in the tool reference and the machine-readable OpenAPI spec.

Copy-paste prompts

Paste these into Claude, ChatGPT, or any client with AI Commander connected. Replace dev-box with your machine's saved alias or its AIC-… session code, and the paths with yours. They are written to be pasted as-is — each one names the machine, so no earlier turn is needed.

1. Start a coding agent run and walk away

Prompt — start a run
On dev-box, start a detached job — do not use remote_exec, this will take a while. cwd: /home/lu/src/api name: fix-billing-tests command: claude -p "The tests in tests/billing are failing. Find out why, fix the source, and run pytest tests/billing until it passes. Do not commit or push." \   --permission-mode acceptEdits Give me the jobId and stop there — don't poll it.

The client answers with a jobId in a second or two, while Claude Code on dev-box is still reading the failing test. Write the id down — it is how the run is picked up in a later conversation. The codex CLI is the same shape:

Prompt — codex instead
On dev-box, start a job in /home/lu/src/api named migrate-v3, running: codex exec "Migrate every call site off the deprecated v2 client to v3, then run make test. Leave the changes uncommitted." Tell me the jobId. Don't wait for it to finish.

2. Ask a longer run to leave you a result file

The job's log already has everything the coding agent printed, but a diff or a report is easier to collect as a file. Make that the last step of the command:

Prompt — leave an artifact
On dev-box, start a job in /home/lu/src/api named perf-pass, running: bash -lc 'mkdir -p aic-out && claude -p "Profile the /search endpoint, make it faster without changing behaviour, and keep the tests green." --permission-mode acceptEdits; rc=$?; git diff > aic-out/perf-pass.diff; exit $rc' Report the jobId, then stop.

3. Check on it later, from anywhere

A brand new chat, on a different device. Nothing has to be resumed first:

Prompt — check on it
On dev-box, what is job 9f2c1b7ad4e05386 doing? Give me remote_job_status, then the last 100 lines of its log, and tell me in one paragraph what the coding agent has actually done so far. If it exited, say so and give me the exit code.

Forgot the id — which is the normal case a day later:

Prompt — find the run
List the jobs on dev-box with their names and statuses. Find the one named fix-billing-tests, and summarise how it ended from its logs.

4. Collect the diff

Prompt — read it in place (any plan)
On dev-box, run git -C /home/lu/src/api diff --stat, and if it's under a few hundred lines show me the full diff. Then tell me whether you'd take this change.
Prompt — bring the file back (Pro)
Pull /home/lu/src/api/aic-out/perf-pass.diff off dev-box and give me the download link, then review the diff and list anything that looks risky.

5. Stop a run that has gone wrong

Prompt — cancel
On dev-box, cancel job 9f2c1b7ad4e05386, then show me the last 200 lines of its log so I can see where it went off the rails, and confirm with git status whether it left the working tree dirty.

Cancelling kills the coding agent's whole process tree — including any build or test it had spawned. Note that a job killed by a signal writes no exit marker, so a cancelled run settles on unknown rather than an exit code; that is honest, not a bug.

What it looks like end to end

Claude — MCP
You: on dev-box, have Claude Code fix the failing billing tests in /home/lu/src/api — as a job, don't wait for it Claude: > remote_exec code=dev-box command=which claude && git -C /home/lu/src/api status --short /home/lu/.local/bin/claude (clean tree) > remote_job_start code=dev-box cwd=/home/lu/src/api name=fix-billing-tests   command=claude -p "Fix the failing tests in tests/billing…" --permission-mode acceptEdits ✓ jobId 9f2c1b7ad4e05386 — running Claude: Started as job 9f2c1b7ad4e05386. The tree was clean before it started, so whatever it changes will show up as a plain diff. Close this whenever — ask me about that id later. You: (that evening, new chat, phone) how did job 9f2c1b7ad4e05386 on dev-box end? Claude: > remote_job_status code=dev-box job_id=9f2c1b7ad4e05386 ✓ exited, exitCode 0 > remote_job_logs code=dev-box job_id=9f2c1b7ad4e05386 tail_lines=100 … 14 passed in 6.02s Done. Root cause: proration used the invoice date, not the period start. Claude: It finished cleanly. Proration was reading the invoice date instead of the period start; it fixed billing/proration.py and tests/billing now passes, 14 tests. Nothing committed. Want the diff?

What survives, and what does not

A remote agent run is durable in the ways that matter, and it is worth being exact about the ways it is not:

A machine holds at most 32 running jobs; past that a start is refused with too_many_jobs. Nothing queues, schedules or retries on your behalf — it is your hardware and a real shell.

What's Free, and what needs Pro

Starting a coding agent on a remote machine and following it to the end is the Free path in full: remote_job_start, remote_job_list, remote_job_status, remote_job_logs and remote_job_cancel all work on a free account, across up to 10 usable saved machines. Records beyond that stay saved and visible but are marked planRestricted and refuse operations with reason:"plan_device_limit"; the 10 oldest are the usable ones, and deleting one promotes the next.

Pro ($49/month) raises that to every saved record up to the technical ceiling of 100 machines*, and adds built-in file transfer — which is what you need to bring an artifact back rather than read it in place:

Details and the transfer quotas are in Docs → File transfer.

* 100 machines is a technical ceiling, not a policy limit. Need more? Get in touch — we'll sort it out.

Set it up

On the machine that has the repo, install the agent and make sure your coding agent CLI is installed and signed in there:

Follow the install steps for your platform — verify the signed installer before sudo on Linux.

Connect your AI client, save the machine under an alias like dev-box, and paste one of the prompts above.

Working from Claude Code? The whole procedure on this page — the job command shape, the artifacts to write, what the exit code means — is packaged as a skill you can install in one command: /skill/coding-agent/SKILL.md. The companion skills cover the other long-job workflows: training, backup, deploy and incident triage.

FAQ

Can I run Claude Code on another machine?
Yes, if that machine runs the AI Commander agent and has the Claude Code CLI installed and already logged in. Your chat client calls remote_job_start with a command like claude -p "…", and the machine spawns it as a detached background job and returns a jobId immediately. There is no special agent-to-agent tool involved: it is an ordinary command started as a job, and the coding agent's own headless mode does the work. The same shape works for the codex CLI or any other headless agent CLI.
How do I let ChatGPT use a coding agent on my server?
Install the AI Commander agent on the server and give ChatGPT the machine's session code or saved alias. ChatGPT can then call POST /api/v1/jobs over plain HTTP — no MCP connector needed — with the command that runs your headless coding agent in the repo directory. It gets back a jobId, and reads GET /api/v1/jobs/{id} and /logs later to see what happened. MCP clients such as Claude use remote_job_start, remote_job_status and remote_job_logs for the same thing.
Does the agent keep running after I close the chat?
Yes. A detached job belongs to the machine, not to the conversation, so it survives the tool call returning, the client disconnecting, the network dropping and the chat ending — you pick it up later from a different chat, a different client or your phone with the jobId. It also survives the AI Commander agent itself restarting: on Linux each job is launched into its own transient systemd scope, outside the agent service's control group, so restarting or upgrading the agent leaves it running — that needs a systemd host with the agent running as root, and without both a restart still ends running jobs.
Why not just let the cloud agent edit the code itself?
Because the machine already is the environment. The repo, the private dependencies, the .env, the SSH and registry credentials, the datasets and the GPU are all there, and none of it has to be uploaded to a chat to be worked on. The local coding agent can build, run the tests and iterate for an hour; the cloud agent only carries the instruction in and the summary out.
Should a coding agent run be an exec or a job?
A job, always. remote_exec has a 1-hour wall-clock deadline that hard-kills the process tree, and an agent run that is chatty hits the 1 MiB output cap long before that — which truncates the reply but is not evidence the work stopped, so you end up blind to a run that is still going. remote_job_start keeps the output in a file on the machine and hands back only bounded slices, which is exactly what a long agent run needs.
Can I get the diff the remote agent produced?
Have the job write it to a file — git diff > aic-out/run.diff as its last step — then read it. A small diff can simply be printed by a follow-up remote_exec. To bring the actual file back, remote_pull returns a temporary download link and needs Pro; the file must be under 100 MiB and the stored copy is unreadable 24 hours after it is created. Starting and monitoring agent jobs needs no Pro plan.

Give your chat a machine that can code

Install the agent where the repo lives, then let Claude or ChatGPT start the work and report back tomorrow.