Seeing what the agent sends
In this lesson we look at what Claude Code sends to the model, in three places. The context meter shows how full the window is while you work. The session record on disk holds every message, tool call and tool result of a session. A request log, which you turn on for one session, holds each request exactly as it was sent. The exercise connects one more tool and follows it through all three.
The concepts course showed a toy harness’s own log of what is in each request: the instructions, the tool descriptions and the history, sent again on every call. The lesson on what the tool list costs estimated what a server’s tool definitions take from that request. Here you look at the real requests of your own agent.
Watch the context meter
Section titled “Watch the context meter”In Claude Code, /context shows what fills the window right now, broken
down by category, with suggestions for what to trim [1].
One of the categories is the tools of Model Context Protocol (MCP)
servers, shown as MCP tools. With tool search on, which is the
default, only the tool names are in the window, and the model loads a
full schema when a task needs it. With ENABLE_TOOL_SEARCH=false every
schema loads at the start [1].
/context answers when you ask. A status line shows a number all the
time. Claude Code runs the status line command after each new reply from
the model, passes it the session data as JSON (JavaScript Object
Notation) on standard input, and shows what it prints
[2]. The command runs on your machine and costs no
tokens. For this lesson the useful fields are these:
context_window.used_percentage, the share of the window in use. It is counted from the input tokens of the last request, and it can be null early in a session.context_window.total_input_tokens, those input tokens, cache reads and cache writes included.transcript_path, the path of the session record on disk.
All three come from the statusline page [2].
statusline.py in site/examples/customizing-agents/seeing-what-the-agent-sends/
prints them on one line, and a dash for a field that is missing or null.
You point Claude Code at it with a statusLine entry in a settings file
[2]:
{ "statusLine": { "type": "command", "command": "python3 /tmp/handbook-inspect/.claude/statusline.py" }}Two status lines
Section titled “Two status lines”Run statusline_demo.py in the fixture directory, and compare with the
output below. The first sample input is from before the first request,
when the share is still null. The second is from after a request.
used_text = "-" if used is None else f"{round(used)}%"total_text = "-" if total is None else f"{total:,} tokens"record = "-" if not transcript else os.path.basename(transcript)return f"context {used_text} | {total_text} | record {record}"context - | 0 tokens | record 2f6c0d1e-5a7b-4c9d-8e3f-1a2b3c4d5e6f.jsonl context 12% | 23,480 tokens | record 2f6c0d1e-5a7b-4c9d-8e3f-1a2b3c4d5e6f.jsonl
Output verified in CI from site/examples/customizing-agents/seeing-what-the-agent-sends/statusline_demo.py.
The meter tells you that the window is filling, and /context tells you
which category fills it. Neither shows the text itself.
Find the session in its record
Section titled “Find the session in its record”Claude Code keeps data under ~/.claude as you work. The transcript of a
session is projects/<project>/<session>.jsonl, and it holds every
message, every tool call and every tool result of that session
[3]. The project directory is named after the
project’s path, with every character other than a letter or a digit
turned into a dash, so /home/user/work/my-repo becomes
-home-user-work-my-repo. On macOS a copy in /tmp is at
/private/tmp, and its directory starts with -private-tmp-.
The status line above gives you the file name, and transcript_path
gives the full path.
Resume and rewind read past sessions from these files, and they are the
place to look when a run went wrong yesterday and you want to see which
file the agent read before it did. They are also plain text and
unencrypted, so whoever can read your files can read them. A .env
file the agent opened, or a key that a command printed, ends up in the
record as well [3]. Claude Code deletes
records older than cleanupPeriodDays, which is 30 days unless you set
it. From version 2.1.288, claude purge <path> deletes a project’s
transcripts, its memory and its lines in the prompt history, after it
shows you the plan [3].
The record holds the session turn by turn. The system prompt and the tool definitions that came with each request aren’t in the page’s list of what it holds. For those you need the request itself.
Which view answers the question?
Section titled “Which view answers the question?”Claude Code offers three views of a session: the context meter (the /context command and a status line), the session record (a transcript in JSON Lines files under ~/.claude/projects/), and a request log that writes each request sent to the model to a local directory while it is turned on.
Match each question to the view that answers it. The request log was off in last week’s and yesterday’s sessions.
Which view is live, which keeps the turns of past sessions, and which holds the parts of a request that are sent every time?
Log the requests on your machine
Section titled “Log the requests on your machine”Claude Code can write every request it sends to a directory on your
machine. It is part of its OpenTelemetry monitoring, the standard it uses
to export usage data [4]. Telemetry is on only with
CLAUDE_CODE_ENABLE_TELEMETRY=1. OTEL_LOG_RAW_API_BODIES=file:<dir>
then writes the full body of each request to <dir>/<uuid>.request.json,
and from version 2.1.274 Claude Code adds one line per successful
response to <dir>/index.jsonl, with the session id, the query_source
that sent the request and the file names [4].
OTEL_METRICS_EXPORTER=none and OTEL_LOGS_EXPORTER=none switch off both
exporters, so the events themselves don’t go to a collector anywhere
[4].
In our run in October 2026, the request files were written with both
exporters set to none. If your organization already collects Claude
Code telemetry, ask its administrators before you turn on the request
log, because their settings may send the events somewhere you don’t
expect.
The monitoring page leaves request bodies out unless you ask for them. The variable’s description warns that a body carries the whole conversation, so it reveals all that the switches for prompt text and tool details would reveal [4]. A request file holds the system prompt, every tool definition and every message so far, with the full text of each file the agent read and any secret a command printed. So keep the log on your own machine, in a directory only your user can read and outside every repository. Turn it on for the session you are investigating, and delete the directory when you have your numbers. Don’t send a request file to an online token counter or paste it into a chat assistant.
Each request lists the tools in its tools field. In the Claude
application programming interface (API), a definition marked
defer_loading is sent to the API but stays out of the model’s context
window until the model searches for that tool
[5]. So /context shows what is in the
window, the request log shows what was sent, and the two can differ. In
our run on 7 October 2026, a claude -p run with tool search on and no
MCP server, the deferred tools were Claude Code’s own built-in tools.
They appeared by name in a message, and the tools field held one
placeholder marked defer_loading. The exercise starts Claude Code
with ENABLE_TOOL_SEARCH=false, which loads every MCP tool definition
upfront [6], so each MCP tool definition in the log is
one the model reads.
A gateway can log requests too. You point ANTHROPIC_BASE_URL at it,
and the gateway can log every request that passes through
[7]. Anthropic doesn’t vouch for gateway products
made by others [7]. A gateway you don’t run
yourself also holds a copy of everything that passes through it, file
contents and secrets included. The log in a local directory never leaves
your machine.
Claude Code also sends requests of its own besides the turns of your
conversation, and the side requests are in the log too. The monitoring
page’s cost counter sorts requests into main, subagent and auxiliary
ones. The query_source in index.jsonl is a different field, with
values such as repl_main_thread for the main conversation and
compact [4].
read_log.py in the fixture directory reads a log directory and prints,
for each request, the estimated tokens of the system prompt, the tools
and the messages, at four characters per token. The mcp tools column
is the tool definitions of MCP servers and their share of the request.
Claude Code names an MCP tool mcp__<server>__<tool>
[8], and the script groups the tools by that
name. The source column is the query_source from index.jsonl. The
script skips a request without tools and leaves out a definition marked
defer_loading, and it prints how many of each it found.
sample_log.py writes a sample log of one side request without tools,
then one prompt that took three model calls, with three built-in tools
and a notes server with five tools, and runs read_log.py on it.
Read the request log
Section titled “Read the request log”Run sample_log.py in the fixture directory, and compare with the
output below.
all_tools = body.get("tools") or []if not all_tools: skipped += 1 continuetools = [tool for tool in all_tools if not tool.get("defer_loading")]estimated tokens, 4 characters per token
request system tools messages total mcp tools source
1 404 926 20 1,350 604 (45%) repl_main_thread
2 404 926 107 1,437 604 (42%) repl_main_thread
3 404 926 235 1,565 604 (39%) repl_main_thread
mcp__notes: 5 tools
skipped 1 request(s) without tools
left out 0 deferred definition(s)Output verified in CI from site/examples/customizing-agents/seeing-what-the-agent-sends/sample_log.py.
The sample is small, so read it for its pattern. The system prompt and
the tools are the same in every request, and only the messages grow. The
notes server’s five definitions are 604 of the 1,350 tokens of the
first request, before the agent has done anything. Two of the five tools
did the work. add_note and delete_note came along on every call, and
any instruction the agent read could ask for them.
Why does the share fall?
Section titled “Why does the share fall?”A request log of one prompt that took three model calls was summarized per request: system prompt 404 tokens each time, tools 926 each time, messages 20, then 107, then 235. The MCP server's tool definitions were 604 tokens in each request, which was 45%, then 42%, then 39% of the request.
The server’s tool definitions are 45% of the first request and 39% of the third. Why does the share fall?
Which columns change from one request to the next, and which stay the same?
The numbers are in
Section titled “The numbers are in”A developer turned on Claude Code's request log for one session with OTEL_LOG_RAW_API_BODIES=file:<dir>, pointing at a directory in their home folder. The directory now holds forty request files from a session that read the project's configuration files.
The measurement is done: the server’s tool definitions are a fifth of every request. What do you do with the log?
What do the forty files hold besides the token counts, and who would see them in each place?
Exercise
Connect one more tool in a copy and follow it through the meter, the
record and the log. Copy the handbook directory and the status line
script to places you can delete, and point the copy’s settings at the
script. Run the shell steps from the course repository’s top level.
cp -r site/examples/customizing-agents/mcp-first-server/handbook /tmp/handbook-inspectmkdir -p /tmp/handbook-inspect/.claudecp site/examples/customizing-agents/seeing-what-the-agent-sends/statusline.py /tmp/handbook-inspect/.claude/printf '%s\n' '{"statusLine": {"type": "command", "command": "python3 /tmp/handbook-inspect/.claude/statusline.py"}}' > /tmp/handbook-inspect/.claude/settings.jsonmkdir -m 700 ~/claude-request-log-
cd /tmp/handbook-inspectand startclaude. Trust the folder, check that the status line shows, and run/context. Write down the total and the MCP tools line, if there is one. Quit. -
Add the file-system server to the copy, as in the lesson on your first server. It can read, write, edit and move files in the directory you give it, which is the copy [9]. Start a logged session with every MCP tool definition loaded, so the log counts what the model reads:
Terminal window cd /tmp/handbook-inspectclaude mcp add handbook -- npx -y @modelcontextprotocol/server-filesystem@2026.8.31 /tmp/handbook-inspectCLAUDE_CODE_ENABLE_TELEMETRY=1 OTEL_METRICS_EXPORTER=none OTEL_LOGS_EXPORTER=none OTEL_LOG_RAW_API_BODIES=file:$HOME/claude-request-log ENABLE_TOOL_SEARCH=false claudeRun
/contextand compare the MCP tools line with step 1. Ask: “Use the handbook server to read on-call.md and tell me when the rota changes.” Watch the status line after the reply. -
In a second terminal, find the record. The status line shows its file name. Run
grep -l "rota changes every Monday" ~/.claude/projects/*/*.jsonland check that it is one of the files grep names. Records of the earlier handbook exercises can match too. -
Quit the session, then run
python3 site/examples/customizing-agents/seeing-what-the-agent-sends/read_log.py ~/claude-request-logfrom the course repository. Read themcp toolscolumn of the first row whose source isrepl_main_thread, the main conversation [4]. If no row shows it, read the first row whose source isn’t a title or another side request, and note its source. If the source column shows-, read the first row. If you do the stretch goal, do it now, before you clean up. -
Clean up:
rm -rf ~/claude-request-log ~/claude-request-log-2, thencd /tmp/handbook-inspect && claude mcp remove handbook. Runclaude purgewithout a path and pick the copy from its list. The list may show it as/private/tmp/handbook-inspect. Check that the plan names the copy before you answery[3]. Last,rm -rf /tmp/handbook-inspect.
A good result is three numbers from your own run: the MCP tools line of
/context before and after, and the handbook share in the first
main-conversation row of read_log.py. Write them in a short note with
one line on whether you would keep the server connected in a project
that reads its files once a week. Then ask yourself: which of the three
views would have shown you that a secret was read, and how long would it
have stayed on disk?
Stretch: Before step 5, deny the server's write tools by name in the copy's .claude/settings.json, run mkdir -m 700 ~/claude-request-log-2, run the logged claude command from step 2 with file:$HOME/claude-request-log-2, ask the same question, quit, run read_log.py on ~/claude-request-log-2, and compare the mcp tools column of its first repl_main_thread row with the one from step 4.
Which view holds it?
Section titled “Which view holds it?”Claude Code offers three views of a session: the context meter (the /context command and a status line), the session record (a transcript in JSON Lines files under ~/.claude/projects/), and a request log that writes each request sent to the model to a local directory while it is turned on.
Place each item in the view that holds it.
Which view is live, which keeps the turns of past sessions, and which holds every part of a request?
Marked defer_loading
Section titled “Marked defer_loading”In the Claude application programming interface (API), a tool definition can carry defer_loading: true, which keeps it out of the model's context window until the model searches for that tool. A request log records each request as it was sent, and /context shows what is in the model's context window.
A request log shows all thirteen tool definitions of a server in every
request, each marked defer_loading: true. A colleague says the server
puts its full definitions in the model’s window on every turn. What do
you answer?
Which of the two views shows what was sent, and which shows what the model reads?
Where do you set the variable?
Section titled “Where do you set the variable?”Claude Code writes the full body of each request to a local directory when OTEL_LOG_RAW_API_BODIES=file:<dir> is set together with CLAUDE_CODE_ENABLE_TELEMETRY=1. A request body holds the system prompt, the tool definitions and the whole conversation so far.
You want to see what the tool definitions add to each request. Where do you turn on the request log?
How long should a log of every file the agent reads exist, and who sets it up?
Recap
/contextbreaks down what fills the window by category, and a status line can show the share in use, the input tokens and the record’s path after every reply [1] [2].- The session record under
~/.claude/projects/holds every message, tool call and tool result in plain text, secrets included, untilcleanupPeriodDaysorclaude purgeremoves it [3]. OTEL_LOG_RAW_API_BODIES=file:<dir>writes each request, with the system prompt, the tool definitions and the messages, to a local directory [4]. The log shows what each part costs in every request.- Turn the log on for one session, keep it in a directory outside every
repository that only you can read, and delete it when you have your
numbers. A gateway on
ANTHROPIC_BASE_URLthat you don’t run holds a copy of the same data. Anthropic doesn’t vouch for gateway products made by others [7].
You can now
- Inspects the requests to see what tools and context cost, and keeps request logs local
References
Section titled “References”- Anthropic. Explore the context window. Claude Code documentation. Reference.
Claude Code context window - Anthropic. Customize your status line. Claude Code documentation. Reference.
Claude Code statusline - Anthropic. Explore the .claude directory. Claude Code documentation. Reference.
Claude Code claude directory - Anthropic. Monitoring. Claude Code documentation. Reference.
Claude Code monitoring - Anthropic. Tool search tool. Claude Platform documentation. Reference.
Claude docs tool-search-tool - Anthropic. Connect Claude Code to tools via MCP. Claude Code documentation. Reference.
Claude Code mcp - Anthropic. Other LLM gateways. Claude Code documentation. Reference.
Claude Code llm gateway - Anthropic. Configure permissions. Claude Code documentation. Reference.
Claude Code permissions - Model Context Protocol a Series of LF Projects, LLC. Filesystem MCP Server. GitHub, modelcontextprotocol/servers, src/filesystem. Reference.
MCP filesystem server