I've been using MCP servers with Claude Code, Cursor, and Codex for months. Every developer who connects more than 2 MCP servers hits the same wall of problems. They're not bugs β they're design gaps in the protocol itself.
Here are the 5 pain points I hit every day, and how I solved them with mcptoon β a 50KB CLI with zero dependencies.
Connect 5 MCP servers with browser tools (Puppeteer, Playwright, etc.) and you get 50-100K tokens of JSON schema injected into your context before you even ask a question.
On a 128K context window, that's 40-80% gone. Your agent hasn't done anything yet.
Before mcptoon: Every request carries ~40K tokens of schema overhead for 255 tools.
After mcptoon: The SLIM format compresses 255 tool schemas to ~3,500 tokens. That's a 91% reduction, measured with tiktoken (OpenAI's official tokenizer).
JSON schema: 39,964 tokens (255 tools)
SLIM format: 3,511 tokens (same 255 tools)
Savings: 91%
All numbers come from tiktoken.get_encoding()
β not chars Γ· 4
approximations.
Want to add a new MCP server? Edit claude_desktop_config.json
by hand. Miss a comma? MCP doesn't load. Wrong path? Doesn't load. And there's no error message β your tool list is just empty.
mcptoon add fetch --stdio npx -y @modelcontextprotocol/server-fetch
mcptoon list
mcptoon doctor
mcptoon doctor
checks every configured server β can it start? Does it respond? Are there path issues? It tells you exactly what's wrong instead of silently failing.
Your agent says: "I need GitHub search to complete this task." It's an AI β it can't edit JSON config files and restart itself.
So you stop coding. You open the config file. You add the server. You restart. Your context is gone. Your flow is broken.
mcptoon fixes this because it's a CLI tool. Your agent can run mcptoon add github --stdio npx -y @modelcontextprotocol/server-github
in its own shell. No human intervention needed.
You set up 15 MCP servers for Claude Code. Then you try Cursor β different config format, different file location. 15 servers, reconfigured from scratch. Then OpenCode. Then Codex.
mcptoon uses one config file (~/.mcptoon/config.json
) that all agents share:
| Agent | Works with mcptoon? |
|---|---|
| Claude Code | β |
| Cursor | β |
| OpenCode | β |
| Codex | β |
| CatPaw | β |
| Any shell-capable agent | β |
One config. All agents. Switch tools without reconfiguring.
You don't know how many tokens your tools eat. You can't audit, can't budget, can't optimize.
mcptoon manifest --compact
mcptoon manifest --slim
mcptoon manifest --json
The format you choose depends on the use case:
| Format | For | When |
|---|---|---|
--json |
||
| LLM | Tool calls (model needs full JSON) | |
--slim |
||
| LLM | Tool discovery (what tools exist?) | |
--toon |
||
| Human | Terminal output, debugging | |
--compact |
||
| Human | Quick "what tools do I have?" |
Optimization only happens at the discovery layer. Actual tool calls are always JSON β that's what models are trained on.
One tool schema in JSON:
{
"name": "search_web",
"description": "Search the web for current information",
"inputSchema": {
"type": "object",
"properties": {
"query": {"type": "string", "description": "The query parameter"},
"num_results": {"type": "number", "description": "The num_results value"}
},
"required": ["query"]
}
}
Same tool in SLIM, one line:
search_web|query:s*|num_results:n
*
= required. s
= string, n
= number, b
= boolean, a[type]
= array, o{keys}
= object.
βββββββββββββββββββββββββββββββββββββββββββ
β Layer 1: mcptoon CLI (~50KB, zero deps) β
β Runs in your agent's shell, optimizes β
βββββββββββββββββββββββββββββββββββββββββββ€
β Layer 2: MCP Server (your existing) β
β Untouched, runs stdio/SSE as normal β
βββββββββββββββββββββββββββββββββββββββββββ€
β Layer 3: Config (~/.mcptoon/config.json)β
β Shared across all agents β
βββββββββββββββββββββββββββββββββββββββββββ
Each layer is independent. Swap agents without touching servers. Swap servers without touching agents. mcptoon is the glue β 50KB, zero dependencies, pure Python standard library.
255 MCP tool schemas, measured with tiktoken:
| Format | cl100k (GPT-4) | o200k (GPT-4o) | vs JSON |
|---|---|---|---|
| JSON (full schema) | 39,964 | 39,978 | β |
| SLIM | |||
| 3,511 | |||
| 3,525 | |||
| 91% saved | |||
| Compact (names only) | 63 | 63 | 99.8% |
At GPT-4o pricing ($5/M tokens), 25 requests with 255 tools:
100 daily sessions = $18/day saved. $540/month. That's 10 servers β scale to 100 and the gap widens.
pip install mcptoon # 50KB, zero dependencies
mcptoon init # Generate example config
mcptoon add fetch --stdio npx -y @modelcontextprotocol/server-fetch
mcptoon manifest --slim # Token-efficient schema for LLM discovery
mcptoon manifest --compact # Just tool names, for quick scanning
mcptoon call fetch fetch '{"url":"https://example.com"}' --toon
Docker:
docker build -t mcptoon .
docker run --rm -v ~/.mcptoon:/root/.mcptoon mcptoon manifest --slim
mcptoon usage
shows real-time token consumption per server--slim
/ --compact
based on remaining contextMCP is a good protocol. JSON schema injection is its Achilles' heel. mcptoon doesn't "fix" it β it makes the pain manageable: schemas don't enter your context until you actually need them.
91% token savings, measured with tiktoken. CLI-based, works with every agent. 50KB, zero dependencies, 309 tests. Apache 2.0.
GitHub: activeing123/mcptoon Β· PyPI: pip install mcptoon Β· License: Apache 2.0 Β· 309 tests Β· Zero dependencies