context-doctor
Provides MCP tools to profile and optimize LLM conversation context, identifying token waste and applying deterministic fixes to reduce context window usage.
README
context-doctor 🩺
See what's eating your LLM context window — and fix it.
Every long-running LLM conversation slowly fills up with junk: duplicated documents, 10k-token tool outputs nobody reads again, base64 blobs, stale history. You pay for those tokens on every single call, and model quality drops as the window fills.
context-doctor is a zero-config profiler + optimizer for LLM contexts. It works with Claude, GPT, Gemini message formats, and plugs into Claude Desktop, ChatGPT (developer mode), Cursor, Claude Code — any MCP-capable app — or runs standalone from the terminal.
Where the tokens go
────────────────────────────────────────────────────────
Tool results ████████████████░░░░░░░░░░░░ 57% ~41k
System prompt ██████░░░░░░░░░░░░░░░░░░░░░░ 21% ~15k
Assistant replies ████░░░░░░░░░░░░░░░░░░░░░░░░ 13% ~9.4k
User messages ██░░░░░░░░░░░░░░░░░░░░░░░░░░ 9% ~6.5k
Findings (4)
────────────────────────────────────────────────────────
✖ Message #12 contains a base64/binary blob (~8.2k tokens). [save ~7.4k]
→ Never put base64 in text content — use the provider's file/image APIs.
▲ Tool result at message #7 (web_search) is ~6.1k tokens. [save ~4.9k]
→ Truncate or summarize large tool outputs before they enter history.
Quick start (30 seconds)
No install needed:
npx context-doctor analyze conversation.json --model claude-sonnet-5
Apply the safe fixes:
npx context-doctor optimize conversation.json --out slimmed.json
Input is any of: OpenAI chat format, Anthropic messages format (with system and content blocks), or a bare [{role, content}] array. Use - to pipe from stdin.
Always-on: optimize every request automatically
Run the proxy and every Anthropic/OpenAI API call your apps make gets optimized in flight — no code changes:
npx context-doctor proxy
Then point your app or SDK at it:
export ANTHROPIC_BASE_URL=http://localhost:8787 # Anthropic SDKs / tools
export OPENAI_BASE_URL=http://localhost:8787/v1 # OpenAI SDKs / tools
The proxy dedupes repeated content, trims stale tool results, and strips base64 blobs from the message history of each request, then forwards it to the real API. Your API key passes through in headers untouched, streaming (SSE) works unchanged, and per-request savings are logged:
[context-doctor] POST /v1/messages → 200 | optimized 7.3k → 518 tokens (2 changes)
Because prompt caching matches byte-identical prefixes, deterministic strategies are chosen so repeated requests stay stable — but if you rely on aggressive cache prefixes, start with --strategy strip-base64 --strategy dedupe and add more as you verify.
Note on desktop chat apps: Claude Desktop and the ChatGPT app talk to their own backends — no tool can sit in that path. For those, use the MCP integration below and add a line to your custom instructions like: "When a conversation gets long or includes large pasted content, proactively use context-doctor's profile_context tool and tell me what to trim." The model will then invoke it on its own.
Use it inside your AI app (MCP)
context-doctor ships an MCP server, so the AI itself can profile and slim context on demand.
Claude Desktop — add to claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"context-doctor": {
"command": "npx",
"args": ["-y", "context-doctor-mcp"]
}
}
}
ChatGPT desktop (developer mode), Cursor, Claude Code (claude mcp add context-doctor -- npx -y context-doctor-mcp), and any other MCP client: same command, their config syntax.
Then just ask: "profile this conversation with context-doctor" or paste an exported chat and say "what's eating my context?"
MCP tools
| Tool | What it does |
|---|---|
profile_context |
Token breakdown by category, largest messages, findings with estimated savings |
optimize_context |
Rewrites the conversation: dedupe, trim stale tool results, strip base64, optional history pruning |
context_best_practices |
Curated checklist, optionally specialized for Anthropic / OpenAI |
Use it as a library
import { parseConversation, profileConversation, optimizeConversation } from "context-doctor";
const profile = profileConversation(parseConversation(chatJson), "claude-sonnet-5");
console.log(profile.totalTokens, profile.findings);
const { conversation, tokensBefore, tokensAfter } = optimizeConversation(chatJson, {
strategies: ["dedupe", "trim-tool-results", "strip-base64"],
});
What it detects
- Oversized tool results — the #1 context killer in agent loops
- Duplicate content — the same doc/result pasted twice
- Repeated identical tool calls — a signal your agent forgot earlier results
- Base64 / binary blobs in text content
- Long history past the point where models track the middle
- Cache-hostile ordering — volatile content before stable content breaks prompt caching (Anthropic
cache_control, OpenAI automatic prefix caching) - Window pressure — usage % against the target model's real context window
What it fixes (deterministically — no LLM calls, no API keys)
| Strategy | Lossy? | Default |
|---|---|---|
dedupe — replace repeated content with a reference |
No | ✅ |
trim-tool-results — truncate stale tool outputs |
Mostly no | ✅ |
strip-base64 — remove inline binary blobs |
No (for the model) | ✅ |
prune-history — collapse old turns into a stub for summarization |
Yes | opt-in |
Everything the optimizer does is inspectable: it prints exactly which messages changed and how many tokens each change saved.
Why token counts are "~"
Exact counts require each provider's private tokenizer. context-doctor uses a calibrated chars-per-token heuristic (denser for code/JSON) that lands within ~10% — plenty accurate for finding what's heavy and measuring savings, and it keeps the tool fully offline with zero configuration.
Roadmap
- [ ] LLM-powered summarization strategy (bring your own key) for
prune-historystubs - [ ] Proxy: per-route strategy config + response token accounting
- [ ]
context-doctor watch— live profiling of an agent's JSONL trace - [ ] Exact tokenizer adapters (tiktoken, Anthropic count-tokens API) as optional plugins
- [ ] Session import from Claude Code / Cursor transcript formats
Contributions welcome — this project is small on purpose. Open an issue before a big PR.
License
MIT
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。