Skip to content

zordon mcp

zordon mcp serves a Model Context Protocol server over stdio. It is an additional surface on the same CLI, not a replacement: zordon stays a CLI, and the MCP server exposes that CLI to agents. Run it from a project directory (one containing an Alphasfile, or nested under one); it resolves the same federation chain the CLI would.

Transport

The server speaks newline-delimited JSON-RPC 2.0 over stdin/stdout (the standard local MCP transport). Diagnostics go to stderr; stdout carries only the protocol. Launch it the way an MCP client launches any local server — as a subprocess whose stdin/stdout it owns.

Discoverability

The agent decides when to use these tools from three signals (it is the model's judgement — there is no hard routing):

  • Server instructions — at initialize the server returns an instructions string (MCP's server-purpose field) that the client injects into the agent's context: what zordon is and when to reach for it, scoped so it is ignored where there is no Alphasfile.
  • Per-tool descriptions — each tool carries a description (a command's help; a provision's resolved cmd, flags, and the no-kill-alpha note).
  • Project context — for Claude Code, a line in CLAUDE.md/AGENTS.md ("this project's stack is managed by zordon — use the zordon MCP tools") is the strongest nudge.

Tool families

The server registers two kinds of tools. Call tools/list to discover them.

Command tools

One tool per zordon subcommand, generated by introspecting the same command tree the CLI uses — so the tool list can never drift from the CLI. Every subcommand is exposed except mcp itself.

Field Value
Name the subcommand name (start, status, stop, clean, sudo, workspace, plan, get)
Input { "args": ["<flag-or-arg>", ...] } — flags and positional arguments, exactly as on the CLI; pass ["-h"] for the full flag list
Output the command's combined stdout+stderr, captured into the tool result

The command runs in-process against capture buffers; its output never reaches the JSON-RPC stdout channel. The result's isError is set when the command exits non-zero.

Provision tools

One tool per provision found in the resolved chain (across every federation level).

Field Value
Name provision__<toolchain>_<service>__<step>, sanitized to ^[A-Za-z0-9_-]{1,64}$ and de-duplicated across levels
Description the provision's description attribute (if set in the Alphasfile), followed by the resolved cmd, env keys, and the no-kill-alpha note
Input { "env": { "KEY": "value", ... } } — overrides overlaid on the provision's own env (highest precedence)
Output the provision's streamed shell output; isError is set on failure

Give a provision a human-readable summary with the optional description attribute; it leads the generated tool description.

Typed arguments

A provision declares typed inputs with argument "<name>" { ... } blocks. Each becomes a named, typed field on the MCP tool's input schema, so the agent sees exactly what to pass:

provision "seed-data" {
  description = "Write the seed marker file from the `key` argument"
  after       = never

  argument "key" {
    type        = "string"   # string | number | bool (default string)
    required    = true
    description = "value written to the seed marker file"
  }

  cmd = "echo ${self.runtime.provision.seed-data.arguments.key} > ${self.vars.seed}"
}
argument field Meaning
type string, number, or bool (default string); drives the schema field type and value coercion
required listed in the schema's required; a missing value at invoke is an error
default a concrete value (resolved at eval) used when the caller omits the argument
description the schema field's description

Reference an argument in check/cmd/verify by its full path self.runtime.provision.<name>.arguments.<arg>. At configure each such reference resolves to a placeholder; alpha substitutes the supplied value at invoke. Rules (enforced at configure): a provision with arguments must be latent (after = never); it may not be a cmd-ref target; and it may reference only its own arguments. The generic env field stays available on every provision tool for undeclared overrides.

Invoking a provision tool dials that level's running alpha and runs the provision inside it (see OpInvoke). If no alpha is running for that level, the tool returns an error result directing you to run zordon start.

Provisions are listed whether or not alpha is running (so an agent can discover them, then start, then invoke), but invoking one requires a running alpha.

OpInvoke

A provision tool call maps to a single control-socket request:

{"op": "invoke", "invoke": {"provision": "service.<tc>.<svc>.runtime.provision.<name>", "args": {"key": "value"}, "env": {"KEY": "value"}}}

provision is the canonical provision id (the same identity alpha keys provisions by). args are validated against the provision's declared argument blocks and substituted into the snippets' placeholders; env is a free-form overlay. alpha then runs the provision via its normal runProvision path — reusing the parent service's env and working directory, the toolchain, and the process-group / shutdown handling. The response is the same streamed Event sequence as configure: log events for shell output, terminated by done (success) or error (failure).

Invariant: a failed invoke never kills alpha

An on-demand invoke runs with failfast = false. A provision that exits non-zero reaches its failure terminal and the tool reports an error, but alpha keeps running — unlike a bringup-time provision under the default --failfast, which shuts the stack down. An invoke also runs immediately (no after wait): the parent service is assumed already up because alpha is running.

Requirements and scope

  • The server resolves the chain from its working directory; launch it inside the project.
  • Provision invocation requires a running alpha for that level; the server does not auto-start one.
  • Re-invoking an auto-run provision is allowed (re-run a migration or smoke test on demand); idempotent provisions short-circuit via their check.