MCP keeps coming up in every AI dev conversation right now. And almost every time, someone asks: "So does this replace REST APIs?"
No. And the comparison itself reveals a misunderstanding worth clearing up - one I ran into myself when I first started building with MCP.
TL;DR: REST APIs are for developer-to-system calls. MCP is for model-to-system calls. They're not competing - in most setups, MCP wraps your existing REST APIs. The math shifts from N×M integrations to N+M. That's the whole game.
The Problem I Kept Running Into
When I first tried giving an LLM a raw REST API to work with, it kept hallucinating parameter names, calling the wrong endpoints, and mangling request bodies - not because the model was broken, but because raw HTTP endpoints carry zero semantic context.
I read POST /tickets and checked the docs. The model couldn't do that reliably at runtime. There's nothing in the endpoint that tells the model what priority means, which values are valid, or when to use this endpoint versus POST /issues.
MCP fixes this by replacing endpoints with named tools. Instead of POST /tickets, the model calls create_support_ticket with typed, described inputs: title, priority (one of: low, medium, high, critical), description. Every parameter has a description written for the model, not a human developer.
The model now knows what the tool does, what it expects, and when to use it. That context is what made the difference between reliable tool use and constant hallucination in my own builds.
What They Each Actually Do
| REST / GraphQL / gRPC | MCP | |
|---|---|---|
| Designed for | Developer-to-system communication | Model-to-system communication |
| Caller | Code you wrote | An AI agent at runtime |
| Discovery | You read the docs | Model discovers tools dynamically |
| Context | None - caller already knows the schema | Rich - names, descriptions, types per parameter |
| Best for | Stable, performance-critical integrations | Agentic workflows, multi-tool orchestration |
| Auth model | OAuth, API keys, RBAC (mature) | Still maturing - prompt injection is a real risk |
| Debugging | Standard HTTP tooling | Depends on the client implementation |
| Replaces the other? | No | No |
The right framing isn't "which one" but "which layer." Most production setups I've seen (and built) that use MCP still have REST APIs running underneath - the MCP server is a translation layer that exposes those APIs to models in a format they can actually use reliably.
A Quick Code Comparison
Here's what the difference looks like in practice. Same action - creating a support ticket - handled two ways.
Raw REST call from your agent code:
// Agent has to know the endpoint, headers, body shape, and error handling
const res = await fetch("https://api.example.com/tickets", {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
title: "Login broken",
priority: 2, // what does 2 mean? the model doesn't know
type: "support" // is this required? the model isn't sure
})
});
MCP tool definition:
{
"name": "create_support_ticket",
"description": "Creates a new support ticket. Use when a customer reports a bug or needs help.",
"inputSchema": {
"title": { "type": "string", "description": "Short summary of the issue" },
"priority": {
"type": "string",
"enum": ["low", "medium", "high", "critical"],
"description": "How urgently this needs attention"
}
}
}
The model calling the MCP tool knows exactly what to pass and why. The model hitting the raw REST endpoint is guessing.
The N×M Problem (This Is the Real Insight)
Before I understood MCP properly, I kept rebuilding the same integrations.
If you have N models and M tools, the traditional approach needs N×M integrations. Each model needs its own connection to each tool: its own auth logic, its own schema handling, its own error handling. Every new tool means N new integrations. Every new model means M new integrations.
MCP changes the math. Each model implements an MCP client once. Each tool implements an MCP server once. Any client can talk to any server because they share the same protocol.
N×M becomes N+M.
This is the actual value proposition - not "MCP vs REST" but "a shared protocol that stops you from rebuilding the same integrations over and over."
The Part Most Articles Skip: Dynamic Discovery
REST APIs are static contracts. You define endpoints, the client knows them, done.
MCP supports runtime discovery. When my agent connects to an MCP server, the server advertises its available tools, their input schemas, and what they return. The agent learns what capabilities exist without prior configuration.
This matters for agentic workflows where the set of available tools changes. I can spin up a new MCP server, connect it to the gateway, and the model discovers it automatically. No code changes on the client side.
This is borrowed from the Language Server Protocol (LSP) - the same mechanism that lets your editor support a new programming language without being rewritten. Once I made that connection, MCP clicked for me immediately.
A Concrete Example From Something I Built
I worked on a support automation agent that needed to:
- Look up a customer record
- Check their open tickets
- Create a new ticket if none exists
- Notify the customer by email
With raw REST: My agent code needed to know four endpoints, handle four different auth schemes, parse four response formats, and implement retry logic for each. Every time one of those APIs changed, I updated integration code.
With MCP: I exposed four tools - get_customer, list_tickets, create_ticket, send_notification - each with clear descriptions and typed parameters. The agent calls them by name. The MCP server handles the actual HTTP calls. When the underlying API changed, I updated the MCP server, not the agent.
The agent stayed clean. The tools stayed focused. The model could actually use them reliably.
What I Use When
Traditional APIs:
- Connecting two services in code I control
- Performance and latency are the primary constraint
- I need ACID transactions (SOAP/gRPC territory)
- The caller always knows exactly which endpoint to call
MCP:
- An AI agent is the caller
- The set of tools changes or grows over time
- I'm building multi-step agentic workflows
- I want one integration point for multiple AI clients (Claude Desktop, Cursor, custom agents)
Both together (most common in my work):
- My MCP server wraps existing REST APIs - this is almost always the pattern
- REST handles structured service-to-service calls, MCP handles agent-to-tool calls
- I want AI capabilities without rearchitecting my backend
Where I Think This Is Going
REST isn't going anywhere. It handles core business logic where consistency matters. MCP adds a layer on top - one that makes AI agents first-class consumers of existing infrastructure without requiring them to understand API schemas at runtime.
If you're already running REST APIs internally, converting them to MCP tools is mostly editorial work: decide which operations to expose, write tool names and parameter descriptions that a model can interpret, and test how the model actually calls them before shipping. The backend doesn't change.
The interesting design question I keep running into isn't whether to use MCP or APIs - it's which operations deserve to be MCP tools, how precisely to describe their parameters, and how to scope what the agent can and cannot do.
If you want to go deeper on MCP - tool design patterns, server architecture, real integration examples - I've been writing about all of it over at MCP360.
💬 Have you built an MCP server on top of existing REST APIs? What broke first - the tool descriptions, the auth, or something else entirely? Drop it in the comments, I'm genuinely curious what failure modes look like across different stacks.
Top comments (0)