5.7 KiB
| title | aliases | tags | sources | created | updated | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| MCP Integration in Agent SDK |
|
|
|
2026-04-17 | 2026-04-17 |
MCP Integration in Agent SDK
The Model Context Protocol (MCP) is an open standard for connecting AI agents to external tools and data sources — databases, GitHub, Slack, APIs — without writing custom tool implementations.
Quickstart
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Use the docs MCP server to explain what hooks are",
options: {
mcpServers: {
"claude-code-docs": {
type: "http",
url: "https://code.claude.com/docs/mcp"
}
},
allowedTools: ["mcp__claude-code-docs__*"]
}
})) {
if (message.type === "result" && message.subtype === "success") {
console.log(message.result);
}
}
Adding MCP Servers
In code (mcpServers option)
Pass directly to query():
options: {
mcpServers: {
filesystem: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
}
}
From .mcp.json config file
Place at project root — loaded automatically when "project" is in settingSources:
{
"mcpServers": {
"filesystem": {
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", "/Users/me/projects"]
}
}
}
Allowing MCP Tools
MCP tools require explicit permission before Claude can call them.
Naming convention
mcp__<server-name>__<tool-name> — e.g., mcp__github__list_issues
allowedTools patterns
allowedTools: [
"mcp__github__*", // all tools from github server
"mcp__db__query", // single tool
"mcp__slack__send_message" // single tool
]
Use allowedTools wildcards, not permission modes:
permissionMode: "acceptEdits"— does NOT auto-approve MCP toolspermissionMode: "bypassPermissions"— approves MCP but disables all safety prompts (too broad)- Wildcard in
allowedTools— grants exactly the server you want, nothing more
Discover available tools
if (message.type === "system" && message.subtype === "init") {
console.log("Available MCP tools:", message.mcp_servers);
}
Transport Types
| Transport | When to use | Config key |
|---|---|---|
| stdio | Local process (npx command given) | command + args |
| HTTP | Cloud-hosted, non-streaming URL | type: "http" + url |
| SSE | Cloud-hosted, streaming URL | type: "sse" + url |
| SDK MCP | Custom in-process tools | See custom tools guide |
stdio example
mcpServers: {
github: {
command: "npx",
args: ["-y", "@modelcontextprotocol/server-github"],
env: { GITHUB_TOKEN: process.env.GITHUB_TOKEN }
}
}
HTTP/SSE example
mcpServers: {
"remote-api": {
type: "sse",
url: "https://api.example.com/mcp/sse",
headers: { Authorization: `Bearer ${process.env.API_TOKEN}` }
}
}
MCP Tool Search
When many tools are configured, definitions can fill the context window. Tool search is enabled by default — it withholds tool definitions from context and loads only what Claude needs per turn.
See wiki/agent-sdk/typescript-api-reference for configuration options.
Authentication
Environment variables (stdio)
env: { GITHUB_TOKEN: process.env.GITHUB_TOKEN }
HTTP headers (remote servers)
headers: { Authorization: `Bearer ${process.env.API_TOKEN}` }
OAuth2
SDK doesn't handle OAuth flows automatically. Complete the flow in your app, then pass the access token via headers:
const accessToken = await getAccessTokenFromOAuthFlow();
headers: { Authorization: `Bearer ${accessToken}` }
Error Handling
Check the system / init message for connection status before the agent starts:
if (message.type === "system" && message.subtype === "init") {
const failedServers = message.mcp_servers.filter(s => s.status !== "connected");
if (failedServers.length > 0) console.warn("Failed:", failedServers);
}
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
| Server shows "failed" | Missing env vars, package not installed, bad connection string, network | Check init message status field |
| Tools not called | Missing allowedTools |
Add "mcp__servername__*" |
| Connection timeout | Server slow to start (60s default) | Pre-warm server or use lighter package |
Key Takeaways
- MCP tool names follow
mcp__<server>__<tool>— wildcards with*allow all tools from a server - Always use
allowedToolsfor MCP access, notpermissionMode - Three transport types: stdio (local process), HTTP (remote non-streaming), SSE (remote streaming)
- Credentials go in
env(stdio) orheaders(HTTP/SSE) — never hardcoded - Check
message.type === "system" && message.subtype === "init"for connection status and tool discovery - Tool search is on by default — prevents context overflow with large tool sets
- Default connection timeout is 60 seconds; pre-warm servers that need longer startup
Related
- wiki/agent-sdk/configure-permissions —
allowedTools,disallowedTools, permission modes - wiki/agent-sdk/typescript-api-reference — full
mcpServersconfig options - wiki/agent-sdk/python-api-reference — Python equivalent
- wiki/agent-sdk/hooks-guide — automate workflows alongside MCP tools
Sources
raw/Connect to external tools with MCP.md