To course

The agent loop

One step of an agent loopPractice: one step of the loopThe loop in codePractice: the loop in codeStopping and retryingPractice: stopping and retryingWhat only code can decidePractice: what code decides

Reliability in production

Timeout and idempotency keyPractice: timeout and idempotency key

Agent designs

Workflow or agentPractice: workflow or agentReAct and plan-and-executePractice: ReAct and plan-and-executeOne agent or a swarmPractice: one agent or a swarm

Context and cost

Why the agent bill growsPractice: tokens and cacheContext engineeringPractice: managing the windowAgent memoryPractice: what the agent keeps

Tools and protocols

MCPPractice: MCP
←→RUSign in
Agents › Tools and protocols

MCP

Builds onThe loop in code

This block explains how a tool built by another team reaches your agent through the Model Context Protocol (MCP), what the current version of the protocol looks like, and what it leaves for you to secure.

The same two forms for every department

The colleague on the phone keeps asking for things other departments own: parcel status from Shipping, stock counts from the Warehouse. Each department has its own procedure, so you keep a folder of instructions for each.

Then all the departments agree on two forms. One asks "what can you do?" and the other says "please do this." Each department fills in its own answers to the first form, and you read them out to your colleague.

Northwind has three agents that need the same three services. Without a shared format, every pair needs its own adapter.

Nine custom adapters become six pieces, because each agent and each service implements the protocol once.
Nine custom adapters become six pieces, because each agent and each service implements the protocol once.

MCP is that pair of forms, written as JSON-RPC 2.0 messages. The service's API stays where it is. Here an MCP server is an adapter in front of it, and any application that speaks MCP can use it without code written for that server.

Who does what

The model is not a party to the protocol and opens no connection. Here is one parcel lookup:

The server talks only to your app, and your app talks to the model. Your app translates between the two.
The server talks only to your app, and your app talks to the model. Your app translates between the two.
  1. Your app sends tools/list, and the Shipping server replies with its definitions.
  2. Your app copies them into the tools field of the model request. MCP calls the schema inputSchema and Anthropic's API calls it input_schema, so your app converts it.
  3. The model replies with a tool_use block for track_parcel.
  4. Your app runs its own checks and sends tools/call.
  5. The server does the work and returns a result. Your app wraps it in a tool_result, and the loop from the earlier blocks continues.

Names need care in step 2. A tool name is unique only inside one server, so two servers can each offer search, and the specification says clients should disambiguate, for example with a server prefix. The prefix should be a label your host assigns, because the specification warns that a server's own name is not guaranteed unique. MCP also allows a dot in a name, which Anthropic's API does not. Northwind's host therefore exposes shipping__track_parcel, with any dot replaced by an underscore, and removes the prefix before it calls the server.

Step 4 on the wire, in the current revision:

{
  "jsonrpc": "2.0",
  "id": 7,
  "method": "tools/call",
  "params": {
    "name": "track_parcel",
    "arguments": {
      "order_id": "4417"
    },
    "_meta": {
      "io.modelcontextprotocol/protocolVersion": "2026-07-28",
      "io.modelcontextprotocol/clientCapabilities": {}
    }
  }
}

And the reply:

{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "resultType": "complete",
    "content": [
      {
        "type": "text",
        "text": "4417: out for delivery"
      }
    ],
    "isError": false
  }
}

Servers can offer more than tools. Tools are functions for the model to run, resources are data for the user or the model, and prompts are message templates for the user. In the other direction, a client can offer elicitation, which lets a server ask the user for information.

Messages travel over one of two standard transports. With stdio, the client launches the server as a subprocess and they exchange lines on its standard streams. With Streamable HTTP, each message is a POST to one endpoint. The older HTTP+SSE transport is deprecated.

Which version you are reading about

As of 2026-11-10 the current revision is 2026-07-28, and it changed the base of the protocol. Articles and SDK examples written earlier describe the handshake on the left.

The old revisions open with a handshake. In the current one every request describes itself.
The old revisions open with a handshake. In the current one every request describes itself.

2025-11-25 and earlier

2026-07-28

Version and client capabilities

Agreed once in initialize

Sent in _meta of every request

Learning a server's capabilities

The initialize reply

server/discover: servers must implement it, clients may skip it

State across calls

Optional Mcp-Session-Id on HTTP

No protocol session; the server issues an ID, called a handle, that is passed as a tool argument

Server needs user input

The server sends a request to the client

The result has resultType: "input_required", and the client retries with inputResponses

Roots, Sampling, Logging

Active

Deprecated, still working for at least twelve months

Deprecated does not mean removed, but new implementations should not adopt these features. In place of Roots, the specification suggests tool parameters, resource URIs or server configuration. Elicitation stays active, and the earliest removal of Roots, Sampling and Logging is the first revision released on or after 2027-07-28.

The two eras do not mix by default. A client that speaks only the new revision fails against a server that knows only the handshake, and a handshake-only client fails against a new-only server. An implementation that needs both supports both, and the specification calls that dual-era.

What MCP leaves to you

The specification says plainly that MCP cannot enforce its security principles at the protocol level. That work belongs to your host and to the service.

The rule from the refund block still holds. customer_id stays out of arguments. MCP's authorization is optional. When a Streamable HTTP server uses it, the token travels with every request, and the server takes the identity from it.

MCP pays off when several agents share a service or when the service comes from another team. One agent with two functions you own does not need it.

Conclusion

Go deeper

Specification 2026-07-28: key changesThe exact list of what changed since 2025-11-25, with the numbered proposals.MCP toolsReal tools/list and tools/call messages and the security notes at the end.Versioning and compatibilityThe matrix of which client and server eras work together.The 2026-07-28 specification (MCP blog)The maintainers explain why the core became stateless.
‹ Previous
Suggest an improvementFound a mistake