How another agent drives Cadora over MCP: wire cadora mcp into a client config as a stdio server, bring the server up on loopback, use its five tools (start_run, run_status, get_artifact, review_gate, submit_review) to start a gated AI-DLC run, watch it reach the requirements review gate, read the artifacts, approve, and let it finish — then expose it over HTTP behind a bearer token and TLS, with the same fail-closed review timeout, fail-soft submit, and traversal-safe artifact reads Cadora enforces everywhere.

Cadora · MCP server

Drive the conductor from inside another agent

cadora mcp runs the audit-grade conductor as an MCP server, so another agent — Claude Desktop, Claude Code, the Codex CLI — can start gated runs, watch them, pull artifacts, and service the human-review gate, all over five tools. It is the programmatic control plane, and the review tools are the same fail-closed / fail-soft HITL surface Cadora enforces everywhere — now reachable by an MCP client.

Surface · MCP server (stdio / http)Role · client agent + reviewerTools · five, HITL-native
01

Wire it into your client

A client launches Cadora as a local stdio server. Drop this block into the client's MCP config — the same mcpServers shape Claude Code, Claude Desktop, and the Codex CLI all read. One command, one args list: no port, no network, nothing to expose.

.mcp.json — Claude Code · Claude Desktop · Codex CLI
{ "mcpServers": { "cadora": { "command": "cadora", "args": ["mcp", "--transport", "stdio"] } } }

Or register it in one line — claude mcp add cadora -- cadora mcp --transport stdio. The server needs the optional extra: pip install 'cadora[mcp]'.

02

The server comes up on stdio

The client spawns cadora mcp. The default transport is stdio and the default bind is loopback — the server talks only to the one client that started it, and nothing on the network can reach it. It registers five tools: start a run, watch it, read its artifacts, and service the review gate.

zsh — cadora mcp
$ cadora mcp --transport stdio # run Cadora as an MCP server (HITL review + run control) # transport stdio · bind 127.0.0.1 (loopback) · unauthenticated — local only # tools: start_run · run_status · get_artifact · review_gate · submit_review [cadora] serving over stdio — waiting for the client

stdio is the local path for Claude Desktop / Code and the Codex CLI; --transport http is the remote path (step 05). The default is the safe one.

03

Five tools, and how each fails

The whole control plane is five tools: two drive the run, one reads its output, two service the human gate. Each ships with a guardrail — the review gate fails closed on timeout, submit_review fails soft on bad input, and get_artifact refuses to read outside the run's workspace.

cadora/mcp/server.py — the five @app.tool()s
ToolReturnsFail-mode
start_run {run_id, status: "started"} fail-closed timeout
run_status {running, result_path, error} read-only
review_gate {pending, node_id, docs_dir, artifacts} read-only
submit_review {submitted} | {error} fail-soft
get_artifact <text> | error: … traversal-safe

Signatures and defaults — start_run(…, review_timeout=3600.0), submit_review(run_id, decision, comments="") — are spelled out in the design spec and manual.

04

A gated run, end to end

Here is the round trip. The client calls start_run, polls run_status, and finds the requirements node waiting at its review gate — Cadora hands back the node id and the artifacts it produced. The client reads one with get_artifact, approves, and the run proceeds to design and construction.

MCP tool-call trace — run "checkout-api"
1start_run(topology="examples/aidlc-hitl.topology.yaml", run_id="checkout-api", review_timeout=0)
→ {"run_id": "checkout-api", "status": "started"}
2run_status(run_id="checkout-api")
→ {"running": true, "result_path": null, "error": null}
3review_gate(run_id="checkout-api")
→ {"pending": true, "node_id": "requirements", "docs_dir": "aidlc-docs", "artifacts": ["aidlc-docs/inception/requirements/requirements.md"]}
4get_artifact(run_id="checkout-api", path="aidlc-docs/inception/requirements/requirements.md")
"# Requirements\n\n## FR-1 Place an order …"
5submit_review(run_id="checkout-api", decision="approve")
→ {"submitted": "approve"}
6run_status(run_id="checkout-api")
→ {"running": false, "result_path": "runs/checkout-api/manifest.json", "error": null}

A request_changes instead of approve re-runs the same node with the reviewer's comments (up to three revisions); an abort stops the run. Poll run_status until running is false — result_path points at the run manifest.

05

Expose it over HTTP, safely

To let a remote agent connect, switch to the http transport. It still binds loopback by default; an --auth-token (or CADORA_MCP_TOKEN) requires Authorization: Bearer <token> on every request — and only a present token lets you bind a routable host. A non-loopback bind with no auth is refused unless you pass --i-understand-no-auth. Either way, front it with TLS.

zsh — cadora mcp --transport http
$ export CADORA_MCP_TOKEN=$(openssl rand -hex 32) $ cadora mcp --transport http --host 127.0.0.1 --port 8000 --auth-token "$CADORA_MCP_TOKEN" # endpoint http://127.0.0.1:8000/mcp — every request needs Authorization: Bearer <token> [cadora] serving streamable-http on 127.0.0.1:8000 — bearer auth required # without a token, a routable bind fails closed: $ cadora mcp --transport http --host 0.0.0.0 refusing to bind the MCP server to '0.0.0.0': it has NO authentication and would be reachable from the network. Front it with TLS + auth, or pass --i-understand-no-auth to bind anyway (do this only on a trusted network).

Bearer auth is transport auth, not a substitute for TLS — a wrong or missing token gets 401 {"error":"unauthorized"}; the token itself still crosses the wire in the clear unless a TLS-terminating proxy sits in front.

06

The same audit guarantees, over MCP

The review tools exposed here are the exact HITL surface Cadora enforces on the CLI — no weaker for being driven by a remote agent. Four guardrails travel with the seam, so an MCP client can automate a run without automating away its safety.

safety posture — exposed over MCP
fail-closed / fail-softthe guarantees that ride the seam
Review fails closed. A gate waits review_timeout seconds (default 3600) then aborts the run — a client that walks away can't pin it forever. Pass 0 to wait indefinitely for a genuinely interactive reviewer.
!Submit fails soft. A bad decision, a request_changes with no comments, or a double-submit returns {"error": …} — never a raw traceback through the tool call.
Artifact reads are traversal-safe. A ../-shaped path returns error: path '…' escapes the run workspace and never reads outside the run.
HTTP is gated on auth. Loopback + stdio by default; a routable bind needs --auth-token (bearer) or the explicit --i-understand-no-auth — TLS in front either way.

Same conductor, same gates, same evidence — the MCP server only changes who holds the controls, not what the controls enforce.

The frames above reproduce real cadora mcp behavior — the stdio startup, the client config, the five-tool table, the tool-call round trip, and the HTTP auth guard — rendered as editable HTML rather than raster captures, so you can lift them into Figma or iterate directly. This is Cadora's control plane: another agent drives the audit-grade conductor, and the gates hold on the other side of the seam.