Serve a cassette (mcptest serve)
mcptest serve is the reverse of mcptest record: it takes a recorded server cassette and answers a live MCP client from it, as if it were the real server. Point any client (Claude Code, Cursor, mcp-inspector) at the tape and it completes the handshake, lists tools, and calls them, getting the recorded responses back. No backend runs. No network. The recording is the server.
This is the offline twin of recording. Record a real server once, then replay that capture to a client (or a teammate, or CI) forever, deterministically.
How it works
MCP client <-- stdio or HTTP --> mcptest serve --> cassette file
Each request the client sends is matched by content against the recorded exchanges (method plus params; the initialize handshake matches on method alone, so a tape survives a client upgrade). The first not-yet-consumed recording that matches wins, its id is rewritten to the live request's id, and it is sent back. Notifications get no response. A request with no matching recording returns a JSON-RPC error rather than hanging, so one unrecorded call fails only itself.
Because the client runs its own initialize, the tape must contain an initialize exchange. mcptest serve warns on startup when it does not, the same caveat mcptest distill reports.
Serving over stdio
The default front speaks newline-delimited JSON-RPC on its own stdin/stdout, exactly like a real stdio MCP server:
mcptest serve --cassette cassettes/session.json
In a client config (.mcp.json, .cursor/mcp.json), point the server entry at the replay. mcptest serve prints this snippet, with your path filled in and rendered absolute, on startup:
{
"mcpServers": {
"replayed": {
"command": "mcptest",
"args": [
"serve",
"--cassette", "/home/you/project/cassettes/session.json"
]
}
}
}
Everything human-facing (the banner, the snippet) goes to stderr; stdout carries only JSON-RPC frames, so the client never sees a stray banner where an envelope should be.
Serving over HTTP
--front http stands up a streamable-HTTP server the client POSTs to, with an SSE stream for any server-initiated message:
mcptest serve --cassette cassettes/session.json --front http --port 8765
--port 0 binds an ephemeral port and prints the one it chose. The banner prints a mcpServers entry keyed on url for clients that dial HTTP. This is the same front mcptest record --front http and mcptest mock --front http serve.
Matching strategy
--strategy controls how strict the request match is, mirroring mcptest verify:
semantic(default): normalizes volatile values (timestamps, UUIDs, and similar) before comparing, so a tape recorded yesterday still matches today.strict: byte-exact JSON.structural: shape only.
Turning a tape into an editable mock
A cassette replays verbatim: useful, but frozen. When you want to edit the canned responses (add a field, change a value, trim the catalog), distill the tape into a mock manifest instead:
mcptest distill cassettes/session.json --as-mock -o mock.yaml
mcptest validate --config mock.yaml
mcptest mock --tools-from mock.yaml --front http --port 8765
--as-mock maps each distinct recorded tool to one mock_server.tools[] entry whose response is the recorded result, lifting description and the input/output schemas from a recorded tools/list when present. Duplicate calls of the same tool collapse into one entry. The result is a plain YAML file you own and edit; mcptest mock serves it over stdio or HTTP. Every value is lifted from real traffic after secret redaction, so review before sharing.
Choosing serve or mock
mcptest serve --cassette: replay a recording faithfully, unedited. The fastest path from a capture to a runnable stand-in.mcptest distill --as-mockthenmcptest mock: when you want to edit the responses, hand-author new tools alongside the recorded ones, or keep a small reviewable fixture in the repo instead of a raw tape.
References
record-to-test.md: capture a real server into a cassette in the first place.mcptest-mock.md: the manifest format--as-mockemits andmcptest mockserves.cassettes.md: the cassette format,cassette:server sources, and distillation into a suite.