In the previous lesson, you mastered maintaining agent state with ClaudeSDKClient, enabling multi-turn conversations in which your agent remembers previous interactions. Throughout those examples, you worked with built-in tools like WebSearch, Bash, Read, Write, and Edit. These tools provide essential capabilities, but what if you need specialized functionality that isn't included in the SDK? This is where MCP (Model Context Protocol) servers come in — external packages that extend your agent with pre-built tools for documentation search, database access, Git operations, and much more. In this lesson, you'll learn how to connect these powerful external servers to your agent with minimal setup.
MCP servers are packages of pre-built tools that extend your agent's capabilities beyond the built-in options. Think of them as plugins or extensions that provide specialized functionality. For example, the Context7 MCP server provides tools for searching documentation across thousands of libraries, while other MCP servers might offer database access, Git operations, or custom business logic specific to your organization.
Each MCP server runs as a separate process that communicates with your agent through a standardized protocol. The server exposes one or more tools, and your agent can call those tools just as it calls built-in tools like WebSearch or Bash. The key difference is that MCP servers are external packages you connect to your agent, rather than functionality that comes pre-installed with the SDK. This architecture means you can add new capabilities to your agent without modifying the SDK itself, and you can leverage tools built by the community or your own team. The Model Context Protocol defines how your agent communicates with these external servers, handling the details of sending tool requests, receiving results, and managing the connection lifecycle.
To connect an MCP server, you need to declare a configuration dictionary that tells the SDK how to run that server. The configuration specifies the communication type, the command to execute, and any arguments needed to start the server process.
The configuration dictionary contains three key fields. The "type" field specifies how your agent will communicate with the server — the value "stdio" means the server will communicate through standard input and output streams, which is the most common approach for MCP servers. The "command" field specifies the executable to run. In this example, "npx" is a Node.js package runner that can execute npm packages directly without installing them globally. The "args" field provides a list of arguments to pass to the command. Here, ["-y", "@upstash/context7-mcp"] tells npx to automatically confirm any prompts and run the Context7 MCP server package. When your agent starts, the SDK will execute this command, establish a communication channel through stdin/stdout, and keep the server process running for the duration of your agent's session.
Once you've declared a server configuration, you connect it to your agent by passing it to ClaudeAgentOptions through the mcp_servers parameter.
The mcp_servers parameter takes a dictionary mapping server names to configurations. In this example, we're connecting one server with the name "context7" using the configuration we declared earlier. The server name you choose here is important because it becomes part of the tool naming scheme you'll use in the next step. You can connect multiple servers by adding more entries to this dictionary, each with its own unique name and configuration. At this point, the server is connected and its tools are available, but your agent can't use them yet because you haven't explicitly granted permission.
Connecting an MCP server makes its tools available, but for security and control, you must explicitly whitelist which tools your agent can actually use. You do this through the allowed_tools parameter using a specific naming format that identifies both the server and the tool.
The allowed_tools list uses a special naming format for MCP tools: mcp__<server_key>__<tool_name>. The prefix mcp__ indicates this is an MCP tool rather than a built-in tool. The <server_key> matches the name you gave the server in the mcp_servers dictionary (in this case, "context7"). The <tool_name> is the actual tool name as defined by the MCP server. For the Context7 server, two tools are available: resolve-library-id searches for libraries by name and returns their identifiers, while get-library-docs retrieves documentation for a specific library. This explicit whitelisting approach gives you fine-grained control over which external capabilities your agent can access, which is particularly important for security and cost management.
With the server connected and tools whitelisted, your agent can now use those tools, but you need to guide it through your prompts. The agent won't automatically know when to use MCP tools versus built-in tools, so your prompt should clearly indicate what you want the agent to do and which tools are relevant.
The prompt explicitly mentions "Using the context7 tools" to guide the agent toward the MCP tools you've connected. This explicit guidance helps the agent understand that you want it to use the external documentation search capabilities rather than, for example, using WebSearch to find information on the public internet. When the agent processes this prompt, it will recognize that it has access to Context7 tools (because they're in the allowed_tools list), understand from your prompt that you want it to use those tools, and then call them appropriately.
Let's examine a complete working example that connects the Context7 MCP server, whitelists its tools, and uses them to search for documentation. We'll start by looking at how to set up the complete configuration.
The example follows a clear two-step pattern for configuration. First, it declares the Context7 server configuration with the stdio communication type and the npx command to run the server. Second, it creates ClaudeAgentOptions that connects the server through mcp_servers, whitelists the two Context7 tools through allowed_tools, and sets other familiar options like model and max turns. This configuration makes the external documentation search tools available to your agent while maintaining the same familiar structure you learned in previous lessons.
With the configuration in place, the final step is to create a client session and send a query that guides the agent to use the MCP tools.
The code creates a client session using the async context manager pattern you learned in the previous lesson, sends a query that explicitly guides the agent to use the Context7 tools, and displays the response using the helper function. The prompt clearly indicates that the agent should use the external documentation search capabilities to find and summarize information about MCP servers in the Claude Agent SDK. When you run this code, the agent demonstrates sophisticated multi-step reasoning using the external MCP tools.
When you run the complete example, the agent begins by explaining its plan and making the first tool call to search for the relevant documentation.
The agent starts by stating its intent — it will look for documentation on how the Claude Agent SDK uses MCP servers. It then makes its first tool call to mcp__context7__resolve-library-id to locate the most relevant library. Notice how the tool name mcp__context7__resolve-library-id follows the mcp__<server_key>__<tool_name> format you configured in allowed_tools, clearly identifying this as an MCP tool from the "context7" server.
After resolving the relevant library, the agent proceeds to fetch documentation from that source.
Here the agent interprets the search results, determines that /websites/platform_claude_en_agent-sdk is the most relevant library for MCP server integration, and then calls mcp__context7__get-library-docs to retrieve documentation about it. The agent uses the information returned by resolve-library-id to drive its next tool call, showing how it chains MCP tool calls together.
To build a more complete understanding, the agent issues another documentation request.
The agent decides that one documentation fetch is not enough for a thorough answer and calls mcp__context7__get-library-docs again, this time to gather additional details. This demonstrates how the agent can iterate, refine, and deepen its understanding by making multiple MCP tool calls, all within the same conversation context.
After collecting the necessary documentation, the agent synthesizes the information into a structured summary.
The agent pulls together everything it learned from the MCP tool calls into a concise, well-structured explanation. It reinforces the configuration concepts you implemented in the code (like mcp_servers and allowed_tools), and connects them to broader architectural patterns such as in-process vs external MCP servers and different communication protocols (stdio, HTTP, SSE).
You've now learned how to expand your agent's capabilities by integrating external MCP servers. By declaring server configurations, connecting them through mcp_servers, whitelisting tools with the mcp__<server_key>__<tool_name> format, and guiding your agent through clear prompts, you can give Claude access to rich, pre-built functionality with minimal setup. In the upcoming practice exercises, you'll apply these concepts by integrating different MCP servers into your own agents and building applications that leverage both built-in and external capabilities to solve real-world problems.
