MCP vs REST API: When to Use Which
Side-by-side comparison of MCP and REST for AI agents — tool discovery, streaming, latency, auth, caching. Concrete rules for picking one over the other.
"Why not just expose a REST API?" is the first question every backend engineer asks when handed an MCP spec. The honest answer is: sometimes you should. MCP is not a replacement for HTTP. It is a specialisation for agent-to-tool traffic, and once you see the wins it earns, the decision becomes easy.
What MCP actually adds over HTTP
Three primitives that REST does not standardise:
- Tool discovery —
tools/listreturns a machine-readable manifest with JSON Schema for arguments and a natural-language description. REST has OpenAPI, but nobody in the wild ships OpenAPI accurate enough for an LLM to plan with. MCP makes the manifest the primary interface. - Bidirectional streaming — a tool can return progress updates while running. For a
run_migrationtool that takes 90 seconds, streamed progress stops the agent from timing out and retrying. - Capabilities handshake — the client tells the server what it supports (sampling, roots, elicitation). The server adapts. REST has nothing equivalent; you get content negotiation and that is it.
The comparison table
| Concern | REST | MCP |
|---|---|---|
| Tool discovery | OpenAPI (often wrong) | Required, machine-readable |
| Streaming | SSE / WebSocket ad-hoc | Built in, standardised |
| Auth | Any | OAuth 2.1 + PKCE spec'd |
| Caching | HTTP cache headers, CDN | Client-level, no CDN story |
| Stateless | Yes by convention | Sessions supported, optional |
| Transport | HTTP only | stdio, HTTP, WebSocket |
| Ecosystem maturity | 30 years | ~2 years |
| LLM-planner fit | Poor (requires wrapper) | Native |
| Human developer fit | Excellent | Awkward (needs client) |
When MCP wins
- Agent-first tools. If the primary caller is an LLM agent, MCP is strictly better. You get discovery, typed arguments, and progress streaming with no glue code.
- Ephemeral, privileged actions. Things like run this migration, grant this permission, deploy this branch. The OAuth + scope model is cleaner than building an RBAC layer on top of REST.
- Local tools. Anything that reads the filesystem or a local database is unambiguously MCP-over-stdio. You get zero network surface and a real auth model (the agent process launched you, that is your auth).
- Multi-client exposure. If the same tool needs to be callable from Claude Code, Cursor, Windsurf, and an internal agent, MCP means you write it once. A REST adapter would require four integrations.
When REST wins
- Human consumers matter. A dashboard, a mobile app, a cron job in a neighbour service — these want plain HTTP. Do not force REST-shaped consumers through an MCP client.
- You need edge caching. CDN caching of idempotent GETs is a solved problem in HTTP and unsolved in MCP. If your tool is really a cacheable read (GitHub stars for a repo, for example), REST + Cloudflare is better.
- Existing ecosystem. Stripe, Twilio, Linear, and 50,000 other APIs are REST. Wrapping them in MCP makes sense (and MCP servers for these exist). Rewriting them does not.
- High-throughput service-to-service. At 10k RPS between two internal services, the MCP framing overhead is noise, but so is the benefit. Stick with REST or gRPC.
The pattern I use
For a new internal tool I ship both. A single handler, two transports:
// tool handler, pure function
async function searchRepos(input: { query: string; limit: number }) {
return db.repos.search(input);
}
// 1) Expose via MCP for agents
mcpServer.tool("search_repos", searchRepos, schema);
// 2) Expose via REST for humans / other services
app.get("/api/repos/search", async (req, res) => {
const result = await searchRepos(req.query);
res.json(result);
});
The extra 20 lines pay for themselves the first time a non-agent caller shows up. Which they always do.
Bottom line
MCP is not a REST replacement, it is a REST complement aimed at agent traffic specifically. If your primary caller is an LLM and the work is tool-shaped rather than document-shaped, pick MCP. If you have humans, browsers, or non-agent services in the call graph, keep REST in the mix. Doing both is cheap; doing the wrong one is expensive.
Running MCP in production?
Centralised auth, cost analytics, and the APC optimization layer — free tier included.