AI agents and the Model Context Protocol (MCP)

What an AI agent is - tool calling, planning, the loop and its guardrails - and the Model Context Protocol from hosts and servers down to the JSON-RPC messages, with real example messages, how to write and connect a server, and the two agent patterns {{brand}} uses.

In short

An AI agent is a language model that works in a loop: it reads a goal, chooses a tool, looks at the result and decides the next step, until the job is done or a limit stops it. The Model Context Protocol (MCP) is the open standard that lets any agent - Claude Code, GitHub Copilot, Cursor - use any program's tools through one kind of connection. {{brand}} uses agents in two ways: an MCP server in its command-line tool lets coding agents run suites, read failures and file bugs, and inside the product a sentence becomes a typed plan that a person confirms before anything runs.

After this lesson you can Explain what an agent is and draw its loop; read and write MCP messages - initialize, tools/list, tools/call - by hand; build a small MCP server and connect it to an agent; and design the guardrails that keep an agent useful without making it dangerous.

Words you need

How an AI agent works

A chat assistant answers one question. A workflow runs steps a programmer fixed in advance. An agent decides its own next step, in a loop, choosing from the tools it was given. That freedom is what makes agents useful - and what makes guardrails necessary.

These three pieces belong to one exchange. OpenAI and Google use other field names for the same idea: a list of tools, a request to call one with arguments, and a result tied to the call by an id.

Planning, loops and guardrails

Agents plan in a few well-known styles. Knowing their names helps you read any agent framework and answer design questions.

A model is not a security boundary: it can misunderstand, loop, or be talked into things by text it reads. So every limit that matters lives outside the model, in code the model cannot change.

The lethal trifecta An agent that reads private data, reads untrusted text and can send data out can be tricked into leaking that data - the pattern Simon Willison named the lethal trifecta. Example: an agent that reads your email (private data), opens web pages (untrusted text) and can send mail (send out): a hidden sentence on a page can make it forward your inbox. Prompt injection has no complete fix today, so design so that at least one of the three legs is missing or tightly bounded.

The Model Context Protocol

Before MCP, every AI application wrote its own connector for every tool: M applications times N tools.

MCP turns that into M plus N: each application is a client once, each tool a server once.

The idea comes from the Language Server Protocol, which did the same for code editors and programming languages. Anthropic published MCP as an open standard in November 2024, and most AI applications and coding tools now support it.

What a server offers: three kinds of thing, each controlled by a different party.

What a client offers: abilities the host lends to a server, if the person allows it.

Tools are what agents use most Most servers - {{brand}}'s included - offer only tools. A tool is a typed function with a description; the model reads the description to decide when to call it, so write it like documentation for a careful colleague.

JSON-RPC 2.0: the messages underneath

Every MCP message is a JSON-RPC 2.0 object, and there are only three shapes. A request carries an id and expects exactly one response with the same id. A notification has no id and is never answered. A response carries either a result or an error, never both.

The id ties an answer to its question Requests may be answered out of order - a slow tool call does not block a quick one. The id is how both sides match them, so a server answers each id exactly once, and the sender never reuses an id within a session.

Transports: stdio and Streamable HTTP

Standard output belongs to the protocol One stray print - a banner, a debug line, a library's warning - lands in the middle of the message stream and breaks the connection. A stdio server must send every line meant for a person to standard error, from the very first line of its start-up.

An OAuth resource server is a service that accepts tokens issued by someone else - the authorisation server - and checks them. That separation is why a shared MCP service never handles passwords.

The handshake, capability negotiation and a tool call

The rule is simple: neither side uses a feature the other did not declare. A server that declared only tools is never asked for resources; a client that did not declare sampling is never asked to lend its model. Version negotiation works the same way: the client offers its newest version; a server that cannot speak it answers with one it can, and the client decides whether to stay.

Tools in depth: schemas, hints and two kinds of failure

Hints are not guarantees Annotations help a host decide what to ask the person to confirm, but a host must not trust them from a server it does not trust. The real protection lives in the server: a read-only tool must simply have no way to write.

Every tool costs context The model reads every tool description and every result. Each one fills the context window and costs tokens, so a server with 200 thin tools wastes the budget and confuses the model. Offer few tools, keep results small and say when text was cut, and let the host show which tools were called.

MCP separates two kinds of failure. A protocol error - an unknown method, a malformed request, an unknown tool - is a JSON-RPC error, and the host handles it. A tool error - the city does not exist, a permission is missing - is a normal result with isError: true, so the model reads the sentence and can correct itself.

The 2026 revision: no handshake

The handshake has a cost: the server must remember each connection, which makes it hard to run many copies of it behind a load balancer. The 2026-07-28 revision makes MCP stateless. There is no initialize and no session id, and ping no longer exists. Every request carries its protocol version and the client's capabilities in _meta, and a server/discover request tells a client what the server offers.

See the specification's changelog for the exact wording of what changed in each revision.

Two eras in one server A client of one era fails against a server of the other, and hosts move to new revisions at different speeds. {{brand}}'s server answers both eras in one process and decides per request: a request that carries its version in _meta is answered on its own; an initialize opens the older handshake.

The options in the market

What {{brand}} chose, and why

{{brand}} uses two agent patterns: an MCP server for the coding agents people bring, and a typed plan for the AI built into the product.

The trade-off accepted A hand-written server means following each protocol revision with tests. stdio keeps the agent, the credential and the runs on the developer's machine; a service shared by cloud agents would use Streamable HTTP with OAuth instead. And every confirmation costs a click - accepted, because an AI change nobody read is the expensive kind.

When another option is right: a service used by agents in the cloud should offer Streamable HTTP with OAuth; a prototype should start from the official SDK; a server whose agents mostly read documents should offer resources as well as tools.

Where {{brand}} uses MCP: the command-line server

{{brand}}'s command-line tool has an mcp command. A coding agent's host starts it as a child process and speaks MCP over stdio; a person never types into it. Which tools exist depends on how the person started it: reads are always there, runs from the developer's machine and changes are switched on separately, and a tool that is not allowed is not even listed, so the model is not tempted. It is refused if called anyway.

A credential made for one task can be given an even smaller set of tools than a personal token.

Propose, confirm, execute: a safe pattern for an in-app agent

Inside {{brand}}, a person can type what they want done - "create a task Fix the login redirect, high priority, due Friday" - and get a plan instead of an action. This is the propose, confirm, execute pattern, and it reuses every check the product already has. The rest of this section is the pattern itself, with a generic example.

How to write an MCP server

Security: when the text an agent reads is hostile

An MCP server hands somebody else's model text that people and systems wrote - card titles, step names, the answers of an API under test. Any of it can carry prompt injection. Defending an agent means listing what can go wrong and putting a limit outside the model against each threat.

Bound what an obeying agent could do You cannot make hostile text safe to obey, so assume the agent will obey it one day. Then ask: with these tools and this token, what is the worst it could do? If the answer is too much, remove a tool, narrow a scope or add a confirmation.

Connect an agent to an MCP server, step by step

Hosts change their settings files The file names and keys above are how these hosts work as this lesson is written. Check the host's own documentation when an entry does not load - the shape of command, args and env stays the same everywhere.

Try it yourself: build and connect a tiny MCP server

On Windows PowerShell The printf one-liner needs a POSIX shell. In PowerShell, run the commands in Git Bash or WSL, or put the four JSON lines in a file and pipe it in with Get-Content messages.jsonl | node server.js. The inspector command works in any shell.

Common mistakes

Interview questions

Related