# mcp-replay trace format (v1)

A trace is a newline-delimited JSON file (`.jsonl`) that records the JSON-RPC traffic between an MCP client and a single MCP server. One JSON object per line. UTF-8 encoded.

The format is open and stable. Any producer can emit traces in this shape; [mcp-tape](https://github.com/craigm26/mcp-tape) is the reference producer.

## Line types

Every line is one of three shapes:

### `meta` — first line

```json
{
  "v": 1,
  "type": "meta",
  "startedAt": "2026-05-12T23:00:00.000Z",
  "label": "filesystem",
  "command": ["npx", "-y", "@modelcontextprotocol/server-filesystem", "/home/me"],
  "mcpTapVersion": "0.1.0-alpha.1"
}
```

| Field | Required | Description |
|---|---|---|
| `v` | yes | Format version. Currently `1`. |
| `type` | yes | Literal `"meta"`. |
| `startedAt` | yes | ISO-8601 UTC timestamp with millisecond precision. |
| `label` | yes | Short human-readable name for the trace (used in UI tabs). |
| `command` | yes | The argv used to launch the server. |
| `mcpTapVersion` | no | Version of the producing tool, if any. |

### Message lines

```json
{"t": "2026-05-12T23:00:00.123Z", "dir": "in", "raw": { ... JSON-RPC payload ... }}
```

| Field | Required | Description |
|---|---|---|
| `t` | yes | ISO-8601 UTC timestamp with millisecond precision. |
| `dir` | yes | `"in"` = client → server. `"out"` = server → client. |
| `raw` | yes | Verbatim JSON-RPC 2.0 message, post-redaction. May be a request, response, or notification. |

The `raw` field contains the unmodified JSON-RPC envelope. Consumers extract `method` / `id` / `params` / `result` / `error` from there.

### `end` — last line

```json
{
  "t": "2026-05-12T23:00:30.000Z",
  "type": "end",
  "exitCode": 0,
  "durationMs": 30000
}
```

| Field | Required | Description |
|---|---|---|
| `t` | yes | ISO-8601 UTC timestamp at which the proxy closed. |
| `type` | yes | Literal `"end"`. |
| `exitCode` | yes | Child process exit code. `0` is success. |
| `durationMs` | yes | Milliseconds between the `meta.startedAt` and this line. |

## Ordering and timing

- Lines appear in the order the proxy observed them on its pipes. This is approximately wall-clock chronological but is not guaranteed to be strictly monotonic across the two pipes — `dir:"in"` and `dir:"out"` are interleaved as the proxy read them, not as the server processed them.
- Timestamps are millisecond precision; messages within the same millisecond are extremely rare in practice but theoretically possible.

## Redaction

Producers may redact sensitive substrings in `raw` before writing the line. The replacement marker is implementation-defined; mcp-tape uses the literal string `"[REDACTED]"`. Consumers MUST NOT assume `raw` round-trips bit-for-bit to what was on the wire.

The `meta.command` may include arguments that were on the original process command line. Producers should treat command-line redaction the same way as message redaction.

## Multi-server traces

This format describes **one server per file**. To represent a multi-server session, write one file per server and merge by timestamp in the renderer. The mcpreplay.dev URL grammar supports this directly:

```
https://mcpreplay.dev/?trace=https://x.example/a.jsonl;https://x.example/b.jsonl
```

## Version policy

Breaking changes increment `v`. Additive fields (e.g., adding optional members to `meta`) do not change `v`. Renderers should ignore unknown fields and fall back gracefully when unfamiliar `type` values appear.
