Skip to content
Agent Month

What is the Model Context Protocol (MCP)?

Last verified: July 2026· MCP

If you have wired an LLM to your internal systems, you have written the same kind of adapter more than once: a function schema here, a REST wrapper there, credential handling bolted on, all of it specific to one app and one integration. MCP exists to make that adapter a shared, reusable thing instead of a private one. It standardises the boundary between an LLM application and the tools and data it needs, so the connector you build for one host works with every other host that speaks the protocol. This guide explains what MCP actually is, the integration problem it solves, how the wire protocol works, and where it fits relative to plain APIs and to native function calling.

What is the Model Context Protocol (MCP)?
ImageFiber Optical CablebychaitawatCC0 1.0tinted
1 protocol
many tools
one wire format across hosts and servers
M + N
not M × N
integrations you build, not per-pair glue
JSON-RPC 2.0
transport-agnostic
stdio or HTTP with streaming
Host + MCP client
Claude Desktop, an IDE, your agent
MCP server
tools · resources · prompts
Tools & data
APIs, databases, files, SaaS
The host embeds an MCP client that opens a session to an MCP server over JSON-RPC. The server is the adapter: it presents capabilities in a uniform shape and does the real work of calling the underlying systems.

What MCP actually is

The Model Context Protocol is an open specification for how an LLM application and an external integration talk to each other. It is not a model, not an SDK, and not a hosted service. It is a contract on the wire: a defined set of JSON-RPC messages for discovering and invoking capabilities, plus the semantics of what those capabilities mean. Anthropic published it in late 2024 and released the specification and reference implementations under an open licence, so anyone can implement either side without depending on a particular vendor.

The shape is deliberately familiar to anyone who has worked with the Language Server Protocol. In LSP, one editor can talk to any language's tooling because the editor and the language server agree on a common protocol. MCP does the same for LLM applications and integrations: the host (the application) embeds an MCP client, and each integration is an MCP server. Because the protocol is fixed, any client can use any server. That decoupling is the entire point.

Concretely, an MCP server exposes three kinds of capability. Tools are actions the model can invoke, like running a query or creating a ticket. Resources are readable context the application can pull in, like a file or a database record, addressed by URI. Prompts are reusable, parameterised message templates the server offers to the user or model. A given server can offer any combination of the three.

Why it exists: the M x N integration problem

Before a shared protocol, every LLM application integrated every tool on its own terms. If you had M applications (a desktop assistant, an IDE plugin, an internal agent) and N systems to connect (GitHub, Postgres, your ticketing system, an internal service), you were on the hook for something close to M x N bespoke integrations. Each one re-implemented the same concerns: how to describe the tool to the model, how to pass arguments, how to authenticate, how to stream results back. None of that work transferred to the next pair.

MCP collapses that to M + N. Each application implements the client side once. Each system is wrapped in a server once. After that, every application can reach every system through the same interface, and a server someone else wrote is a server you can adopt without touching your host. This is the same economic argument that made device drivers, LSP, and ODBC worth standardising: the value is not any single connector but the removal of the combinatorial glue.

The second reason it exists is ecosystem leverage. Because the interface is uniform, integrations become shareable artifacts. A team that builds a solid server for its data warehouse can hand it to another team, or publish it, and it works in any MCP-aware host unchanged. The standard turns one-off adapters into reusable infrastructure, which is where the real time saving shows up over a fleet of applications.

How it works: client, server, and JSON-RPC

Every MCP interaction is a session between one client and one server. The client lives inside the host application; the server is a separate process or service that fronts the actual tools and data. Messages between them are JSON-RPC 2.0 — a small, well-understood format of requests, responses, and notifications. The protocol is transport-agnostic: a local server typically runs as a subprocess and communicates over stdio, while a remote server is reached over HTTP with streaming for server-initiated messages. The message semantics are identical either way.

A session opens with an initialize handshake in which both sides declare protocol version and capabilities, so each knows what the other supports before any real work happens. After that, the client discovers what the server offers — it lists available tools, resources, and prompts — and can subscribe to change notifications so the catalogue stays current. When the model decides to act, the host sends a tools/call request naming the tool and its arguments; the server executes against the underlying system and returns a structured result. Reading context works the same way through resource requests.

The design keeps a clear separation of concerns. The model reasons about which capability to use; the client mediates and enforces host policy, including asking the user to approve an action; the server owns the actual credentials and the real side effects. That boundary is what lets a host expose powerful tools without the model, or a third-party server author, ever holding raw secrets — the server runs in the trust domain that already has legitimate access to the system it wraps.

MCP vs an API

This is the comparison that trips people up, because MCP is not an alternative to APIs — it sits a layer above them. A REST or gRPC API is how a specific service exposes its functionality: it has its own endpoints, its own auth, its own payload shapes, and it was designed to be called by code you write. MCP is a uniform protocol for exposing capabilities to an LLM application, and an MCP server almost always calls ordinary APIs underneath to get its work done.

The difference that matters is who the interface is for and how uniform it is. Every API is different, so integrating one means reading its docs and writing service-specific client code. MCP standardises the outer shape: capability discovery, invocation, and result format look the same regardless of what the server wraps. It also carries LLM-specific affordances a raw API does not — machine-readable tool descriptions the model uses to decide what to call, resource URIs for pulling context, and prompt templates — plus the notion of a stateful session with a consent boundary the host controls.

So the honest framing is MCP wraps APIs; it does not replace them. If you are writing conventional software that calls one service, use its API directly. If you are giving an LLM application a consistent, discoverable way to reach many systems, MCP gives you one interface over all of them, and each server translates that uniform interface into the specific API calls behind it.

MCP vs function calling

Function calling is a capability of a model: given a set of tool schemas in the request, the model can emit a structured call — a tool name and JSON arguments — instead of prose. It is the mechanism by which a model expresses intent to use a tool. Crucially, the model does not run anything; it returns a request, and your application code is responsible for executing it and feeding the result back. Function calling says nothing about where those tools come from, how they are hosted, or how they are shared.

MCP operates one level out. It is the protocol that supplies and executes those tools. An MCP client discovers a server's tools, presents their schemas to the model for function calling, and when the model emits a call, routes it to the server that owns the implementation. In other words, function calling is how the model asks; MCP is how the tool is delivered and run. They are complementary: MCP relies on the model's function-calling ability to trigger tools, and function calling relies on something like MCP to make tools portable across hosts.

The practical distinction is reuse. Hand-wired function calling ties each tool's schema and executor to one application's codebase; move to another app and you re-implement it. An MCP server defines the tool once, behind a standard interface, and any MCP-aware host can present it to its model for calling. If you only ever have one application and a couple of tools, raw function calling is less machinery. Once you have several hosts, or want integrations that outlive one app, MCP is what stops you re-writing the same executors.

When to use MCP (and when not to)

Reach for MCP when the same integration needs to be available from more than one host, when you want integrations to be shareable or reusable rather than baked into a single codebase, or when you are building against clients you do not own — an assistant, an IDE, a third-party agent runtime — that already speak the protocol. It also earns its place when you want a clean consent and audit boundary between the model and systems with real side effects, since the client mediates every call and the server holds the credentials.

Skip it when the extra layer buys you nothing. A single application calling one or two internal functions is simpler with direct function calling; standing up a server and a client session is overhead you will not recoup. Very high-throughput, latency-sensitive machine-to-machine paths are usually better served by calling the underlying API directly, since MCP's value is uniformity for LLM hosts, not raw performance. And MCP does not remove the hard parts of exposing tools to a model — authorisation, rate limiting, careful tool descriptions, and guarding against prompt-injected tool use still have to be designed; the protocol standardises the plumbing, not the judgement.

A reasonable default: prototype with direct function calling to prove the tool is useful, then promote it to an MCP server once a second consumer appears or once you want it to live independently of the app that first needed it. That keeps early work light while giving you a clean path to reuse when the integration has earned it.

Frequently asked questions

What is the Model Context Protocol (MCP)?

MCP is an open standard, introduced by Anthropic in late 2024, that defines a uniform client-server protocol for connecting LLM applications to external tools and data. Built on JSON-RPC, it lets any compliant application (the host and its client) talk to any compliant integration (a server) that exposes tools, resources, and prompts.

Why is MCP needed?

Without a shared protocol, every LLM application integrates every system on its own terms, which scales as M x N bespoke connectors. MCP standardises the interface so each app implements the client once and each system is wrapped in a server once, collapsing the work to M + N and making integrations reusable across hosts.

What is the difference between MCP and an API?

An API is how one specific service exposes its functionality, with its own endpoints and payloads meant to be called by code. MCP is a uniform protocol above that layer for exposing capabilities to LLM applications, and an MCP server typically calls ordinary APIs underneath. MCP wraps APIs; it does not replace them.

What is the difference between MCP and function calling?

Function calling is a model capability: the model emits a structured tool call but does not execute it. MCP is the protocol that supplies and runs those tools, discovering them from a server, presenting their schemas for function calling, and routing the model's call to the server that owns the implementation. Function calling is how the model asks; MCP is how the tool is delivered and run.

When should I use MCP?

Use MCP when an integration must be reachable from more than one host, when you want tools to be shareable or to outlive a single app, or when you build against clients you do not own that already speak the protocol. For a single application calling one or two internal functions, direct function calling is simpler; promote to an MCP server once a second consumer appears.

What the community is debating

Community: r/mcp