MCP vs API: What Actually Changes When an Agent Calls Your Product
Oct 21, 2026 · 6 min read · by Jordan Kwan
TL;DR: Most of what MCP changes is real but narrow. Scored across 8 dimensions against the spec, exactly 3 differences survive scrutiny: the client discovers your capabilities at runtime instead of reading docs at build time, your tool descriptions and schemas are written for a model to choose among rather than for code to call, and tool failures come back as results the model can recover from instead of status codes. The other 5, including state, auth, and transport, are the same machinery your API already runs on. That is not a dismissal. The 3 real differences are the ones that decide whether agents can use your product at all, which is the argument in the flagship case for building an MCP.
What exactly did I compare?
The marketing version of this comparison pits "MCP" against "APIs" as if one replaces the other. It cannot, mechanically: an MCP server is a layer that calls your product's internals, which for most SaaS teams means it sits directly on top of the existing API. So the honest comparison is narrower. I took the current specification (2026-07-28), cross-checked it against the 2025-11-25 revision that most deployed servers and clients still run, and scored the 8 dimensions where the difference is usually claimed: discovery, tool semantics, state, errors, auth, observability, schemas, and transport. For each one the question was the same: does the spec require something a competent REST plus OpenAPI stack does not already do?
Which differences are real?
Discovery is real. An API's capabilities are documented for humans and wired in by developers at build time. An MCP client calls tools/list at runtime and receives names, descriptions, and schemas it can act on immediately, with no code change on the client when you add a tool. In the session era the server could also push a tools/list_changed notification mid-conversation. The current revision adds cache hints (ttlMs, cacheScope) so clients know how fresh a cached list is. No part of HTTP or OpenAPI standardizes that runtime handshake. This is the difference the whole protocol is built around, and it is genuine.
Tool semantics are real. Your API's descriptions are written for developers skimming docs. An MCP tool's description is an input to a model's decision about whether to call it, alongside annotations that tell the client whether the tool is read-only, destructive, idempotent, or open-world, and, since the 2025-06-18 revision, an optional output schema with structured results the model can parse instead of scraping prose. The consumer of your interface changed from a compiler to a model, and the spec encodes that change.
The error split is real. REST folds every failure into a status code and a body. MCP separates protocol errors (a malformed request, an unknown tool, an unsupported version, returned as JSON-RPC errors) from execution errors: a tool that ran and failed returns a successful response with isError: true and content written for the model to read and recover from. That split exists because the caller can act on a good error message in a way a compiled client cannot. It is a small design decision with outsized effects on whether agent tasks actually complete.
Which differences are fog?
State is fog, and the spec now admits it. Early MCP had connection state: an initialize handshake, negotiated capabilities, a session. The 2026-07-28 revision removed the handshake from the core protocol. Every request is now self-contained and carries its own version, which is precisely the statelessness REST was always mocked for needing. Whatever state your product has lives server-side behind tool arguments, exactly as it does behind an API. Five revisions in, the protocol converged to the API answer.
Auth is fog. The authorization specification is a tight profile of the standard OAuth stack: OAuth 2.1, Protected Resource Metadata (RFC 9728), resource indicators (RFC 8707), authorization server discovery through RFC 8414 or OpenID Connect. Profiling it well is real work, and it matters that clients can discover how to authenticate instead of reading your docs. But nobody replaced API auth. MCP adopted it, because it is the machinery that already works.
Schemas and transport are fog. Tool inputs are JSON Schema, the same language OpenAPI uses for parameters. The wire protocol is JSON-RPC 2.0 over HTTP POST, with optional streaming over server-sent events, or newline-delimited messages over stdio for local servers. JSON-RPC versus resource URLs is a styling choice with real ergonomics on both sides. It is not a new capability. One honest caveat in MCP's disfavor: the single-endpoint design hid the method name inside the body, where gateways and logs could not see it, and the current revision had to add Mcp-Method and Mcp-Name headers to fix that. Observability was not improved by MCP. It had to be repaired back to what per-route HTTP gives you for free.
What does the scorecard look like?
| Dimension | Verdict | Why |
|---|---|---|
| Discovery | Different | Runtime tools/list, list-changed notifications, cache hints |
| Tool semantics | Different | Descriptions and annotations written for a model, structured output |
| Errors | Different | Execution errors return as results with isError, not status codes |
| State | Same machinery | 2026-07-28 made the core stateless, state lives behind arguments |
| Auth | Same machinery | OAuth 2.1 profile, RFC 9728, RFC 8707, RFC 8414 |
| Observability | Same machinery | Standard HTTP logging, method headers added to recover route visibility |
| Schemas | Same machinery | JSON Schema, as in OpenAPI |
| Transport | Same machinery | JSON-RPC over HTTP POST or stdio |
8 dimensions, 3 different, 5 inherited. If you want the builder's version of what to do with the 3 real ones, the playbook walks through them step by step. And if you are evaluating servers rather than building one, what is inside the MCP server you installed applies the same skepticism from the client side, as does the protocol survey in the A2A agent card audit.
So what should you actually do differently?
Keep your API. It is the foundation, and 5 of the 8 dimensions say nothing about it needs to change. Build the thin layer where the real differences live: a tool surface designed for a model reader, discovered at runtime, with errors written to be recovered from. That is a smaller and stranger job than "rebuild for agents", and it is the job described in the flagship: every software company will need an MCP not because APIs failed, but because the caller changed.
What would change my mind?
Two things. First, if the fog dimensions start differentiating in the spec: the extensions now landing, tasks for long-running work and server-hosted apps among them, could move the state and semantics scores if they become core and widely implemented. Second, if clients stop using the real differences: if hosts hardcode tool lists or ignore annotations and structured output, discovery and semantics become theory, and the honest score drops to 1 of 8. I will re-score when the next spec revision ships.
Written by Jordan Kwan, founder of Reachium.
I build Reachium, the LinkedIn outreach platform behind the tactics you just read. Same brain, live product.
See what Reachium does ↗Prefer the long version first? What Reachium is and how it works