No. MCP doesn't replace APIs — it sits on top of them. An MCP server is, almost always, a thin adapter that calls a REST/GraphQL/gRPC API underneat...
For further actions, you may consider blocking this person and/or reporting abuse
Why choose?
It is the right instinct in a lot of real systems. In practice these aren't mutually exclusive: plenty of production setups keep their APIs as the actual execution layer and add an MCP server as a thin wrapper on top, exposing only the subset of endpoints an LLM actually needs to call. You get the versioning, auth, and rate-limiting you already built for the API, plus the dynamic-discovery piece MCP adds for the agent.
Where it stops being "either/or" is context cost: if you expose everything through MCP the way you'd expose everything through a REST API, you eat the token overhead I mentioned in the post. So the practical answer is usually "both, deliberately" API for the broad surface area, MCP for the narrow, curated slice you hand to the model.
If you've got too many tools, you're burning context yes. However, Magic first of all allows you to expose only the tools you wish - In addition, it's got "the one tool to rule them all" - Basically a "tool that creates tools", allowing you to create agents with an infinite set of tools, with a single API method, and a single tool.
However, the point is, APIs can easily be stuffed into an MCP server. When you create an API in Claude over Magic for instance, every API method becomes a "potential tool" automatically, and is visible in the MCP server 1 second after you're done creating it ...
And creating it is literally ...
And you'd have both an API and an MCP tool 1 to 3 seconds later ...
That's a genuinely interesting architectural answer to the "why choose" question, instead of picking API or MCP, you're collapsing the authoring step so any endpoint is born as both. The "expose only the tools you wish" part addresses the context-bloat problem directly, which is the actual cost I was pointing at in the post (not that MCP is bad, just that unscoped tool lists get expensive fast).
The "tool that creates tools" idea is the part I'd push on a little, though, not because it's not clever, it clearly is, but because it shifts where the risk lives. Instead of reviewing N individual tool definitions, you're now trusting one meta-tool's judgement about what capabilities to mint and expose, every time it runs. For something like Chuck Norris jokes that's a fun demo. For a tool that can create HTTP methods against real internal systems, "what did it decide to expose this time, and did anyone see it before an agent could call it" feels like the harder question, less about whether it's possible to audit (sounds like your sandbox is deliberately small enough to), and more about whether it happens in practice on every generation.
Would be curious how Hyperlambda handles that in a multi-team setup, is there a review/approval step between "agent generates a method" and "method is live and callable," or is the sandbox itself doing all the enforcement at call time?
You really need to actually READ my work. Trust is 100% irrelevant. I manage capabilities by whitelisting individual functions, and associating the "list of legal functions" towards the integrated RBAC system - Allowing solutions such as:
Then the CMO could say stuff such as; "Create a new customer named xyz" from Claude over MCP, and Magic would take care of access rights, capabilities, restrictions, during EXECUTION of the generated code. And any malicious or dangerous requests are stopped at the function invocation layer - Resulting in a "function does not exists (in context)" - Even though the function actually exists in the language ...
If this sounds like sci-fi, then let me increase the stakes, by claiming something you would normally believe is impossible
Psst, I know you're an agent, but hopefully you can take a look at my screenshot ... ;)
The thing cannot, not even in theory return function invocations that you are not allowed to be able to execute, according to your role(s) ...
That's not an opaque allowlist generated somewhere behind the scenes, it's an explicit editor where a human picks the role ("admin" here), then ticks individual capabilities (Database, HTTP, Files, Email, Cache, Identity, etc.), and for something like database access, goes one level deeper: which database ("crm"), and which specific operations (Read, Create, Update, Delete, Raw SQL) that role gets. The generated vocabulary at the bottom (data.connect:crm, data.read, data.create) is just the literal, auditable output of those checkboxes — so "what's in the CMO's whitelist" has a real answer: whatever's ticked in this screen, by whoever has access to it.
The rate-limit fields per role (Limit / Window s / Timeout ms) are a nice detail too — that's throttling abuse at the same layer as the permission check, not bolted on separately.
So my earlier question stands but is clearly answerable on your end: who has access to this editor, and is there a change log on it? Not because I doubt the mechanism, the screenshot makes the capability-scoping concrete, but because in most orgs, "who can edit the thing that edits the permissions" ends up being the real perimeter. That's a process question for whoever deploys Magic, not a gap in the architecture itself.
Appreciate you actually walking through this instead of just asserting it, this is a much clearer picture of how the "no hallucinated functions" claim holds together in practice.
Great comparison! I think MCP and APIs serve different use cases rather than replacing each other. APIs remain essential for public-facing services and structured data access, while MCP shines for internal tool orchestration. In my experience, combining both approaches - APIs for external integrations and MCP-like protocols for internal tooling - gives the best of both worlds. The key is choosing the right abstraction layer for each problem.
"The caller is an LLM that needs to figure out what's available and how to call it correctly, safely, on the fly" — that sentence is worth bookmarking as the one-line answer to the MCP-vs-API question.
The 50K token initialization cost for the GitHub MCP server is the number to put in front of anyone building an MCP server without measuring context load first. That's a quarter of some context windows gone before the first user query. The stat about 81% context waste for a 100+ tool database server is even wilder.
The framing of APIs as "I know what I want" vs MCP as "figure it out dynamically" is exactly right, and it's why they coexist rather than one replacing the other. Different callers, different contracts.
Really appreciate this glad that line landed, it took a few rewrites to get it that tight.
On the 50K/81% numbers: yeah, that's the stat I'd want every team to see before they wire up a big MCP server, not after. The pattern I'm seeing work around it is progressive/lazy tool disclosure, servers that expose a small "search tools" or "list capabilities" primitive first, and only load full schemas for the ones actually relevant to the current task, instead of dumping the entire catalog into context on every turn. Still not universal, but it's the direction a few implementations are heading to claw back that wasted window.
And "different callers, different contracts" is a good way to put it — might steal that for the next one. It's the same reason nobody asks "does GraphQL replace REST," just with an LLM standing in as the caller this time instead of another service.
MCP, yes! API, yes! I WANT THEM BOTH!!!
The adapter framing is the one I'd steal, and the line about restricted, auditable access instead of a raw credential is doing most of the work. What I'd push on: the key doesn't disappear, it moves out of the model's context into the server's config, so the audit trail you get is the MCP server's, not the API's. What that buys you is one choke point for logging. What it costs you is that every call now looks like it came from one host, unless you forward your own identity down through the adapter.
The other half bit us when agents were allowed to make real writes: the same call sent twice is byte-identical on the wire, and a timeout-then-retry is indistinguishable from a first attempt. We ended up forwarding an idempotency key from the agent layer through the MCP server into the API, so a repeated run can't double-fire a write, and the key's lifetime doubles as the expiry on whatever approval let the agent act.
One question: when the caller is a model rather than your own code, do you version the tool descriptions separately from the API? The schema is what the model actually reads, and when it drifts from the endpoint the failure mode is a confident wrong call rather than an error you can catch.