mcptoon
MCP tool discovery costs 10,000+ tokens. mcptoon's costs 350.
One MCP client for every AI agent. Cross-platform. Zero dependencies.
Here's what happens in a typical MCP-enabled conversation:
- Your agent connects to 5 MCP servers. Listing their tools: ~10,000 tokens of JSON —
{"name":"...","description":"...","inputSchema":{"type":"object","properties":{...}}}repeated for every tool. - Your agent calls 20 tools. Each returns 500-3,000 tokens wrapped in
{"content":[{"type":"text","text":"..."}]}. - Total MCP overhead: 40,000-70,000 tokens — brackets, quotes, commas, schema declarations — before any actual thinking happens.
On a 128K context window, that's 30-55% gone. Not on work. On syntax.
mcptoon fixes this. It's a CLI client that connects to any MCP server (stdio or HTTP transport) and outputs TOON (Token-Optimized Object Notation) instead of JSON.
| Operation | JSON tokens | mcptoon tokens | Savings |
|---|---|---|---|
| Tool discovery (96 tools) | ~2,000 | ~60 | 97% |
| Tool result (structured data) | ~800 | ~350 | 56% |
| Tool result (raw HTML/text) | ~1,000 | ~900 | 10% |
TOON strips JSON syntax — brackets, quotes, commas, repeated type declarations. What remains is real data: repo names, star counts, search results, web page content. That's the part you actually need.
Zero dependencies. Pure Python. 50KB. And because it's a CLI tool, it works with every AI agent — Claude Code, Codex, OpenCode, Cursor, CatPaw, anything that runs shell commands. One config, one command, every agent gets MCP access.
Show me
JSON (287 tokens) — what every other MCP client returns:
[
{"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
TOON with full schema (115 tokens) — when you need the details:
name:search_web|description:Search_the_web|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
98% reduction for tool discovery, 60% for full schema, zero information lost.
Install
pip install mcptoon
Zero dependencies. 50KB. Python 3.10+. Windows, macOS, Linux. Done.
30 seconds to your first saved tokens
mcptoon init
# Sample config created: ~/.mcptoon/config.json
mcptoon add fetch --stdio npx -y @modelcontextprotocol/server-fetch
mcptoon manifest --toon
# → fetch:fetch
mcptoon call fetch fetch '{"url":"https://example.com"}' --toon
mcptoon call fetch fetch '{"url":"https://example.com"}' --json # when you need JSON
That's it. Every --toon call saves tokens: 97% on tool discovery, 40-60% on structured results, 10-20% on raw content.
How TOON works
TOON strips the structural scaffolding JSON needs for machine parsing — brackets, quotes, commas, repeated type declarations — none of which adds semantic value for an LLM.
| JSON | TOON | Why |
|---|---|---|
{"name":"search","count":3} |
name:search|count:3 |
Pipes replace braces + quotes + colons |
[1, 2, 3] |
1 2 3 |
Spaces replace brackets + commas |
true / false |
T / F |
1 char vs 4-5 |
null |
∅ |
1 symbol vs 4 chars |
"line1\nline2" |
line1↲line2 |
↲ replaces escape sequence |
{"a":{"b":[1,2]}} |
a:b:1_2 |
Recursive compaction |
The AI gets the same data. It can reconstruct the full structure from TOON output. We just stopped charging you tokens for {"type":"object","properties": over and over.
Output formats
| Flag | What you get | Token footprint |
|---|---|---|
--toon |
Compact notation, full semantics | 40-60% less than JSON |
--compact |
Tool names only, space-separated | 97% less than JSON |
--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 |
Set MCPTOON_AGENT_TYPE=claude and every call auto-selects --toon. No need to add the flag manually.
Examples
GitHub repo search — 287 → 115 tokens (60% saved)
$ mcptoon call github search_repos '{"query":"mcp"}' --toon
total_count:234|items:name:mcp-server|full_name:anthropic/mcp-server|stargazers_count:1234|description:Official_MCP_server name:mcp-client|full_name:anthropic/mcp-client|stargazers_count:567|description:MCP_client_library
$ mcptoon call github search_repos '{"query":"mcp"}' --compact
mcp-server mcp-client
96-tool manifest discovery — 2,034 → 62 tokens (97% saved)
$ mcptoon manifest --toon
fetch:fetch filesystem:read_file filesystem:write_file github:search_repos github:create_issue ...
Your agent now knows all 96 available tools and still has 97% of its context left to actually use them.
Web fetch — strips the MCP wrapper
$ mcptoon call fetch fetch '{"url":"https://example.com"}' --toon
<!DOCTYPE html><html><head><title>Example</title>...</html>
No {"content":[{"type":"text","text":"..."}]} wrapper. Just the content.
vs. other MCP clients
| mcptoon | mcp-cli | mcporter | raw MCP SDK | |
|---|---|---|---|---|
| Token savings | 97% manifest, 40-60% results | 0% | 0% | 0% |
| Works with all agents | yes (Claude Code, Codex, OpenCode, Cursor, any) | Claude only | Claude only | varies |
| One config for all agents | yes | no | no | no |
| Output formats | TOON + JSON + compact | JSON | JSON | JSON |
| Dependencies | 0 | 5-20 | npm | 3-8 |
| stdio transport (MCP servers) | yes | no | yes | yes |
| HTTP transport (MCP servers) | yes | yes (proxy) | yes | yes |
| Dangerous-op blocking | yes | no | no | no |
| Usage tracking | yes (local) | no | no | no |
| Schema cache | yes (5min) | no | no | no |
| Custom handlers | yes | no | no | no |
| Install size | ~50KB | ~50MB+ | ~30MB | ~10MB |
| Platform support | Windows, macOS, Linux | Linux/macOS | macOS | varies |
Same MCP servers. Same MCP protocol. Same results. 97% less tokens on discovery, 40-60% on results. Works on Windows, macOS, and Linux.
Works with every agent
mcptoon is a CLI tool. If your agent can run shell commands, it can use mcptoon. No SDK integration, no plugin, no per-agent config.
You configure your MCP servers once in ~/.mcptoon/config.json. Every agent shares the same servers, the same tools, the same token savings.
| Agent | How to use |
|---|---|
| Claude Code | Write mcptoon commands in SKILL.md files or custom instructions |
| Codex (OpenAI) | Add mcptoon to your AGENTS.md or prompt instructions |
| OpenCode | Use mcptoon in your custom commands or system prompt |
| Cursor | Add mcptoon to your .cursorrules or custom prompt |
| CatPaw | Write mcptoon commands in skill files |
| Any agent | If it runs shell commands, it can call mcptoon |
Claude Code
export MCPTOON_AGENT_TYPE=claude # auto-select --toon
# In ~/.claude/skills/mcp-tools/SKILL.md
Search the web:
`mcptoon call exa search '{"query":"AI news"}'`
List available tools:
`mcptoon manifest --toon`
Fetch a URL:
`mcptoon call fetch fetch '{"url":"https://example.com"}'`
Codex (OpenAI)
# In AGENTS.md or system prompt
Use mcptoon to call MCP tools. It saves 60% tokens vs JSON.
- List tools: `mcptoon manifest --toon`
- Call a tool: `mcptoon call <server> <tool> '{"args":"here"}' --toon`
- Inspect a tool: `mcptoon inspect <server> <tool>`
OpenCode
# In your OpenCode config or system prompt
export MCPTOON_AGENT_TYPE=claude
## Available MCP tools
Run `mcptoon manifest --toon` to see all tools.
Run `mcptoon call <server> <tool> '<json_args>' --toon` to call one.
Why one unified layer?
Without mcptoon, you configure MCP servers separately for each agent — Claude Code's claude_desktop_config.json, Cursor's MCP settings, OpenCode's config, etc. Same servers, different formats, different setups.
With mcptoon, you configure once. ~/.mcptoon/config.json is your single source of truth. Every agent calls mcptoon the same way. Add a server, every agent sees it instantly. Remove a server, it's gone everywhere.
Plus: every call saves 97% tokens on manifest discovery and 40-60% on tool results, no matter which agent you're using.
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))
Custom handlers — bypass MCP entirely
from mcptoon.router import register
@register("my-database", "db")
def handle_db(tool, args):
if tool == "query":
return {"rows": my_db.execute(args["sql"])}
return None # falls through to MCP
mcptoon call db query '{"sql":"SELECT * FROM users"}' goes straight to your handler. No MCP server needed.
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. Env var MCPTOON_SERVERS (JSON string) takes highest priority.
{
"servers": {
"fetch": {
"transport": "stdio",
"command": ["npx", "-y"],
"args": ["@modelcontextprotocol/server-fetch"]
},
"github": {
"transport": "stdio",
"command": ["npx", "-y"],
"args": ["@modelcontextprotocol/server-github"],
"env": {"GITHUB_PERSONAL_ACCESS_TOKEN": "ghp_xxx"}
}
}
}
Safety
mcptoon blocks operations that match dangerous patterns (delete, drop, purge, wipe, kill, force=true, confirm=true, etc.) unless you pass --destructive.
$ mcptoon call db delete_table '{"name":"users"}'
Error [CONFIRMATION_REQUIRED]: Dangerous operation needs confirmation
$ mcptoon call db delete_table '{"name":"users"}' --destructive
# runs
No surprises. No accidental data loss from an AI agent that got too creative.
Usage tracking
$ mcptoon usage
Total calls: 142
Success rate: 138/142
Tokens (est): 84,200
By server:
fetch 89
github 53
Top tools:
fetch:fetch 45
github:search_repos 38
Stored locally at ~/.cache/mcptoon/usage.json. Never transmitted.
Architecture
src/mcptoon/
├── cli.py # CLI entry + arg parsing
├── client.py # MCPClient — stdio + HTTP transport, MCPClientPool
├── router.py # Tool call routing, custom handlers, safety checks
├── config.py # Server config (~/.mcptoon/config.json + overrides)
├── manifest.py # Tool discovery with cache
├── output.py # TOON / JSON / compact rendering
├── cache.py # Schema cache (5-min TTL)
├── usage.py # Local usage tracking
└── errors.py # Structured error envelopes
~1,700 lines total. Zero third-party imports. The only network calls are to MCP servers you configure.
Privacy
- No telemetry. No analytics, no crash reports, no phone-home. Nothing leaves your machine.
- No credential storage. API keys pass through from your config or env vars. Never logged, never cached.
- No dependencies. Pure Python stdlib. No supply chain to audit, no packages to hijack, no updates to chase.
Local files: ~/.mcptoon/config.json (your config), ~/.cache/mcptoon/schema_cache.json (5-min cache), ~/.cache/mcptoon/usage.json (stats). Delete any of them, mcptoon recreates as needed.
Found a vulnerability? Email security@activeing123.github.io — don't open a public issue. 48h response, 7-day fix window. See SECURITY.md.
License
Apache 2.0. Commercial use, modification, distribution — all fine. Keep the LICENSE and NOTICE files, state your changes. The TOON format is open — implement it in your own tools, just attribute mcptoon. See LICENSE and NOTICE.
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 # 98 tests, 0.09s
Zero dependencies is a hard rule. New features need tests. See CONTRIBUTING.md.
mcptoon is an independent third-party MCP client. Not affiliated with Anthropic.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mcptoon-0.1.0.tar.gz.
File metadata
- Download URL: mcptoon-0.1.0.tar.gz
- Upload date:
- Size: 36.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ea55562622f8085b8e96702d5faabc4ea4111dee8398cbb63ad4e18ed617f191
|
|
| MD5 |
515aa0ba1feab2c4d06c4074606f92dd
|
|
| BLAKE2b-256 |
20642f4fdd48dff6b5d726124076ea6d8ddd962d06ece402776a1d1b25a715ff
|
File details
Details for the file mcptoon-0.1.0-py3-none-any.whl.
File metadata
- Download URL: mcptoon-0.1.0-py3-none-any.whl
- Upload date:
- Size: 33.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.10
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b1006bfc77469cd85015e5c9c07778edffa0ea92780c34f1e97d392433b324ad
|
|
| MD5 |
1be3bcac93650cf4987819053ed8ed3c
|
|
| BLAKE2b-256 |
713d6c162747329f9c3b1594b16c6a5b540fea1029c196acee7663ff7770038b
|