How to read agent traces in Claude Code and Cursor
mcpd is also an MCP server. Add it to Claude Code or Cursor and your coding agent can find the run that failed, read its steps and prompts, and check whether it is one run or a pattern, while it works on the fix.
Last updated
When you finish, you can ask your coding agent "why did the last support run
fail?" and it answers from your traces. You need the mcpd binary
on the machine where Claude Code or Cursor runs (see
Install), a daemon that holds your
runs, and a read key for it when the daemon has keys set.
1. Make a read key for the agent
mcpd mcp is a client of a running daemon. It opens no data
itself, and every tool call is a request to the daemon's query API with the
key you give it. What the key reaches is what the agent reaches.
keys on the daemon
# A read key for the coding agent, and an admin key so the read key cannot delete.
mcpd --ingest-key "$INGEST_KEY" --read-key "$AGENT_READ_KEY" --admin-key "$ADMIN_KEY"
On a local daemon with no keys set, skip this step and leave
MCPD_API_KEY out below. The endpoint defaults to
http://127.0.0.1:4317.
2. Add mcpd to Claude Code
Claude Code starts the server as a child process when a session needs it. The
-e options set its environment, and everything after
-- is the command.
Claude Code
claude mcp add mcpd \
-e MCPD_ENDPOINT=https://mcpd.example.com \
-e MCPD_API_KEY=YOUR_READ_KEY \
-- mcpd mcp
The server is added for you in this project. Add -s project to
write it to .mcp.json for the whole team, and keep the key out of
that file. Run /mcp inside Claude Code to see that the server is
connected.
3. Add mcpd to Cursor
Put the server in .cursor/mcp.json in the project, or in
~/.cursor/mcp.json for every project. Cursor asks before it runs
an MCP tool, unless you change that.
.cursor/mcp.json
{
"mcpServers": {
"mcpd": {
"command": "mcpd",
"args": ["mcp"],
"env": {
"MCPD_ENDPOINT": "https://mcpd.example.com",
"MCPD_API_KEY": "YOUR_READ_KEY"
}
}
}
} 4. Ask about your runs
The server has three tools. The agent picks them; you ask in plain words.
| Tool | What it answers | Arguments it takes |
|---|---|---|
find_runs | Which runs: one line each with id, age, status, duration, cost and steps. Last 24 hours by default. | status, q, name, model, environment, session_id, user_id, tags, since, until, min_duration_ms, sort, limit |
get_run | What happened in one run: the waterfall, the failing step and its error, the prompts and answers, the logs and scores. | trace_id, payloads (all, errors or none), max_payload_chars |
run_stats | One run or a pattern: runs, failures, latency, tokens and cost over a window. | since, until, group_by (model, name, status, user_id and more) |
Questions that work well:
- "Find the support_agent runs that failed in the last hour and tell me which step failed."
- "Open the slowest run today and show me the prompt the model got."
- "Is the error in this run common? Compare failures by model over the last day."
Every tool takes project too, and uses the daemon's default
project when the agent leaves it out. Results come back as text, not JSON, so
a run with forty steps costs the agent a few hundred tokens of context.
Payloads are cut at 1,200 characters a step and 20,000 a run.
5. Check the server from a terminal
The server speaks JSON-RPC over standard input and output, so you can call a tool without an agent. This asks for the runs of the last hour:
call find_runs by hand
printf '%s\n' \
'{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"check","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"find_runs","arguments":{"since":"-1h"}}}' \
| MCPD_ENDPOINT=https://mcpd.example.com MCPD_API_KEY=YOUR_READ_KEY mcpd mcp \
| tail -n 1 | jq -r '.result.content[0].text' 5 runs in project "default", matching since=-1h.Ages are relative to 2026-10-30 06:16:13Z.trace_id age status duration cost steps failed name22513f03006692c0234fdc02617f4484 11m ok 33ms $0.000768 4 0 ai.generateText support-agentb88940b91edb3192054ba6f41db7f9ce 11m ok 56ms $0.000768 4 0 invoke_agent support_agent7a5421ccc21bc12f857691a42b77bbb1 11m error 55ms $0.000768 5 1 invoke_agent support_agentb296ba7068b0efa2cdc2d42f64be1d83 12m ok 35ms $0.000768 4 0 ai.generateText support-agent25f87801d1208c1d8085bd97ac98245e 17m ok 20ms $0.000384 7 0 LangGraphPass a trace_id to get_run for the waterfall, the failing step and the prompts. Troubleshooting
| What the agent reports | Why, and what to do |
|---|---|
Cannot reach the mcpd daemon at ... | The daemon is not running or MCPD_ENDPOINT names the wrong address. The address must work from the machine the editor runs on. |
The daemon refused the credential | MCPD_API_KEY is missing or is not one of the daemon's read keys. |
That key is not allowed to read this | The key is scoped to another project. Ask about a project the key covers. |
| The server does not start | The editor cannot find mcpd on its PATH. Put the full path to the binary in the command. |
Related guides
- How to log OpenAI API calls with tokens and cost
- How to trace LangChain and LangGraph agents
- How to collect thumbs-up and thumbs-down feedback on LLM answers
mcpd is free and open source. Start free at mcpd.sh , or run the daemon yourself.