Loading video…
Sign in to react
The protocolSolid

Why a protocol for tools

Mei works in support at a small company that sells booking software to gyms and yoga studios. On Monday morning she opens claude.ai and types:

Text
What is ticket 2318 about?

The assistant answers politely. It explains that it cannot see the ticket, and asks her to paste it. On a worse day, it guesses, and the guess sounds confident.

Ticket 2318 is real. It sits in the company's helpdesk database. It is from Blue Heron Yoga, a studio on the $49 a month plan, and its subject is "Charged twice for October". The answer Mei needs is one query away. The assistant cannot make that query.

Here is the puzzle for this lesson. Tom, an engineer at the same company, once solved this problem. He wrote a script that connects the helpdesk to one model API, using a feature called function calling. It worked. Then the team started using three different AI apps: Mei uses claude.ai, Tom uses Claude Code in the company's main repository, and two other engineers use VS Code with GitHub Copilot. None of the three apps can use Tom's script. And the team wants the assistant to see three more systems besides the helpdesk.

How many integrations does the company need now? Who writes them, and who keeps them working? By the end of this lesson you will have the number, and you will know why one protocol changes it.

ThingValue
the companyabout 30 people; about 3,100 gyms and studios as customers
plansStudio $49 a month, Studio Plus $99 a month
the helpdeskthe company's own database: about 12,400 tickets, 180 open on a normal day
Meisupport; uses claude.ai
Tomengineer; uses Claude Code
ticket 2318Blue Heron Yoga, customer cus_1042, "Charged twice for October"
AI apps the team uses3: claude.ai, Claude Code, VS Code with GitHub Copilot
systems the team wants the assistant to see4: the helpdesk, the billing provider, the code repository, the internal runbooks

What the Model Can See

Start with what the model receives. A language model takes text in and produces text out. The text it takes in is called its context: the conversation so far, plus any instructions the app adds. The model knows two things: what it learned in training, and what is in its context right now.

Ticket 2318 is in neither. Training ended long before Blue Heron Yoga was charged twice. And nothing in Mei's conversation contains the ticket. So the model has three choices: say it cannot see the ticket, ask Mei to paste it, or guess. A careful model does one of the first two. None of them answers Mei's question.

There are two ways to get the ticket into the context.

  1. Mei pastes it. She opens the helpdesk, copies the ticket, and pastes it into the chat. This works. It also makes Mei the integration: she does the lookup, she decides what is relevant, and she does it again for every question.
  2. The model asks for it. The app gives the model a way to say "I need ticket 2318", and the app fetches it.

The second way is the subject of this course. It already exists in every major model API, under the name function calling.

Function Calling, the Mechanism Underneath

Tom's script uses this second way. Here is what it does, step by step, when Mei asks her question through it.

Text
1. the script sends the model API two things:
     - Mei's message: "What is ticket 2318 about?"
     - a description of one tool:
         name:         get_ticket
         description:  Fetch one support ticket by its number.
         input schema: an object with one string field, ticket_id
2. the model answers, but not with text for Mei. It answers with a request:
     call get_ticket with ticket_id = "2318"
3. the script runs its own code: a query against the helpdesk database
4. the script sends the result back to the model API:
     subject "Charged twice for October", customer cus_1042, status open, ...
5. the model now has the ticket in its context, and writes the answer for Mei

Look at step 2 closely, because the whole course rests on it. The model does not run anything. It cannot reach the database. It cannot open a network connection. All it can do is write text, and in step 2 the text it writes is a structured request: a tool name and its arguments. The script reads that request and decides whether to run it. The script runs the query. The model only asked.

This is called function calling or tool use, depending on the model provider. Each provider defines its own format for step 1. In the Claude API, a tool definition is an object with a name, a description and an input_schema. Other model APIs use the same three ideas with their own field names. The input schema is written in JSON Schema, a standard way to describe the shape of a JSON object: which fields exist, their types, which are required.

Two facts about function calling matter for the rest of this lesson.

  • The tool definitions are part of the context. The model reads the name, the description and the schema the same way it reads Mei's message. That is how it knows the tool exists and what it is for. OpenAI's function calling guide says it directly: "callable function definitions count against the model's context limit and are billed as input tokens". Lesson 4 measures that cost.
  • The code that runs the tool lives in the app. In Tom's case, the app is his script. The query, the database password and the decision to run it are all in the script.

The second fact is where the trouble starts.

Where It Stops Scaling

Tom's script works for anyone who uses Tom's script. Nobody does. Mei uses claude.ai. Tom himself now spends his day in Claude Code. Two engineers use VS Code.

Each of those apps runs its own loop with the model, the same five steps as above. Each app decides which tools to describe to the model in step 1, and each app runs the tool in step 3. So to give claude.ai a get_ticket tool, the code for step 3 must live somewhere claude.ai can call it. Tom's script is not that place. The same is true for Claude Code and for VS Code.

Now count. The team uses 3 apps. It wants the assistant to see 4 systems. If every app needs its own integration with every system, written to that app's own rules:

Text
integrations = apps x systems
             = 3 x 4
             = 12

Twelve pieces of glue code, each written against a different app's rules, each with its own copy of the helpdesk query or the billing API call. Now see what happens when things change.

  • One system changes. The billing provider changes its API. The company must fix 3 integrations, one per app.
  • A new app arrives. A fourth AI app becomes popular, and Dana, the support lead, wants to use it. That is 4 new integrations, one per system: 4 x 4 = 16 in total.
  • Who writes them? The company cannot add code to claude.ai or VS Code. The makers of those apps cannot write the company's helpdesk query. Nobody is in a position to write all twelve.

This shape has a name: the N x M problem. N apps times M systems gives N x M integrations, and the number grows with both.

One Protocol in the Middle

Here is the experiment. Suppose every app and every system agreed on one way to talk about tools: how to list them, how to call them, what a result looks like. Then each app would implement its side once, and work with any system. Each system would implement its side once, and work with any app.

Text
pieces = apps + systems
       = 3 + 4
       = 7

Seven pieces instead of twelve. Replay the three changes:

ChangeEvery app wired to every systemOne protocol in the middle
the billing API changesfix 3 integrationsfix 1 piece: the billing one
a fourth app arriveswrite 4 new integrations0: the app already speaks the protocol
who writes whatnobody can write all of themapp makers write their side; the company writes its own systems' side

The gap grows with the numbers. At 10 apps and 20 systems, wiring every pair needs 10 x 20 = 200 integrations. One protocol needs 10 + 20 = 30 pieces.

That shared agreement is the Model Context Protocol, or MCP. It is not the first protocol to fix this shape. The MCP specification names its model: "MCP takes some inspiration from the Language Server Protocol, which standardizes how to add support for programming languages across a whole ecosystem of development tools." Before the Language Server Protocol, each code editor needed its own support for each programming language. With it, a language team writes one language server, and every editor that speaks the protocol can use it. MCP applies the same idea to AI apps and the systems they need to reach.

For the company, the piece on its side of the protocol is a program that knows the helpdesk. Call it our helpdesk server. This course builds it, line by line, starting in lesson 2.

Host, Client and Server

The protocol names three roles. Each one has a precise job, and the course uses these words with exactly these meanings.

Text
+--------------------------- host: Claude Code ---------------------------+
|                                                                         |
|   the model  <--->  the host's loop  ---+--->  client A  ---------------+---> server: helpdesk ---> helpdesk database
|                                         |                               |
|                                         +--->  client B  ---------------+---> server: github  -----> GitHub
|                                                                         |
+-------------------------------------------------------------------------+
  • The host is the AI application the person uses: claude.ai for Mei, Claude Code for Tom, VS Code for the other engineers. The host runs the conversation with the model, and it owns the user's consent: it decides what the model may do and asks the user when it should.
  • A client is the part of the host that talks to one server. The specification is exact about this: "A host application creates and manages multiple clients, with each client having a 1:1 relationship with a particular server." Tom's Claude Code, connected to our helpdesk server and to a GitHub server, holds two clients. The specification calls them "MCP clients". This course says "client" from here on.
  • A server is the program that exposes tools, resources and prompts. Our helpdesk server is one. It can run on the same machine as the host, or somewhere on the internet.

The model sits inside the host. The model never talks to a server. It talks only to the host, through the model API. The host talks to each server through that server's client.

The specification lists what the host is responsible for. Among them: it "creates and manages multiple client instances", "enforces security policies and consent requirements", "handles user authorization decisions" and "manages context aggregation across clients". That last one means the host decides what goes into the model's context.

One more line from the specification's design principles explains why the roles are split this way: "Servers should not be able to read the whole conversation, nor 'see into' other servers." The full conversation stays with the host. Our helpdesk server sees a request for ticket 2318. It never sees the rest of Mei's chat, and it never sees what the GitHub server returned to Tom.

MCP Does Not Replace Function Calling

You might expect MCP to be a new way for models to call tools, one that replaces function calling. It is not. MCP feeds function calling. The model still does exactly what it did in Tom's script.

Here is Mei's question again, with a host that speaks MCP and our helpdesk server connected to it. Each step says who talks to whom.

Text
                                                              who talks to whom
1. the host asks the helpdesk server for its tool list        client  -> server   (MCP)
2. the host turns each tool into the model API's tool format  inside the host
3. the host sends Mei's message and those tools to the model  host    -> model    (function calling)
4. the model asks to call get_ticket with ticket_id "2318"    model   -> host     (function calling)
5. the host checks with Mei, if its settings say to ask       host    -> Mei
6. the host's client asks the server to call get_ticket       client  -> server   (MCP)
7. the server queries the helpdesk database and answers       server  -> client   (MCP)
8. the host gives the result to the model                     host    -> model    (function calling)
9. the model writes the answer for Mei                        model   -> host

Steps 3, 4 and 8 are the function calling from Tom's script, unchanged. The model receives a tool definition in its provider's format, writes a request, and reads a result. It never sees a single MCP message. Steps 1, 6 and 7 are MCP: they happen between the client and the server, and the model is not part of them.

So the two do different jobs:

Function callingMCP
betweenthe host and the modelthe client and the server
carriestool definitions, the model's request to call, the resultthe tool list, the call, the result
defined byeach model providerone shared specification
who must implement itevery app that uses a model with toolsevery app and every server that want to work together

Step 2 is where the two meet. The host reads the tool list from the server and writes each tool into the format its model API expects: the name, the description and the input schema. Claude Code, for example, gives our tool the name mcp__helpdesk__get_ticket, so that two servers with a tool of the same name cannot collide.

Step 5 deserves a sentence of its own. It is the host that pauses and asks Mei, not the model and not the server. The specification puts it this way for tools: "there SHOULD always be a human in the loop with the ability to deny tool invocations." Who asks, and what that question is worth, comes back in lesson 7 and lesson 10.

The correct model, in one sentence: function calling is how a model asks for a tool; MCP is how the host finds the tool and runs it, without the tool's code living inside the host.

Three Primitives, Three Controllers

A tool is not the only thing a server can offer. MCP defines three kinds of thing, called primitives, and the difference between them is who decides when each one is used.

Take three things the company wants the assistant to have.

  • Ticket 2318. Mei asks a question, and the model decides it needs the ticket. The model chooses when. This is a tool: get_ticket.
  • The refund policy. A short document that says when a refund is allowed and who must approve it. The model should follow it whenever refunds come up. But you do not want the policy's use to depend on the model remembering to fetch it. The host should decide when to include it, or let Mei attach it. This is a resource: data the host reads by its address, helpdesk://policies/refunds.
  • "Triage this ticket." A standard set of instructions that Mei runs on a ticket: read it, check the customer's charges, propose a next step. Mei picks it from a menu, the same way every time. This is a prompt in MCP's sense: a template the user chooses, triage_ticket.

The specification states the three controllers directly:

PrimitiveWho decides to use itIn the specificationIn our helpdesk server
toolthe model"model-controlled"get_ticket, search_tickets, issue_refund, and three more
resourcethe host application"application-driven"helpdesk://policies/refunds, helpdesk://tickets/{ticket_id}
promptthe user"user-controlled"triage_ticket

The word "prompt" has two meanings in this course, so watch for it. The prompt to the model is the text the model receives. An MCP prompt is a template a user picks from a menu. When the two could be confused, the course says "MCP prompt".

Why does the protocol care who decides? Because the three need different behaviour from the host. A tool needs a loop in which the model can ask, and a check with the user before anything happens. A resource needs a way for the host or the user to attach data. A prompt needs a menu. One shape would serve all three badly. Lesson 6 builds the resource and the prompt, and shows why putting the refund policy in a tool description fails.

What MCP Is Not

Three wrong expectations are common. Each one costs a learner time later, so clear them now.

MCP is not a model API. It does not carry Mei's conversation to a model, and it does not care which model the host uses. The host could change models tomorrow, and our helpdesk server would not notice. The protocol's messages are between a client and a server only.

MCP is not an agent framework. It does not decide when to call a tool, how many times to try, or when the task is done. That is the host's loop, steps 3 to 9 above, and every host runs its own. MCP defines what crosses the line between client and server, nothing more. Lesson 3 walks through that loop in the amount this course needs.

MCP is not a security boundary. Connecting a server does not make it safe, and the protocol does not stop a tool from doing harm. The specification says so plainly: "Tools represent arbitrary code execution and must be treated with appropriate caution", and "While MCP itself cannot enforce these security principles at the protocol level, implementors SHOULD" build consent and authorization into their apps. The protections in this course are things the host and our server do. The protocol gives them a place to happen. Lesson 9 and lesson 10 are about exactly that.

One more thing to know before lesson 2. MCP is versioned by date. Each revision of the specification is named by the day it was released, and the current one is 2026-07-28. This course teaches that revision. MCP is a young protocol, and it has changed shape more than once. Where an older revision did something differently, and you are likely to meet it in an older tutorial, an older server or an app that has not updated, a short note headed What changed says so, right after the current mechanism is taught.

Seeing It in a Real Host

Every host that speaks MCP shows you the same picture: a list of servers, and under each server, its tools. Open the one you use and look before you build anything.

  • Claude Code. claude mcp list in a terminal lists the configured servers. Inside Claude Code, the /mcp command opens a panel that lists each server, lets you read its tools, and lets you switch it off. Servers are added with claude mcp add, which lesson 3 uses to connect our own.
  • claude.ai. Remote servers are added in claude.ai's settings, where a server you add yourself is called a "custom connector". claude.ai connects from Anthropic's cloud, so the server must be reachable on the internet. That is why Mei gets our helpdesk server in lesson 8, not sooner.
  • VS Code. Servers live in an mcp.json file. The chat has a tool picker that lists every tool from every server and lets you turn tools off for a request.

The interfaces differ. What each one lists is the same, because each host asks each server the same question, in the same protocol. The next lesson types that question by hand.

Mei's Question, Answered

Back to the company. Without a shared protocol, giving three apps access to four systems takes twelve integrations, and nobody can write all of them. With MCP it takes seven pieces. Three of them already exist: claude.ai, Claude Code and VS Code each implemented the client side once. The company writes the other four, one server per system. The first of those is our helpdesk server.

Tom's script is not wasted. Its core, the query that fetches a ticket by number, becomes the get_ticket tool inside the server. What changes is where it lives. Before, it lived inside one app. Now it lives in one server that every host can reach.

Here is what is missing today, drawn as the host sees it:

Text
claude.ai (host)            Claude Code (host)            VS Code (host)
     |                            |                            |
  client                       client                       client
     |                            |                            |
     +-------------+--------------+--------------+-------------+
                   |                             |
          [ helpdesk server ]          [ the other three systems' servers ]
            does not exist yet                    later
                   |
          helpdesk database: 12,400 tickets, ticket 2318 among them

When the box in the middle exists, Mei's question takes nine steps, and she sees none of them. She types "What is ticket 2318 about?", approves the call if her settings ask her to, and reads: Blue Heron Yoga was charged $49 twice on 1 October.

The Takeaway

  1. A model knows only its training and its context. Data like ticket 2318 must be put into the context, by a person pasting it or by the model asking for it.
  2. Function calling lets the model ask. The app describes tools to the model (name, description, input schema), the model writes a request to call one, and the app runs it. The model never runs anything.
  3. Function calling alone leaves the tool's code inside each app. With 3 apps and 4 systems that is 3 x 4 = 12 integrations. One protocol in the middle makes it 3 + 4 = 7 pieces, and each side is written by the people who own it.
  4. MCP names three roles. The host is the AI app and owns the user's consent. A client is the part of the host that talks to exactly one server. A server exposes tools, resources and prompts. The model talks only to the host.
  5. MCP does not replace function calling, it feeds it. The host reads the server's tools and gives them to the model in the model API's own format. The model never sees an MCP message.
  6. Tools are model-controlled, resources are application-driven, and MCP prompts are user-controlled. MCP is not a model API, not an agent framework and not a security boundary.

The one sentence to keep: function calling is how a model asks for a tool; MCP is how any host finds that tool and runs it, without the tool's code living inside the host.

An open question for the next lesson: when the host asks our helpdesk server for its tools in step 1, what exactly does it send, and how does the server know the question is finished? The answer is a line of JSON, and you will type it yourself: JSON-RPC on the wire.

References