What the Model Context Protocol actually is

by Corneliu Dumitru5 min readGuides

The Model Context Protocol is usually introduced as "USB-C for AI", which is a good slogan and a bad explanation. Here is the version that helps you build something.

The problem it solves

A language model can only act on the world through tools you give it. Before MCP, every combination of model host and tool was its own integration: your GitHub tool for Claude Desktop was different code from your GitHub tool for Cursor, which was different again from your GitHub tool for an agent you wrote yourself.

M hosts times N tools is a lot of integrations, and almost all of them are the same work done again.

MCP makes it M plus N. A tool is exposed once, by a server. Any client that speaks the protocol can use it. Write the GitHub server once, and every MCP client gets GitHub.

The three nouns

A server exposes capabilities. In practice this almost always means tools — named, described functions with a JSON Schema for their arguments. The protocol also defines resources, prompts and a few other things, and you can build a useful server that offers only tools.

A client is the thing that connects to servers. Claude, ChatGPT, Cursor, VS Code, Codex and your own agent are all clients.

A host is the application the client lives inside. The distinction matters occasionally and can be ignored most of the time.

What actually goes over the wire

JSON-RPC. That is the whole answer, and it is worth seeing because it demystifies the rest.

A client opens with initialize, announcing which protocol version it speaks and what it supports. The server replies with its own name, version and capabilities.

Then two methods carry essentially everything:

  • tools/list — "what can I call?" The server returns names, descriptions and argument schemas.
  • tools/call — "call this one, with these arguments." The server does the work and returns a result.

That is it. The interesting engineering is on either side of those two calls, not in the protocol between them.

Two transports

stdio — the client starts the server as a child process and talks to it over standard input and output. Simple, local, no network. This is what most "run this npx command" instructions produce.

Streamable HTTP — the server is a remote endpoint. Nothing is spawned. This is what a hosted server or gateway uses, and it is why remote MCP setup is a URL rather than a command.

What MCP deliberately does not do

This is the part usually skipped, and it is the part that decides how you build.

It does not do permissions. The protocol has no concept of "this agent may read but not delete". A server exposing a DELETE tool is offering it to any client that connects. If you want rules, they live in the server — or in something the calls pass through.

It does not do identity in itself. Newer revisions specify OAuth for HTTP transports, but what a token means is entirely the server's business.

It does not stop prompt injection. A tool result is text going into a model's context. If that text contains instructions and the model follows them, MCP has no opinion about it. Servers returning content from the outside world should be labelling it as untrusted data, and clients should be treating it that way.

It does not make tools good. A badly named tool with a vague description is exactly as confusing over MCP as it was before. Naming and descriptions are the interface, and models read them the way a developer reads a function signature.

The thing everyone hits second

Not connecting a server. That part usually works.

The second problem is that every tool definition costs context on every single request. Ten connected apps is a few hundred tools, and now a meaningful fraction of the model's attention is spent reading a catalogue before anyone has said anything.

The answers in circulation are all variations on do not send them all: filter to what a task needs, or send a small set of search tools and let the agent look up the rest. Both work. Both are worth knowing about before you connect the tenth app rather than after.

Large results are the same shape of problem from the other direction. A tool that returns a 4 MB export has just spent your context window on a CSV. Sensible servers truncate, paginate, or hand back a handle you can read in pieces.

The shortest path to something working

You can spend a week building servers, or you can borrow one that already exists and find out in ten minutes whether any of this helps you.

Spinrun is an MCP gateway: one HTTP endpoint that already carries the OAuth applications, the token refresh, the secret storage and the audit trail for a catalogue of apps. You connect an app through its own consent screen, point a client at one URL, and the tools are there. It also answers the two problems above — permissions are read/write/destructive rules enforced on every call rather than a sentence in a prompt, and large results are paged rather than dumped into your context window.

Pick a client, connect one app, and give it a real task rather than a test. The gap between "the tools are listed" and "this is actually useful" is where all the learning is, and it is much shorter than building the server first.

Before anything loads

We would like to switch on analytics, so we can see which pages are worth keeping. Nothing has loaded yet and nothing will until you choose. The cookies that keep you signed in and remember your language are not part of this.

Read the Cookie Policy