Fleet MCP transport
Fleet MCP — the transport contract
Section titled “Fleet MCP — the transport contract”The guiding line between the fleet and what threatens it.
petrova.host is the federated MCP server for the petrova-codes constellation — read across registry, governance state, decisions and prompts, and a small, explicitly-flagged set of verbs that write. Named for the line that named the threat.
This page is the transport contract. It moved here from the petrova.host apex,
which is now the console (see
docs/decisions/2026-08-06-petrova-host-apex-re-root.md): good copy, wrong
room. An operator opening petrova.host wants the fleet verdict, not a curl
recipe.
Two dialects, one registry
Section titled “Two dialects, one registry”There are two endpoints, and only one of them an MCP client can drive.
| Endpoint | Dialect | Use it when |
|---|---|---|
POST https://petrova.host/mcp | Streamable HTTP MCP, JSON response mode. initialize, tools/list with real inputSchemas, tools/call. | You are an MCP client — Claude Code, pebble, anything speaking the spec. |
POST https://petrova.host/rpc | Legacy: the tool name is the JSON-RPC method. No initialize, no tools/call. | You are the petrova CLI or the dashboard’s same-origin RPC. Kept for those; an MCP client cannot drive it. |
/rpc answers -32601 to an initialize — that gap is exactly what /mcp
closes (DEC 2026-07-14).
Both dialects derive every tool from one definition in host/src/registry.ts:
name, description, schema and handler in a single object. No transport keeps its
own map, and neither does this page — the instrument list below is generated
from that registry at docs-build time.
Endpoint
Section titled “Endpoint”POST https://petrova.host/mcpauthorization: Bearer <token>content-type: application/jsonHandshake against the spec-compliant endpoint:
curl -X POST https://petrova.host/mcp \ -H "authorization: Bearer $PETROVA_HOST_BEARER" \ -H "content-type: application/json" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05"}}'List the tools with their schemas:
curl -X POST https://petrova.host/mcp \ -H "authorization: Bearer $PETROVA_HOST_BEARER" \ -H "content-type: application/json" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'Run it locally over stdio instead:
cd host && npm run build && npx petrova-host --transport stdioReads and writes
Section titled “Reads and writes”Tools carry a mutating flag, and that flag — not the name — is what a
read-only surface must filter on. petrova.sweeps.trigger fires a
workflow_dispatch and carries no act. prefix, so a name-prefix filter admits
a write.
Instruments
Section titled “Instruments”42 tools, federating PETROVA + KAHN + EVA + GRACE under one namespace. 17 of them mutate.
Reads (25)
Section titled “Reads (25)”| Tool | Description |
|---|---|
petrova.context | Federated read for one consumer slug. |
petrova.registry.query | Filter the fleet registry. |
petrova.registry.get | Get a single registry row by slug. |
petrova.state.get | Get observed state for a slug. |
petrova.governance.phase | Get the current phase for a slug. |
petrova.governance.audit | MR-N audit across the registered fleet (MR-1, MR-3, MR-4, MR-5, MR-7, MR-8, MR-10, MR-12, MR-13). Pass slug to scope to one repo. |
petrova.decisions.search | Full-text search decision docs across the fleet. Empty query lists the latest decisions. |
petrova.decisions.get | Get a single decision doc with full body by id (filename without .md). |
petrova.transitions.recent | Recent phase transitions for a slug (derived from decision-doc history). |
petrova.prompts.list | List EVA prompts (metadata only). |
petrova.prompts.get | Get a single EVA prompt with body. |
petrova.routing.resolve | Resolve a cross-namespace URI via GRACE. |
petrova.acts.recent | Recent petrova-act PRs across the registered fleet (read-only audit). |
petrova.acts.get | Get a single petrova-act PR by slug and PR number. |
petrova.phases.list | Fleet-wide phase grid: closed/open/not-started status for every phase per repo. Pass slug to scope to one repo. |
petrova.sweeps.status | State-file freshness per repo: last_full_sweep timestamp, age in minutes, and per-integration verification age. Pass slug to scope to one repo. |
petrova.sweeps.last_run | Last state-sweep workflow run: status, conclusion, started/completed timestamps. Read-only. |
petrova.ralph.runs | Live read of ROCKY’s RALPH runs (ralph serve /runs). Read-only federation (neverland E8). Returns { ok:true, data } or a { ok:false, degraded:true } envelope when RALPH is unreachable or unconfigured — never throws. |
petrova.ralph.run | Live read of a single RALPH run by id (ralph serve /runs/{run_id}). Same degrade-never-throw contract as petrova.ralph.runs. |
petrova.kahn.runs | Live read of KAHN Scope runs (GET /api/runs). Read-only federation (neverland E7). Optional limit. Returns { ok:true, data } or a { ok:false, degraded:true } envelope when KAHN is unreachable or unconfigured — never throws. |
petrova.kahn.run | Live read of a single KAHN run by id (GET /api/runs/{run_id}) — summary + transitions + graph. Same degrade-never-throw contract as petrova.kahn.runs. |
petrova.stratt.councils | Live read of STRATT’s council catalogue (GET /councils). Read-only federation of STRATT’s law surface (neverland E9). Optional domain filter. Returns { ok:true, data } or a { ok:false, degraded:true } envelope when STRATT is unreachable or unconfigured — never throws. |
petrova.stratt.graph | Live read of STRATT’s full chain DAG (GET /graph) — nodes, edges, topological order over the live published library. Read-only federation (neverland E9). Optional domain/type/workspace filters. Same degrade-never-throw contract. |
petrova.stratt.fingerprints | Live read of STRATT’s fingerprint verification status (GET /fingerprints) — per-unit verified/tampered/error + counts. Read-only federation (neverland E9). Optional workspace. Same degrade-never-throw contract. |
petrova.federation.status | One-call status of the whole neverland reader plane (E7 kahn / E8 ralph / E9 stratt): per-edge live/degraded + item count + reason. Live-derived (degrade-never-throw), the aggregate view the console renders as reader-edge pills. |
Writes (17)
Section titled “Writes (17)”| Tool | Description |
|---|---|
petrova.sweeps.trigger | Trigger the state-sweep GitHub workflow (workflow_dispatch). Rate-limited by a server-side cooldown. Mutating. |
petrova.act.open_decision | Open a dated decision doc as a PR. |
petrova.act.start_phase | Open a new phase via decision doc + milestones PR. |
petrova.act.close_phase | Close a phase with verification round + sign-off. |
petrova.act.update_milestone | Add or transition a milestone in MILESTONES.md. |
petrova.act.verify_round | Emit a verification-round friction doc. |
petrova.act.request_review | Open a PR with explicit grounding for human review. |
petrova.act.request_merge_when_green | Open a PR with auto-merge enabled (profile-gated). |
petrova.act.propose_fix | Compose a fix PR bound to a prior diagnosis. |
petrova.act.petrova_install_playbook | Step 0 of consumer onboarding. Deposits the petrova playbook (META-RULES.md, 00-bootstrap.md, partials, progress schema) into the target repo’s .petrova/playbook/ so bootstrap prompts can resolve {{...}} references against literal local paths. Refuses if playbook already present (set overwrite: true to re-sync). |
petrova.act.petrova_onboard | Initialise a registered repo’s mechanical petrova floor: write .petrova/contract.yaml (all integrations pending by default) and install .github/workflows/docs-invariants.yml if missing. Narrow compliance verb — does not generate CLAUDE.md / MILESTONES.md / AGENTS.xml / north-star. |
petrova.act.declare_baseline | Ratify a new petrova baseline version. Pre-flight runs full server-side audit and refuses to proceed if any MR check is fail. Emits docs/decisions/ |
petrova.act.wire_integration | Flip a registered consumer repo’s .petrova/contract.yaml integration block from pending → wired with a validated evidence object. Generic over ares/traceo/crumb/rocky/eva. Refuses re-wires; requires a ratifying decision doc. |
petrova.act.petrova_act_reconcile_drift | Reconcile a drifted consumer registry entry. Bumps registry.yaml > repos[slug].contract_sha to match the consumer’s current .petrova/contract.yaml SHA via a PR against petrova-codes:main. Co-emits an ADR. NOT auto-merged (MR-12). target_repo must be petrova-codes. |
petrova.act.petrova_act_register_consumer | Register a new consumer repo in registry.yaml. Reads the repo’s .petrova/contract.yaml on its default branch, derives all fields, opens a PR against petrova-codes:main, and co-emits an ADR. NOT auto-merged (MR-12). target_repo must be petrova-codes. |
petrova.act.petrova_act_registry_edit | Generic registry-mutation substrate. Applies a list of set/add/remove ops scoped to repos[slug].*, opens a PR against petrova-codes:main with the diff plus a co-emitted ADR carrying the rationale. NOT auto-merged (MR-12). target_repo must be petrova-codes. |
petrova.act.petrova_act_deregister_consumer | Remove a consumer entry from registry.yaml. Requires confirm_slug=slug as a fat-finger guard plus a ≥40-char rationale. Refuses to deregister petrova-codes itself. Opens a PR against petrova-codes:main co-emitting an ADR. NOT auto-merged (MR-12). target_repo must be petrova-codes. |
Discovery
Section titled “Discovery”Service descriptor: GET https://petrova.host/rpc. Console and fleet verdict:
https://petrova.host/.