But MCP today isn’t ideal. I think we need to have some catalogs where the agents can fetch more information about MCP services instead of filling the context with not relevant noise.
I know I saw something about the Next.js devs experimenting with just dumping an entire index of doc files into AGENTS.md and it being used significantly more by Claude than any skills/tool call stuff.
LLM only know `linear` tool exists.
I ask "get me the comments in the last issue"
Next call LLM does is
`linear --help 2>&1 | grep -i -E "search|list.issue|get.issue")` then `linear list-issues --raw '{"limit": 3}' -o json 2>&1 | head -80)` then `linear list-comments --issue-id "abc1ceae-aaaa-bbbb-9aaa-6bef0325ebd0" 2>&1)`
So even the --help has filtering by default. Current models are pretty good
First, MCP tools are sent on every request. If you look at the notion MCP the search tool description is basically a mini tutorial. This is going right into the context window. Given that in most cases MCP tool loading is all or nothing (unless you pre-select the tools by some other means) MCP in general will bloat your context significantly. I think I counted about 20 tools in GitHub Copilot VSCode extension recently. That's a lot!
Second, MCP tools are not compossible. When I call the notion search tool I get a dump of whatever they decide to return which might be a lot. The model has no means to decide how much data to process. You normally get a JSON data dump with many token-unfriendly data-points like identifiers, urls, etc. The CLI-based approach on the other hand is scriptable. Coding assistant will typically pipe the tool in jq or tail to process the data chunk by chunk because this is how they are trained these days.
If you want to use MCP in your agent, you need to bring in the MCP model and all of its baggage which is a lot. You need to handle oauth, handle tool loading and selection, reloading, etc.
The simpler solution is to have a single MCP server handling all of the things at system level and then have a tiny CLI that can call into the tools.
In the case of mcpshim (which I posted in another comment) the CLI communicates with the sever via a very simple unix socket using simple json. In fact, it is so simple that you can create a bash client in 5 lines of code.
This method is practically universal because most AI agents these days know how to use SKILLs. So the goal is to have more CLI tools. But instead of writing CLI for every service you can simply pivot on top of their existing MCP.
This solves the context problem in a very elegant way in my opinion.
I've also launched https://mcpshim.dev (https://github.com/mcpshim/mcpshim).
The unix way is the best way.
> Before your agent can do anything useful, it needs to know what tools are available. MCP’s answer is to dump the entire tool catalog into the conversation as JSON Schema. Every tool, every parameter, every option.
Because this simply isn't true anymore for the best clients, like Claude Code.
Similar to how Skills were designed[1] to be searchable without dumping everything into context, MCP tools can (and does in Claude Code) work the same way.
See https://www.anthropic.com/engineering/advanced-tool-use and https://x.com/trq212/status/2011523109871108570 and https://platform.claude.com/docs/en/agents-and-tools/tool-us...
[1] https://agentskills.io/specification#progressive-disclosure
Awesome TUIs: https://github.com/rothgar/awesome-tuis
Awesome CLIs: https://github.com/agarrharr/awesome-cli-apps
Terminal Trove: https://terminaltrove.com/
I guess this is another one shows that the CLI and Unix is coming back in 2026.
Even the smallest models are RL trained to use shell commands perfectly. Gemini 3 flash performs better with a cli with 20 commands vs 20+ tools in my testing.
cli also works well in terms of maintaining KV cache (changing tools mid say to improve model performance suffers from kv cache vs cli —help command only showing manual for specific command in append only fashion)
Writing your tools as unix like cli also has a nice benefit of model being able to pipe multiple commands together. In the case of browser, i wrote mini-browser which frontier models use much better than explicit tools to control browser because they can compose a giant command sequence to one shot task.
ALSO... the permission boundary is clearer. You can whitelist commands, flags, working dir... it becomes manageable.
HOWEVER... packaging still matters. A “small” CLI that pulls in a giant runtime kills the benefit.
I want the discipline of small protocol plus big cache. Cheap models can summarize what they did and avoid full context in every step...
But yeah, a concrete example is playwright-mcp vs playwright-cli: https://testcollab.com/blog/playwright-cli
I can see a future where software is built with a CLI interface underneath the (optional) GUI, letting an LLM hook directly into the underlying "business" logic to drive the application. Since LLM's are basically text machines, we just need somebody to invent a text-driven interface for them to use...oh wait!
Imagine booking a flight - the LLM connects to whatever booking software, pulls a list of commands, issues commands to the software, and then displays the output to the user in some fashion. It's basically just one big language translation task, something an LLM is best at, but you still have the guardrails of the CLI tool itself instead of having the LLM generate arbitrary code.
Another benefit is that the CLI output is introspectable. You can trace everything the LLM is doing if you want, as well as validate its commands if necessary (I want to check before it uses my credit card). You don't get this if it's generating a python script to hit some API.
Even before LLM's developers have been writing GUI applications as basically a CLI + GUI for testability, separation of concerns etc. Hopefully that will become more common.
Also this article was obviously AI generated. I'm not going to share my feelings about that.
Edit: took out because I think that was something different.
Compared both
---
TL;DR CLIHUB compiles MCP servers into portable, self-contained binaries — think of it like a compiler. Best for distribution, CI, and environments where you can't run a daemon.
mcpshim is a runtime bridge — think of it like a local proxy. Best for developers juggling many MCP servers locally, especially when paired with LLM agents that benefit from persistent connections and lightweight aliases.
---
https://cdn.zappy.app/b908e63a442179801e406b01cf412433.png (table comparison)
---
Regardless, most MCPs are dumping. I know Cloudflare MCP is amazing but other 1000 useful MCPs are not.
I was actually thinking if I should support daemons just to support playwright. Now I don't have a use case for it
CLIHub
- written in go
- zero-dependency binaries
- cross-compilation built-in (works on all platforms)
- supports OAuth2 w/ PKCE, S2S, Google SA, API key, basic, bearer. Can be extended further
MCPorter
- TS
- huge dependency list
- runtime dependency on bun
- Auth supports OAuth + basic token
- Has many features like SDK, daemons (for certain MCPs), auto config discovery etc.
MCPorter is more complete tbh. Has many nice to have features for advanced use cases.
My use case is simple. Does it generate a CLI that works? Mainly oauth is the blocker since that logic needs to be custom implemented to the CLI.
https://github.com/thellimist/thellimist.github.io/blob/mast...
https://github.com/thellimist/thellimist.github.io/blob/mast...
I dump a voice message, then blog comes out. Then I modify a bunch of things, and iterate 1-2 hours to get it right

Every AI agent using MCP is quietly overpaying. Not on the API calls themselves - those are fine. The tax is on the instruction manual.
Before your agent can do anything useful, it needs to know what tools are available. MCP’s answer is to dump the entire tool catalog into the conversation as JSON Schema. Every tool, every parameter, every option.
CLI does the same job but cheaper.
I took an MCP server and generated a CLI from it using CLIHub. Same tools, same OAuth, same API underneath. Two things change: what loads at session start, and how the agent calls a tool.
The numbers below assume a typical setup: 6 MCP servers, 14 tools each, 84 tools total.
MCP dumps every tool schema into the conversation upfront. CLI uses a lightweight skill listing - just names and locations. The agent discovers details when it needs them.1
MCP loads this (~185 tokens * 84 = 15540):
{
"name": "notion-search",
"description": "Search for pages and databases",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "The search query text"
},
"filter": {
"type": "object",
"properties": {
"property": { "type": "string", "enum": ["object"] },
"value": { "type": "string", "enum": ["page", "database"] }
}
}
}
},
{
"name": "notion-fetch",
...
}
... (84 tools total)
}
CLI loads this (~50 tokens * 6 = 300):
<available_tools>
<tool>
<name>notion</name>
<description>CLI for Notion</description>
<location>~/bin/notion</location>
</tool>
<tool>
<name>linear</name>
...
</tool>
... (6 tools total)
</available_tools>
Once the agent knows what’s available, it still needs to call a tool.
MCP tool call (~30 tokens):
{
"tool_call": {
"name": "notion-search",
"arguments": {
"query": "my search"
}
}
}
CLI tool call (~610 tokens):
# Step 1: Discover tools (~4 + ~600 tokens)
$ notion --help
notion search <query> [--filter-property ...]
Search for pages and databases
notion create-page <title> [--parent-id ID]
Create a new page
... 12 more tools
------------------------------------------------
# Step 2: Execute (~6 tokens)
$ notion search "my search"
MCP’s call is cheaper because definitions are pre-loaded. CLI pays at discovery time - --help returns the full command reference (~600 tokens for 14 tools), then the agent knows what to execute.
| Tools used | MCP | CLI | Savings |
|---|---|---|---|
| Session start | ~15,540 | ~300 | 98% |
| 1 tool | ~15,570 | ~910 | 94% |
| 10 tools | ~15,840 | ~964 | 94% |
| 100 tools | ~18,540 | ~1,504 | 92% |
CLI uses ~94% fewer tokens overall.
Anthropic launched Tool Search which loads a search index instead of every schema then uses fetch tools on demand. It typically drops token usage by 85%.
Same idea as CLI’s lazy loading. But when Tool Search fetches a tool, it still pulls the full JSON Schema.2
| Tools used | MCP | TS | CLI | Savings vs TS |
|---|---|---|---|---|
| Session start | ~15,540 | ~500 | ~300 | 40% |
| 1 tool | ~15,570 | ~3,530 | ~910 | 74% |
| 10 tools | ~15,840 | ~3,800 | ~964 | 75% |
| 100 tools | ~18,540 | ~12,500 | ~1,504 | 88% |
Tool Search is more expensive, and it’s Anthropic-only. CLI is cheaper and works with any model.
I struggled finding CLIs for many tools so built CLIHub a directory of CLIs for agent use.
Open sourced the converter - one command to create CLIs from MCPs.
I like using formatting of Openclaw's available_skills block for CLI. It can be modified to other formats.
Tool Search: ~500 session start + ~3K per search (loads 3-5 tools) + ~30 per call. Assumes 1 search for 1-10 calls, 3 searches for 100.
Official MCPs are trusted. Official MCPs CLIs are trusted.
I didn't release the website yet. I'll remove the link
One important aspect of mcpshim which you might want to bring into clihub is the history idea. Imagine if the model wants to know what it did couple of days ago. It will be nice to have an answer for that if you record the tool calls in a file and then allow the agent to query the file.
My use cases are almost all 3rd party integrations.
Have you seen any improvements converting on MCPs that require persistency into CLI?