Reducing MCP token cost: Code Mode, context-mode and CLI-plus-skill routes
Reducing MCP token cost means keeping bulky tool output and unused tool definitions out of a coding agent’s context window. In 2026 the main levers are running commands in a sandbox that returns only a summary (context-mode), code-running servers such as Cloudflare Code Mode, narrower server URLs, and replacing a server with a CLI plus a skill.
You ask the agent to run the test suite. It pipes 4,000 lines of runner output into the conversation, finds the two failures, and fixes them. Twenty minutes later it compacts the session and forgets the plan it was following, because the context filled up with output nobody needed to read.
This page is for developers who run long agent sessions and for tech leads who own the team’s shared MCP configuration. New to MCP? Start with the MCP hub and the starter stack, then come back once servers are connected.
What you get from this page
Section titled “What you get from this page”- A way to measure what each server and plugin costs, in Claude Code, Codex and Cursor.
- context-mode installed in all three tools, and a test run where only the failures reach the context.
- The server-side switches that shrink results: Cloudflare Code Mode, GitHub toolset URLs and Microsoft Learn’s
?maxTokenBudget=. - Three CLI-plus-skill swaps (Playwright CLI,
ctx7,mslearn) and a generator for servers without one. - A monthly MCP budget review your team can run in under an hour, with a sign-off rule.
Where does MCP token cost come from in 2026?
Section titled “Where does MCP token cost come from in 2026?”The cost moved. Claude Code and Codex both load MCP tools through tool search, which is on by default (Claude Code docs; Codex since 0.143.0). The agent sees an index of tool names and pulls a full schema only when it needs one. Ten connected servers no longer mean ten full schema dumps in every request. Check Cursor’s MCP settings for how many tools each server exposes; this page does not describe Cursor’s loading behaviour.
What still fills the window is tool output: a CI log, a page snapshot, an issue list, a schema dump. A result stays in context until the session compacts or ends, and chained calls push every intermediate payload through the model. Anthropic’s engineering post “Code execution with MCP” (2025-11-04) describes the fix: let the model write code that calls the tools, filter the data outside the context, and return only the result. In the post’s own example, token usage fell from 150,000 to 2,000, which Anthropic reports as a 98.7% saving. That is one vendor example, not a benchmark you should expect on your repo.
The routes below apply that idea at different layers:
| Route | What it removes from context | Reach for it when |
|---|---|---|
| context-mode sandbox tools | Raw command, file and fetch output | Test runs, logs, large files, web pages |
| Code Mode servers (Cloudflare) | Hundreds of per-endpoint tool schemas | One server fronts a whole platform API |
Scoped server URLs (GitHub toolsets, ?maxTokenBudget=) | Tools you never call, oversized results | You keep the server but use a slice of it |
CLI plus skill (Playwright CLI, ctx7, mslearn) | The MCP server itself | The vendor ships a CLI that does the same job |
Caps on result size (MAX_MCP_OUTPUT_TOKENS, Codex enabled_tools) are covered in MCP best practices. They are safety nets; the routes on this page change what the agent sees in the first place.
How do you measure what an MCP server costs?
Section titled “How do you measure what an MCP server costs?”Measure before you change anything, or you cannot prove the change helped.
Start a fresh session and run /context. Run one representative task, then run /context again; the difference is what that task cost. For anything installed as a plugin, check the always-on cost from a terminal:
claude plugin details context-modeOn Claude Code 2.1.286 this prints a component inventory and a “Projected token cost” section. For context-mode 1.0.169 it reported about 972 tokens always-on. MCP tool schemas are listed as “resolved at runtime; not counted”, so pair it with /context.
Run codex mcp list in a terminal to see each server and whether it is enabled. In the TUI, run /status (it shows the current session configuration and token usage) before and after one representative task and compare the numbers. With context-mode installed, type ctx stats in the chat for per-tool savings; the README documents that phrase for every non-Claude client.
Servers live in .cursor/mcp.json (project) or ~/.cursor/mcp.json (global), and each one can be turned off in Cursor’s settings without deleting its entry. With context-mode installed, ctx stats in the chat gives the same per-tool breakdown as in Codex.
Write the numbers down: the baseline after a fresh start, and the cost of the representative task. The monthly review below compares against them.
Keep command output out of context with context-mode
Section titled “Keep command output out of context with context-mode”context-mode is a community MCP server, plus hooks, that runs commands and fetches in a subprocess and lets only the printed result into the conversation. Its sandbox tools are ctx_execute, ctx_batch_execute, ctx_execute_file, ctx_index, ctx_search and ctx_fetch_and_index. In Claude Code the plugin’s hooks steer the model toward those tools instead of raw Bash, Read and WebFetch.
As of 2026-09-26: 24.1k GitHub stars on mksglu/context-mode, npm context-mode 1.0.169 (last published 2026-06-29). It is not in the Official MCP Registry and not in claude-plugins-official. The license is Elastic-2.0, not an OSI license, so check it with whoever approves your dependencies. It needs Node.js 22.5+ (or Bun) in every tool.
Install context-mode
Section titled “Install context-mode”In a Claude Code session:
/plugin marketplace add mksglu/context-mode/plugin install context-mode@context-modeThe same two steps work from a terminal as claude plugin marketplace add mksglu/context-mode and claude plugin install context-mode@context-mode (subcommands checked with claude plugin --help, 2.1.286). Restart the session, then run /context-mode:ctx-doctor; every check should show [x].
A lighter trial with no hooks and no slash commands:
claude mcp add context-mode -- npx -y context-modeWithout hooks the tools are available but the model is not nudged to use them, so name ctx_execute in your prompt.
In a terminal (tested on codex-cli 0.157.1 with a throwaway CODEX_HOME):
codex plugin marketplace add mksglu/context-modecodex plugin add context-mode@context-modecodex mcp list # context-mode shows as enabledThe plugin brings its MCP server, skills and hooks. Codex asks you to trust plugin hooks before they run. The README still tells you to set plugin_hooks = true under [features]; in 0.157.1 that flag is stage “removed” and hooks is stable and on, so leave [features] alone. Start a session and type ctx stats to confirm the server answers.
In Codex the hooks can block a raw shell call but cannot rewrite it (the README tracks this as openai/codex#18491), so name ctx_execute in prompts there too.
The README lists the Cursor Marketplace entry as awaiting review. Until it is approved, the README recommends its local-folder plugin (Option A): git clone https://github.com/mksglu/context-mode.git, then symlink the clone into ~/.cursor/plugins/local/context-mode and restart Cursor. If you prefer plain project config, use the README’s manual route (Option B) below. Neither route was tested in Cursor for this page.
npm install -g context-mode{ "mcpServers": { "context-mode": { "command": "context-mode" } } }// .cursor/hooks.json — routes shell, read and fetch calls through context-mode{ "version": 1, "hooks": { "preToolUse": [{ "command": "context-mode hook cursor pretooluse", "matcher": "Shell|Read|Grep|WebFetch|Task|MCP:ctx_execute|MCP:ctx_execute_file|MCP:ctx_batch_execute" }], "postToolUse": [{ "command": "context-mode hook cursor posttooluse" }], "stop": [{ "command": "context-mode hook cursor stop" }] }}Cursor rejects the sessionStart hook, so a rules file is what gives the model its routing instructions at session start. Copy it from the global install:
mkdir -p .cursor/rules && cp "$(npm root -g)/context-mode/configs/cursor/context-mode.mdc" .cursor/rules/context-mode.mdcRestart Cursor and type ctx doctor in the agent chat.
Example: run the full test suite, keep only the failures
Section titled “Example: run the full test suite, keep only the failures”This is the case context-mode is built for. The runner writes thousands of lines; you need a dozen.
What you should see: one ctx_execute call whose result is a short block of counts and error excerpts, not the log. Run /context-mode:ctx-stats (Claude Code) or ctx stats (Codex, Cursor) afterwards; it reports the bytes kept out of context for that call. The README’s own benchmark table claims large reductions per tool; treat those as the vendor’s figures and trust your own ctx-stats output instead.
How do you know the summary did not hide a failure?
Section titled “How do you know the summary did not hide a failure?”A filtered result is only useful if it is complete. Check it without reading the log:
- The counts must add up. Passed + failed + skipped must equal the total, and a non-zero exit code with zero reported failures is a script bug, not a green run. The prompt asks for both numbers so you can compare them at a glance.
- Re-run one failure directly. Pick one reported test and run it by name with your runner in the terminal. If it does not fail the same way, the summary is wrong.
- CI stays the gate. context-mode changes what the agent reads, not what is true. The merge decision still comes from CI’s full run, and the reviewer checks the CI result, not the agent’s summary.
Use Code Mode instead of hundreds of tool schemas
Section titled “Use Code Mode instead of hundreds of tool schemas”Cloudflare’s Code Mode server at https://mcp.cloudflare.com/mcp exposes three tools, search, execute and docs. The agent searches the Cloudflare OpenAPI spec, then writes JavaScript that calls cloudflare.request(), and only the script’s result comes back. Cloudflare’s README puts that at “2500 endpoints in 1k tokens”, against about 244k tokens for minimal native tool schemas (vendor figures from the cloudflare/mcp README). Results are capped at about 6,000 tokens by default; ?truncateToolResult=false lifts the cap, which is rarely what you want.
claude mcp add --transport http cloudflare https://mcp.cloudflare.com/mcpThen run claude mcp login cloudflare to complete the OAuth login. The cloudflare plugin in claude-plugins-official wires the same URL together with Cloudflare’s skills.
codex mcp add cloudflare --url https://mcp.cloudflare.com/mcpcodex mcp login cloudflareThe second command completes the OAuth login. If you are signed in to Codex, you can instead run /plugins in the TUI and install the cloudflare plugin from openai-curated; its cloudflare-api server points at the same Code Mode URL.
{ "mcpServers": { "cloudflare": { "url": "https://mcp.cloudflare.com/mcp" } } }The same idea appears elsewhere: Composio Connect puts “1000+ apps” behind seven meta-tools (see integration hubs). The domain servers, such as observability.mcp.cloudflare.com, are covered in Cloudflare MCP.
Scope a server you keep: GitHub toolsets and token budgets
Section titled “Scope a server you keep: GitHub toolsets and token budgets”Some servers shrink themselves if you ask at the URL.
GitHub. The remote server publishes one URL per toolset, each with a /readonly variant: https://api.githubcopilot.com/mcp/x/actions/readonly gives the agent only read access to Actions (GitHub’s docs/remote-server.md). The same scoping works through the X-MCP-Toolsets and X-MCP-Readonly headers, or --toolsets and --read-only on the local server.
# Claude Code: a CI-debugging session that only needs Actions logsclaude mcp add --transport http github-actions \ https://api.githubcopilot.com/mcp/x/actions/readonly \ -H "Authorization: Bearer $GITHUB_PAT"# Codex: the same scoped URL, token read from an environment variablecodex mcp add github-actions --url https://api.githubcopilot.com/mcp/x/actions/readonly \ --bearer-token-env-var GITHUB_PATIn Cursor, put the scoped URL in the url field of the github entry in .cursor/mcp.json. The claude mcp add line expands $GITHUB_PAT in your shell and writes the value into the local config, so never use it with --scope project. Full setup, lockdown mode and PAT scopes are on the GitHub MCP page.
Microsoft Learn. Append maxTokenBudget to the endpoint to truncate search results to a token budget. Microsoft labels it experimental.
claude mcp add --transport http microsoft-learn "https://learn.microsoft.com/api/mcp?maxTokenBudget=2000"codex mcp add microsoft-learn --url "https://learn.microsoft.com/api/mcp?maxTokenBudget=2000"Swap a server for a CLI plus a skill
Section titled “Swap a server for a CLI plus a skill”When a vendor ships a CLI that does the server’s job, a skill that teaches the agent the CLI costs a short description until it is used, and the CLI’s output can be filtered with ordinary shell tools. Playwright’s own MCP README now says coding agents “might benefit from using the CLI+SKILLS instead”.
| Server | CLI-plus-skill replacement | Setup (terminal) |
|---|---|---|
| Playwright MCP | @playwright/cli (binary playwright-cli) | npm install -g @playwright/cli@latest, then playwright-cli install --skills (--skills agents writes to .agents/skills/) |
| Context7 MCP | ctx7 CLI in CLI + Skills mode | npx ctx7 setup --cli --claude (or --codex, --cursor) |
| Microsoft Learn MCP | @microsoft/learn-cli (binary mslearn) | npm install -g @microsoft/learn-cli, then mslearn setup --cli --claude (or --codex) |
Flags checked against playwright-cli install --help (0.1.22), ctx7 setup --help (0.5.12) and the MicrosoftDocs/mcp README. mslearn setup has no Cursor target (checked with mslearn setup --help, @microsoft/learn-cli 1.0.0). Details and trade-offs live on Playwright MCP vs Playwright CLI and Context7.
No vendor CLI? mcporter (npm mcporter 0.14.1; the repo moved from steipete/mcporter to openclaw/mcporter) generates a standalone CLI from any server, with tool schemas as subcommands. npx mcporter generate-cli linear --include-tools issues_list,issues_create keeps only the tools you name. It needs Node 24+, and linear must already be a configured server in mcporter, or pass --command <url> instead. --compile builds a single binary and needs Bun. Wrap the result in a skill so the agent learns it through --help only when it needs it (see building custom skills).
Run a monthly MCP budget review
Section titled “Run a monthly MCP budget review”Servers accumulate. A one-hour review each month keeps the context budget honest. The tech lead who owns the shared config (.mcp.json, the team’s Codex config.toml, .cursor/mcp.json) runs it, and the change lands as a pull request with before-and-after numbers.
-
Measure the baseline. In a fresh session, record
/context(Claude Code) or the TUI’s token figure (Codex), plusclaude plugin detailsfor each plugin. List what is configured withclaude mcp listandcodex mcp list. -
Run the same representative task. Use one real task from the last month, such as fixing a red CI run, and record what it cost. Keep the task fixed from month to month so the numbers compare.
-
Find what was not used. Ask the agent which servers and tools it called (prompt below). A server with no calls in a month is a candidate for removal.
-
Prune and scope. Remove unused servers with
claude mcp remove NAMEorcodex mcp remove NAME. Point the ones you keep at a toolset URL, a read-only URL or a token budget. -
Swap where a CLI exists. Replace Playwright MCP, Context7 MCP or Microsoft Learn MCP with its CLI-plus-skill route if the team’s usage fits it.
-
Route bulky output. Add context-mode, or tighten the prompt, for the tasks whose cost came from output rather than schemas.
-
Re-measure and ship. Repeat steps 1 and 2. Put both sets of numbers in the pull-request description. Merge only if the representative task still passes its own check (tests green, the same bug found) at the lower cost.
Sign-off rule. The review passes when the representative task costs less and its outcome is unchanged. A cheaper run that misses the bug the expensive run found is a regression, not a saving.
When cutting MCP token cost breaks
Section titled “When cutting MCP token cost breaks”The agent keeps using Bash instead of ctx_execute. You installed the MCP-only route, which has no routing hooks, or the hooks are not trusted yet. In Claude Code, install the plugin and run /context-mode:ctx-doctor. In Codex, accept the plugin’s hooks when prompted. In any tool, name ctx_execute in the prompt.
The summary says “0 failed” but CI is red. The script printed counts from the wrong source, or the runner’s exit code was swallowed. Ask for the exit code in every ctx_execute summary, as the example prompt does, and treat a mismatch as a failed run.
A sandboxed command reaches more than you expected. context-mode’s subprocess is a process boundary, not a security boundary: authenticated CLIs such as gh, aws and kubectl inherit your credentials. It applies your Claude Code permission deny rules inside the sandbox, so keep those rules in .claude/settings.json (see MCP security).
Code Mode returned a truncated result. The default cap cut it at about 6,000 tokens. Filter harder inside the execute script rather than adding ?truncateToolResult=false.
A toolset URL hides the tool you need. The agent reports that a tool does not exist. Switch to the base URL https://api.githubcopilot.com/mcp/ with the header X-MCP-Toolsets: actions,pull_requests (and X-MCP-Readonly: true), or register a second scoped URL entry, rather than going back to the full server.
Token usage did not drop. Measure again with /context or ctx stats. If the cost is in the agent’s own answers or in files it read, MCP was not the problem; see context windows and token limits and skills for context and token discipline.