Adding a provider
Use this checklist to judge whether a third agent CLI can become a built-in provider. Fill in the [template](new-provider-template.md). Public material only: do not write account names or keys.
Use this checklist to judge whether a third agent CLI can become a built-in provider. Fill in the template. Public material only: do not write account names or keys.
The factory is provider-neutral. A built-in is a runner that speaks the shared interface, not a special case in the factory. The factory uses real permission presets (read_only, edit, interview), not a skip-all bypass, even when a sandbox wraps the step.
Each item points at the runner method, the conformance cases, and the capability rows that prove it. A doc test fails if the suite and this list drift.
Verdict
Every must item is yes → the CLI can be a built-in provider. Then add a runner package, a fake, a flags file, and pass the conformance suite.
Any must item is no → do not add a built-in. Use a custom command step instead. See Using a CLI that isn't a built-in provider.
partly on a must item counts as no. partly on a nice item does not block a built-in.
Checklist
| # | Item | Must or nice | Proved by |
|---|---|---|---|
| P1 | Non-interactive mode that runs one task and exits | must | Runner.Run; C06, C10; capability headless |
| P2 | Prompt from stdin, or from a file, not only argv | must | C06 (a 200 KB prompt must still arrive via stdin or a file) |
| P3 | Line-delimited JSON events while it works, with a final result event | must | C01, C02, C07, C19, C20, C22 |
| P4 | Honest exit codes, and a final result that says success or error | must | C08, C09, C10 |
| P5 | Tool permission control: an allow list or modes matching read_only, edit and interview, without skipping checks | must | C03, C14, C15; capabilities read_only, edit, tool_allowlist |
| P6 | Model selection by flag | must | C16; capability model |
| P7 | Auth from its own login or an environment variable, with a clear "not signed in" error | must | C11, C17 |
| P8 | Usage in the final result (input, output, cache tokens); per-call usage for context size | nice | C04, C05; capabilities token_usage, reported_cost |
| P9 | A session id, and resume by id | nice | C18, C24 |
| P10 | Control of which MCP servers and skills load, and a way to list them | nice | capabilities mcp, skills |
| P11 | A way to turn off its own sandbox when the factory sandbox wraps it, and documented state folders | nice | capability sandbox |
| P12 | --help and --version that Probe can read without a model call | must | Probe; C21; capability interactive |
| P13 | Ends cleanly when its process group gets SIGTERM (Unix) or its Job Object closes (Windows) | must | C12, C13 |
| P14 | Doesn't send the prompt to a cloud agent or remote worker by default (local runs only) | must | capability no_cloud_handoff; flags file review; & prefix rule as the model |
Using a CLI that isn't a built-in provider
A CLI that fails a must item can still run as a custom command step. To fit in like a built-in, the step must speak protocol v2 fields that already exist:
- emit
agent_action,tool_call, andusageevents, includingusage.tokens_input,usage.tokens_output, andusage.tokens_cachedwhen known - honour
limits.time_left_mson the request
Each line links to the protocol schema. Do not invent fields.
Appendix: filled examples
Filled from the public CLI docs and the existing provider pages. Both verdicts are built-in.
Claude Code
Public docs: CLI reference. Setup: Claude Code.
| # | Status | Flag or event | Public docs |
|---|---|---|---|
| P1 | yes | -p / --print runs one query and exits | CLI reference (--print) |
| P2 | yes | Prompt on stdin (piped into -p), not only argv | CLI reference (piped content) |
| P3 | yes | --output-format stream-json --verbose; stream ends with a result | CLI reference (--output-format) |
| P4 | yes | Print mode exits; stream result reports success or error | CLI reference |
| P5 | yes | --permission-mode acceptEdits (edit) and dontAsk (read-only / interview) plus --allowedTools / --disallowedTools. The factory does not pass --dangerously-skip-permissions. | CLI reference (--permission-mode) |
| P6 | yes | --model | CLI reference (--model) |
| P7 | yes | claude auth login, or env the CLI already documents; claude auth status exits 1 when not signed in. The factory never stores credentials. | CLI reference (claude auth) |
| P8 | yes | Final result includes input, output, and cache tokens | CLI reference (--output-format) |
| P9 | yes | --resume / -r by session id; --fork-session exists. The first call of an attempt stays fresh (C18). Extract resumes that session (C24). | CLI reference (--resume) |
| P10 | yes | --mcp-config, --strict-mcp-config, --plugin-dir, --setting-sources; claude mcp lists servers | CLI reference |
| P11 | yes | State under ~/.claude (claude purge). The factory sandbox wraps the process (capability sandbox). | CLI reference (claude purge) |
| P12 | yes | --help, --version / -v. Probe reads those with no model call. | CLI reference |
| P13 | yes | Local -p process. The factory stops the process group (Unix) or Job Object (Windows) (C12, C13). | CLI reference |
| P14 | yes | Default -p is local. --cloud is opt-in, not default. | CLI reference (--cloud) |
Verdict: built-in (every must item is yes).
Cursor
Public docs: CLI, headless, parameters, authentication, output format. Setup: Cursor.
| # | Status | Flag or event | Public docs |
|---|---|---|---|
| P1 | yes | -p / --print runs one task and exits | Headless, parameters |
| P2 | yes | Piped stdin is the prompt (the runner writes stdin, then closes it) | Cursor, parameters |
| P3 | yes | --output-format stream-json; stream ends with a result event | Output format |
| P4 | yes | Non-zero exit on failure; result event has is_error; "not signed in" is a clear reject | Output format, Cursor |
| P5 | yes | --mode ask for read-only (plus the git-tree guard) and --force for edit. Interview is not supported; grill stays on Claude Code. Not a skip-all bypass. | CLI (Ask mode), headless (--force) |
| P6 | yes | --model; agent models lists names | Parameters, Cursor |
| P7 | yes | agent login, or CURSOR_API_KEY in the environment kusaw serve starts from. --api-key is refused (visible in the process list). | Authentication, Cursor |
| P8 | partly | Tokens arrive on the final result. Cost is not reported (computed or unknown). | Output format, Cursor |
| P9 | yes | --resume by chat id; agent resume / --continue. The first call of an attempt stays fresh (C18). Extract resumes that session (C24). | CLI (Sessions) |
| P10 | partly | Per-run .cursor/mcp.json and --approve-mcps; agent mcp. Skills are inlined into the prompt, not loaded from a Cursor skills folder. | Using Agent, Cursor |
| P11 | yes | --sandbox disabled when the factory sandbox wraps the step; state under ~/.cursor and .cursor/ | Parameters (--sandbox), Cursor |
| P12 | yes | --help, --version. Probe checks identity from those with no model call. | Parameters, Cursor |
| P13 | yes | Local -p process. The factory stops the process group (Unix) or Job Object (Windows) (C12, C13). | Headless |
| P14 | yes | Default -p is local. Cloud Agent handoff is an & prefix, not the default. The prompt must start with a heading so it can never be handed to a cloud agent. | CLI (Cloud Agent handoff), Cursor |
Verdict: built-in (every must item is yes; P8 and P10 are nice).