> curl -s -X POST "https://mcpclock.firasd.workers.dev/mcp" -H "Content-Type: application/json" -H "Accept: application/json, text/event-stream" -d '{"jsonrpc":"2.0","id": 1,"method":"tools/call","params":{"name":"clock_get","arguments":{}}}' | grep '^data:' | sed 's/^data: //'| jq
{"result": {"content": [{"type": "text",
"text": "[\n {\n \"timezone\": \"UTC\",\n \"iso\": \"2026-08-05T04:44:41.707Z\",\n \"unixtime\": 1785905081\n },\n {\n \"timezone\": \"Alphadec\",\n \"alphadec\": \"2026_P4A0_466322\"\n }\n]"
}]},"jsonrpc": "2.0", "id": 1}
The "just use a CLI" crowd is implicitly assuming:1) You're a developer 2) On a laptop 3) With a shell open inside an agentic coding harness (Claude Code, Codex CLI, Cursor) 4) Working on a software project
That's maybe 2% of AI usage.
The other 98% is: Someone on the ChatGPT iOS app asking a question on the subway; Someone in Claude.ai web chatting about their calendar; Someone using ChatGPT Desktop to summarize their Notion; A non-developer using AI in a browser at work; Voice mode on a phone; An embedded chat widget on some company's website...
This essentially makes MCP just another REST API endpoint, and lets you use the same infrastructure you already have set up for REST APIs (like load balancers, API gateways, progressive rollouts, etc).
disable-model-invocation: true
Most MCP servers still bloat up my context even when I am not using them at all. Why can't they be configured to allow me to keep them out unless I really need to use them?
a few months ago I tried to implement an MCP server from scratch in python (instead of using the existing reference implementation) and I could not get it to work reliably across clients
What about mcp-inspector? It’s a nice tool, can be used interactively, can be used as a CLI.
Wrote about this back in March: https://chrlschn.dev/blog/2026/03/mcp-is-dead-long-live-mcp/
MCP is going to be a foundational piece of enterprise agent infra.
Like a tool where the AI can only call out to certain APIs based on a config file the agent cannot change.
That way you can leverage all the shell knowledge agents already have while still limiting what network calls they can make, and you wouldn't have to set up a server to use an agent.
All those teams, including ChatGPT and Claude.ai, have figured out that you will eventually need to give your agent a small sandbox Linux environment to unlock the same level of “intelligence“ those coding harness exhibit. Stitching together the results of a cli command through scripting or coding gives the agent a ton more flexibility in what it can do as it can utilize its text generation capability into executable logic. toolcalls mostly work for actions rather than complex and novel problem solving. You are making the agent represent a programming control flow through toolcalls while carrying the context between them in a lossy, nondeterministic, wasteful, slow and rigid way.
It’s one thing if you want to artificially limit that agent to a very strict set of available APIs that it must use in a specific way while transferring context between them through the LLM and you don’t want to incur the cost of the extra sandbox compute. But coding harnesses have demonstrated that letting the agent write a small shell or python script can let the agents solve problems that you haven’t even really anticipated in your toolcall approach or that tool calls make prohibitively expensive or not even possible.
But also the token cost tends to dwarf the sandbox compute cost, so why not pay the $0.05/hour to have a sandbox where the agent can run free when you are already paying orders of magnitude more for the tokens
All of those use cases you mentioned benefit from the agent having access to a temporary virtual machine with a set of standard CLI tools and the ability to write and execute arbitrary code.
Most already do. ChatGPT has been running Python in the cloud to answer questions before we even had functional coding harnesses.
So why not augment their repertoire of CLI tools instead of a completely new protocol?
This doesn't cover the case when you're talking to an LLM from web, or via Slack or Linear, etc. There, you will want MCP so the LLM can use services on your behalf as you. That's portability.
your messages causing your LLM (harness) to run CLIs on your computer? charming, thrilling, great fun.
other people’s messages causing your LLM to run CLIs on your (cloud) computer? terrifying, awful, sickening, no fun at all
I learnt this with Sun RPC and the whole "The network is the computer".
Somehow this keeps having to be relearnt.
1. a REST-like API
2. with a spec (OpenAPI, introspection, etc.)
3. with harness-level authz (the ability to allow / deny specific methods in the harness)
The only part that's actually new is #3, but it seems like it should be fairly easy to provide similar support for REST APIs. There might already be a Pi extension that allows you to allow / deny particular method / path patterns for particular sites. Regardless, there's always service-level authz with service accounts, at least for the more sophisticated APIs.
So ya, I don't see why we need a whole new set of standards and protocols just to have harness-level fine-grained API permissions. We could have just done it all with REST.
npx @modelcontextprotocol/inspector --cli \
https://agentic-mermaid.dev/mcp \
--method tools/call \
--tool-name render_svg \
--tool-args-json '{"source":"graph TD; A-->B","options":{"padding":24}}'
Equivalent with my mcp-explorer tool: uvx mcp-explorer call \
https://agentic-mermaid.dev/mcp render_svg \
-a source 'graph TD; A-->B' \
-a options '{"padding":24}'
So yeah, they're pretty similar.Then for my list command:
uvx mcp-explorer list https://agentic-mermaid.dev/mcp
With the inspector one you would do: npx @modelcontextprotocol/inspector --cli \
https://agentic-mermaid.dev/mcp \
--method tools/list
Mine returns a human-readable list (unless you add --json), the inspector one returns a big dump of raw JSON.As a result, everything compounds. The work I do doesn't need to be re-derived by the work you do. Typed models keep everything repeatable and deterministic. Huge reduction in token spend and huge increase in speed.
I love this question because of the diverse answers given and we learn from each other.
Nowadays, these agents are more capable and I think you can replace MCP (which is a pain on macOS), with simple CLI tools and expose them to agents via system prompt, skills, or other API documentation.
I am guessing keeping them all in every request is cache efficient though.
But you can have both: rund the agent outside the vm/sandbox and orchestrate work on it, either directly via shell calls or kicking off an ephemeral subagent on the box.
This makes the agent and session that runs outside the vm more durable and opens new orchestration pattern.
I’m building the oss version of this here: https://github.com/smartcomputer-ai/lightspeed
When you talk to an LLM on the web, the harnesses spin up a fresh environment (I would hope it’s a VM…) so that the LLM can do stuff like run arbitrary Python and Bash scripts to complete the task you asked it for.
There’s no reason why you shouldn’t be able to customize this environment to add whatever CLI tools and credentials you need for the agent to act on your behalf.
The UX would be exactly the same.
I maintain https://endara.ai and you can very quickly introduce a ton of capabilities for Claude/Cursor/ChatGPT by configuring all the stuff you use in a single place (and slicing them with profiles if needed).
Might break the caching, perhaps this can be solved with snapshot ids or cache ids like "Replacing context line 434-500 with hint; checking last request before that context even was added and running that cache before"
Companies can implement Individual Oauth with DCR (which makes it as easy as "log in with Google"), but many don't
But let’s take my MCP clock for example if you ask ChatGPT what’s the time in Tokyo it’s not even gonna think of booting up the code interpreter. It’s gonna just do web search and give you the wrong time (I just tried it and there may be an OpenAI built in widget it pops up now—but again that’s a specific tool call with an iframe output not arbitrary code)
It’s not true. It’s not totally untrue, but don’t hide your head in the sand.
In this specific post the SQL example gets around this by being super low-level, inherently composable, and low context consumption itself. I’m not sure this works for everyone.
Looking at the Linear MCP for example, they basically just want to expose an API surface and provide 32 MCP tools as a result of that. My agents do run into composability problems here all the time and fall back to the tool they included which allows you to run arbitrary GraphQL. This takes a couple tries usually. I don’t really know what the sensible alternative to this is.
Cloudflare switched to “code mode” which basically provides 2 MCP tools: search and execute. Both take a TS arrow function, the first allows you to programmatically search a TS api spec, the second to compose and run the methods in that spec.
I think this is a very interesting approach, and certainly better than providing the ~1000 actions as MCP tools but I feel the jury is still out on exactly how well this pans out.
From my experience, instructions in `.md` files aren't enough. In fact, Claude seems to prefer the shell over even its own built-in tools (e.g. `read`, `edit` etc.) See: https://github.com/anthropics/claude-code/issues/19649. It's like an old dog that needs to be tricked to learn new tricks.
Not sure whats the downside of this approach is but its serving us well so far.
I would love to see a proper engineering post-mortem for how this happened.
Is that roughly accurate? We are talking about a technology that would allow SaaS API vendors to publish a second set of documentation (or adapt the same one to both human and LLM targetted channels)?
I'm being a bit cynical, but here's my minimal naïve alternative solution, not proposing it be used, but just saying that this would be equivalent:
1- Publish a well known endpoint like /docs_url , which could return something like "docs.domain".
2- Support an alternative content-type header, where instead of 'text/html' the client could ask for 'text/plain', or 'text/markdown'
2b- Alternatively, changing the extension type could achieve the same result, where requesting docs.domain/endpoint.txt would return the docs in text instead of in html
So now I ask, how is MCP better than the solution I proposed? Did I grossly misunderstand something? Or am I on track to avoiding hundreds of engineering hours due to accidental complexity by recognizing and avoiding a privately funded protocol that serves to increase vendor lock instead of reducing complexity of our systems?
If we're talking protocols, it's useful to know the distinction.
There have been many flame wars around REST vs RPC and whether most "RESTful" implementations out there are actually RPC with a funny nose.
What? I never realized it was the case. I was calling my handcrafted MCP server without the header all the time!
I thought it was The Browser Company’s invention?
https://claude.com/blog/skills
> Introducing Agent Skills
> October 16, 2025
I can find articles and Reddit posts about Dia Browser’s Skills from July 2025.
I propose AII - AI Interface. Lets make it happen!
The idea could be that the agent runs as a unix user. That user has execute access to these scripts but not read or write access.
So the agent can only do what those scripts allow, the scripts present an API. You could let agents call the scripts with -h to get instructions, and just put some text into context saying like "to access helper scripts call ./showHelp".
Now that the models are getting better, you can trust them to book barber appointments, order groceries, manage your calendar, etc etc. It's significantly lazier to ask an agent to do something than manually doing it. Especially with voice to text.
I'm predicting that chat bots will auto-discover MCPs from trusted websites and make life much easier.
I feel like 5% of people who develop MCP Servers for a living and 10% of the people who develop MCP Clients for a living use the MCP Inspector and understand the Protocol.
The point is that even web search should be a CLI tool, and all ChatGPT would know to do other than talk to you is how interact with a shell.
Then if you ask it what’s the time in Tokyo, it would likely reach for the POSIX date command, instead of web search, because both would be equally visible.
This is easy to see when you think in terms of a client: It is pretty much impossible to build an opinionated UI for any kind of RESTful API, while creating one for an MCP server is fairly self-explanatory: MCP servers offer a mandatory and complete runtime introspection endpoint (you can retrieve a listing of available tools/resources/prompts etc. along with their parameter and return type schemas). So that means clients have a way to exhaustively describe everything an MCP server is able to do with a vocabulary that carries over exactly to other servers - a tool is a tool everywhere.
I think that’s a future plenty of people see or want. But simpler and composable Linux commands are far more flexible than pre-defined Windows or Mac “Settings App”. The barrier to entry for the former was knowledge and familiarity, while the latter optimizes for simpler user experience. Agents don’t have to worry about knowledge or familiarity the way users do.
Optimizing the interface for agents to do a “get_clock | get_calendar_events | filter_by(2_hours_from_now)” or then thinking “we should add a get_calendar_events(filter_by_start=now() + 2h) tool” is too rigid for little benefit. And makes it more likely that you will optimize for scenarios you care about and lose a lot of what makes coding harnesses appear really “intelligent” by solving problems quickly as they go
An MCP tool call that returns the top N spenders puts the result in the agent’s context window.
A CLI tool call on the other hand… The agent can pipe their results into other completely unrelated CLI tools. It can write a loop that calls multiple tools.
These things are not possible with MCP but are trivial with CLIs.
The difference is that we already have Bash :)
There are multiple products that turn OpenAPI schemas into front-ends nowadays.
they do but more importantly model does not give a flying fuck about what you put in there in any consistent way.
ppl have been mislead by ai companies that they've invented some sort of agi that you can 'explain' to using skills. So ppl have come up with also sorts of skills that dont do jack shit.
[1] Recently: Opus 4.7/4.8 and Kimi K3
Code mode is great but not needed anymore in 95% of use-cases.
But I wouldn't discount how uphill it was to probably even argue for something like MCP cause the labs still very scientist-driven and focused on solving everything in token space. The idea that tool use could be super transformative probably wasn't obvious from inside before Claude Code
The actual implementation may have been very janky but the idea itself is sound: If you want to interact with arbitrary services then providing one single protocol (ideally not JSONRPC but hey) with a standard api discovery method and standard starting method call means your super-intelligent machine god can connect to any MCP service with just a URL and figure everything out from there.
I have long observed that tooling+methodology is a very distinct skillset in software developers - those who treat both subjects with appropriate governance, excel - those who ignore one for the other, tend to make a mess of it.
If you don't have the methods, you will re-invent tools to find those methods. If you don't have tools, you will develop methods sufficient to the creation of those tools. Too many times, folks who have no method of finding existing tools, will instead just build a duplicate tool .. which they will use until they learn the tool-discovery method.
I think AI/ML is really turning the tooling+methodology equation into a maelstrom. Apropos proper engineering post-mortem, I would question the impact on AI/ML-derived riches on the drive to turn standard methods into Subscription Services© behind Yet Another Tool™ ..
Someone should have said to the llm coming up with it -- "that sounds like an API with extra steps ... how about we keep these things (tool descriptions) and get rid of all this irrelevant - this will look good in my promotion meeting - overengineering (everything else)"
You are absolutely right is what it would have replied with.
Of course they do. Do you really think that there's a magical bag of holding for the potentially infinite amount of skills?
Only when my AI and its subagents are modelled through a graph of producing agents, consuming agents, and agentic mailboxes, will Claude Code truly shine.
The reason is that these "folks getting paid several hundred thousand dollars a year" are mostly youngsters without any care to learn about computing history, which is why IT is a fashion industry.
See HTMX as another example, that is basically ASP.NET Ajax or JSF Ajax.
Now when I ask ChatGPT for a product, it does a web_search tool call and then gives me a link to a webshop product page. But next step would be automatically using the MCP of that webshop to embed checkout inside chat.
31st July 2026
Tuesday was Stateless MCP day—the rollout of MCP 2.0, or the 2026-07-28 Model Context Protocol specification to use the more formal but less memorable name. This is the most significant change to the MCP spec since it first launched, and has also served to reignite my personal interest in the protocol.
For background: MCP is the Model Context Protocol, which describes a standard way to expose new tools to LLM-powered agent frameworks. It was introduced by Anthropic back in November 2024, had a huge spike of interest through much of 2025, and then became somewhat eclipsed by Skills (another Anthropic invention) when it became apparent that an agent harness with access to a terminal and curl could do most of what MCP did in a more flexible way. I wrote about that in my review of 2025.
I’m coming back around to MCP now. Giving an agent a shell environment with the ability to access the internet is fraught with risk, and requires a strong model that is capable of effectively driving such an environment. MCP tools are easier to audit and control, and simple enough that smaller models that run on a laptop can still drive them reasonably well.
The new stateless MCP specification also greatly decreases the complexity of implementing both clients and servers for the protocol. I built three of those this week!
The best demonstration of the difference between stateful and stateless MCP is in this May 21st blog post that introduced the RC for the new specification. It included a clear before-and-after example.
The older stateful MCP (I’m going to call it “legacy MCP”) required two HTTP requests—the first to initialize a session and obtain a Mcp-Session-Id, and the second to actually call the tool:
POST /mcp HTTP/1.1
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-11-25",
"capabilities": {
},
"clientInfo": {
"name": "my-app",
"version": "1.0"
}
}
}
POST /mcp HTTP/1.1
Mcp-Session-Id: 1868a90c-3a3f-4f5b
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "otters"
}
}
}
The new stateless way uses a single HTTP request which looks like this:
POST /mcp HTTP/1.1
MCP-Protocol-Version: 2026-07-28
Mcp-Method: tools/call
Mcp-Name: search
Content-Type: application/json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "search",
"arguments": {
"q": "otters"
},
"_meta": {
"io.modelcontextprotocol/clientInfo": {
"name": "my-app",
"version": "1.0"
}
}
}
}
This is so much cleaner from both a client- and server-side implementation perspective. It’s also a better fit for building scalable web applications, since now you don’t need to maintain server-side state to keep track of those session IDs, or worry about routing the same session to the same backend machine.
I couldn’t find a great CLI tool for interactively probing an MCP server, so I had Codex help build my own.
mcp-explorer is the result. It’s a stateless Python CLI tool, so you don’t even need to install it to try it out—it works with uvx like this:
uvx mcp-explorer list https://agentic-mermaid.dev/mcp
This queries Ade Oshineye’s agentic-mermaid.dev demo MCP. The above command returns the following list of tools:
execute(code: string, timeoutMs?: integer) - Execute Mermaid SDK code
Run JavaScript in an isolated sandbox; return a value.
describe_sdk(family: string, detail?: string) - Describe Mermaid SDK operations
Return version-matched mutation operations for one diagram family.
render_svg(source: string, options?: object) - Render Mermaid as SVG
Render a Mermaid source string to themeable SVG. Returns { ok, svg }.
render_ascii(source: string, useAscii?: boolean, targetWidth?: integer, options?: object) - Render Mermaid as text
Render a Mermaid source string to text. Returns { ok, text }.
render_png(source: string, scale?: number, background?: string, fitTo?: object, options?: object) - Render Mermaid as PNG
Rasterize a Mermaid source string to PNG. Returns { ok, png_base64 }.
...
Then to inspect a tool:
uvx mcp-explorer inspect render_svg
This outputs a whole bunch of information, including the JSON schema of the inputs and outputs.
To call that tool and pass arguments to it:
uvx mcp-explorer call \ https://agentic-mermaid.dev/mcp \ render_svg \ -a source 'graph TD; A-->B' \ -a options '{"padding":24}'
Which returns:
{"ok":true,"svg":"<svg xmlns=\"http://www.w3.org/2000/svg\" width=...
To get just the raw SVG try adding | jq .svg -r to that command. I got back this image:
There are a few more commands in the README, but you get the general idea. I find building CLI tools like this to be a really productive way to get familiar with a specification, even if an agent writes most of the actual code.
The second project is datasette-mcp, a Datasette plugin which adds a /-/mcp endpoint to any Datasette instance.
This is probably the fourth time I’ve tried building this plugin, but thanks to the new stateless MCP specification I finally have a version that feels good to release.
It provides just three tools: list_databases(), get_database_schema(database_name), and execute_sql(database_name, sql). They do exactly what you would expect them to do—though execute_sql() is read-only for the moment.
Wire these into an agent, or a chat tool like ChatGPT or Claude, and they’ll gain the ability to run SQL queries against your hosted Datasette instance.
So far I’m running it on the Datasette mirror of my blog, at datasette.simonwillison.net/-/mcp. It took a bit of fiddling to figure out how to attach that to ChatGPT and Claude, but I got there in the end. Here’s a new TIL showing exactly how to do that.
Here’s a shared Claude session where I asked it:
list tables in simonwillison.net
And then:
what has Simon said recently about MCP?
It ran 7 separate SQL queries to figure out the answer.
My LLM tool is long overdue for an official MCP integration. The new alpha llm-mcp-client plugin is my attempt at exactly that:
llm install llm-mcp-client llm -T 'MCP("https://datasette.simonwillison.net/-/mcp")' 'count the notes'
Here’s the output (including reasoning trace, I’m using LLM 0.32rc2):
Considering note count
I see the question “count the notes” is probably asking me to tally up blog notes. It could also mean published notes or drafts, so there’s some ambiguity there. I’ll need to figure out the total number of notes, likely by querying the count for both published notes and drafts to get a clear answer. Let’s execute that count!
There are 151 notes.
And the output of llm logs for that prompt.
Once this is fully baked, I’m considering bringing it directly into LLM core. I’m excited to experiment with MCP in Datasette Agent and llm-coding-agent as well.
A few months after MCP was first released, I wrote Model Context Protocol has prompt injection security problems, where I noted that the pattern of having end users mix and match tools pushed responsibility for avoiding data exfiltration attacks out to the users themselves. I hadn’t coined the Lethal Trifecta yet, but that was absolutely what I had in mind.
Then general agents with arbitrary shell and curl access came along, and that’s so much harder to keep secure!
Something I’ve come to appreciate about MCP is that it’s much easier to reason about agent capabilities and what might go wrong than with arbitrary command execution in an open network environment—the default for most of today’s general and coding agent tools.
I plan to lean into MCP a whole lot more when I’m building sensitive applications on top of LLMs.
Edit: I read it. Yep.
We have text interfaces refined by humans for decades and there's an endless sea of training data for them, but they imagine these amateur-hour homegrown solutions will ever outdo an agent with shell access?
If I understand correctly, you’re not answering my question, and you’re not talking about MCP either. Have you considered that maybe you’re in the wrong thread?
It's a terrible protocol with zero value beyond bigtech sponsorship. We're all worse off for it.
(To your point...having knocked out CORBA and DCOM, perhaps we may next look forward to SOAP.)
Why not just pre-train the model to interact with JSONRPC endpoints?
LLMs need to say stuff like “your company sells sparkling water, you should not build and maintain another in-house product board and CRM”, and then stand their ground.
Maybe Microsoft should bring back Biztalk for agentic workflows.
But yes, that is the crux of the problem indeed. Agency is nothing if you don't have methods to turn it into tool-use.
I do think a lot of the standard would have been easier if they'd been stateless first, and allowed for GET requests, but it evolved from a starting point that has since evolved.
And then the model will randomly decide to load the .md file that is the "skill" randomly at any point. Again polluting the context.
There's no magic.
There is no magic and people should be more precise when discussing skills.
Even when it is disabled? The point is to have the skill or mcp app to not use ANY tokens until I call it by name. I can do that with a skill. Can I do that with an mcp app?
But yeah. You could have files with skills outside of the auto-discovered skill tree, and invoke them manually.
You can probably throw together a passible auth system on top of it that works with the htaccess format. Which is another cgi script but chowned so it can't be called from the outside. If not that, public key crypto - give your agents certificates that are part of the chain of trust. Mint those out of band and give them an insanely short TTL. Fail2ban or something like that to prevent abuse (agent getting handsy with the server gets blocked, credentials revoked).
The side benefit is that everybody starts writing perl and awk again. Who needs a JS runtime when you have CGI?
Token count is a less important factor in context pollution than idea count. The worst of the rot factors are when models latch onto irrelevant information, or over-index on some vague idea/suggestion as if it was a hard direction, and then go off course.
The names + one-line descriptions of 10 tools can do as much (or more!) to distract the focus and intentionality of an agent than a 30k token exhaustive API documentation of some tool.
Or you may choose another plugin that works differently.
That's the whole point of extensible systems like Pi or Emacs, you don't need to pray that maintainers will have the same vision as you, you just pick one of the many alternatives instead. Or ask pi to write one for you.