Skip to content

The Rust executable serves the repository's AI layer to an MCP client over stdio, with protocol frames alone on stdout

majordomus mcp, the Rust executable's command in apps/majordomus-cli/ that an MCP client spawns, reads the .ai/ layer, answers initialize, resources/list, resources/read, tools/list and tools/call over stdin and stdout, and ends when the client closes the pipe. Nothing but JSON-RPC frames is written to stdout; everything else goes to stderr. The first one in a checkout becomes its shared server: it binds the loopback HTTP projection and writes one file, its lease under .ai/local/state/mcp/ (docs/MCP.md); --standalone serves this client alone, with no port and no lease. Every tool is announced with what it changes: most read, and the ones whose registry effect is repository_mutation write the repository and are named in the initialize instructions.

declared statusdeclared status: guaranteed Declared deterministic and blocking, implemented, and naming the behavioural test that is to prove it. Whether a recorded run supports it is the evidence verdict, shown beside it.

recorded evidencerecorded evidence: not run Declared guaranteed, and not supported by a recorded run: the test is named, and no passing run of the current inputs is recorded. how evidence is recorded

One process per client, alive as long as its pipe; diagnostics go to stderr; a session leaves the repository byte-identical. The crate's own suite, tests/mcp_stdio.rs, holds the same frames to the same rules.

What it means

majordomus mcp, the Rust executable's command in apps/majordomus-cli/ that an MCP client spawns, reads the .ai/ layer, answers initialize, resources/list, resources/read, tools/list and tools/call over stdin and stdout, and ends when the client closes the pipe. Nothing but JSON-RPC frames is written to stdout; everything else goes to stderr. The first one in a checkout becomes its shared server: it binds the loopback HTTP projection and writes one file, its lease under .ai/local/state/mcp/ (docs/MCP.md); --standalone serves this client alone, with no port and no lease. Every tool is announced with what it changes: most read, and the ones whose registry effect is repository_mutation write the repository and are named in the initialize instructions.

How it works

src/repository.rs finds the root, src/index.rs builds the in-memory index, src/mcp/surface.rs projects it into resources and tools, src/mcp/protocol.rs speaks the protocol over that surface, and src/mcp/stdio.rs moves one frame per line. Logging goes through tracing to stderr under MAJORDOMUS_LOG. There is no MCP library and no async runtime: the subset of the protocol a server needs is small enough to keep in one file behind the index.

How to see it

cargo build --manifest-path apps/majordomus-cli/Cargo.toml
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"you","version":"0"}}}' \
              '{"jsonrpc":"2.0","id":2,"method":"resources/read","params":{"uri":"majordomus://prompt/continue"}}' \
  | apps/majordomus-cli/target/debug/majordomus mcp 2>/dev/null

Two lines come back, both JSON; the second carries .ai/repo/prompts/continue.md as read. Add MAJORDOMUS_LOG=debug and the diagnostics appear on stderr while stdout stays the same two lines.

What it does not cover

One transport, stdio; no subscriptions, no list-change notifications, no prompts capability (the repository's prompt assets render {{CONTEXT}} from checkout-local state the shell tool owns, so they are served as resources, unrendered and labelled so). Interoperability is proven against real protocol frames, not against every client.

Why it exists

Tools that speak MCP cannot read a shell tool. The layer is the repository's, readable without any tool, and this is the reader for clients that read through a protocol, kept subordinate to the shell tool that validates and enforces the layer. test/cases/72_rust_mcp.sh speaks to the built binary inside a repository the shell tool's own init wrote; apps/majordomus-cli/tests/mcp_stdio.rs holds every frame to the rules above, including that a session mutates nothing.

Detail rendered from docs/claims/mcp-stdio-surface.md.

From the statement to the proof

  1. 1 · the public statement

    The Rust executable serves the repository's AI layer to an MCP client over stdio, with protocol frames alone on stdout

    Made on Interfaces.

  2. 2 · the canonical claim

    mcp-stdio-surfacedeclared status: guaranteed in docs/CLAIMS.yaml

    Defined in read it on this site · docs/MCP.md

  3. 3 · the implementation

    apps/majordomus-cli/src/mcp/protocol.rs

  4. 4 · the test and the scenarios

    Test: test/cases/72_rust_mcp.sh

    Executed in Serve the repository's AI layer to every AI client through one shared server, Find an object of the layer without reading everything.

  5. 5 · the recorded runs

    recorded evidence: not run how evidence is recorded

Verify it yourself

The test runs in a disposable temporary repository and asserts the behaviour, not a string in the source.

from a clone of the repository
bash test/run.sh 72_rust_mcp

Searches the titles and descriptions of every page this site publishes.