The Model Context Protocol (MCP) is an open standard for connecting LLM applications to the tools, data, and prompt templates that live outside them. Before it, every assistant that wanted to read your files or query your database shipped its own bespoke connector, and every system that wanted to be reachable shipped one adapter per assistant. MCP replaces that combinatorial mess with a single wire protocol: write a server once, and any compliant application can use it. This article is the map of MCP — the problem it solves, the three roles, the three primitives and who may invoke each, how a connection begins and ends, how bytes move, why a protocol is worth the ceremony, and the class of problems MCP pointedly leaves to you. Each piece has its own deep dive; this is the sketch that makes them fit together.
The problem: N applications, M systems, N x M connectors
A language model on its own is a closed box. It becomes useful when it can reach the world — read a repository, query a warehouse, call an internal service. The obvious way to build that is one integration at a time: your chat app grows a GitHub connector, then a Postgres connector, then a Jira connector, each with its own auth handling, schema format, and error conventions.
The trouble is that this cost is multiplicative. With N applications that want context and M systems that hold it, the industry writes on the order of N × M connectors, most re-solving the same problems badly. Worse, none of that work is portable: a connector built for one assistant’s plugin format is dead weight for every other. The pattern is familiar — the same pressure produced ODBC for databases and the Language Server Protocol for editors. In each case the fix had the same shape: stop writing adapters, agree on a protocol, and turn N × M into N + M.
What MCP actually is: an open protocol, not a framework
MCP is a specification for messages, not a library you are obliged to adopt. Its message layer is built on JSON-RPC 2.0: requests carry a method, params, and an id; responses echo that id with a result or an error; notifications are one-way and expect no reply. That deliberately boring foundation means an MCP implementation can be written in any language that can serialize JSON and move it over a pipe or a socket; the exact envelope shapes and method families are the subject of the protocol deep dive.
Two consequences follow from “open protocol.” First, the spec is public and versioned, so implementations from different vendors interoperate without a business relationship. Second, the official SDKs are a convenience, not the standard — they save you from hand-rolling framing and lifecycle logic, but a server that speaks the right JSON is a valid server no matter how it was built. MCP describes the conversation; it does not prescribe your architecture, your language, or your agent loop.
Three roles: host, client, and server
MCP splits the world into three parts. The host is the application the human uses — a desktop assistant, an IDE, an agent runtime. It owns the model, the user interface, and the trust decisions. The client is a connector inside the host that maintains one dedicated session with one server; a host running five integrations runs five clients. The server is the separate program that exposes capabilities — filesystem, database, ticketing — and knows nothing about the model or the user.
The one-client-per-server rule keeps the model clean: each connection is independently negotiated, scoped, and killable, so a misbehaving server cannot reach into another server’s session. The diagram below compresses host and client into a single box, as informal usage often does; the client/server article separates them properly.
The three primitives, and who is allowed to invoke each
Servers offer three kinds of capability, and the design idea most newcomers miss is that they differ by who pulls the trigger, not just by what they contain.
| Primitive | What it is | Controlled by |
|---|---|---|
| Tools | Callable functions with typed inputs and side effects | The model decides to call one |
| Resources | Readable, URI-addressed context: files, records, documents | The application decides what to attach |
| Prompts | Parameterized templates and workflows | The user explicitly picks one |
That control axis is a safety property as much as an architectural one. Tools are the only primitive the model can reach for on its own, which is exactly why they are the primitive that needs consent and annotations. Resources are inert — reading one has no side effects — so the host can attach them freely. Prompts surface as visible affordances such as slash commands, so nothing happens until a human chooses one. Each primitive has its own article covering discovery, schemas, and edge cases.
The other direction: sampling, roots, and elicitation
The three primitives point one way, server to host. MCP also defines capabilities that point back, and they are what separate it from a plain remote-procedure-call layer.
Sampling lets a server ask the host to run a model completion on its behalf. A summarization server needs no API key of its own; it asks the host, which stays in control of cost, model choice, and whether the request is shown to the user. Roots let the host tell the server which directories or URIs are in scope, so a filesystem server is bounded by the workspace the user opened rather than the whole disk. Elicitation lets a server ask the user for a missing input mid-operation instead of failing with a vague error. Together these keep secrets, model access, and scope on the host side, where the trust already lives, while still letting servers be interactive.
The connection lifecycle at a glance
Every MCP session follows the same three-act shape. First, initialization: the client opens a connection and sends an initialize request declaring the protocol version it speaks and the capabilities it supports; the server replies with its own version, capability set, and identity; the client acknowledges, and the session is live. Nothing else may happen before that exchange completes.
Second, operation: the client discovers what exists by listing tools, resources, and prompts, then calls and reads them as the conversation demands. Servers can push notifications — a tool list changed, a resource was updated, a long job made progress — and both sides can cancel in-flight work. Third, shutdown: the connection closes, and whatever session state existed goes with it. The consequence of the handshake is that neither side assumes features the other did not advertise, which is how a spec that keeps evolving stays backward-compatible; the dedicated article on capability negotiation covers that exchange in full.
Transports: how the bytes actually move
MCP separates what is said from how it travels. The message layer is JSON-RPC regardless; the transport decides the pipe. Two families dominate. stdio runs the server as a local child process of the host and exchanges newline-delimited JSON over standard input and output — no ports, no network, no TLS, with the operating system’s process boundary as the security perimeter. It is the natural fit for a server that touches local files or credentials. HTTP-based transports carry the same messages to a remote server over the network, with server-to-client streaming layered on so notifications and progress updates flow without polling; that is what makes a shared, multi-user, independently deployed server possible at all. Because the message layer is identical, the same server logic can usually be exposed either way. The transport articles cover framing, streaming, and the operational trade-offs.
Why a protocol beats a pile of bespoke integrations
The obvious win is arithmetic: build M servers and N hosts instead of N × M connectors. The less obvious wins compound. Portability means the server you write for your internal wiki works in whatever assistant your company adopts next year, including one that does not yet exist. Composability means a host can run many servers at once and the user gets the union of their capabilities.
Separation of concerns means the team that owns a system owns its server and never has to think about prompts, context windows, or which model is in use. Testability follows: a server is an ordinary process speaking a documented protocol, so you can exercise it with a script and no model at all. And a shared protocol lets cross-cutting infrastructure exist — registries, gateways, proxies, audit layers — because there is finally a single thing for it to sit in front of.
Trust, consent, and the surface a protocol creates
Connecting a model to real systems is a security event, and MCP is explicit that the host is where trust lives. The guiding principles are user consent before consequential actions, clear disclosure of what a server can do, and no silent escalation: a server cannot grant itself permissions the host did not extend. In practice, tool calls surface for approval, servers receive only the scope the host chooses to share, and credentials stay on the host side.
What a protocol cannot do is make an untrusted server safe. A server you install is code you are running, and its tool descriptions become text your model reads — which makes description text an injection surface, not just documentation; aggregating many servers multiplies that exposure. The security and tool-annotation articles cover threat models, consent policy, and authorization; treat this paragraph as the reason to read them.
What MCP does not solve
MCP is a connectivity standard, and it is worth being precise about its edges. It is not an agent framework: it says nothing about planning, memory, multi-step reasoning, retries, or how your loop decides what to do next. It does not make a model good at using tools — a badly named tool with a vague description is misused just as reliably over MCP as over any bespoke integration, and schema design remains your job.
It does not manage context budget: connect thirty servers and their combined tool listings can crowd out the conversation, which is why filtering, gateways, and scoping matter at scale. It is not an authentication system, though it defines how authorization plugs in. And it does not guarantee quality — conformance means your messages are well-formed, not that your server is fast, correct, or safe. What MCP gives you is the boring, load-bearing part: a common language.