Command Palette

Search for a command to run...

Hectal
PHASE 7Intermediate ~21 min· topic 8 of 9

Topic 7.8

The Model Context Protocol in Brief

In one line

The Model Context Protocol (MCP) is an open standard that lets an AI application connect to tool servers through one common JSON-RPC protocol, instead of writing custom glue for every tool. It also covers resources and prompts. The same safety rules still apply.

Think of it like this

The wall sockets in a country. Before a standard, every appliance maker needed its own plug and every house its own wiring. With one socket shape, any appliance works in any house. MCP aims to be that socket between AI applications and the tools and data they use.

Words you'll meet

New words in this topic, in plain English. Come back here whenever one feels fuzzy.

MCP
Model Context Protocol: an open standard for connecting AI applications to tools and data through servers.
Host
The AI application that manages connections to MCP servers.
MCP client
The part of the host that holds one connection to one MCP server.
MCP server
A program that offers tools, resources or prompts to clients.
JSON-RPC 2.0
A simple message format for calling remote methods: requests with an id, method and params, and responses with a result or an error.
Transport
How the messages travel: stdio for a local process, Streamable HTTP for a remote one.
Primitive
One of the things a server can offer: tools, resources or prompts.
Server-Sent Events (SSE)
A way for a server to push a stream of text events over one HTTP response (Topic 5.2). Streamable HTTP can use it for replies.
_meta
A field on every request in the current MCP revision. It carries the protocol version and the client's identity and capabilities, so no handshake is needed.

Step by step

01Step 1: the problem

Every app writing its own connector for every tool does not scale. A common protocol turns many-times-many into many-plus-many.

Step 1: the problemdiagram
Rendering diagram…

02Step 2: discover the tools

The client sends tools/list. The fake server answers with a tools array: each tool has a name, a description and an inputSchema. This is the same information you wrote by hand in Topic 7.3.

03Step 3: give them to the model

The client maps each MCP tool to the model's tool format: inputSchema becomes function.parameters. From here the Topic 7.2 loop is unchanged: when the model asks for get_weather, the host routes the call to the right server.

04Step 4: call a tool

The client sends tools/call with the tool name and arguments. The result holds content and isError. The example prints ok for Pune and error for the misspelt city, whose text goes back to the model as in Topic 7.5.

05Step 5: errors and safety stay yours

A method the server does not support gets a JSON-RPC error. Whatever the server returns, your host still validates, confirms and logs as in Topics 7.4 to 7.7.

Try it yourself

  1. 1

    Read the traffic

    Run the example and find the id in each request and in its response. What links a response to its request?

  2. 2

    Add a second tool

    Add a tool get_time to the server's list (no arguments, inputSchema of {"type":"object","properties":{}}) and a branch in tools/call that returns a fixed text. Run: which line of output changes by itself?

  3. 3

    Spot the untrusted part

    Which strings in the exchange come from the server and end up in your model's prompt (the tool description, the result text)? For a server you did not write, what could a malicious string in them try to do, and which topic of this phase defends against it?

Code & diagrams

A tools/list and tools/call exchange with a fake server New tab

A sketch of the JSON-RPC shape, not a real MCP implementation. Real messages carry more fields: in revision 2026-07-28 every request also has a `_meta` with the protocol version, client info and client capabilities (earlier revisions started with an `initialize` handshake instead), and results add a `resultType` such as "complete". The tool and result shapes follow the specification's examples.

Sign in to run this example in your browser.

Expected output

>> {"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
<< {"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"get_weather","description":"Get the current weather for a city.","inputSchema":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}]}}
tools for the model: get_weather
>> {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"Pune"}}}
<< {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"Pune: 31 C"}],"isError":false}}
call 2 -> ok: Pune: 31 C
>> {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"Punee"}}}
<< {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"unknown city: Punee"}],"isError":true}}
call 3 -> error: unknown city: Punee
>> {"jsonrpc":"2.0","id":4,"method":"resources/list","params":{}}
<< {"jsonrpc":"2.0","id":4,"error":{"code":-32601,"message":"Method not found"}}
call 4 -> error -32601 Method not found

Break it on purpose

Errors are the best teachers. Make each change, read the error, guess what went wrong, then reveal the answer.

Break #1

Ignore isError

In the client loop (Python), compute status as always "ok" instead of checking result["isError"].

terminal
$ Run
── what you'll see ──
>> {"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}
<< {"jsonrpc":"2.0","id":1,"result":{"tools":[{"name":"get_weather","description":"Get the current weather for a city.","inputSchema":{"type":"object","properties":{"city":{"type":"string"}},"required":["city"]}}]}}
tools for the model: get_weather
>> {"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"Pune"}}}
<< {"jsonrpc":"2.0","id":2,"result":{"content":[{"type":"text","text":"Pune: 31 C"}],"isError":false}}
call 2 -> ok: Pune: 31 C
>> {"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"get_weather","arguments":{"city":"Punee"}}}
<< {"jsonrpc":"2.0","id":3,"result":{"content":[{"type":"text","text":"unknown city: Punee"}],"isError":true}}
call 3 -> ok: unknown city: Punee
>> {"jsonrpc":"2.0","id":4,"method":"resources/list","params":{}}
<< {"jsonrpc":"2.0","id":4,"error":{"code":-32601,"message":"Method not found"}}
call 4 -> error -32601 Method not found

Myth vs fact

Myth

MCP is a new way for models to call tools.

Fact

The model still uses ordinary tool calling. MCP standardises how an application discovers and runs tools from other programs.

Myth

An MCP server is automatically safe to connect.

Fact

A server is code someone else wrote, and its descriptions and results are untrusted input. Choose servers carefully, limit their permissions and keep a human in the loop.

Myth

You need MCP for any tool use.

Fact

Tools inside your own app need only functions and a registry. MCP helps when tools are shared across applications or come from other people.

Pro corner

Extra depth for experienced readers. New to this? Skip it for now and come back later.

  • ▸

    Aggregating tools from several servers can cause name clashes (two servers each offering search). The specification suggests clients disambiguate, for example by prefixing the tool name with a server identifier.

  • ▸

    Every connected server's tools add to the tool list sent with each request (Topic 7.3). Connect only the servers a task needs, or load tools on demand.

  • ▸

    Pin and review the servers you run: a local stdio server runs with your user's permissions. Run it with the least privilege, as in Topic 7.7.

Remember this

  1. 1

    Why this exists. Without a standard, each AI application (an IDE, a chat app, your own bot) writes its own code for each tool: one connector for the calendar, another for the issue tracker. Ten applications and ten tools means up to a hundred connectors. MCP defines one protocol. A tool is wrapped once as an MCP server, and any application that speaks MCP can use it.

  2. 2

    The roles. The host is the AI application (for example an IDE or a chat app). For each server it connects to, the host creates an MCP client, a connector that talks to that one MCP server, a program that provides context and tools. A server can run on your machine or remotely.

  3. 3

    What a server can offer. Three kinds of things, called primitives: tools (functions the model can call to act), resources (data for context, such as file contents or database records) and prompts (reusable templates). Discovery uses */list methods such as tools/list, and a tool is run with tools/call. Servers can also tell clients when the list changes. This phase is about tools.

  4. 4

    How it talks. The messages follow JSON-RPC 2.0: a request has an id, a method and params, and the response carries the same id with a result or an error. Two transports are defined: stdio (the host starts the server as a local process and exchanges newline-separated messages over its standard input and output) and Streamable HTTP for remote servers (each message is an HTTP POST to one endpoint, and the reply comes back either as a single JSON body or as a stream of Server-Sent Events, the data: line format from Topic 5.2). The example below is a small fake server and client exchanging those messages, so you can see the shapes.

  5. 5

    No handshake in the current revision. The current specification revision is 2026-07-28. In it, requests are stateless and self-contained: every request carries the protocol version, the client's identity and its capabilities in a _meta field, so there is no session to open first and the server accepts or rejects each request on its own. A server must also answer server/discover, which a client may call to learn the supported versions up front. Revisions up to 2025-11-25 worked differently: the client opened a session with an initialize request and an initialized notification, and many tutorials still show that flow. A client that must talk to older servers detects which kind it faces and falls back.

  6. 6

    Tool results and errors. A tool's definition has a name, a description and an inputSchema (JSON Schema): the same ingredients as Topic 7.3. Your client turns each into a model tool, inputSchema becoming parameters. A tools/call result has a content list (for example items of type text) and an isError flag: when the tool itself failed, isError is true and the text tells the model what went wrong (Topic 7.5). Problems with the request itself, such as an unknown method or an unknown tool name, come back as JSON-RPC errors instead; the example shows code -32601, 'Method not found'. The specification keeps the split deliberate: tool execution errors (isError: true) are for the model to read and correct, while protocol errors are less likely to be fixable by the model.

  7. 7

    What does not change. MCP is plumbing. It does not decide how your application uses the model, and it does not make tools safe. The specification itself says there should be a human in the loop with the ability to deny tool calls. It says servers must validate inputs, and clients should confirm sensitive actions, implement timeouts, log tool use and treat tool annotations as untrusted unless they come from a trusted server. A third-party server's tool descriptions and results are untrusted input to your model (Phase 10). Everything in Topics 7.4 to 7.7 still applies.

  8. 8

    When to use it. If the tools live inside one application, plain function calling (Topics 7.1 to 7.3) is simpler. MCP pays off when many applications need the same tools, or when you want to use servers others have built. A practical detail: MCP tool names may contain dots, while OpenAI-style APIs accept only letters, digits, underscores and hyphens (Topic 7.3), so a client may need to rename tools when it passes them to the model. The coming AI Agents course goes deeper. The protocol has changed between revisions, so check the current specification at modelcontextprotocol.io before building.

Explain it without notes

01

What problem does MCP solve and what are the roles in it?

02

What do tools/list and tools/call do, and how are tool errors reported?

03

Which safety responsibilities remain with the application when it uses MCP servers?

04

Your team can expose its tools through plain function calling or through an MCP server. How do you choose?

Practice

01

Write make_request(id, method, params) that returns the compact JSON text of a JSON-RPC 2.0 request with keys in the order jsonrpc, id, method, params.

02

Write to_model_tool(mcp_tool) that converts an MCP tool dict (name, description, inputSchema) into the model's function-tool dict.

Trade-offs

  • ↔

    A standard protocol saves connector work and adds a layer to run, secure and monitor.

  • ↔

    Third-party servers give you tools quickly and put code you did not write in your model's path.

  • ↔

    Loading every tool from every server maximises capability and costs tokens and accuracy (Topic 7.3).

Done when you can

  • Done when you can explain host, client and server and what each does.

  • Done when you can name the three server primitives and the two transports.

  • Done when you can read a tools/list and tools/call exchange and map it to the model's tool format.

  • Done when you treat server descriptions and results as untrusted and keep Topics 7.4 to 7.7 in force.