Engineering Guide

MCP vs API: How Model Context Protocol Actually Relates (It Wraps, Not Replaces)

The honest one-line answer: MCP does not replace your REST or LLM API — it is a standardized client-server layer that sits on top of them so a model can discover and invoke capabilities at runtime instead of a developer hardcoding each integration. Anthropic open-sourced the Model Context Protocol on 25 November 2024 and calls it a USB-C port for AI applications. This guide explains what MCP is, its host/client/server architecture, its primitives, a real JSON-RPC exchange, how it relates to function calling and tool use, and a decision table for when to use each.

MCP vs API — MCP wraps your API so a model can discover and invoke tools at runtime

What MCP is

The Model Context Protocol (MCP) is an open standard for connecting AI applications to external systems — data sources, tools, and workflows. Anthropic introduced and open-sourced it on 25 November 2024 and describes it as a USB-C port for AI applications: one connector shape that any compliant tool can plug into, instead of a bespoke cable per integration.

The phrase people search for — MCP vs API — sets up a versus that does not really exist. MCP is not a competitor to your REST or LLM API. It is a layer that sits on top of those APIs. An MCP server typically wraps an existing API: the API still does the real work, and MCP makes that capability discoverable and callable by a model through a single standardized protocol. Keep that thesis in mind for the rest of this guide — MCP wraps your API; it does not replace it.

How this is sourced. Architecture and protocol facts here are drawn from the official docs at modelcontextprotocol.io. The control framing (model-decides vs app-decides) is an explanatory characterization from developer write-ups, not a spec-defined rule. Related reading: what is an LLM gateway and the OpenAI-compatible API.

The who-is-in-control distinction

The cleanest way to feel the difference is to ask who decides what gets called. With a plain API, your application decides what endpoint to hit and when — the control flow is written into your code, one hardcoded call at a time. With MCP, the model decides which tool to invoke based on the user's request, and the client discovers the menu of available tools at runtime before choosing.

That shift is why MCP matters for AI agents: an agent that can list a server's tools and pick among them adapts to new capabilities without a redeploy. A static REST integration cannot — adding a capability means writing new client code. The distinction is a teaching device, not a spec clause, but it captures the practical reason the protocol exists.

Client glue code vs number of toolsIllustrative — hardcoded API integration grows with each tool; MCP discovery stays flat2 tools10 toolshardcodedMCP20 toolshardcoded
Chart: DataLLM Lab — illustrative client integration effort. Hardcoded API glue grows with each added tool; MCP runtime discovery stays roughly flat because the client asks the server what it can do. Units are relative, not measured.

Architecture: host, client, server

MCP follows a client-server architecture with three participants:

So a host running three servers holds three clients, each pinned to one server. This one-to-one pairing is what keeps sessions, capabilities, and permissions cleanly scoped per connection. If you have built a Claude Code skill or used Claude Code, you have already been the host in this diagram — the tool servers you attach are MCP servers.

Primitives and layers

MCP is built from two layers: a data layer (the JSON-RPC 2.0 protocol, lifecycle management, primitives, and notifications) and a transport layer (the communication channels plus authentication). It is a stateful protocol: a connection opens with an initialize handshake that negotiates capabilities before any tools are called.

Servers expose three core primitives:

Server primitiveWhat it isExample
ToolsExecutable functions the model can invokecreate_ticket, run_query, send_email
ResourcesData sources that provide contexta file, a table row, a doc
PromptsReusable interaction templatesa saved review-this-PR prompt

Clients can expose primitives back to servers too: sampling (the server asks the client to run an LLM completion), elicitation (the server asks the user for more info), and roots (filesystem or URI boundaries the server may operate within), with logging also supported. The official pages frame this client set slightly differently — the introduction highlights sampling, elicitation, and logging; the specification lists sampling, roots, and elicitation — so treat it as the full set rather than a fixed count of three. A newer cross-cutting primitive, Tasks, is marked experimental and may change.

Transport comes in two flavors: stdio for local, same-machine servers (communicating over standard input and output) and Streamable HTTP for remote servers (HTTP POST with optional Server-Sent Events). Older material references an HTTP+SSE transport; that is deprecated — use Streamable HTTP. For remote servers, MCP recommends OAuth for obtaining auth tokens. The current latest spec revision is dated 2025-11-25, though the protocolVersion negotiated in any given handshake may differ from the latest revision string.

Point your MCP servers at 300+ models

DataLLM Lab is an OpenAI-compatible gateway. When an MCP server needs sampling — or your host needs a model behind the tools — reach every provider through one key and one endpoint.

A real JSON-RPC exchange

Under the hood MCP is JSON-RPC 2.0. Here is the shape of an initialize handshake, a runtime discovery call, and an execution call — the exact sequence that makes MCP feel dynamic where REST is static:

// 1. Client opens the connection and negotiates capabilities
{ "jsonrpc": "2.0", "id": 1, "method": "initialize",
  "params": { "protocolVersion": "2025-06-18",
    "capabilities": {}, "clientInfo": { "name": "host-app" } } }

// 2. Client discovers what the server can do — at runtime
{ "jsonrpc": "2.0", "id": 2, "method": "tools/list" }
// -> server returns [{ name: "search_orders", inputSchema: {...} }, ...]

// 3. The model picks a tool; the client executes it
{ "jsonrpc": "2.0", "id": 3, "method": "tools/call",
  "params": { "name": "search_orders",
    "arguments": { "customer": "acme" } } }

The load-bearing step is #2. A REST client already knows every endpoint at build time; an MCP client asks tools/list at runtime and can be told the menu changed via a notifications/tools/list_changed message. That runtime discovery — not the wire format — is the real contrast with a static API.

Because tool descriptions travel from the server to the model, the spec is explicit about security: require user consent before exposing data or invoking a tool, treat tool descriptions and annotations as untrusted unless they come from a server you trust, and get user approval for sampling requests. A server can describe a tool in whatever words it likes, so a hostile server is a prompt-injection surface — trust boundaries matter.

MCP vs function calling vs tool use

The three-way confusion is the heart of the topic, so untangle it directly. These are complementary layers, not rivals:

In practice they stack: the model uses function calling to say I want to call search_orders with these args; MCP is how search_orders got onto the menu in the first place and how the result comes back. You can do function calling with no MCP at all (hardcode the tools), and MCP relies on function-calling-capable models to be useful. For choosing such a model, see our best LLM for AI agents guide.

AspectPlain API / function callingMCP
Who decides the callYour app / the model, hardcoded toolsModel, from runtime-discovered tools
Tool discoveryBuild time, in your codeRuntime, via tools/list
Reuse across clientsRe-integrate per appOne server, many clients
Wire formatHTTP / provider SDKJSON-RPC 2.0, stateful
Does the actual workThe APIWraps and calls the API

MCP has broad ecosystem support: it is widely reported that OpenAI adopted it across its Agents SDK, Responses API, and ChatGPT desktop app in March 2025, that Google DeepMind confirmed Gemini support in April 2025, and that Microsoft and GitHub joined the steering committee in May 2025. Those adoption dates come from secondary reporting rather than each vendor's primary page, so treat them as approximate.

When to use each

You do not always need MCP. The decision is about scale and sharing, not sophistication:

Your situationReach for
Single model, simple project, a few stable tools you ownDirect API or native function calling
One app, tools that rarely changeFunction calling, no MCP
Many tools across many client appsMCP
Tools that update independently of the appMCP
You want new capabilities to appear without a client redeployMCP

The tidy summary: if you would otherwise hardcode two or three calls into one app, a direct API is simpler and you should skip the protocol overhead. Once you are maintaining a growing tool surface shared by multiple clients — or you want the model, not your code, to choose among a menu that changes over time — MCP earns its keep. Either way, remember what it is doing underneath: standardizing discovery and execution on top of the APIs you already have.

FAQ

Does MCP replace REST or LLM APIs?

No. An MCP server usually wraps an existing API — the API still does the work, MCP just makes it discoverable and callable by a model through one standard protocol. Wrap, not replace.

What is the difference between MCP and a plain API?

With a plain API your app decides what to call, hardcoded. With MCP the model picks a tool, and the client discovers available tools at runtime via tools/list before calling tools/call.

Is MCP the same as function calling?

No — complementary layers. Function calling turns language into a structured tool call your app runs; MCP standardizes how tools are discovered, described, and executed across external servers.

What are the three MCP server primitives?

Tools (executable functions), Resources (context data), and Prompts (reusable templates). Clients can also expose sampling, elicitation, and roots back to servers, plus logging.

What transports and auth does MCP use?

stdio for local servers and Streamable HTTP (POST plus optional SSE) for remote ones; the older HTTP+SSE transport is deprecated. MCP recommends OAuth for remote auth tokens.

When should I use MCP versus a direct API?

Direct API or native function calling for a single model or a few stable tools. MCP when you have many tools, multiple clients sharing them, independently updated tools, or want runtime discovery.

Written by
Kevin Fan

Founder of DataLLM Lab, the unified LLM gateway. Kevin tests models the boring way — same prompts, real costs, unedited outputs — and writes up what the runs actually show.

One API for every model

One API, every model.

Get a single API key for Claude Opus 4.7, GPT-5.4, and 300+ more — with automatic price comparison and routing to the best model for every request.