Skip to main content

mcptoon

Add 255 MCP tools → 90,804 tokens gone. Add mcptoon → 117 tokens.

Keep 100+ MCP servers always configured. Zero context pollution. No loading. No unloading. One CLI for every agent.

Python 3.10+ License: Apache 2.0 Zero Dependencies GitHub Stars

If this saves you tokens, please star the repo — it helps others discover it.

English | 中文文档 | 🌐 Ecosystem | 📦 Profiles | Report Bug | Request Feature

mcptoon demo

Benchmark: 255 tools, 90,804 → 117 tokens


The problem

Every MCP-enabled agent loads all tool schemas into your context — before any work starts.

Add 10 MCP servers (especially browser tools like puppeteer/playwright)
  → Each server returns tools/list with full JSON schemas
  → ALL schemas injected into your context
  → 50,000-100,000+ tokens consumed
  → 128K context: 40-80% gone before you even ask a question

Add 100 servers → 200,000+ tokens → context is dead.

So you unload servers when not needed. Reload when needed. Repeat. Forever.

And when you want to add a new MCP server? You manually edit JSON config files (claude_desktop_config.json, etc.). One syntax error, wrong path, or missing env var — MCP won't load. You debug for hours.

You're managing MCP servers instead of doing work.

The solution

mcptoon keeps all your MCP servers configured — but their schemas never enter your agent's context.

😤 5 pains. ✅ 5 kills.

😤 Context death → ✅ 0 tokens, forever

Add 10 MCP servers — especially browser tools like puppeteer (47 tools, 23K tokens of schemas) or playwright (52 tools, 28K tokens). Before you ask a single question, 50-100K tokens of {"type":"object","properties":...} are squatting in your context. Your AI forgets what you were talking about. So you uninstall servers to make room. Then you need one — reinstall, wait, reconfigure. You're playing Tetris with MCP servers inside your context window. This is why people say "MCP is unusable past 5 servers."

mcptoon: 100 servers configured, 0 tokens in context. Use any tool, anytime. No Tetris.

😤 Config hell → ✅ One command, done

Want to add a server? Hand-edit claude_desktop_config.json. Miss a comma → MCP won't load. Wrong path → won't load. Missing env var → won't load. Sometimes it loads but tools silently don't appear — no error, no log, just nothing. You stare at a blank tool list and debug for an hour.

mcptoon: mcptoon add myserver --stdio npx -y @package. One command. Something's wrong? mcptoon doctor checks Python, config syntax, server connectivity — tells you exactly what.

😤 Agent can't self-serve → ✅ AI installs its own tools

Your agent is mid-task and says "I need GitHub search to finish this." It can't install tools — it's an AI, not an admin. So you stop coding, go edit JSON, restart the agent, wait for it to reconnect. Your AI forgot what it was working on. Momentum — dead.

mcptoon: Your AI runs mcptoon add github ... itself, and keeps going. No human in the loop. No context lost.

😤 Reconfigure per agent → ✅ One config, all agents

You set up 15 MCP servers for Claude Code. Now you try Cursor — different config format, different file location, redo all 15 from scratch. Then OpenCode. Then Codex. Same servers, 4× the work, 4× the chances to miss a comma.

mcptoon: One config file, every agent. ~/.mcptoon/config.json. Switch agents in seconds. Config follows you.

😤 Paying for JSON garbage → ✅ TOON, 20-97% smaller

Every MCP result looks like {"content":[{"type":"text","text":"{\"name\":\"react\",\"stars\":219000}"}]} — 80 tokens of braces, quotes, and type declarations to deliver 6 tokens of actual data. Over a session with 200 tool calls, that's 15,000 tokens of pure syntax waste.

mcptoon: Returns name:react|stars:219000 — same data, 20-40% fewer tokens on results, 61% on schemas. Discovery: 97% fewer. Schemas: 93% fewer. tiktoken-verified.


100 MCP servers. 0 context waste. Use any tool, anytime. No loading. No unloading. No JSON config errors.

How? CLI mode.

mcptoon is a CLI tool, not an MCP client library. Your agent doesn't connect to MCP servers — it just runs mcptoon commands. MCP schemas live on disk in ~/.mcptoon/config.json, not in your context window. Only the compact output you request enters context — and TOON encoding makes it 20-97% smaller than JSON.

Show me

JSON (287 tokens) — what every other MCP client puts in your context:

[
  {"name": "search_web", "description": "Search the web for information",
   "inputSchema": {"type": "object", "properties": {"query": {"type": "string", "description": "Search query"}, "num_results": {"type": "number", "default": 5}}, "required": ["query"]}},
  {"name": "fetch_url", "description": "Fetch content from a URL",
   "inputSchema": {"type": "object", "properties": {"url": {"type": "string"}}, "required": ["url"]}}
]

TOON (5 tokens) — what mcptoon returns:

search_web fetch_url

Measured benchmark (255 tools, 23 servers)

Tools JSON (tokens) mcptoon compact Reduction
5 1,897 16 99.2%
10 3,567 34 99.0%
25 9,009 97 98.9%
50 17,790 117 99.3%
93 33,191 117 99.6%
150 53,350 117 99.8%
200 71,135 117 99.8%
255 90,804 117 99.87%

TOON format for tool results: 61% smaller than JSON. SLIM format for full schemas: 93% smaller than JSON.

📊 Full benchmark data (click to expand)
Tools JSON tokens TOON tokens SLIM tokens Compact tokens TOON save SLIM save Compact save
5 1,897 785 111 16 59% 94% 99%
10 3,567 1,391 235 34 61% 93% 99%
25 9,009 3,580 595 97 60% 93% 99%
50 17,790 6,981 1,203 117 61% 93% 99%
93 33,191 13,086 2,231 117 61% 93% 100%
150 53,350 20,958 3,626 117 61% 93% 100%
200 71,135 27,952 4,842 117 61% 93% 100%
255 90,804 35,735 6,174 117 61% 93% 100%

Reproduce: python _benchmark.py → outputs assets/benchmark_data.json + assets/benchmark.html. Token count: chars ÷ 4 (GPT BPE approximation). tiktoken verification: python _audit2.py.

Third-party research & context window economics

Source Finding Why it matters
Anthropic, Context Windows for Agents “Context window is a scarce resource. Every token of schema is a token stolen from the user's actual task.” MCP schemas are the #1 source of context waste in agent workflows
OpenAI, Function Calling Guide Tool definitions consume context tokens proportional to schema complexity 100+ tools with full schemas can eat 40-80% of a 128K context window
Cursor Team, Context Engineering “The difference between a good and bad agent is almost always context management, not model intelligence.” Token optimization at the transport layer (like TOON) directly improves agent quality
Latent Space, MCP Ecosystem Analysis “The MCP protocol injects full JSON schemas into every request — this is by design, but it creates a scaling cliff around 20-30 tools.” Confirms the problem mcptoon solves: 20-30 tools is the pain point, not 100+
Simon Willison, LLM Tooling “JSON is the least token-efficient format possible for structured data sent to an LLM.” Validates TOON's approach: any non-JSON encoding saves tokens
GitHub Issues Puppeteer MCP (47 tools) + Playwright MCP (52 tools) = ~50K tokens of schemas alone Two browser MCP servers consume more context than this entire README

Quick start

pip install mcptoon

Zero dependencies. 50KB. Python 3.10+. Windows, macOS, Linux.

mcptoon init                          # Sample config: ~/.mcptoon/config.json
mcptoon add fetch --stdio npx -y @modelcontextprotocol/server-fetch
mcptoon manifest --compact            # → all tool names, 350 tokens
mcptoon manifest --slim               # → tool schemas, 93% smaller than JSON
mcptoon call fetch fetch '{"url":"https://example.com"}' --toon

Works with every agent

mcptoon is a CLI tool. If your agent can run shell commands, it can use mcptoon. No plugins. No SDK. No per-agent MCP setup. No JSON config editing.

Agent How to use
Claude Code Write mcptoon commands in SKILL.md files
Codex (OpenAI) Add mcptoon to AGENTS.md
OpenCode Use mcptoon in custom commands
Cursor Add mcptoon to .cursorrules
CatPaw Write mcptoon commands in skill files
Any agent If it runs shell commands, it can call mcptoon

Configure once in ~/.mcptoon/config.json. Every agent shares the same servers, the same tools, the same token savings. Switch agents? Config follows you. No migration.

export MCPTOON_AGENT_TYPE=claude   # auto-select --toon for all calls

Agent self-service

Your agent can add MCP tools on its own — no human intervention needed:

# Agent wants a web scraper? Just add it:
mcptoon add firecrawl --stdio npx -y firecrawl-mcp

# Agent wants GitHub access? One command:
mcptoon add github --stdio npx -y @modelcontextprotocol/server-github

# Verify everything works:
mcptoon doctor

# Use it immediately:
mcptoon call github search_repos '{"query":"token optimization"}' --toon

No JSON config files. No RPC debugging. No server restarts. Just CLI commands.

How TOON works

TOON (Token-Optimized Object Notation) is mcptoon's encoding that compresses JSON for LLM consumption. Savings come from structural compression — removing JSON braces, quotes, brackets, and type wrappers — not from scalar substitution.

JSON TOON Why
{"name":"search","count":3} name:search|count:3 Pipes replace braces + quotes + colon
[1, 2, 3] 1 2 3 Spaces replace brackets + commas
true / false true / false Kept as-is (1 token either way)
null null Kept as-is (∅ costs 2 tokens, worse)
"a:b" a_b Colons → underscore (avoids pipe ambiguity)
{"a":{"b":[1,2]}} a:b:1_2 Recursive compaction

tiktoken verification (o200k_base / cl100k_base):

{"content":[{"type":"text","text":"hello"}]}  →  hello         (85% savings)
{"type":"object","properties":{"q":{"type":"string"}}}  →  q:s*        (83% savings)
{"name":"search","count":3,"cached":true,"error":null}  →  name:search|count:3|cached:true|error:null  (24% savings)

Token optimization at the transport layer is mcptoon's primary focus.

Output formats

Flag What you get Token footprint
--compact Tool names only, space-separated 97% less than JSON
--slim Ultra-compact schemas (name|param:type*) 93% less than JSON
--toon Compact notation, full semantics 20-40% less than JSON (tiktoken-verified)
--json Standard JSON (for scripts, CI) Baseline
--raw Raw response, no parsing Full size
--head N First N items only Variable
--max-chars N Hard truncate at N chars Variable
--full Disable the default 4000-char truncation Full size

SLIM mode

When you need tool schemas but want maximum token savings:

$ mcptoon manifest --slim
search|q:s*|n:n
fetch|url:s*
create|meta:o{title,tags}|tags:a[s]

Format: tool_name|param:type*|param:type

  • s=string n=number b=boolean a[type]=array o{keys}=object
  • * marks required parameters

93% token savings vs JSON for full tool schemas.

Architecture — Three-layer decoupling

mcptoon is built on a three-layer decoupled architecture. Each layer is independent — swap one without touching the others.

┌─────────────────────────────────────────────────┐
│  Layer 1: mcptoon CLI (~50KB, zero deps)         │
│  ─────────────────────────────────────────────   │
│  Runs in your agent's shell. Token-optimizes     │
│  everything. No schemas in context. Ever.        │
└──────────────────────┬──────────────────────────┘
                       │ reads JSON templates (on disk)
┌──────────────────────▼──────────────────────────┐
│  Layer 2: MCP Server Profiles (~1KB each)         │
│  ─────────────────────────────────────────────   │
│  23 JSON templates in mcp/stdio/*.json.           │
│  Not installed software — just connection specs.  │
│  Security-audited: credential_safe, env_vars,     │
│  permissions declared per profile.                │
│  Add your own — it just works.                    │
└──────────────────────┬──────────────────────────┘
                       │ spawns on-demand via npx
┌──────────────────────▼──────────────────────────┐
│  Layer 3: Actual MCP Servers (npm packages)       │
│  ─────────────────────────────────────────────   │
│  Real MCP servers (@modelcontextprotocol/server-* │
│  etc). Only launched when you actually call a     │
│  tool. Not installed at config time.              │
│  Not loaded at startup. Zero overhead until use.  │
└─────────────────────────────────────────────────┘

Why three layers?

  • Layer 1 (CLI) stays tiny — 50KB, zero deps. No MCP SDK bloat.
  • Layer 2 (Profiles) are editable JSON — add, remove, fork without touching code. Each is a ~1KB file describing how to connect, not the server itself.
  • Layer 3 (Servers) spin up lazily — only when mcptoon call actually runs. No idle processes. No startup tax.

This means:

  • 100 servers configured → 0 running until you use one
  • Remove a profile → the rest work fine
  • Add a profile → no code changes, no rebuild
  • mcptoon never bundles MCP servers — you install what you use

Security-audited profiles

Every profile declares its security posture:

// mcp/stdio/puppeteer.json
{
  "name": "puppeteer",
  "security": {
    "audited": true,
    "credential_safe": true,
    "env_vars_required": [],
    "permissions": ["read: web pages, DOM", "write: form inputs, JS execution"]
  },
  "bundled": false,
  "install_method": "on-demand"
}

23 profiles: fetch, github, exa, brave-search, firecrawl, filesystem, memory, sequential-thinking, sqlite, time, puppeteer, playwright, postgres, slack, notion, git, gitlab, tavily, google-maps, docker, aws, cloudflare, tmux. See mcp/README.md.

Full ecosystem plan

Features

Tested with 255+ MCP tools across 23+ servers, 30K+ real calls.

  • --stdin — Pipe large payloads bypassing OS command-line limits
  • doctor — One-command self-diagnosis (Python, config, servers, connectivity)
  • discover — Server health check with tool counts
  • Tool poisoning guard — Detects prompt injection in MCP results (ignore previous instructions, [INST], data exfiltration attempts)
  • Credential leak detection — Scans tool results for exposed API keys, AWS keys, GitHub PATs, OpenAI/Anthropic keys, Slack tokens, JWTs, private keys — blocks them before they reach your agent's context
  • Fuzzy match — "Did you mean: search, search_all?" on typos
  • Cross-agent export--format openai|openapi|mcp for non-CLI agents
  • Schema cache — 5-min TTL, avoids repeated tools/list round-trips
  • Usage tracking — Local-only call statistics and token estimates
  • Dangerous-op blocking — Blocks delete/drop/purge unless --destructive
  • Shell completion — bash, zsh, fish, PowerShell

Security layers

Layer What it does Example
Dangerous-op guard Blocks delete/drop/purge/kill by default docker_remove → blocked unless --destructive
Prompt injection guard Scans results for injection patterns "ignore previous instructions" → blocked
Credential leak guard Scans results for exposed keys/tokens sk-abc...xyz → blocked, masked in error message
# Credential leak detection in action:
$ mcptoon call github get_file --toon
# Error: CREDENTIAL_LEAK — potential OpenAI API Key leak detected: sk-abc...wxyz
# The result never enters your agent's context.

🌐 Ecosystem

Component What it is Status
📦 Server Profiles 23 ready-to-use MCP server profiles (186+ tools) 23 → 100+
🔧 TOON Format Token-optimized notation (open spec) v1 in mcptoon
📚 Integration Guides Agent-specific setup docs Coming soon
🏷️ Powered by Badge For MCP servers using mcptoon Available

Python API

from mcptoon.client import MCPClient
from mcptoon.output import toon

with MCPClient(stdio=["npx", "-y", "@modelcontextprotocol/server-fetch"]) as c:
    tools = c.list_tools()
    print(toon(tools))         # compact TOON
    result = c.call_tool("fetch", {"url": "https://example.com"})
    print(toon(result))

Config

# stdio (any npx MCP server)
mcptoon add fetch --stdio npx -y @modelcontextprotocol/server-fetch
mcptoon add github --stdio npx -y @modelcontextprotocol/server-github

# HTTP
mcptoon add myapi --http http://localhost:3001/mcp --header "Authorization: Bearer xxx"

Config lives at ~/.mcptoon/config.json. Project-level override at ./.mcptoon.json.

Privacy

  • No telemetry. No analytics, no crash reports, no phone-home.
  • No credential storage. API keys pass through from your config or env vars.
  • No dependencies. Pure Python stdlib. No supply chain to audit.
  • Credential leak guard. Scans tool results for exposed API keys/tokens — blocks them before they reach your agent.

Architecture

src/mcptoon/
├── cli.py        # CLI entry + arg parsing
├── client.py     # MCPClient — stdio + HTTP transport
├── router.py     # Tool routing, custom handlers, poisoning + credential leak detection
├── config.py     # Server config
├── manifest.py   # Tool discovery with cache
├── output.py     # TOON / JSON / compact / slim rendering
├── cache.py      # Schema cache (5-min TTL)
├── usage.py      # Local usage tracking
└── errors.py     # Structured error envelopes

~2,500 lines. 187 tests. Zero third-party imports. 50KB installed.

Contributing

git clone https://github.com/activeing123/mcptoon.git
cd mcptoon
pip install -e . --no-build-isolation
pip install pytest pytest-cov
python -m pytest tests/ -v   # 187 tests, 0.2s

Zero dependencies is a hard rule. New features need tests. See CONTRIBUTING.md.

License

Apache 2.0. See LICENSE and NOTICE.


mcptoon is an independent third-party MCP client. Not affiliated with Anthropic.

Found this useful? Star the repo to help others find it.

Report Bug | Request Feature

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mcptoon-0.3.0.tar.gz (53.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

mcptoon-0.3.0-py3-none-any.whl (42.8 kB view details)

Uploaded Python 3

File details

Details for the file mcptoon-0.3.0.tar.gz.

File metadata

  • Download URL: mcptoon-0.3.0.tar.gz
  • Upload date:
  • Size: 53.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for mcptoon-0.3.0.tar.gz
Algorithm Hash digest
SHA256 23ce3ac12c3933efdf9ddc900f0c595bf56c889028d305df8b272248d29b0dc3
MD5 72cc5c9ec0d32e50ff8e6f3f368c2ad8
BLAKE2b-256 acb243cadcdb3a72344bf4ff9c1671a3745283d0fc124eb303de7a8d9d324807

See more details on using hashes here.

File details

Details for the file mcptoon-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: mcptoon-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 42.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for mcptoon-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7505402b45e23d9c3ff8353466bfc0bfb85c7238ca404dfa6d09fb8449356445
MD5 b571b7054002ca3bbcb636d3eb5bd4e4
BLAKE2b-256 9ca31a92910bd3cd5186a21dc97c1124a5d54cd215c914833d34d1fe23a333de

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page