So I don't disagree with any of the criticisms of MCPs but no one here has mentioned why they are useful:
1. Claude Code is aware of what MCPs it has access to at all times.
2. Adding an MCP is like adding to the agent's actuators/vocabulary/tools because unlike cli tools or APIs you don't have to constantly remind it what MCPs it has available.
3. This effect is _significantly_ stronger than putting info into CLAUDE.md.
4. You can almost trivially create an MCP that does X by asking the agent to create an MCP that does X. This saves you from having to constantly remind an agent it can do X.
NOTE: I cannot stress enough that this property of MCPs is COMPLETELY ORTHOGONAL to the nutty way they are implemented, and I am IN NO WAY defending the implementation. But currently we are talking past the primary value prop.
I've noticed with AI people seem to want to latch onto frameworks. I think this happens because the field is changing quite quickly and it's difficult to navigate without being in it - offloading decisions to a framework is an attempt to constrain your complexity.
This occurred with langchain and now seems to be occurring with mcp. Neither of those really solved the actual problems that are difficult with deploying AI - creativity, context, manual testing, tool design etc. The owners of these frameworks are incentivized to drag people into them to attain some sort of vendor lock-in.
At my company we started building our tool based data scientist agent before MCP came out and it's working great.
AI has lots of this 'fake till you make it' vibe from startups. And unfortunately it wins - because these hustler guys get a lot of money from VCs before their tools are vetted by the developers.
MCP was a really shitty attempt at building a plugin framework that was vague enough to lure people into and then allow other companies to build plugin platforms to take care of the MCP non-sense.
"What is MCP, what does it bring to the table? Who knows. What does it do? The LLM stuff! Pay us $10 a month thanks!"
LLM's have function / tool calling built into them. No major models have any direct knowledge of MCP.
Not only do you not need MCP, but you should actively avoid using it.
Stick with tried and proven API standards that are actually observable and secure and let your models/agents directly interact with those API endpoints.
yesss, and OpenAI tried this first when they were going to do a “GPT store”. But REST APIs tend to be complicated because they’re supporting apps. MCP, when it works, is very simple functions
in practice it seems like command line tools work better than either of those approaches
Yeah, I'm still confused as to why so many people in "AI engineering" seem to think that MCPs are the key to everything.
They are great if you have a UI that you want and it needs a plugin system, obviously.
But the benefits become much more marginal for a developer of enterprise AI systems with predefined tool selections. They are actually getting overused in this space, if anything, sometimes with security as a primary casualty.
You don’t need formal tools. You only need a bash tool that can run shell scripts and cli tools!
Overwhelmed by Sentry errors recently I remembered sentry-cli. I asked the agent to use it to query for unresolved Sentry errors and make a plan that addresses all of them at once. Zeroed out my Sentry inbox in one Claude Code plan. All up it took about an hour.
The agent was capable of sussing out sentry-cli, even running it with --help to understand how to use it.
The same goes for gh, the github cli tool.
So rather than MCPs or function style tools, I highly recommend building custom cli tools (ie. shell scripts), and adding a 10-20 word description of each one in your initial prompt. Add --help capabilities for your agent to use if it gets confused or curious.
I like MCP for _remote_ services such as Linear, Notion, or Sentry. I authenticate once and Claude has the relevant access to access the remote data. Same goes for my team by committing the config.
Can I “just call the API”? Yeah, but that takes extra work, and my goal is to reduce extra work.
I can see where Mario is coming from, but IMO MCP still has a place because it 1) solves authentication+discoverability, 2) doesn't require code execution.
MCP shines when you want to add external functionality to an agent quickly, and in situations where it's not practical to let an agent go wild with code execution and network access.
Feels like we're in the "backlash to the early hype" part of the hype cycle. MCP is one way to give agents access to tools; it's OK that it doesn't work for every possible use case.
IMO MCP isn't totally dead, but its role has shrunk. Quoting from my post [1]:
"Instead of a bloated API, an MCP should be a simple, secure gateway... MCP’s job isn’t to abstract reality for the agent; its job is to manage the auth, networking, and security boundaries and then get out of the way."
You still need some standard to hook up data to agents esp when the agents are not running on your local dev machine. I don't think e.g. REST/etc are nearly specific enough to do this without a more constrained standard for requests.
Mario has some fantastic content, and has really shaped how I think about my interface to coding tools. I use a modified version of his LLM-as-crappy-state-machine model (https://github.com/badlogic/claude-commands) for nearly all my coding work now. It seems pretty clear these days that progressive discovery is the way forward (e.g. skills), and using CLI tools rather than MCP really facilitates that. I've gone pretty far down the road of writing complex LLM tooling, and the more I do that the more the simplicity and composability is appealing. He has a coding agent designed along the same principles, which I'm planning to try out (https://github.com/badlogic/pi-mono/tree/main/packages/codin...).
MCP was created so llm companies can have a plugin system. So instead of them being the API provider, they can become the platform that we build apps/plugins for, and they become the user interface to end consumers.
MCP defines the API so vendors of LLM tools like cursor, claude code, codex etc don't all make their own bespoke, custom ways to call tools.
The main issue is the disagreement on how to declare the MCP tool exists. Cursor, vscode, claude all use basically the same mcp.json file, but then codex uses `config.toml`. There's very little uniformity in project-specific MCP tools as well, they tend to be defined globally.
LLMs were trained on the how we use text interfaces. You don't need to adopt command line for an LLM to use. You don't really need RAG - just connect the LLM to the shell tools we are using for search. And ultimately it would be much more useful if the language servers had good cli commands and LLMs were using them instead of going via MCP or some other internal path - ripgrep is already showing how much more usable it is this way.
I agree with what Mario says overall and I can be honest, I don't really use MCP I don't think - at least not what it's intended for (some sort of plugin system for extensbile capabilities). I use it for an orchestration layer, and for that it's great.
When MCP itself works it's great. For example, we organize units of work into "detective cases" for framing and the corresponding tool is wanderland__get_detective_case. Spawn a Claude Code session, speak "get up to speed on our current case" and we have instant context loading in a sub-agent session, useful when the Jira ticket requires input from another repository (or two). They're all writing back through the same wanderland__add_detective_case_note call and that routes everything through the central attractor to the active case.
Most of the time, the case we're working on was just a "read DVOPS-XXXXX in Jira and create a case for me". That's wanderland_get_jira_ticket (a thin wrapper on the jira cli) and wanderland__create_detecive_case in turn.
The secret to mcp is that it breaks a lot, or they forget about it because their context is polluted (or you broke it because you're working on it). But it's just a thin wrapper over your API anyways, so just ensure you've got a good /docs endpoint hanging off that and a built in fetch (or typically a fallback to bash with curl -s for some reason) and you're back up and running until you can offload that context. At least you should be if you've designed it properly. Throw in a CLI wrapper for your API as well, they love those :) Three interfaces to the same tool.
The MCP just offers the lowest friction, the context on how to use it injected automatically at a level low enough to pick it up in those natural language emissions and map it to the appropriate calls.
And, if you're building your own stack anyways, you can do naughty things to the protocol like like inject reminders from your agenda with weighted probabilities (gets more nagging the more you're overdue) or inject user-guides from the computational markdown graph the platform is built on when their tools are first used (we call that the helpful, yet somewhat forceful barrista pattern, no choice but to accept the paper and a summary of the morning news with your coffee in the morning). Or restrict the tools available based on previous responses (the more frustrated you get, the more we're likely to suggest you read a book Claude). Or when your knowledge graph is spatially oriented, you can do fun things like make sure we go east or west once in a while (variations on related items) rather than purely north south (into and out of specific knowledge veriticals) with simple vector math.
MCP isn't strictly necessary for all of this, that could be (and in some cases rightly is) implemented at the API layer, but the MCP layer does give us a simple place to reason about agentic behaviour and keeps it away from the tools itself. In other words, modeling error rates as frustration and restricting tool use / injecting help guides make sense in one layer and injecting reminders into a response from the same system that's processing the underlying tool calls makes sense in another, if the protocol you've designed for such things allows for such two way context passing. Absent any other layer in the current stack (and no real desire to implement the agentic loop on my own at the moment), the MCP protocol seems perfectly suited for these types of shennanigans - view it like something like Apigee or (...) API Gateway, adding a bit of intelligence and remixability on top of your tools for better UX with your agents
MCP is yet another waste of effort trying to recreate what we had with REST over 20 years ago.
Yes, APIs should be self-documenting. Yes, response data should follow defined schemas that are understandable without deep knowledge of the backend. No, you don't need MCP for this.
I wish Google would have realized, or acknowledged, that XML and proper REST APIs solve both of these use cases rather than killing off XSLT support and presumably helping to coerce the other browsers and WhatWG to do the same.
Yeah, "MCP" felt like BS from jump. Basically it's the problem that will always be a problem, namely "AI stuff is non-deterministic."
If there was some certainty MCP could add to this equation that would perhaps be theoretically nice, but otherwise it's just .. parsing, a perhaps not "solved" problem, but one for which there's already ample solutions.
Will have a think about how this can extended to other types of uses.
I have personally been trying to replace all tools/MCPs with a single “write code” tool which is a bit harder to get to work reliably in large projects.
Moderne Ai agent tool have have a setting where you can trimm down the numbers of tools from an MCP server. Usefull to avoid overwhelming the LLM with 80 tools description when you only need 1
I don't find that to help much at all, particularly because some tools really only make sense with a bunch of other tools and then your context is already polluted. It's surprisingly hard to do this right, unless you have a single tool MCP (eg: a code/eval based tool, or an inference based tool).
Don't you have a post about writing Python instead of using MCP? I can't see how MCP is more efficient than giving the LLM a bunch of function signatures and allow it to call them, but maybe I'm not familiar enough with MCP.
> Don't you have a post about writing Python instead of using MCP?
Yes, and that works really well. I also tried various attempts of letting agents to write code that exposes MCP tool calls via an in-language API. But it's just really, really hard to work with because MCP tools are generally not in the training set, but normal APIs are.
Yeah, I've always thought that your proposal was much better. I don't know why one of the big companies hasn't released something that standardised on tool-calling via code, hm.
So I don't disagree with any of the criticisms of MCPs but no one here has mentioned why they are useful:
1. Claude Code is aware of what MCPs it has access to at all times.
2. Adding an MCP is like adding to the agent's actuators/vocabulary/tools because unlike cli tools or APIs you don't have to constantly remind it what MCPs it has available.
3. This effect is _significantly_ stronger than putting info into CLAUDE.md.
4. You can almost trivially create an MCP that does X by asking the agent to create an MCP that does X. This saves you from having to constantly remind an agent it can do X.
NOTE: I cannot stress enough that this property of MCPs is COMPLETELY ORTHOGONAL to the nutty way they are implemented, and I am IN NO WAY defending the implementation. But currently we are talking past the primary value prop.
So far I have seen two genuinely good arguments for the use of MCPs:
* They can encapsulate (API) credentials, keeping those out of reach of the model,
* Contrary to APIs, they can change their interface whenever they want and with little consequences.
I've noticed with AI people seem to want to latch onto frameworks. I think this happens because the field is changing quite quickly and it's difficult to navigate without being in it - offloading decisions to a framework is an attempt to constrain your complexity.
This occurred with langchain and now seems to be occurring with mcp. Neither of those really solved the actual problems that are difficult with deploying AI - creativity, context, manual testing, tool design etc. The owners of these frameworks are incentivized to drag people into them to attain some sort of vendor lock-in.
At my company we started building our tool based data scientist agent before MCP came out and it's working great.
https://www.truestate.io/
AI is in it's "pre react" state if you were to compare this with FE software development of 2008-2015
>TrueState unburdens analytics teams from the repetitive analysis and accelerates the delivery of high-impact solutions.
Ehh, that's pretty vague. How does it work?
>Request demo
Oh. Well how much is it?
>Request pricing
Oh never mind
AI has lots of this 'fake till you make it' vibe from startups. And unfortunately it wins - because these hustler guys get a lot of money from VCs before their tools are vetted by the developers.
MCP was a really shitty attempt at building a plugin framework that was vague enough to lure people into and then allow other companies to build plugin platforms to take care of the MCP non-sense.
"What is MCP, what does it bring to the table? Who knows. What does it do? The LLM stuff! Pay us $10 a month thanks!"
LLM's have function / tool calling built into them. No major models have any direct knowledge of MCP.
Not only do you not need MCP, but you should actively avoid using it.
Stick with tried and proven API standards that are actually observable and secure and let your models/agents directly interact with those API endpoints.
probably easier to just tell people: You want MCP? Add a "description" field to your rest API that describes how to call it.
That's all it's doing. Just plain ole context pollution. World could be better served by continuing to build out the APIs that exist.
> Add a "description" field to your rest API that describes how to call it.
Isn't that swagger\grpc etc?
yesss, and OpenAI tried this first when they were going to do a “GPT store”. But REST APIs tend to be complicated because they’re supporting apps. MCP, when it works, is very simple functions
in practice it seems like command line tools work better than either of those approaches
Yeah, I'm still confused as to why so many people in "AI engineering" seem to think that MCPs are the key to everything.
They are great if you have a UI that you want and it needs a plugin system, obviously.
But the benefits become much more marginal for a developer of enterprise AI systems with predefined tool selections. They are actually getting overused in this space, if anything, sometimes with security as a primary casualty.
You don’t need formal tools. You only need a bash tool that can run shell scripts and cli tools!
Overwhelmed by Sentry errors recently I remembered sentry-cli. I asked the agent to use it to query for unresolved Sentry errors and make a plan that addresses all of them at once. Zeroed out my Sentry inbox in one Claude Code plan. All up it took about an hour.
The agent was capable of sussing out sentry-cli, even running it with --help to understand how to use it.
The same goes for gh, the github cli tool.
So rather than MCPs or function style tools, I highly recommend building custom cli tools (ie. shell scripts), and adding a 10-20 word description of each one in your initial prompt. Add --help capabilities for your agent to use if it gets confused or curious.
I like MCP for _remote_ services such as Linear, Notion, or Sentry. I authenticate once and Claude has the relevant access to access the remote data. Same goes for my team by committing the config.
Can I “just call the API”? Yeah, but that takes extra work, and my goal is to reduce extra work.
I can see where Mario is coming from, but IMO MCP still has a place because it 1) solves authentication+discoverability, 2) doesn't require code execution.
MCP shines when you want to add external functionality to an agent quickly, and in situations where it's not practical to let an agent go wild with code execution and network access.
Feels like we're in the "backlash to the early hype" part of the hype cycle. MCP is one way to give agents access to tools; it's OK that it doesn't work for every possible use case.
IMO MCP isn't totally dead, but its role has shrunk. Quoting from my post [1]:
"Instead of a bloated API, an MCP should be a simple, secure gateway... MCP’s job isn’t to abstract reality for the agent; its job is to manage the auth, networking, and security boundaries and then get out of the way."
You still need some standard to hook up data to agents esp when the agents are not running on your local dev machine. I don't think e.g. REST/etc are nearly specific enough to do this without a more constrained standard for requests.
[1] https://blog.sshh.io/p/how-i-use-every-claude-code-feature
Mario has some fantastic content, and has really shaped how I think about my interface to coding tools. I use a modified version of his LLM-as-crappy-state-machine model (https://github.com/badlogic/claude-commands) for nearly all my coding work now. It seems pretty clear these days that progressive discovery is the way forward (e.g. skills), and using CLI tools rather than MCP really facilitates that. I've gone pretty far down the road of writing complex LLM tooling, and the more I do that the more the simplicity and composability is appealing. He has a coding agent designed along the same principles, which I'm planning to try out (https://github.com/badlogic/pi-mono/tree/main/packages/codin...).
I have a feeling that MCP is going the way GraphQL is going ...
Oh you're misunderstanding MCP here.
MCP was created so llm companies can have a plugin system. So instead of them being the API provider, they can become the platform that we build apps/plugins for, and they become the user interface to end consumers.
what's the difference between that and those providers exposing an api?
MCP defines the API so vendors of LLM tools like cursor, claude code, codex etc don't all make their own bespoke, custom ways to call tools.
The main issue is the disagreement on how to declare the MCP tool exists. Cursor, vscode, claude all use basically the same mcp.json file, but then codex uses `config.toml`. There's very little uniformity in project-specific MCP tools as well, they tend to be defined globally.
Maybe this is a dumb question, but isn't this solved by publishing good API docs, and then pointing the LLM to those docs as a training resource?
https://elefunc.com/#ai
You guys should just see https://rtcode.io Agent Folder Share feature!
Browser → FS → AI CLI = perfection with nothing but files!
LLMs were trained on the how we use text interfaces. You don't need to adopt command line for an LLM to use. You don't really need RAG - just connect the LLM to the shell tools we are using for search. And ultimately it would be much more useful if the language servers had good cli commands and LLMs were using them instead of going via MCP or some other internal path - ripgrep is already showing how much more usable it is this way.
I agree with what Mario says overall and I can be honest, I don't really use MCP I don't think - at least not what it's intended for (some sort of plugin system for extensbile capabilities). I use it for an orchestration layer, and for that it's great.
When MCP itself works it's great. For example, we organize units of work into "detective cases" for framing and the corresponding tool is wanderland__get_detective_case. Spawn a Claude Code session, speak "get up to speed on our current case" and we have instant context loading in a sub-agent session, useful when the Jira ticket requires input from another repository (or two). They're all writing back through the same wanderland__add_detective_case_note call and that routes everything through the central attractor to the active case.
Most of the time, the case we're working on was just a "read DVOPS-XXXXX in Jira and create a case for me". That's wanderland_get_jira_ticket (a thin wrapper on the jira cli) and wanderland__create_detecive_case in turn.
The secret to mcp is that it breaks a lot, or they forget about it because their context is polluted (or you broke it because you're working on it). But it's just a thin wrapper over your API anyways, so just ensure you've got a good /docs endpoint hanging off that and a built in fetch (or typically a fallback to bash with curl -s for some reason) and you're back up and running until you can offload that context. At least you should be if you've designed it properly. Throw in a CLI wrapper for your API as well, they love those :) Three interfaces to the same tool.
The MCP just offers the lowest friction, the context on how to use it injected automatically at a level low enough to pick it up in those natural language emissions and map it to the appropriate calls.
And, if you're building your own stack anyways, you can do naughty things to the protocol like like inject reminders from your agenda with weighted probabilities (gets more nagging the more you're overdue) or inject user-guides from the computational markdown graph the platform is built on when their tools are first used (we call that the helpful, yet somewhat forceful barrista pattern, no choice but to accept the paper and a summary of the morning news with your coffee in the morning). Or restrict the tools available based on previous responses (the more frustrated you get, the more we're likely to suggest you read a book Claude). Or when your knowledge graph is spatially oriented, you can do fun things like make sure we go east or west once in a while (variations on related items) rather than purely north south (into and out of specific knowledge veriticals) with simple vector math.
MCP isn't strictly necessary for all of this, that could be (and in some cases rightly is) implemented at the API layer, but the MCP layer does give us a simple place to reason about agentic behaviour and keeps it away from the tools itself. In other words, modeling error rates as frustration and restricting tool use / injecting help guides make sense in one layer and injecting reminders into a response from the same system that's processing the underlying tool calls makes sense in another, if the protocol you've designed for such things allows for such two way context passing. Absent any other layer in the current stack (and no real desire to implement the agentic loop on my own at the moment), the MCP protocol seems perfectly suited for these types of shennanigans - view it like something like Apigee or (...) API Gateway, adding a bit of intelligence and remixability on top of your tools for better UX with your agents
MCP is yet another waste of effort trying to recreate what we had with REST over 20 years ago.
Yes, APIs should be self-documenting. Yes, response data should follow defined schemas that are understandable without deep knowledge of the backend. No, you don't need MCP for this.
I wish Google would have realized, or acknowledged, that XML and proper REST APIs solve both of these use cases rather than killing off XSLT support and presumably helping to coerce the other browsers and WhatWG to do the same.
Yeah, "MCP" felt like BS from jump. Basically it's the problem that will always be a problem, namely "AI stuff is non-deterministic."
If there was some certainty MCP could add to this equation that would perhaps be theoretically nice, but otherwise it's just .. parsing, a perhaps not "solved" problem, but one for which there's already ample solutions.
Why are they nondeterministic? You can use a fixed seed or temperature=0.
This is incredibly simple and neat! Love it!
Will have a think about how this can extended to other types of uses.
I have personally been trying to replace all tools/MCPs with a single “write code” tool which is a bit harder to get to work reliably in large projects.
Moderne Ai agent tool have have a setting where you can trimm down the numbers of tools from an MCP server. Usefull to avoid overwhelming the LLM with 80 tools description when you only need 1
Remote MCP with API key which has claims works well to reduce the tool count to only that of what you need.
I don't find that to help much at all, particularly because some tools really only make sense with a bunch of other tools and then your context is already polluted. It's surprisingly hard to do this right, unless you have a single tool MCP (eg: a code/eval based tool, or an inference based tool).
Don't you have a post about writing Python instead of using MCP? I can't see how MCP is more efficient than giving the LLM a bunch of function signatures and allow it to call them, but maybe I'm not familiar enough with MCP.
> Don't you have a post about writing Python instead of using MCP?
Yes, and that works really well. I also tried various attempts of letting agents to write code that exposes MCP tool calls via an in-language API. But it's just really, really hard to work with because MCP tools are generally not in the training set, but normal APIs are.
Yeah, I've always thought that your proposal was much better. I don't know why one of the big companies hasn't released something that standardised on tool-calling via code, hm.
MCP is convenient and the context pollution issue is easily solved by running them in subagents. The real miss here was not doing that from the start.
Well, stdio security issues when not sandboxed are another huge miss, although that's a bit of a derail.
You don't need MCP.
You need Claude Skills.
Actually you just need a prompt and some tools
For Claude Code this approach looks easy. But if you use Cursor you need other approach as it doesn't have a format for tools.
The agent in Cursor is constantly using command line tools.
fwiw, for those on a Mac, osascript can run JavaScript in chrome if you let it.