MCP is an open protocol that standardizes how LLM applications connect to external tools, data sources, and prompts — think of it as "USB-C for LLMs." Before MCP, every tool integration was bespoke; with MCP, any compliant client can talk to any compliant server.

The problem it solves

The "M × N integration problem." If you have M LLM apps (Claude Desktop, Cursor, your custom agent, etc.) and N tools/data sources (GitHub, Slack, your internal CRM, a database), you'd traditionally need M × N integrations. MCP makes it M + N — each app implements the protocol once, each tool exposes itself once, and they all interoperate.

Architecture (this is the canonical phrasing — memorize it)

Three roles:

  1. Host — the LLM application the user interacts with (Claude Desktop, an IDE, your custom agent runtime).
  2. Client — lives inside the host, manages one connection to one server (1:1).
  3. Server — a process that exposes capabilities (tools, resources, prompts) over the protocol.

So a single host can have many clients, each connected to a different server. Your IDE host might have one client connected to a GitHub MCP server, another to a Postgres MCP server, another to your internal docs MCP server.

The three primitives a server exposes

Primitive What it is Who controls invocation
Tools Executable functions (e.g., search_jira(query)) Model decides to call
Resources Read-only data (files, DB rows, API responses) — addressable by URI Application/User attaches
Prompts Reusable parameterized prompt templates User selects

Tools are model-controlled. Resources are application-controlled (the host/user picks what to give the model). Prompts are user-controlled (a slash-command-like menu).

Transport

JSON-RPC under the hood for the message format.

MCP vs function calling — the question they will ask you

This is the differentiator question. Canonical answer:

"Function calling is a model capability — the LLM emits a structured tool-call token sequence. MCP is a protocol — it defines how a host application discovers and invokes tools that live in a separate process or server. They're not alternatives; they compose. The model decides what to call (function calling); MCP defines how that call gets routed to a server that actually runs it. The win is portability: I write one MCP server and any MCP-compliant host can use it."

When MCP is the right answer (and when it isn't)