An interactive explainer

What Actually Changes When You Put MCP in Front of Your REST API?

Compared to a REST API, less integration code for developers to write and maintain, because the MCP provider ships the tools already described.

What is the difference between REST API and MCP? It should be a simple question with a jargon-free answer. Instead you read things like "an API for AI agents", "REST is stateless by design", or analogies trying to dumb it down for you: "MCPs are like USB ports, one universal connector for every tool". All technically correct, decorative definitions, but not explaining what changes mechanically when you build an agentic system using an MCP.

Maybe you are on the other side of this. You have wrapped your data platform in an MCP server and you are telling customers to use this new thing. Do they need it? And can you clearly tell them why? I was not able to, so I built this explainer for myself.

TL;DR: With a REST API, you build and maintain the integration code for every tool your agent uses, changing it each time the API changes. With MCP, the provider ships a description of each tool (what it does, what inputs it takes) in a format the LLM can read at runtime, so you write less integration code of your own.

What is a "tool"?

In an agentic system, a tool is any action the agent can take beyond its own reasoning, out in the systems where your data and services actually live: fetch a calendar, query a database, send an email, look up a deal. Each one is a function the model can call, wrapped with a description of what it does and what inputs it needs. Unlike traditional code, the agent does not run tools on a fixed schedule; it reads the descriptions and decides, mid-task, which to call and in what order.

A simple example: give an agent a get_weather tool and ask "should I cycle to work?" It calls the tool, reads the forecast, and answers. Ask "what's a good recipe for chocolate brownie?" and it ignores the tool entirely, since nothing in the question needs it. Same tool, available both times; the agent decides when it is relevant. That runtime choice is what makes it agentic.

So far, no MCP needed. You could write get_weather yourself, and the agent would use it the same way. For a single tool that you own, it is a reasonable request. So where does MCP come in?

The moment the tool is not yours, MCP earns its place. If the weather service ships an MCP server, you point your agent at it and it discovers what tools are available, instead of you reading their API docs, writing the call, and updating your code every time they change a field.

For some use cases, writing the tool yourself is still the simpler choice. If you only need one stable call from a large external service, a single hand-written tool can be less code than depending on a whole server, and easier on the model too.

Let the LLM read the docs and figure it out?

You could argue the LLM can just read the API docs and work out the call itself. Fair, but now it does that every single time, at runtime. Every call spends tokens and context re-deriving what a tool description would have told it. That is load you are paying for on every request, to work out something a tool description would have handed it up front.

"MCP is a design choice" - you can understand that now, instead of just being a throwaway statement. The tool descriptions live inside the MCP server, not in separate docs, because the model reads them at runtime and turns them into calls itself, rather than a developer reading docs ahead of time and writing the calls into code.

And just like a badly written API doc makes an API harder for a developer to integrate and use, a badly written or misconfigured tool description leads to the LLM using the MCP tool incorrectly, or failing to invoke the right one when it is needed.

The key difference between MCP and a REST API: with REST, you write and maintain the integration code for each tool yourself; with MCP, the provider describes the tool and the model reads that description at runtime. If that is what you came for, you can stop here.

If you like the kind of explainer that shows the underlying mechanics, keep reading. The next section describes what's actually happening when the model picks a tool - the protocol, the round trips, and ends on one product, a usual morning, handled two ways: a developer's fixed path on one side, a decision made at runtime on the other.

What is an API

An API is a mechanism for one program to call functions on another. A server exposes what it can do. A client asks for those things. The API is the contract between them: what messages you can send, in what shape, and what comes back.

The dominant style today is REST, defined by Roy Fielding in his 2000 doctoral dissertation. REST is not a protocol; it is a set of architectural constraints. Most REST APIs run over HTTP as the transport, with verbs like GET and POST applied to resource URLs. Each request stands alone: the server does not remember your previous call. This property has a name.

REST is stateless. That's a big part of why you end up writing and maintaining integration code per tool. MCP does keep some state, the session stays open between calls, but not the state people usually assume. The context of the task, what the user asked and what's been worked out so far, lives in the LLM, not in MCP.

The MCP protocol

Anthropic published MCP in November 2024. Messages are JSON-RPC 2.0. A client (an LLM host like Claude Desktop or Cursor) opens a persistent session with a server, negotiates capabilities during initialization, and exchanges messages until either side disconnects. Transports are stdio for local servers and Streamable HTTP for remote ones.

Inside a session, MCP exposes three kinds of things a server can offer, each answering a different question about who decides when to use it.

Model-controlled
Tools
Functions the LLM decides to invoke when it needs them. Think of them as callable actions: query a database, send a message, look up a customer.
App-controlled
Resources
Data or context the application can attach to the model's window. Files, records, snippets. The app decides what to include, based on what the user is doing.
User-controlled
Prompts
Pre-written templates a user can invoke. Usually surfaced as slash commands or menu items. The user picks one; the LLM runs it.

To ground this in an example, a CRM MCP server might expose tools like find_at_risk_accounts and summarize_account_activity; resources like crm://accounts/{id}/notes and crm://deals/pipeline; and prompts like /weekly_pipeline_review and /draft_forecast_narrative.

Notice what the three primitives are doing together. Tools give the model agency. Resources give the application curation. Prompts give the user shortcuts.

To see what an actual JSON-RPC message for each primitive looks like, click through the tabs in the figure below.

Figure 1 - The three primitives
Each tab shows the JSON-RPC message the client sends and the who controls invocation badge. Notice the method name changes with the primitive: tools/call, resources/read, prompts/get.

Good to know: You will read that "MCP is bidirectional" in several places. What makes it feel like that is because it runs JSON-RPC over a persistent session (stdio locally, Streamable HTTP for remote servers). The session stays open, so both sides can send messages while it is live, for instance a server asking the model to generate something mid-task rather than only answering when it is called.

REST works the other way, and for good reason. A REST call is one round trip because the caller already knows the endpoint. Nothing needs negotiating, so a single ask-and-answer is enough. MCP's caller is a model discovering what is available at runtime and chaining several calls to answer one request, so the connection stays open as a session instead of closing after each exchange.

The tool description is where the whole thing lives or dies. It is what the LLM reads to figure out what a tool does, when to call it, and with what arguments. Click through the three buttons below to see the same tool described three ways, and what the LLM does with each.

Figure 2 - Tool description quality
Tool description (server-side)
LLM's response
User: "Which deals should I worry about this quarter?"
Same tool, three descriptions. Click to compare. Watch how the LLM's call and answer change. MCP is a mechanism, not magic; the description is where the mechanism becomes useful.

Two scenarios, one product, different choice

The best way to see when to reach for each is to take one product and use it two ways. Same underlying data, same user, same moment. Only the caller changes.

Same sales rep, same morning. Two very different flows.

Scenario A - Static widget

The mobile app's home screen shows a "Today's meetings" widget. When the screen loads, the app fires GET /users/me/meetings?date=today. The server returns a JSON list of meetings. The app renders each one into a pre-built row: time, attendees, account name. Deterministic query, deterministic layout, developer wrote every line of this path.

Scenario B - AI assistant

The rep taps the AI assistant and asks, "What should I focus on this morning?" The LLM decides on the fly to fetch meetings, then to check which are with hot accounts, then to pull recent call notes, then to summarize. Each decision is a tool call over MCP. No developer wrote a "morning brief" flow. The LLM invented it.

What the widget looks like
Today's meetings
9:00
Q3 Business Review
11:30
Renewal Check-in
2:00
Discovery Call
4:30
Weekly Standup
What the AI assistant looks like
What should I focus on this morning?
Priority order for this morning:
  • 9am Q3 Review with Acme: their champion changed roles last week; identify a new sponsor.
  • 11:30 Renewal with Beacon Health: prep the renewal ROI slide (they went silent for two weeks).
  • 2pm Discovery with Northwind: exploratory, no prep needed.
Under the hood · Scenario B A simple agent orchestrator. Real frameworks add memory, guardrails, and error handling on top.
User "What should I focus on this morning?"
↓
Orchestrator Receives the query, plans the task, coordinates the calls below
↓
Retrieval Pulls internal context: rep's territory, past preferences, agent instructions
↓
LLM Reads available MCP tools, decides which ones to call and in what order
↓
MCP tools/call get_todays_meetingsReturns 4 meetings: Acme, Beacon, Northwind, Internal standup
↓
MCP tools/call get_account_signals(acme)Returns "champion changed roles last week"
↓
MCP tools/call get_account_signals(beacon)Returns "silent for 2 weeks"
↓
LLM Integrates tool results with retrieved context, prioritizes by risk signal
↓
Generator Formats the response as a prioritized bulleted brief
↓
Reply "Priority order for this morning: 9am Q3 Review with Acme..."

Same CRM, same data, same rep, same time of day. What changed is the caller. Scenario A has a developer-written program that already knows what it wants. Scenario B has an LLM that is deciding at runtime. That distinction, more than anything about the technology, is what tells you which protocol to reach for.

Play the two scenarios side by side in the figure below. Watch what flies over the wire in each.

Figure 3 - Widget flow vs AI assistant flow
The same underlying data, accessed two different ways. In Scenario A, the app knows exactly which endpoint to call. In Scenario B, the LLM decides at runtime which tools to invoke and in what order.

Scenario B ends up making Scenario A's API call underneath. The MCP server takes the LLM's get_todays_meetings tool call and turns around to hit the same GET /users/me/meetings?date=today that the widget uses. MCP wraps the API you already had.

Rule of thumb: reach for REST when your caller is deterministic code that already knows the endpoint. Reach for MCP when your caller is an LLM that has to decide the endpoint at runtime. In most real systems, both live in the same product: the app UI hits REST directly, the AI assistant hits MCP, and the MCP server calls the same REST endpoints behind the scenes.

MCP does not replace your API. It adds a caller that decides at runtime instead of following a path you wrote.

Appendix: Glossary

A quick reference for the vocabulary used throughout this article.

Host
The top-level application you interact with (Claude Desktop, ChatGPT, Cursor). Owns the UI, the user session, and holds one or more MCP clients inside it.
MCP client
A component inside the host that manages ONE connection to ONE MCP server. If your host is connected to Gmail, Salesforce, and GitHub, three MCP clients are running.
MCP server
A program that exposes tools, resources, and prompts for one service. The Gmail MCP server wraps Gmail's underlying REST API. Servers can be local (running as a subprocess) or remote (running at a hosted URL).
LLM (Large Language Model)
The reasoning engine. Claude, GPT, Gemini. Lives at the provider's data center and is accessed by the host through the provider's API. The LLM decides which tools to invoke based on what the user is asking.
API (Application Programming Interface)
A mechanism for one program to call functions on another. A contract for what messages you can send, what shape they take, and what will come back.
REST API
A common style of API built on HTTP verbs (GET, POST, PUT, DELETE) applied to URLs that represent resources. Stateless per request. Most public APIs are REST.
GraphQL
An alternative API style where the client asks for exactly the fields it wants in one query, and the server returns just those fields. Includes runtime introspection so clients can discover the schema. Used by GitHub, Shopify, Salesforce.
Plugin
A vendor-specific integration format that predated MCP. ChatGPT plugins, Cursor extensions, Claude tool-use APIs. Each vendor had its own format, so tool builders had to write one per vendor. MCP replaced this fragmentation with a shared format any client can consume.
Protocol
An agreed set of rules for how two parties exchange messages: the format, the sequence, the meaning, the timing. Every conversation between systems needs one.
JSON-RPC 2.0
The specific protocol MCP uses. JSON is the data format. RPC stands for Remote Procedure Call, meaning one system invoking a function on another. Transport-agnostic, so messages can move over HTTP, WebSockets, or stdio.
Transport
How bytes physically move between MCP client and server. MCP supports stdio (subprocess pipes, for local servers) and Streamable HTTP with Server-Sent Events (for remote servers).
Tools, Resources, Prompts
MCP's three primitives. Tools are actions the LLM invokes. Resources are data the application injects into context. Prompts are templates the user triggers.