Tejas Kumar

MCP vs API: Why Not Just Give Agents an OpenAPI Spec?

Yes, I ship an MCP server when I want people to use my service from inside ChatGPT, Claude, Cursor or any other app that already speaks MCP. For my own agent calling my own API, an OpenAPI spec is usually enough. MCP doesn’t give a model any ability to call APIs that it was missing. It gives me a protocol that a long list of existing applications already implement. So I write the integration once and all of them can use it.

The question comes up every month and the people asking it already know both sides. A thread on r/mcp from May 2026 (182 upvotes, 198 comments) put it like this:

I’m still not able to understand why one needs an MCP Server when we already have REST APIs.
The strongest argument against MCP is: “OpenAPI already solved most of this.”
The strongest argument for MCP is: “OpenAPI describes APIs for humans/devs. MCP describes capabilities for autonomous LLM agents.”

3 months later r/AI_Agents asked it again (217 upvotes): “MCP feels more and more like a heavy redundancy” and “the biggest value MCP now represents is the consensus around it”. In September, Ask HN: Who is using MCP in production? got 201 comments asking what MCP offers over “a normal API, direct tool integration, or CLI”. I get the same question after talks. So here’s my answer, with every number I could find and the demo I did on stage in Bucharest.

What is the difference between MCP and an API?

An API is any interface one program offers another. MCP is one specific protocol, a client-server one similar to HTTP, where the client is an AI application and the server hands it tools. That’s how I defined it at How to Web (recording, transcript): the client wakes up, asks the server “what do you have for me?”, the server answers “a tool for the calendar, a tool for this, a tool for that”, and the client calls those tools remotely.

So “MCP vs API” is a slightly crooked comparison. An MCP server is an API (JSON-RPC messages over stdio or HTTP). The comparison people mean is between an MCP server and the API I already have, described by an OpenAPI document.

My API with an OpenAPI spec An MCP server
What it describes Every operation of my HTTP API: paths, methods, inputs, responses, security A set of tools designed for a model (and prompts and resources)
How a client learns what’s there Reads the spec from a URL or a file Calls tools/list
How a client calls something Builds the HTTP request the spec describes Sends tools/call with a name and arguments
How a failure comes back Whatever status code and body my API chose A result with isError: true and text the model can read
Asking the user something mid-call My own design Defined by the protocol (elicitation)
Who implements the client side Me, or a framework that imports OpenAPI ChatGPT, Claude, Cursor, Gemini, Copilot, VS Code and the rest

Google’s AI Overview for this query says OpenAPI discovery is “static; developers must read docs and write custom code” while MCP’s is “dynamic”. That’s wrong. An OpenAPI document is machine-readable by design (that is what it’s for!!) and the agent frameworks below read it at runtime. The difference between the 2 is who already implements each side.

OpenAPI already works for agents

Microsoft Semantic Kernel imports an OpenAPI document, makes each operation a function the model can call and executes the HTTP request for it. I never hand-write an integration per endpoint. OpenAPI was a standard for machines a decade before anybody said “agent”.

It performs too. In February 2026 Tobrun Van Nuland ran Claude Code against the same API 6 ways, 36 runs in all and published the results. On his conversion API the raw OpenAPI document came last: 2 of 3 runs succeeded, at 8.3 turns and $0.16 a run, while the same API wrapped as an MCP tool succeeded 3 of 3 times in 2 turns for $0.03. On his simpler image API the spec did fine (3 of 3, 3.7 turns, $0.07). His verdict was that the spec “added information without reducing ambiguity”. The model had every endpoint in front of it and still had to work out which 3 to call in which order.

Conversion API, 3 runs each Success Turns Cost per run
API wrapped as 1 MCP tool 3 of 3 2.0 $0.03
A small CLI 3 of 3 3.0 $0.06
The official SDK 3 of 3 4.0 $0.07
No context at all 3 of 3 6.3 $0.12
The raw OpenAPI document 2 of 3 8.3 $0.16

Then there’s the size of the spec itself. In March 2026 Scalar counted what it costs to put an API in front of a model, in tokens, using the Zoom Meetings API:

Tokens to put the Zoom Meetings API in front of a model, 4 ways (Scalar, March 2026)
The whole OpenAPI document in the prompt
295,656 tokens
An MCP server, 1 tool per endpoint, full schemas
178,811 tokens
The same MCP server, required parameters only
95,034 tokens
3 tools: summarize, search, execute
412 tokens

The Zoom spec is 295,656 tokens, which is bigger than a 200K context window… the document doesn’t fit before I’ve asked my first question!! An MCP server with 1 tool per endpoint was better and still ate 89% of the window. 3 tools that search the spec and execute a call cost 412. “Just give the agent the spec” is a fine idea for a 12-endpoint API and a terrible one for Zoom’s. Whichever protocol I choose, the work is deciding what a tool should do. Converting a schema doesn’t make that decision for me.

Why use MCP when an API already exists?

1. The apps people already use speak MCP

At How to Web I built an Apple Calendar tool in Langflow (it ran on my laptop, against the calendar on my laptop) and exposed it as an MCP server. Then I opened Claude and asked for a lunch appointment at 3 p.m. Bucharest time. The appointment appeared in my calendar!! Then I did it from Cursor while coding: same tool, 2 apps, 0 extra code. The function already worked before MCP. What MCP gave me was every MCP client as a front end for it.

I can’t do that with my OpenAPI document because those apps don’t read it. They call tools/list. And the list of those apps is long: when Anthropic donated MCP to the Linux Foundation’s Agentic AI Foundation in December 2025, its announcement counted “more than 10,000 active public MCP servers”, “97M+ monthly SDK downloads” and adoption by ChatGPT, Cursor, Gemini, Microsoft Copilot and Visual Studio Code. OpenAI’s own apps platform is MCP: its Apps SDK “is built on the Model Context Protocol (MCP)” so an app inside ChatGPT is an MCP server with a user interface attached. The foundation is co-founded by Anthropic, Block and OpenAI, which is the 2 biggest model companies agreeing on one plug.

That’s what the production stories on Hacker News have in common. One commenter runs a sports analytics product where “MCP is the backbone behind the product and enables regular users to do things without knowing anything about it”. Another sells a SaaS whose customers “care about whether they can get tasks done in our SaaS using Claude or ChatGPT”. A third connects voice agents on other companies’ platforms to their scheduling tools: “When you don’t own every piece of an integration with another system, there needs to be a well defined standard.” Every one of them chose MCP because the app on the other end wasn’t theirs.

MCP’s co-creators, David Soria Parra and Justin Spahr-Summers, said the same thing more gently in their April 2025 interview on Latent Space: OpenAPI is “a very great tool”, the 2 are “more complimentary” than people assume, and they wanted primitives “purpose built” for models. I agree with the conditional. If someone wants my calendar inside the app they already use, I need the interface that app supports, even when another standard could describe the same calendar.

2. The client already did the boring parts

A generic OpenAPI client learns each API’s paths, methods and response formats from its description. An MCP client learns 2 operations once: tools/list and tools/call. The tool specification fixes the result format too, with structured content and an isError flag for a failed call. And the list a server returns can depend on who’s asking. The top comment on the March 2025 Hacker News thread about this exact comparison (186 points) put it in 1 line: “MCP allows tools to be added at runtime instead of design-time. That’s it.”

Suppose my calendar rejects an appointment because 25:00 isn’t a time. With MCP the client has a standard place to find the error and hand it back to the model. OpenAPI can describe an error response, but it doesn’t make every API use the same one. So a generic client has to cope with all of them. The same goes for signing in: MCP has an authorization framework built on OAuth that Claude and ChatGPT already implement, which is why the top reply on the r/AI_Agents thread lists “being able to smoothly use OAuth in most common MCP clients” as the advantage left once you stop writing API wrappers. And a narrower tool list is a smaller blast radius: one HN commenter keeps MCP for exactly that reason because direct shell and HTTP access is “a lot more unpredictable and with much higher blast radius if it starts misbehaving”.

MCP picks a set of conventions that every participating client agrees to implement. That saves me work whenever I can reuse their implementation. An OpenAPI-based agent can execute a request and read an error as well. The difference is that I’d be writing that part myself.

3. A tool can stop and ask

Suppose my calendar tool needs to know which calendar to put the lunch in. MCP defines elicitation: the server answers the tool call with “I need input”, the client shows the person a small form (or sends them to a URL for anything sensitive, like signing in to a third party), and then retries the call with their answer. The person can decline. Since the July 2026 revision this works as a multi round-trip request so the server keeps no session between the 2 calls.

My calendar demo didn’t use it. It’s an interaction I could add, provided the app on the other end declares support for it (not all do). For longer work there’s an optional Tasks extension with task handles and polling, and again both sides have to support it.

An API can return a “missing input” response or a job id too and OpenAPI can describe both. What MCP adds is an agreed meaning that a supporting app already understands. If I invent my own over HTTP, the client has to implement my version as well.

MCP vs OpenAPI: when is the spec enough?

When the only client is mine. If my agent imports the spec, executes the requests and handles the interactions I need, adding MCP gives me a second protocol to maintain and nothing to show for it. Both approaches need running software anyway: neither document executes anything by itself.

I can also design focused, task-shaped operations instead of exposing every internal endpoint and that’s good tool design whichever interface I choose. Even multi-step workflows have a standard on the OpenAPI side: Arazzo describes sequences of calls and the dependencies between them. This is where I’d qualify the co-creators’ argument that OpenAPI is “too granular for what you want to do with LLMs”. Granularity is a design choice. Booking lunch means looking up calendars, checking availability and creating an event, and I can expose that as 1 operation through OpenAPI or 1 tool through MCP. The top r/AI_Agents reply, from someone who had shipped several MCP servers, said it plainly: “MCPs shouldn’t just be API wrappers.” On this site the 4 tools an agent gets are search, list talks, the schedule and booking info. That’s 4 tools in front of every page.

I can even generate the adapter. Azure App Service’s built-in MCP preview reads an OpenAPI spec and exposes its operations as MCP tools. And Speakeasy does the same with overrides for names, descriptions and scopes. Speakeasy’s own guide shows the failure mode though: asked about a driver who wasn’t in the database, the model called a generated lapsPostLap tool and created a fictional lap record instead of saying it had no data. A thin spec makes thin tools so generation gets me a working server in minutes and nothing about that makes it a good one.

The API can stay the same
With OpenAPI
My own agent, or a framework like Semantic Kernel, imports the description and executes the operations it lists.
With MCP
ChatGPT, Claude or Cursor calls a few tools I designed. My MCP server turns each call into requests to that same API.

What does MCP cost me?

Tokens, before the first question

Most MCP clients load every tool definition up front. Apideck measured in March 2026 that connecting GitHub, Slack and Sentry, about 40 tools, puts “over 55,000 tokens of tool definitions” into the context before the agent reads the user’s message. Scalekit ran 5 read-only GitHub tasks 25 times each through GitHub’s official MCP server (43 tools) and through the gh command line and published the medians:

Median tokens per task, the gh CLI against GitHub's MCP server, 5 runs each (Scalekit, March 2026)
TaskCLIMCP
Language1,36544,026
PR status1,64832,279
Merged PRs5,01033,712
Release8,75037,402
Metadata9,38682,835

32× more tokens to find out what language a repo is written in. 7 of the 25 MCP runs also failed on a connection timeout before the server answered at all. Those are the numbers behind the “waaaay cheaper and faster” comments on Hacker News and they check out. The CLI is a fair fight only for a tool the model has seen a million times in training, like gh. And the cost comes from the size of the tool list: Scalar’s 3-tool server above cost 412 tokens.

Anthropic measured the other half of the bill, the intermediate results, in its November 2025 post on code execution with MCP. Copying a 2-hour meeting transcript from Google Drive to Salesforce through the model means the model reads it once and writes it out again (about 50,000 extra tokens). Let the agent write a short script that calls both tools and only the final line comes back:

Tokens for the same Google Drive to Salesforce task, direct tool calls against code execution (Anthropic, November 2025)
Every tool loaded and every result through the model
150,000
The agent writes code that calls the tools
2,000

A 98.7% drop. Armin Ronacher got there a few months earlier in Your MCP Doesn’t Need 30 Tools: It Needs Code. His debugging server exposes 1 tool that runs Python because “when moving to MCP, you immediately lose the ability to compose without inference”. The agent debugged a crashing C program in about 7 tool calls and 45 seconds, then saved the session as a script that ran in 1 call in under 5. Kenton Varda and Sunil Pai built the same idea into Cloudflare’s Agents SDK as Code Mode, turning the MCP tools into a TypeScript API the model writes code against: “LLMs are better at writing code to call MCP, than at calling MCP directly.”

Look, all 3 of those still use MCP!! Choosing MCP doesn’t oblige me to make the model request every tiny operation by hand. For my calendar, finding a lunch slot across 20 calendars means fetching and filtering those 20 responses in code and returning the free times. And I’d measure completed bookings, wrong changes, latency and the bill against the version where the model reads all 20. Arize ran that kind of comparison on GitHub tasks in May 2026, 500 trials: correctness was a wash (0.834 for MCP against 0.845 for bare shell access), while on the hardest tier MCP cost over 6× as much and made 12 tool calls where a CLI skill made 5. Their conclusion is mine too. Use the command line for local, well-known tools. Use MCP for remote or proprietary ones, OAuth, and anything shipped to customers.

Another protocol to keep up with

MCP is 2 years old and still changing. On 28 July 2026 David Soria Parra and Den Delimarsky shipped a revision in which “MCP is transforming from a bidirectional stateful protocol into a request/response stateless protocol”. The session id is gone, the handshake is gone, and any request “can now land on any server instance behind a plain round-robin load balancer”. Roots, sampling and logging are deprecated with a 12-month window (the changelog has the full list). In April 2025 the co-creators had called statefulness “a deliberate design decision”. 15 months later it was out, which is good news… the protocol now looks more like the HTTP API everyone said it was pretending not to be. It also means a server I wrote last year has migration work this year and the clients I care about support features at different speeds. Before I build on elicitation or Tasks, I check the actual apps I intend to ship to.

Permissions are still mine

The authorization framework gets a client signed in. It doesn’t know which appointments that person may read or change. A shorter tool list isn’t a permission check either. Every tool still has to check, when it runs, that this caller may do this thing to this record, the same as the API behind it. Evaluations are how I find out whether the agent actually completes the tasks people bring, which is a separate question from whether the protocol works.

So, do I need an MCP server?

If people want my service inside ChatGPT, Claude, Cursor or another MCP client, yes. I keep the API I have and put a small, task-shaped set of tools in front of it. That’s the integration those apps can use and it lets a tool ask the person a question.

If the only client is my own agent making a handful of known calls, I keep the OpenAPI integration (or a thin CLI) and skip the second protocol. And in either case I keep the tool list short and let the model write code for long chains because the tokens go to the size of the list and to the results passing through the model.

If the tools belong to a web page a person has open, that’s a different integration and I cover it in my WebMCP explainer. Tool calling, the agent loop and evaluations sit at steps 8 and 12 of my AI engineer roadmap. When a team has to make this call for a product with users, that’s what my AI engineering workshops are for.

Questions

Why not just give an AI agent an OpenAPI spec?

I can and for my own agent I do. Frameworks like Semantic Kernel import an OpenAPI spec and turn its operations into tools. I add an MCP server when I want my service inside ChatGPT, Claude, Cursor or another app that already speaks MCP. Those apps only ever call tools/list.

What is the difference between MCP and an API?

An API is any interface one program offers another. MCP is one specific protocol, client-server like HTTP, where the client is an AI application and the server hands it tools. An MCP server is itself an API, usually sitting in front of the API I already have.

Is MCP just a REST API?

No. MCP is a remote procedure call (RPC) protocol in JSON, over stdio or HTTP, with fixed operations like tools/list and tools/call, a fixed result format with an isError flag and a defined way for a tool to ask the user for input. A REST API describes its own operations and error formats. MCP fixes them so a client can implement them once.

Will MCP replace APIs?

No. An MCP server calls my existing API behind it. Since the July 2026 revision the protocol is stateless request and response. So it looks more like an ordinary HTTP API than it used to. I keep the API for every other integration and add MCP for MCP clients.

Is MCP just JSON?

MCP messages are JSON remote procedure calls (RPC), but the protocol also fixes which methods exist, what a tool result looks like, how capabilities are declared and how a tool asks the user for more input. An API that returns JSON isn't an MCP server until it answers those methods.

Is MCP like an API gateway?

No, but a gateway can speak it. A gateway routes requests and enforces policy. MCP is the protocol an AI app uses to list and call tools. Azure App Service and several gateways can read an OpenAPI spec and expose its operations as MCP tools, with limits on what they translate.

Can I generate an MCP server from OpenAPI?

Yes. Azure App Service's built-in MCP preview and tools like Speakeasy generate tools from an OpenAPI document. The catch is that one tool per endpoint and descriptions written for humans make a bad tool set. So I curate the tools afterward and test them against the tasks people bring.

Do I need an MCP server if I already have an API?

Only if people want my service inside MCP clients like ChatGPT or Claude. For my own agent making a few known calls, the OpenAPI integration I already have is enough. The API stays either way and MCP can sit in front of it.

Does MCP make API calls cheaper?

No. Loading every tool definition costs tokens before the first question: GitHub's MCP server with 43 tools used 44,026 tokens on a task a CLI did in 1,365. A raw OpenAPI document in the prompt can cost even more. I keep the tool list small and let the model write code for long chains.