Own Your Context Window
Read what your agent actually loads, cut the tool definitions and bundled extras you never use, and start fresh before quality drops.
The one line: everything the model reads is a file you can open, and most of it loaded before you typed a word.
The order of a session
A session is a stack assembled for you, in this order:
- Your prompt. The only part you wrote.
- Tool definitions. One schema per callable tool: MCP servers, LSP, task and worktree tools, web fetch, browser and computer-use tools. The biggest block, and the one you control most directly.
- The client-side system prompt. The harness's own instructions, shipped from your machine. You cannot edit it. The server-side half you never see at all.
- Rules files.
CLAUDE.mdandAGENTS.mdat each scope, plus auto memory. See Rules Files and Scope. - The skill listing. Name and description for every installed skill, global and project, roughly 100 tokens each.
- Then the turn: tool calls and tool results, which is what actually fills the window.
Steps 2 to 5 are your baseline. You pay it on every turn, in every session, whether the work needs it or not.
Look at the file, not the UI
Claude Code writes each session to disk as JSONL under ~/.claude/projects/<encoded-project-path>/, where the encoding is your project path with the slashes swapped for dashes. Every line is one event: the user prompt, the attachments block, each tool_use and its tool_result. Subagent transcripts sit in the same tree. Open one and you see exactly what the model saw, in order, including the search it ran before it answered wrong.
The built-in view is /context, which prints the current window broken down by what is holding it, with /context all for the fuller listing (docs). It answers "what is in there now". The JSONL answers "how did it get there".
Read the JSONL with something
Raw JSONL is technically readable and practically miserable. One turn is a wall of metadata wrapping the few hundred tokens you actually care about, and the interesting thing is usually a size, not a string, so you end up counting characters by eye.
I wrote peektrace for exactly this. peektrace serve binds a local server and opens every Claude Code, Codex and Pi session in the browser: it charts peak context against the window and partitions that peak into system and tool definitions, CLAUDE.md / AGENTS.md, files, prompts, tool results and the hidden thinking band, then marks on a growth timeline the turn the session crossed into the dumb zone and every compaction cliff after it. Loaded artifacts and tool calls are searchable. The same binary is scriptable one-shot — peektrace sessions ls, peektrace sessions analyze <session-id>, --json to pipe it. Nothing leaves the machine: the server binds 127.0.0.1, transcripts are secret-redacted, and no transcript is ever sent to a model. Free and open source (GitHub).
curl -fsSL https://raw.githubusercontent.com/Mark-Life/peektrace/main/scripts/install.sh | shTool definitions are the lever
Do this once and you will not forget it. Open the attachments block of a fresh session and read the tool list. Then run /mcp, which lists the MCP servers you have connected, disable the Chrome and computer-use tools, start a new session, and read the block again. If that list is empty, skip ahead to MCP Without Tool Bloat and come back. It is visibly shorter. Those tools also bundle their own usage skill, so turning them off drops that too.
Claude Code softens this by default: tool search is on, so only tool names and server instructions load at startup and ToolSearch fetches full schemas on demand. Tune it with ENABLE_TOOL_SEARCH: unset defers MCP tools, true always defers, auto loads everything upfront only if it fits inside 10 percent of the window (auto:N for your own percentage), false loads all upfront. Anthropic's own measurements put 58 tools across 5 servers at roughly 55K tokens before the conversation starts, and report tool-call accuracy on Opus 4.5 rising from 79.5 to 88.1 percent once schemas load on demand (advanced tool use).
My rule of thumb: past roughly 40 tool definitions the model starts picking the wrong one. Enable the browser tools for the hour you need a browser, then turn them off.
A settings.json that cuts the baseline
This is my ~/.claude/settings.json, trimmed to the context-relevant keys:
{
"permissions": {
"deny": [
"EnterPlanMode",
"ExitPlanMode",
"NotebookEdit",
"AskUserQuestion",
"ScheduleWakeup",
"CronCreate",
"CronDelete",
"CronList"
]
},
"disableClaudeAiConnectors": true,
"disableBundledSkills": true,
"disableRemoteControl": true,
"effortLevel": "high",
"tui": "fullscreen",
"skipDangerousModePermissionPrompt": true
}permissions.deny, disableClaudeAiConnectors, disableBundledSkills, disableRemoteControl, effortLevel, tui and skipDangerousModePermissionPrompt are all in the settings reference. disableClaudeAiConnectors is the heaviest cut: it drops the built-in connectors and their tool definitions. disableBundledSkills removes the shipped skills, leaving /doctor, and has an env twin, CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1. disableRemoteControl blocks Remote Control entirely, and tui: "fullscreen" selects the alt-screen renderer.
The denies are personal: I plan in the context window or in a markdown file, I write no Python notebooks, and I do not want a separate tool for asking me a question. Deny what you never invoke. A short, unambiguous tool list beats a complete one.
The danger zone
Output quality falls off well before the window is full. My working number is roughly 40 percent: past that, hallucinations and dropped instructions get noticeably more common. That is a heuristic from watching sessions, not a published figure. Treat it as a prompt to start fresh, not as a threshold to tune.
Auto-compaction is the fallback, not the plan. Compaction re-injects the system prompt, project-root CLAUDE.md, unscoped rules and auto memory, but drops path-scoped rules, nested CLAUDE.md files and the skill listing. A new session with a three-line handoff prompt gives the model a cleaner stack than a compacted one. /clear between tasks costs you nothing.
Skipping the permission prompts
I run alias tc='claude --dangerously-skip-permissions' and have for about a year. I asked the agent to do work, not to ask me questions.
Be clear about what that flag is. It equals --permission-mode bypassPermissions. The docs say to use it only in "isolated environments like containers, VMs, or dev containers without internet access" and that it "offers no protection against prompt injection" (permission modes). It refuses to start as root or sudo. It still stops for explicit ask rules and for the rm -rf / circuit breaker, but it allows writes to protected paths such as .git and .claude. Outside a sandbox, anything the model decides to run, runs. Nothing has gone wrong for me; that is one person's sample, not evidence.
Auto mode is the better default now
auto mode is no longer a compromise, and from 14 August 2026 it becomes the default permission mode for new sessions on Pro, Max and Team plans. Set your own default and it stays; accept the one-time switch prompt and you move.
The mechanism is the interesting part. A separate classifier model reviews each action before it runs and blocks "anything that escalates beyond your request, targets unrecognized infrastructure, or appears driven by hostile content Claude read". It owns the rm -rf / and rm -rf ~ decision too. Blocked by default: curl | bash, sending sensitive data to external endpoints, production deploys and migrations, mass deletion on cloud storage, granting IAM or repo permissions. Your working directory and the git remotes present at session start are trusted; a remote added mid-session is not. Explicit ask rules still prompt. It needs a recent model — Opus 4.6 or later, Sonnet 4.6 or later, or Fable 5 on the Anthropic API.
That is a genuinely safer setting than what I run, and you get it without answering prompts. Anthropic still hedges it: auto mode "reduces permission prompts but does not guarantee safety". Note also that defaultMode: "auto" only works in ~/.claude/settings.json; the project-level files are ignored so a repository cannot grant itself auto mode.
My honest position: I stay on bypass out of habit, not analysis. The one real argument for it is speed — bypass runs the command, while auto mode puts a classifier call in front of every action. If you are setting this up today, start on auto.
Audit your own setup
Your baseline drifts: a plugin here, a skill you tried once, an MCP server from three months ago. My context-doctor skill reads the context auto-loaded into every session, cross-checks it against what you actually invoke, and ranks the cuts as prune, gate behind a trigger, or route elsewhere. Skills you never call get flagged; you can keep them and hide them from the model, covered in Skills.
What to do
- Install
peektrace, runpeektrace serve, and read one session's attachments block top to bottom. - Run
/mcp, turn off the Chrome and computer-use tools, restart, and compare the tool list. - Add
disableClaudeAiConnectorsanddisableBundledSkillsto~/.claude/settings.json, then deny every tool you never invoke. - Check
/contextmid-task; when it passes roughly 40 percent,/clearand restate the task in three lines. - Run
automode unless you have a reason not to; putdefaultMode: "auto"in~/.claude/settings.json, not in the project settings.