Live mode#
Watch a Claude / MCP-client session unfold in real time at
mcpreplay.dev. Live mode pairs the mcp-tape --serve
websocket on your machine with a ?live=… URL in the browser; nothing leaves
your machine, no public host is involved.
┌─────────────┐ stdio ┌──────────┐ stdio ┌────────────┐
│ Claude Code │ ──────▶ │ mcp-tape │ ─────▶ │ MCP server │
└─────────────┘ └──────────┘ └────────────┘
│
│ ws://127.0.0.1:7777 (snapshot + appends)
▼
┌─────────────────┐
│ mcpreplay.dev │
│ ?live=ws://… │
└─────────────────┘
The websocket lives on 127.0.0.1 only: no TLS, no auth, no remote-access
path. mcp-replay refuses to connect to any host other than localhost /
127.0.0.1.
Set it up#
1. Make sure mcp-tape is recent enough. Live mode needs the --serve
flag and a couple of subsequent fixes (port fallback, --no-file,
per-OS Claude Desktop paths):
npm i -g mcp-tape
mcp-tape --version
2. Wrap with --serve. The simplest way: run a single server through the
proxy with --serve:
mcp-tape --serve -- npx -y @modelcontextprotocol/server-filesystem /home/me
This prints something like:
mcp-tape: live mode on ws://127.0.0.1:7777/ (open https://mcpreplay.dev/?live=ws://127.0.0.1:7777)
mcp-tape: tracing to ./mcp-traces/2026-05-15T01-20-00-000Z-server-filesystem.jsonl
Open the printed URL. The page connects, hydrates from the snapshot of everything-so-far, and starts streaming each new JSON-RPC frame as it lands.
3. (Optional) Enable live mode for every wrapped server. When you ran
mcp-tape install, each server got mcp-tape as its launch wrapper. To make
all of them stream live, set the env var your client passes to the wrapper:
# bash / zsh
export MCP_TAPE_SERVE=7777
# Windows / PowerShell
$env:MCP_TAPE_SERVE = 7777
Then restart your MCP client. Every server it launches will broadcast on its own port. See Port conflicts below for how mcp-tape picks a free port when 7777 is taken.
--serve vs MCP_TAPE_SERVE#
| Setting | What it does | When to reach for it |
|---|---|---|
--serve [PORT] | Enables live mode for the current invocation only. PORT is optional; omitted = 7777. | One-off debugging from the command line. |
MCP_TAPE_SERVE=PORT | Default port for every invocation that doesn't pass --serve explicitly. | All servers in an installed config. |
The CLI flag wins over the env var when both are set.
Port conflicts#
If port 7777 (or whatever you asked for) is already in use, mcp-tape does not fail. It scans a short range above the requested port, then falls back to an OS-assigned free port if none of those work. The stderr line tells you which port it actually bound:
mcp-tape: port 7777 was unavailable, bound 7778 instead
mcp-tape: live mode on ws://127.0.0.1:7778/ (open https://mcpreplay.dev/?live=ws://127.0.0.1:7778)
The ?live= URL on the second line is the one to open. (The first one is
just an informational warning.) If you launched several servers through their
wrapped configs, each one will print its own URL on its own port.
--no-file: serve-only mode#
For short debug sessions where you don't want a .jsonl file to clean up
afterwards, add --no-file:
mcp-tape --serve --no-file -- node my-server.js
This streams every frame to the websocket but writes nothing to disk: useful when you're sharing a tab with someone over screen-share and just want a clean run with no leftover traces.
--no-file requires --serve; on its own it has no other output path. If
the websocket fails to bind entirely (extremely rare; usually means every
fallback port refused), mcp-tape automatically reverts to writing a .jsonl
so the session isn't silently lost.
Per-OS Claude Desktop config paths#
mcp-tape install walks every detected MCP-client config and wraps every
entry. Claude Desktop's config lives in a different directory on each OS:
| OS | Location |
|---|---|
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
(Older mcp-tape installs on Linux used ~/.config/claude/ with lowercase
claude; we still detect that one for back-compat.)
mcp-tape install does the right thing on every platform automatically, with no
arguments needed. mcp-tape install --dry-run previews what it would do.
Troubleshooting#
Connection chip stays on "connecting…" or flips to "disconnected".
- Confirm mcp-tape is actually running: the stderr banner with
live mode on ws://127.0.0.1:<port> should be visible.
- Confirm the URL bar matches the port from that banner. (Port fallback may
have moved it.)
- Check that nothing is blocking loopback websockets (security software,
strict firewall rules). mcp-replay only ever talks to 127.0.0.1.
- Reload the page. The loader includes an auto-reconnect with
?since=,
but a hard reload resets every state machine cleanly.
"Refused to connect to …" / "Couldn't connect to live mode."
Live mode only accepts ws://127.0.0.1:<port> or ws://localhost:<port>.
This is intentional: there's no auth, so we won't connect to anything else.
The error panel also shows the live-mode setup checklist below the message.
Frames don't appear, but the chip says "live".
The session may not have produced any JSON-RPC yet. Wait for your client to
actually call a tool, or check the .jsonl on disk to confirm mcp-tape is
seeing frames.
The chip shows "N dropped".
The browser fell behind the server, or the server's ring buffer evicted frames before the page could resume. The session continues; reload to get a fresh snapshot of everything still in memory.
"port 7777 was unavailable, bound NNNN instead" appears every run.
A stale mcp-tape (probably from a crashed Claude session) is still holding the port. Find and kill it, or just open the URL it prints. Both work.