This page was written by an AI — and that's not a disclaimer, it's the demonstration. A language model can do exactly one thing: read text and produce more text. It cannot open Notion, cannot create pages, cannot upload the interactive diagrams you're about to click. Yet here this page is. The gap between "can only produce text" and "made this page" is precisely what the Model Context Protocol (MCP) exists to close — and by the end of this page, you'll know exactly how.

One tool call, from the inside

Let's not start with an architecture diagram. Let's start with the single mechanism everything else is built on: a tool call. The player below replays the call that created this page. As you step through it, keep your eye on the right-hand panel — the model's context window. That list of text is the model's entire world: it can't see your screen, your files, or Notion. It sees the list, and nothing else.

mcp-01-one-tool-call.html

That loop is worth restating, because everything in MCP hangs off it: the model proposes, the host executes, and the result comes back as text. A model "acting on the world" is an illusion produced by this loop running quickly. Once that's solid, the rest of MCP is plumbing — and we can ask the more interesting question: why does this plumbing need a protocol?

Why a protocol?

Tool calling itself isn't new — models have been emitting structured "call this function" text for years. What was missing was agreement on the boring parts: how an app finds out what tools exist, how tools describe their inputs, how results come back, what an error looks like.

Without that agreement, every AI app that wants to talk to Notion writes a custom Notion integration; every app that wants GitHub writes a custom GitHub integration. Four apps × six services is twenty-four integrations, each with its own bugs. Worse, when a new service appears, it's invisible to every AI app until each one ships bespoke support for it.

MCP is the agreement. A service implements one MCP server, once; any AI app that speaks MCP can use it. An app implements one MCP client, once; it can then use every MCP server ever written — including ones that didn't exist when the app shipped. Four apps + six services = ten things to build, and the two sides never need to know about each other. It's the same trick USB-C pulled on chargers, which is why that analogy is in every MCP talk ever given.

The protocol itself is small. It specifies three things: how the two sides say hello (initialization), how a server advertises what it offers (discovery), and how a call and its result are encoded (invocation). You've already watched invocation. Let's zoom out and meet who's talking.

The cast: host, client, server

MCP uses three words precisely, and they map exactly onto what you just stepped through. Drag the slider — it's the same moment at three zoom levels.

mcp-02-three-altitudes.html

Notice what the middle level shows: the model is not a party to the protocol. MCP messages flow between the client (inside the host app) and the server. The model just reads and writes text at the top, and the host decides what to do about it. That separation matters: the host can enforce permissions, ask you before a destructive call, or log everything — and the model can't bypass any of it, because the model never holds the connection.

Discovery, or: how the model knows what it can do

Here's the part that makes MCP servers plug-and-play. Claude was never programmed with knowledge of Notion's tools. At connection time, the client asked the server — a message called tools/list — and the server answered with names, one-line descriptions, and input schemas. That reply is everything the model will ever know about the server.

Which raises a question worth feeling rather than reading: is a name and a one-line description really enough to act on? Try it — you're the model now.

mcp-03-you-are-the-model.html

This is why people who build MCP servers obsess over tool descriptions. A description is not documentation that a developer might read — it is the interface that the model definitely reads, in every single conversation.

A tool is a typed function