Docs
The CLI, the agent skill
and MCP
One command to submit, one to take the patch. Everything in between, what is uploaded and when money moves, is shown first and asked about.
pipx install autooptmits own environmentautooptm loginapprove this machine in the browserautooptm run . --entrypoint train.pyfree estimate, asks before it chargesInstall
autooptm is a command-line tool: install it into its own environment with pipx or uv tool. Homebrew's Python on macOS and recent Debian / Ubuntu refuse a bare pip install into the system environment; neither of these is affected.
$ pipx install autooptm # or $ uv tool install autooptm $ autooptm --help
The MCP server needs one extra dependency: pipx install 'autooptm[mcp]'.
Sign in
autooptm login opens the browser, where you approve this machine. The terminal receives a 30-day token that slides on every use, stored at ~/.config/autooptm/token.
$ autooptm login signed in as you@example.com; token saved to ~/.config/autooptm/token (valid 30 days, and it slides on use) # a server with no browser: print the approval URL, open it anywhere $ autooptm login --no-browser # or the email code (QQ / 163 mail work): one command sends it, the next verifies $ autooptm login --email you@example.com $ autooptm login --email you@example.com --code 482913 $ autooptm balance 12.4 credits (≈ $12.4) $ autooptm logout
CI and scripts: API keys
Where a browser is out of reach, use an API key. It is shown once; the default scopes are read,submit, and unlock, which spends credits, has to be asked for. Put it in AUTOOPTM_TOKEN and the CLI picks it up.
$ autooptm keys create "CI pipeline" --scopes read,submit --expires-in-days 90 $ autooptm keys list $ autooptm keys revoke <keyId> $ export AUTOOPTM_TOKEN=ao_…
One full run
run takes a public git URL or a local directory and drives the whole loop: packing, the free estimate, asking whether to continue, waiting, and telling you what the patch costs. A dropped connection changes nothing, the job keeps running on our side and wait picks it back up.
Copy the command you normally run: the entry script in --entrypoint, the rest in --args. Leave the GPU on auto for an RTX 4090; pick RTX5090 when it does not fit; pick CPU when the program uses no GPU, and there is no machine line at all.
A local directory is listed on your machine first: weights, data, large files and crowded directories are each asked about, and nothing leaves before you confirm. See what gets uploaded.
A static scan of seconds; none of your code runs and nothing is charged. It prints the expected speedup and its range, then asks whether to continue.
Answer y and the 2-credit analysis deposit is taken, credited in full against the patch and returned when no speedup is found or the failure is ours. Answer n, or nothing, and the job stays at the estimate for free.
At the end it prints the measured end-to-end speedup and the patch price. unlock asks once more before spending, writes autooptm.patch, and git apply does the rest. Under 1.10× no patch is sold and the deposit comes back.
$ autooptm run . --entrypoint train.py --workload training --gpu auto skipped: .git (1), __pycache__ (14) y = into the code archive · n = leave out · d = upload as the private dataset instead (sandbox only, 7 days, up to 1 GB, one per run) checkpoints/ weight files: 2, 1.9 GB (.pt×2) include? [y/N/d] n data/ crowded directory: 1204 files, 310 MB (0 of 1204 files are code) include? [y/N/d] d data/ goes up as the dataset, unpacked at ./data packing 87 files, 1.4 MB before compression: src/ 62 files 1.1 MB configs/ 14 files 38 KB train.py 1 files 12 KB dataset: /home/you/repo/data -> ./data in the sandbox upload? [Y/n] y job 7f3c2a1b queued estimate: expected 1.6x · range 1.2x - 2.3x · lossless 1.4x next: autooptm decide 7f3c2a1b continue (takes the deposit, credited against the unlock) autooptm decide 7f3c2a1b stop (free) continue? takes the analysis deposit (2 credits), credited against the unlock. [y/N] y … 1.61x (937.8s -> 582.5s) patch: locked. unlock for 4.6 credits (autooptm unlock 7f3c2a1b) report: https://api.autooptm.com/api/my/reports/… $ autooptm unlock 7f3c2a1b Unlock spends 4.6 credits. Continue? [y/N] y $ git apply autooptm.patch
autooptm wait <jobId> resumes waiting, autooptm status <jobId> takes a look, autooptm estimate <jobId> shows the estimate again.What gets uploaded
A local directory is packed on your machine, and scanned first. What goes into the code archive is your call:
| Kind | What happens |
|---|---|
| .git, caches, virtualenvs, editor state | Dropped, said once on a skipped: line: __pycache__, .venv, node_modules, wandb, .idea, .DS_Store and the like. |
| Weight filesasked | .pt .pth .ckpt .safetensors .onnx .npz .bin .gguf and so on, listed per directory, out by default. |
| Data filesasked | Images, audio, video, tables, .npy / .h5 / .pkl, archives and the like, listed per directory, out by default. |
| Any file over 8 MBasked | Listed one by one, out by default. |
| A directory with over 200 filesasked | Listed with its file count, size and how much of it is code. In by default when at least half is code (src/), out when it is not (outputs/). |
Each group takes one of three answers: y into the code archive, n leave out, d upload as the private dataset instead. The dataset goes through its own channel, sandbox only, deleted after seven days, up to 1 GB, unpacked at the same relative path so your command does not change; one dataset per run. After the questions the packing list is printed, and nothing is uploaded until you confirm. The code archive is capped at 64 MB compressed.
# only show the list; nothing leaves the machine $ autooptm run . --entrypoint train.py --dry-run # answer from the command line instead of the prompts $ autooptm run . --entrypoint train.py --include checkpoints --exclude outputs --yes # send a directory as the dataset, unpacked at ./data in the sandbox $ autooptm run . --entrypoint train.py --dataset ./data --dataset-path data --yes
--yes, run prints the list and stops (exit 1). Look with --dry-run first, then submit with --include / --exclude and --yes.Command reference
| Command | What it does | Flags |
|---|---|---|
| run SOURCE | Submit a public git URL or a local directory and wait to the end. The free estimate comes first and asks; --no-wait returns right after submitting. | --entrypoint main.py--workload training|inference--gpu auto|RTX4090|RTX5090|CPU--args "…"--setup FILE--git-ref REF--model opus|glm--lang zh|en--dataset DIR_OR_ARCHIVE--dataset-path ./data--include PATH--exclude PATH--dry-run--no-estimate--no-wait--yes |
| wait JOB | Resume waiting on a job after a dropped connection or --no-wait. A job parked at the estimate is asked about again. | --yes--timeout SECONDS |
| estimate JOB | The free estimate again: expected, range, the lossless line, and the review note. | |
| decide JOB continue|stop | Answer the estimate. continue takes the 2-credit deposit, stop is free; seven days of silence is a stop. | --yes |
| status JOB | One job's state, speedup and price. | |
| unlock JOB | Pay the quoted credits and download the patch. Asks first; never more than the quote. | --yes--out autooptm.patch |
| cancel JOB | Stop a queued or running job. A cancelled run is not charged. | |
| balance | Credits available. | |
| datasets | Datasets this account uploaded and still keeps; a key can be reused as is. | |
| login | Sign in: opens the browser to approve this machine; --email for the mailed code instead. | --no-browser--email ADDR--code NNNNNN--role … |
| logout | Forget the saved token. | |
| keys create|list|revoke | API keys for CI and scripts. | create NAME --scopes read,submit,unlock --expires-in-days N |
| install-skill | Write the Claude Code skill into this machine's skills directory, below. | --dest DIR |
The Claude Code skill
The skill ships inside the package; there is nothing else to fetch. With the CLI installed and signed in, one command writes it into Claude Code's skills directory:
$ pipx install autooptm $ autooptm login $ autooptm install-skill installed autooptm-optimize -> ~/.claude/skills/autooptm-optimize/SKILL.md # somewhere else, e.g. a project-level skills directory $ autooptm install-skill --dest ./.claude/skills
Then open your repository in Claude Code and say "speed this repo up with AutoOptm", or invoke /autooptm-optimize. The skill teaches Claude Code the whole loop:
The command that runs training or inference end to end; it asks when unsure.
--dry-run first, and shows you the listAn agent has no terminal, so it lists what would be uploaded and what stays out, and only after you agree does it submit with --include and --yes.
Only your yes leads to decide continue; otherwise the job stays at the free estimate.
It reports the speedup and the price, waits for your go before unlock, then git apply.
pipx install autooptm, autooptm login and autooptm install-skill; the token does not travel with the skill.MCP
Claude Code, Cursor or any MCP client can call it directly. Install the package with the mcp extra and register autooptm-mcp in the client's configuration:
$ pipx install 'autooptm[mcp]' $ autooptm login
{
"mcpServers": {
"autooptm": { "command": "autooptm-mcp" }
}
}
Tools: optimize_submit, optimize_estimate, optimize_decide, optimize_status, optimize_wait, optimize_cancel, unlock_patch, download_patch, account_balance. The rules match the CLI: optimize_submit parks at the free estimate, only optimize_decide takes the deposit, and unlock_patch needs the user's explicit confirmation. A local directory submit returns upload, what was packed and what was left out, and a second submit with include adds a group back.
Environment and scripts
| AUTOOPTM_TOKEN | An API key or a login token; when set, the saved file is not read. |
| AUTOOPTM_API | The API base, https://api.autooptm.com by default. |
| XDG_CONFIG_HOME | Parent of the token file's directory, ~/.config by default. |
Off a terminal
Every step that spends money or sends files out wants one explicit yes, which a script gives with --yes. Without it: run on a local directory prints the list and exits 1 without uploading; once the estimate is in, run prints parked at the estimate and exits 0, the job waits for free and decide answers it later; unlock refuses. Transient failures (rate limits, network blips) are retried; a submit, which must not happen twice, is resent only when the server itself said "not now".