Lesson 8.3
Using MCP Servers from Code
What the Model Context Protocol standardises, and the three ways a developer connects Claude to an MCP server: the API's MCP connector, a local MCP client in your own loop, and the Agent SDK.
The Model Context Protocol (MCP) is an open standard for connecting AI applications to external tools and data. Instead of writing a bespoke integration for every service, you run or connect to an MCP server that exposes tools, resources and prompts in a common format, and any MCP-capable client can use them. The exam tests the vocabulary, the transports, and how each Anthropic surface consumes MCP.
The vocabulary
| Term | Meaning |
|---|---|
| Host | The application the user interacts with (Claude Code, Claude Desktop, your app) |
| Client | The component inside the host that holds a connection to one server |
| Server | A process that exposes tools, resources and prompts over MCP |
| Tools | Callable functions with JSON Schema inputs, the same shape as Messages API tools |
| Resources | Read-only data identified by URI (files, database rows, documents) |
| Prompts | Reusable prompt templates the server offers |
| Transport | How client and server talk: stdio for local processes, streamable HTTP for remote servers |
A server advertises its tools; the client lists them, presents them to the model, and relays calls and results. MCP standardises the plumbing; the model still decides when to call a tool based on its description.
Option 1: the MCP connector in the Messages API
The simplest route for remote servers is to let the API connect for you. Declare the server in mcp_servers and reference it from tools with an mcp_toolset; both are required, and the names must match. The feature is in beta, so it uses client.beta.messages and a beta flag.
resp = client.beta.messages.create(
model=MODEL, max_tokens=1024,
betas=["mcp-client-2025-11-20"],
mcp_servers=[{"type": "url", "url": "https://mcp.example.com/mcp",
"name": "docs", "authorization_token": DOCS_TOKEN}],
tools=[{"type": "mcp_toolset", "mcp_server_name": "docs"}],
messages=[{"role": "user", "content": "Find the retry policy in our API docs."}],
)
const resp = await client.beta.messages.create({
model: MODEL, max_tokens: 1024,
betas: ["mcp-client-2025-11-20"],
mcp_servers: [{ type: "url", url: "https://mcp.example.com/mcp", name: "docs" }],
tools: [{ type: "mcp_toolset", mcp_server_name: "docs" }],
messages: [{ role: "user", content: "Find the retry policy in our API docs." }],
});
Anthropic's servers open the connection, fetch the tool list, execute calls and return results as content blocks; you do not run a loop. The toolset accepts default_config and per-tool configs to disable or allow specific tools. Only remote HTTP servers are supported, and an OAuth or bearer token is passed through authorization_token. Check the MCP connector page for platform availability.
Option 2: your own MCP client in a manual loop
For local stdio servers, or when you want full control, use the MCP client library for your language, list the server's tools, convert them to Messages API tool definitions, and dispatch tool_use blocks to the server yourself.
from mcp import ClientSession
from mcp.client.stdio import stdio_client, StdioServerParameters
from anthropic.lib.tools.mcp import async_mcp_tool
async with stdio_client(StdioServerParameters(command="npx",
args=["-y", "@modelcontextprotocol/server-filesystem", "/data"])) as (r, w):
async with ClientSession(r, w) as mcp:
await mcp.initialize()
tools = (await mcp.list_tools()).tools
runner = client.beta.messages.tool_runner(
model=MODEL, max_tokens=2048,
tools=[async_mcp_tool(t, mcp) for t in tools],
messages=[{"role": "user", "content": "List the CSV files and summarise each."}],
)
async for message in runner:
...
The SDK's anthropic[mcp] extra provides helpers (mcp_tool, async_mcp_tool, mcp_resource_to_content) that bridge MCP types to Anthropic types. In TypeScript, the @modelcontextprotocol/sdk client gives you listTools() and callTool(), and you map results into tool_result blocks exactly as in lesson 8-2. This pattern works on every platform because the API sees ordinary tools.
Option 3: the Agent SDK and Claude Code
The Claude Agent SDK takes an mcp_servers option mapping a name to either a stdio command or a remote URL. Tools appear as mcp__<server>__<tool> and must be included in allowed_tools to run without a prompt. Claude Code uses the same configuration through claude mcp add and .mcp.json. For custom in-process tools, the Agent SDK's create_sdk_mcp_server lets you define tools as plain functions without running a separate process.
Security
An MCP server is code you are trusting with tool execution and a channel for untrusted content to enter the model's context. Install servers from reputable sources, pin versions, review tool descriptions for injected instructions, run local servers with least privilege, and apply approval gates to any tool that writes or sends. Remote servers should use HTTPS and scoped tokens; never pass your Anthropic API key to an MCP server.
Choosing an approach
- Remote server, minimal code, Anthropic-hosted connection: MCP connector.
- Local server, or you need resources and prompts, or a platform without the connector: your own MCP client.
- You want a coding agent with built-in tools plus MCP: Agent SDK or Claude Code.
Exam focus
- MCP standardises how hosts connect to servers exposing tools, resources and prompts over
stdioor HTTP transports. - The Messages API MCP connector requires both
mcp_serversand a matchingmcp_toolsetentry intools, under a beta flag, and supports remote servers only. - A local MCP client lists tools, maps them to Messages API tool definitions and dispatches
tool_useblocks itself; the API sees ordinary tools. - In the Agent SDK and Claude Code, MCP tools appear as
mcp__<server>__<tool>and must be allow-listed. - MCP tool results are untrusted content; servers need vetting, least privilege and approval gates on consequential actions.
- An MCP server receives its own scoped credentials, never your Anthropic API key.
Check yourself
5 questions
1.What is the Model Context Protocol (MCP)?
2.A developer uses the Messages API's MCP connector: mcp_servers: [{ type: "url", url: "https://mcp.example.com/sse", name: "example" }] What else is required for this to work?
3.A response from an MCP-connector request contains mcp_tool_use and mcp_tool_result blocks. The developer's loop tries to execute the call locally and send back a tool_result. Is that correct?
4.A Node application (not Claude Code) must use a local MCP server that runs over stdio, such as a filesystem server. How can it do this with the Messages API?
5.A remote MCP server protected by OAuth must be used through the MCP connector. How is the credential supplied?
