Skip to content

Fleet MCP transport

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.

There are two endpoints, and only one of them an MCP client can drive.

EndpointDialectUse it when
POST https://petrova.host/mcpStreamable 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/rpcLegacy: 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.

POST https://petrova.host/mcp
authorization: Bearer <token>
content-type: application/json

Handshake against the spec-compliant endpoint:

Terminal window
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:

Terminal window
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:

Terminal window
cd host && npm run build && npx petrova-host --transport stdio

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.

42 tools, federating PETROVA + KAHN + EVA + GRACE under one namespace. 17 of them mutate.

ToolDescription
petrova.contextFederated read for one consumer slug.
petrova.registry.queryFilter the fleet registry.
petrova.registry.getGet a single registry row by slug.
petrova.state.getGet observed state for a slug.
petrova.governance.phaseGet the current phase for a slug.
petrova.governance.auditMR-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.searchFull-text search decision docs across the fleet. Empty query lists the latest decisions.
petrova.decisions.getGet a single decision doc with full body by id (filename without .md).
petrova.transitions.recentRecent phase transitions for a slug (derived from decision-doc history).
petrova.prompts.listList EVA prompts (metadata only).
petrova.prompts.getGet a single EVA prompt with body.
petrova.routing.resolveResolve a cross-namespace URI via GRACE.
petrova.acts.recentRecent petrova-act PRs across the registered fleet (read-only audit).
petrova.acts.getGet a single petrova-act PR by slug and PR number.
petrova.phases.listFleet-wide phase grid: closed/open/not-started status for every phase per repo. Pass slug to scope to one repo.
petrova.sweeps.statusState-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_runLast state-sweep workflow run: status, conclusion, started/completed timestamps. Read-only.
petrova.ralph.runsLive 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.runLive read of a single RALPH run by id (ralph serve /runs/{run_id}). Same degrade-never-throw contract as petrova.ralph.runs.
petrova.kahn.runsLive 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.runLive 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.councilsLive 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.graphLive 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.fingerprintsLive 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.statusOne-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.
ToolDescription
petrova.sweeps.triggerTrigger the state-sweep GitHub workflow (workflow_dispatch). Rate-limited by a server-side cooldown. Mutating.
petrova.act.open_decisionOpen a dated decision doc as a PR.
petrova.act.start_phaseOpen a new phase via decision doc + milestones PR.
petrova.act.close_phaseClose a phase with verification round + sign-off.
petrova.act.update_milestoneAdd or transition a milestone in MILESTONES.md.
petrova.act.verify_roundEmit a verification-round friction doc.
petrova.act.request_reviewOpen a PR with explicit grounding for human review.
petrova.act.request_merge_when_greenOpen a PR with auto-merge enabled (profile-gated).
petrova.act.propose_fixCompose a fix PR bound to a prior diagnosis.
petrova.act.petrova_install_playbookStep 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_onboardInitialise 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_baselineRatify 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-baseline-v.md in petrova-codes.
petrova.act.wire_integrationFlip 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_driftReconcile 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_consumerRegister 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_editGeneric 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_consumerRemove 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.

Service descriptor: GET https://petrova.host/rpc. Console and fleet verdict: https://petrova.host/.