Agents & Retrieval · Agent SDK & MCP

The Claude Agent SDK and Model Context Protocol (MCP)

The Agent SDK packages Claude Code's own agent loop so you can embed it in your own applications, and MCP standardizes how that loop — or any AI application — connects to the outside world. One gives Claude a way to keep acting; the other gives it a common plug for everything it might act on.

☺ Explain it like I'm 10

Picture a kid working through a chore list: look at the list, do one chore, cross it off, look again — repeat until the list is empty. That's Claude's agent loop. Now imagine every chore used to need its own hand-built tool that only fit that one chore. MCP is like agreeing that every tool gets the same universal handle, so any kid — or robot — can pick one up and use it without someone re-building it first.

🐦🐙Your hosts for this topic: Pip the Hummingbird (darts between MCP's client-server connections) and Olly the Octopus (keeps every arm of the agent loop moving at once).

The agent loop, underneath everything

☺ Like you're 10: It's like doing homework — read the question, try a step, check it, then look at the next question — except Claude keeps going until there's nothing left to check.

Every module up to this point has really been building toward the same cycle. The Claude Agent SDK lets you "embed Claude Code's autonomous agent loop in your own applications" without needing the Claude Code CLI itself, and it describes that loop in five steps: receive a prompt, Claude evaluates it and responds with text and/or tool calls, the SDK executes those tools and feeds the results back automatically, this repeats — each cycle is one "turn" — until Claude produces output with no tool calls, and finally the SDK returns a result.

Promptthe input arrives Claude respondstext and/or tool calls SDK runs toolsfeeds results back Repeat, thenreturn resultno more tool calls

This is the same shape Claude Code's own documentation describes more informally as three blended, repeating phases: gather context, take action, verify work — where verification leans on deterministic signals like linters, type checkers, tests, and runtime errors, not just the model's own judgment. If you've been hand-rolling a tool_use / tool_result loop against the raw Messages API, this is that same loop. It's just been given a name and a lot of supporting infrastructure.

What the SDK gives you on top of the raw loop

A hand-written tool-use loop gets you the mechanics: send tools, read back tool_use blocks, execute them, send tool_result blocks, repeat. The Agent SDK ships the same built-in tools Claude Code uses — file tools like Read/Edit/Write, search tools like Glob/Grep, Bash, WebSearch/WebFetch, ToolSearch, and orchestration tools like Agent/Skill/AskUserQuestion/TaskCreate/TaskUpdate — plus the surrounding controls that make a loop safe and steerable enough to run unattended:

→ Tip

None of this replaces good tool design. Everything you learned about writing detailed tool descriptions, tight input schemas, and instructive error messages still applies — the SDK just removes the boilerplate of running the loop and managing permissions around it.

The problem MCP solves

☺ Like you're 10: Before MCP, hooking Claude up to Slack, and hooking some other assistant up to Slack, meant building the "talk to Slack" adapter twice — with slightly different wiring each time.

Once an agent has a loop, it needs things to act on: your ticketing system, your codebase, your internal docs, a calendar, a CRM. Historically, every pairing of AI application and data source has meant custom, non-reusable integration code — the auth handling, error handling, and schema mapping for "Claude talks to Slack" gets written again, slightly differently, for "ChatGPT talks to Slack," and again for "my in-house agent talks to Slack." Multiply that across every application and every system, and you get an M×N tangle of bespoke connectors that nobody wants to maintain.

The Model Context Protocol is Anthropic's answer to that specific problem: "an open-source standard for connecting AI applications to external systems." The canonical framing is a hardware analogy: "Think of MCP like a USB-C port for AI applications." Instead of a custom cable for every device, you build one MCP server for a system, and any MCP-compatible client — Claude Code, Claude Desktop, or your own Agent SDK application — can plug into it.

The host, client, and server model

MCP's architecture has three named roles, and it's worth being precise about which is which, because the terms get used loosely elsewhere:

Underneath, MCP separates a data layer from a transport layer. The data layer is JSON-RPC 2.0-based and handles the connection lifecycle, the three primitives below, and notifications; the transport layer is just how those JSON-RPC messages physically travel — stdio for a server running as a local subprocess, Streamable HTTP for one running remotely.

Three primitives: tools, resources, prompts

☺ Like you're 10: Tools are things Claude decides to grab on its own; resources are things the app hands Claude without asking; prompts are things only you can pull off the shelf.

An MCP server can expose context to a client in three distinct shapes, each with a different party deciding when it gets used:

PrimitiveWho controls itDiscovered viaInvoked viaExample
ToolsModel — Claude decides when to call ittools/listtools/callsearch flights, send an email
ResourcesApplication — the host decides how to retrieve and use itresources/list, resources/templates/listresources/readfile contents, a database schema, calendar entries
PromptsUser — requires explicit invocationprompts/listprompts/geta pre-built instruction template surfaced as a slash command

Tools are executable functions the model itself decides to invoke, the same way it would call any function you define directly in a tools array — MCP just means the function's implementation lives in a separate server process instead of your own code. Resources are passive, read-only data: the host application, not the model, decides when to fetch and inject them, each one addressable by a unique URI and MIME type, with support for both fixed "direct resources" and parameterized "resource templates." Prompts are pre-built instruction templates that tell the model how to work with a server's specific tools and resources — because they're user-controlled, they require explicit invocation rather than the model reaching for them on its own, which is exactly how they show up as slash commands in a chat UI.

MCP also defines the reverse direction: capabilities a server can request from the host's client. Sampling (sampling/createMessage) lets a server ask the host's own LLM for a completion without bundling a model of its own; Elicitation (elicitation/create) lets a server request additional input or confirmation from the user mid-task; Logging carries diagnostic messages back to the client.

⚠ Careful

An MCP server's tool results are still just tool results — treat them with the same suspicion you'd apply to any tool output that might contain adversarial or injected content. Connecting to a third-party server means trusting its code the way you'd trust any dependency; scope its tools with least privilege, and don't assume text returned from a resource or tool call is safe to follow as instructions.

Wiring an MCP server into an agent

Conceptually, connecting a server to a host follows the same handshake regardless of which client library is doing the talking: negotiate capabilities, discover what the server offers, then call into it when the model decides to.

// 1. Client <-> server handshake (stdio or Streamable HTTP transport)
{"jsonrpc": "2.0", "id": 1, "method": "initialize",
 "params": {"protocolVersion": "...", "capabilities": {}}}

// 2. Client asks what the server offers
{"jsonrpc": "2.0", "id": 2, "method": "tools/list"}
{"jsonrpc": "2.0", "id": 3, "method": "resources/list"}
{"jsonrpc": "2.0", "id": 4, "method": "prompts/list"}

// 3. Claude decides to use a tool; the client invokes it on Claude's behalf
{"jsonrpc": "2.0", "id": 5, "method": "tools/call",
 "params": {"name": "search_flights", "arguments": {"origin": "SFO", "destination": "JFK"}}}

From the Agent SDK side, that handshake is something your host application configures once — pointing at a server, then letting the model treat its tools like any other tool in the loop. The shape of that configuration looks roughly like this (check your SDK's reference for exact class and parameter names, since these evolve):

Python
# Conceptual: wiring an MCP server into an Agent SDK-based agent
agent = ClaudeAgent(
    model="claude-sonnet-5",
    mcp_servers=[
        {"name": "internal-docs", "transport": "stdio", "command": ["python", "docs_server.py"]},
    ],
    allowed_tools=["mcp__internal-docs__*"],
    permission_mode="default",
)

result = agent.run("Find our current refund policy and summarize it.")
JavaScript
// Conceptual: wiring an MCP server into an Agent SDK-based agent
const agent = new ClaudeAgent({
  model: "claude-sonnet-5",
  mcpServers: [
    { name: "internal-docs", transport: "stdio", command: ["python", "docs_server.py"] }
  ],
  allowedTools: ["mcp__internal-docs__*"],
  permissionMode: "default"
});

const result = await agent.run("Find our current refund policy and summarize it.");

Once connected, the server's tools appear to Claude alongside any tools you defined directly — the model doesn't need to know or care that one came from your own code and the other came over an MCP connection. Claude Code and its VS Code extension expose this same wiring through an /mcp command: in the terminal it's a slash command, in the VS Code extension it's an in-panel management dialog for adding and inspecting connected servers.

🎬 At the Claude Crew
🦊

Foxy: Wait, is the Agent SDK the thing that loops, or the thing that plugs into MCP servers?

🐙

Olly: Both, sort of! I run the loop — prompt in, tool calls out, repeat until Claude's done and hands back a result.

🐦

Pip: And when one of those tools happens to live in an MCP server, Olly's loop just calls it like any other tool. I handle the handshake underneath so Olly never has to think about it.

🦉

Professor Owl: So the loop doesn't know or care where a tool's code physically lives — MCP just makes "somewhere else" cheap and standard to plug in.

🐙

Olly: Exactly. One tool_use block either way — mine or Pip's, Claude can't tell the difference, and it doesn't need to.

Build it once, or build it every time

☺ Like you're 10: It's the difference between building one universal charger everyone can use, versus every friend building their own charger for the exact same phone.

The practical case for MCP is what it does to your integration surface as the number of tools and data sources grows.

◆ Pattern

Expose a system's capabilities through one MCP server — its auth, error handling, and schema mapping live in a single place. Any MCP-compatible client can then connect to it: Claude Code today, your own Agent SDK application tomorrow, a teammate's setup next month, all reusing the same server without touching its internals.

⚠ Anti-pattern

Write a bespoke, one-off integration in your agent's own codebase for each new tool or data source it needs. Auth handling, retry logic, and error formatting get duplicated across every integration and every application that needs the same system — and every one of those copies has to be maintained separately as the underlying system's API changes.

The savings compound because the protocol is symmetric: you're not just making life easier for your own agent, you're making that system usable, with zero extra integration work, by every other MCP host someone connects to it later.

✎ Try it yourself

In Claude Code (terminal or the VS Code extension), run /mcp to open the MCP server management dialog and connect any MCP server you have available — a small local stdio server is the easiest starting point. Then ask Claude a question that requires one of that server's tools, and watch the permission prompt and tool-call exchange: it looks identical to Claude Code's own built-in tools, because from the model's point of view, it is.

🐦🐙 Pip and Olly's checkpoint

You should now be able to walk through the Agent SDK's five-step loop and explain how it maps to Claude Code's gather-act-verify description, and you should be able to say precisely who plays Host, Client, and Server in an MCP connection and which of the three primitives — tools, resources, or prompts — belongs to the model, the application, and the user. Next, see all of this running end-to-end inside a real coding agent in Claude Code.

Check your answers
  1. What are the Agent SDK's five loop steps, and how do they relate to Claude Code's own description of its process? The five steps are: receive a prompt, Claude evaluates and responds with text and/or tool calls, the SDK executes those tools and feeds results back, this repeats (each cycle is a "turn") until Claude returns no tool calls, and the SDK returns a result. This is the same cycle Claude Code describes more informally as three blended phases — gather context, take action, verify work — where verification includes deterministic signals like linters and tests, not just the model's judgment.
  2. What problem does MCP solve, and what analogy does Anthropic use for it? MCP replaces the M×N problem — every AI application needing its own custom, non-reusable integration code for every external system — with one open-source standard that any MCP-compatible client can plug into. Anthropic's analogy is a USB-C port for AI applications: build one server for a system, and any client can connect to it instead of needing a custom cable each time.
  3. What are MCP's three primitives, and who decides when each one is used? Tools are model-controlled (Claude decides when to call them, discovered via tools/list and invoked via tools/call); Resources are application-controlled (the host decides when to fetch them, via resources/list and resources/read); Prompts are user-controlled and require explicit invocation, via prompts/list and prompts/get, which is why they surface as slash commands.