How to test an MCP server: record real sessions, check them in CI
Updated
Unit tests cover your functions, but the thing that breaks agents is the protocol surface: tool schemas, result shapes, error behavior. The most realistic test input is a session a real agent actually produced. Record one, then check every future build against it.
1. Record a real session
Point your agent at the server through RelayOrb and do the task you care about.
Record
relayorb record --name my-server -- node dist/server.js2. Save it as a fixture
Export the session to a JSON file and commit it. Review it first: recordings contain everything the tools returned.
Export
relayorb export my-server -o tests/fixtures/session.json3. Check the server in CI
relayorb check starts the server, replays the handshake, re-sends every recorded call, and diffs each answer. It exits 0 when everything matches, 1 when an answer changed, and 2 if the server couldn't start. Use --ignore-key for fields that change on every run, like timestamps.
GitHub Actions step
- name: MCP regression check
run: |
curl -fsSL https://relayorb.com/install.sh | sh
~/.local/bin/relayorb check tests/fixtures/session.json --ignore-key timestamp -- node dist/server.js4. Test agents without the real server
The reverse also works. relayorb replay pretends to be the server and answers from the recording, so agent tests run offline, without API keys, and get the same answers every time.
Replay
relayorb replay tests/fixtures/session.jsonInstall RelayOrb
Free and open source (Apache-2.0). A single binary for macOS, Linux, and Windows. No account, no cloud, no telemetry.
macOS / Linux
curl -fsSL https://relayorb.com/install.sh | shWindows and other options: GitHub Releases.
FAQ
- What does relayorb check compare?
- The result or error of each recorded request, after dropping the JSON-RPC id and any keys you pass with --ignore-key. Differences are printed as path: old -> new.
- Does it test tools/list too?
- Yes. Every recorded request except initialize and ping is re-sent, so tool schema changes show up as failures.