Custom harnesses
A harness runs the Claude Code runtime — its agent loop, tools, and file editing — but points the model at any endpoint you choose. Same experience, different brain, on your budget instead of your Claude limits.
What a harness is
Adding a harness does not fork the model — it forks the runtime. The claude host binary still drives the loop, but its requests go to your endpoint with your model and your key. So a run on a DeepSeek harness spends DeepSeek tokens through your provider and zero Claude quota, while every Claude Code tool still works. A harness is stored as a profile YAML under ~/.agents/profiles/; the agents harness commands are the shortest path to create and inspect one. For the full YAML reference and the built-in preset catalog, see profiles.
Add one
One command pins the host, model, endpoint, and auth provider:
agents harness add deepseek-flash \
--host claude \
--model deepseek/deepseek-v4-flash-0731 \
--base-url https://openrouter.ai/api \
--auth-provider openrouterThe --model value is an OpenRouter model id — browse openrouter.ai/models for the live catalog, since slugs change as models ship. This example uses DeepSeek V4 Flash 0731, a cheap, strong open coding model, but any id there works.
--auth-provider prompts once for the API key and stores it in the OS keychain (never on disk). For scripts, pipe the key in with --key-stdin instead of the prompt. The result is a profile YAML that records the endpoint, the model, and the keychain item to read at run time:
name: deepseek-flash
host:
agent: claude
env:
ANTHROPIC_BASE_URL: https://openrouter.ai/api
ANTHROPIC_MODEL: deepseek/deepseek-v4-flash-0731
provider: openrouter
auth:
envVar: ANTHROPIC_AUTH_TOKEN
keychainItem: agents-cli.openrouter.tokenInspect and run
agents harness view deepseek-flash # host, model, provider, auth status
agents harness list # your harnesses + addable presets + native agents
agents run deepseek-flash "summarize the diff"The harness name replaces the agent argument. It is a first-class run target — and a first-class teammate: drop it straight into a team and the model, endpoint, and key are injected automatically.
agents teams add my-feature deepseek-flash "write the tests" --mode editKeep data in-region
When you route an open model through an aggregator like OpenRouter, the request lands on whichever upstream provider is cheapest by default — which may not be one you want. Pin it at the account level so every request (including the ones the harness sends) is constrained. In the OpenRouter dashboard, under Settings → Privacy → Zero Data Retention, enable the Non-frontier toggle: all non-frontier requests are then forced to endpoints that do not retain your data, which excludes the retaining and out-of-region hosts.
Verify what the harness actually gets by reading the serving provider back from a plain request — no per-request pin, exactly what the runtime sends:
curl -s https://openrouter.ai/api/v1/chat/completions \
-H "Authorization: Bearer $OPENROUTER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"deepseek/deepseek-v4-flash-0731",
"messages":[{"role":"user","content":"hi"}],
"max_tokens":1}' | jq .providerModel origin is not the same as where your data goes: a China-trained open model served from a US provider keeps your prompts on US infrastructure. What matters is the serving endpoint, and that is what the retention policy constrains.
Cap the spend
Set a hard monthly limit on the key itself in the provider dashboard so a runaway loop or a leaked key can never exceed it. Read the current usage and remaining budget back at any time:
curl -s https://openrouter.ai/api/v1/key \
-H "Authorization: Bearer $OPENROUTER_API_KEY" | jq '.data | {limit, usage, limit_remaining}'Headless caveat
The claude host sends thinking:{type:"enabled"} by default, and its headless output is empty when a response carries thinking blocks. So reasoning models work interactively but return nothing under --print / a headless agents run. Non-reasoning variants ignore that flag and are safe for scripted pipelines and teams. Test a new harness headless before you rely on it for automation; if it comes back empty, pin a print-safe model.
Related
- Profiles — the YAML reference and built-in preset catalog
- Secrets — Keychain-backed credential bundles
- Teams — mix harnesses across a parallel team
- Account rotation — spread load across Claude accounts