obsidian/wiki/agent-sdk/mcp-integration.md
2026-04-17 12:40:31 +01:00

5.7 KiB

title aliases tags sources created updated
MCP Integration in Agent SDK
mcp-servers
model-context-protocol
agent-mcp
agent-sdk
mcp
tools
typescript
authentication
raw/Connect to external tools with MCP.md
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 tools
  • permissionMode: "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}` }
  }
}

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 allowedTools for MCP access, not permissionMode
  • Three transport types: stdio (local process), HTTP (remote non-streaming), SSE (remote streaming)
  • Credentials go in env (stdio) or headers (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

Sources

  • raw/Connect to external tools with MCP.md