CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-claude-agent-sdk

Python SDK for programmatically interacting with Claude Code, enabling AI-powered automation workflows with support for bidirectional conversations, custom in-process tools, hooks, and fine-grained permission control

Quality

Does it follow best practices?

Run evals on this skill

Adds up to 20 points to the overall score

View guide

SecuritybySnyk

The risk profile of this skill

This plugin was archived by the owner on Jun 3, 2026

Reason: Retiring all tiles created prior to the transition to plugin support

Overview
Eval results
Files

mcp-config.mddocs/

MCP Server Configuration

MCP (Model Context Protocol) servers provide custom tools for Claude to use. Configure external MCP servers that run as separate processes or SDK MCP servers that run in-process within your Python application.

Capabilities

MCP Server Config Union

Union of all MCP server configuration types.

McpServerConfig = (
    McpStdioServerConfig | McpSSEServerConfig | McpHttpServerConfig | McpSdkServerConfig
)
"""
Union of MCP server configuration types.

MCP servers can be configured in four ways:

- McpStdioServerConfig: External process communicating via stdio
- McpSSEServerConfig: Remote server using Server-Sent Events
- McpHttpServerConfig: Remote server using HTTP
- McpSdkServerConfig: In-process SDK server (recommended for Python)

Used in ClaudeAgentOptions.mcp_servers.
"""

Stdio Server Configuration

Configuration for MCP servers that run as external processes.

class McpStdioServerConfig(TypedDict):
    """
    MCP stdio server configuration.

    Configures an external MCP server that runs as a separate process and
    communicates via stdin/stdout. This is the traditional MCP server mode.

    Fields:
        type: Server type marker (optional for backward compatibility)
        command: Command to execute
        args: Command line arguments
        env: Environment variables
    """

    type: NotRequired[Literal["stdio"]]
    """Server type marker.

    Optional type field. Set to "stdio" for clarity, but can be omitted
    for backward compatibility with older configurations.
    """

    command: str
    """Command to execute.

    The command to run the MCP server. Can be:
    - An absolute path: "/usr/local/bin/my-mcp-server"
    - A command in PATH: "npx"
    - A Python script: "python"

    Examples:
        "npx"
        "node"
        "/usr/local/bin/mcp-server"
        "python"
    """

    args: NotRequired[list[str]]
    """Command arguments.

    List of arguments to pass to the command. Order matters.

    Examples:
        ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/data"]
        ["mcp_server.py", "--config", "config.json"]
        ["/path/to/server.js"]
    """

    env: NotRequired[dict[str, str]]
    """Environment variables.

    Environment variables to set for the server process. Merged with
    the current process environment.

    Example:
        {"API_KEY": "secret", "DEBUG": "true"}
    """

SSE Server Configuration

Configuration for MCP servers using Server-Sent Events.

class McpSSEServerConfig(TypedDict):
    """
    MCP SSE server configuration.

    Configures a remote MCP server that uses Server-Sent Events (SSE)
    for communication. Useful for remote or cloud-hosted MCP servers.

    Fields:
        type: Must be "sse"
        url: Server URL
        headers: Optional HTTP headers
    """

    type: Literal["sse"]
    """Server type marker.

    Must be "sse" to indicate SSE transport.
    """

    url: str
    """Server URL.

    The full URL of the SSE endpoint.

    Example:
        "https://mcp.example.com/sse"
        "http://localhost:8080/events"
    """

    headers: NotRequired[dict[str, str]]
    """HTTP headers.

    Optional headers to include in the SSE connection request.
    Useful for authentication.

    Example:
        {"Authorization": "Bearer token123"}
    """

HTTP Server Configuration

Configuration for MCP servers using HTTP.

class McpHttpServerConfig(TypedDict):
    """
    MCP HTTP server configuration.

    Configures a remote MCP server that uses HTTP for communication.

    Fields:
        type: Must be "http"
        url: Server URL
        headers: Optional HTTP headers
    """

    type: Literal["http"]
    """Server type marker.

    Must be "http" to indicate HTTP transport.
    """

    url: str
    """Server URL.

    The base URL of the HTTP server.

    Example:
        "https://mcp.example.com/api"
        "http://localhost:3000"
    """

    headers: NotRequired[dict[str, str]]
    """HTTP headers.

    Optional headers to include in HTTP requests.
    Useful for authentication and API keys.

    Example:
        {"X-API-Key": "secret", "Content-Type": "application/json"}
    """

SDK Server Configuration

Configuration for in-process SDK MCP servers.

class McpSdkServerConfig(TypedDict):
    """
    SDK MCP server configuration.

    Configures an in-process MCP server created with create_sdk_mcp_server().
    These servers run within your Python application for better performance.

    Fields:
        type: Must be "sdk"
        name: Server name
        instance: Server instance
    """

    type: Literal["sdk"]
    """Server type marker.

    Must be "sdk" to indicate an SDK server.
    """

    name: str
    """Server name.

    Unique identifier for this server. Used in logging and debugging.
    """

    instance: "McpServer"
    """Server instance.

    The MCP server instance created by create_sdk_mcp_server().
    This is an actual mcp.server.Server object.
    """

Usage Examples

SDK Server (Recommended for Python)

from claude_agent_sdk import (
    tool, create_sdk_mcp_server, ClaudeAgentOptions, query
)

# Define tools
@tool("greet", "Greet a user", {"name": str})
async def greet(args):
    return {"content": [{"type": "text", "text": f"Hello, {args['name']}!"}]}

@tool("calculate", "Do math", {"expression": str})
async def calculate(args):
    result = eval(args["expression"])  # Use safely in production!
    return {"content": [{"type": "text", "text": f"Result: {result}"}]}

# Create SDK server
server = create_sdk_mcp_server("mytools", tools=[greet, calculate])

# Use in options
options = ClaudeAgentOptions(
    mcp_servers={"mytools": server},
    allowed_tools=["greet", "calculate"]
)

async for msg in query(prompt="Greet Alice and calculate 2+2", options=options):
    print(msg)

Stdio Server (NPX)

from claude_agent_sdk import ClaudeAgentOptions, query

# Filesystem server using npx
filesystem_server = {
    "type": "stdio",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/documents"]
}

options = ClaudeAgentOptions(
    mcp_servers={"filesystem": filesystem_server}
)

async for msg in query(prompt="List files in my documents", options=options):
    print(msg)

Stdio Server (Python Script)

from claude_agent_sdk import ClaudeAgentOptions, query

# Python MCP server
python_server = {
    "type": "stdio",
    "command": "python",
    "args": ["/path/to/my_mcp_server.py"],
    "env": {
        "SERVER_MODE": "production",
        "API_KEY": "secret"
    }
}

options = ClaudeAgentOptions(
    mcp_servers={"custom": python_server}
)

async for msg in query(prompt="Use custom server", options=options):
    print(msg)

Stdio Server (Node.js)

from claude_agent_sdk import ClaudeAgentOptions, query

# Node.js MCP server
node_server = {
    "command": "node",  # 'type' is optional for stdio
    "args": ["/path/to/server.js"],
    "env": {"DEBUG": "mcp:*"}
}

options = ClaudeAgentOptions(
    mcp_servers={"nodeserver": node_server}
)

async for msg in query(prompt="Query node server", options=options):
    print(msg)

SSE Server

from claude_agent_sdk import ClaudeAgentOptions, query

# Remote SSE server
sse_server = {
    "type": "sse",
    "url": "https://mcp.example.com/sse",
    "headers": {
        "Authorization": "Bearer your-token-here"
    }
}

options = ClaudeAgentOptions(
    mcp_servers={"remote": sse_server}
)

async for msg in query(prompt="Use remote server", options=options):
    print(msg)

HTTP Server

from claude_agent_sdk import ClaudeAgentOptions, query

# HTTP MCP server
http_server = {
    "type": "http",
    "url": "https://api.example.com/mcp",
    "headers": {
        "X-API-Key": "your-api-key",
        "Content-Type": "application/json"
    }
}

options = ClaudeAgentOptions(
    mcp_servers={"api": http_server}
)

async for msg in query(prompt="Use HTTP API", options=options):
    print(msg)

Multiple Servers

from claude_agent_sdk import (
    tool, create_sdk_mcp_server, ClaudeAgentOptions, query
)

# SDK server for custom tools
@tool("custom_tool", "My custom tool", {"param": str})
async def custom_tool(args):
    return {"content": [{"type": "text", "text": f"Got: {args['param']}"}]}

sdk_server = create_sdk_mcp_server("custom", tools=[custom_tool])

# External filesystem server
filesystem_server = {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/data"]
}

# External database server
db_server = {
    "command": "python",
    "args": ["/path/to/db_server.py"],
    "env": {"DATABASE_URL": "postgresql://localhost/mydb"}
}

# Configure all servers
options = ClaudeAgentOptions(
    mcp_servers={
        "custom": sdk_server,
        "files": filesystem_server,
        "database": db_server
    }
)

async for msg in query(prompt="Use all servers", options=options):
    print(msg)

Loading Config from File

from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query

# Point to MCP config file
config_path = Path.home() / ".config" / "claude" / "mcp.json"

options = ClaudeAgentOptions(
    mcp_servers=config_path  # Can be string or Path
)

async for msg in query(prompt="Use configured servers", options=options):
    print(msg)

Environment-Specific Configuration

import os
from claude_agent_sdk import ClaudeAgentOptions, query

# Different config for dev/prod
environment = os.getenv("ENVIRONMENT", "development")

if environment == "production":
    servers = {
        "api": {
            "type": "http",
            "url": "https://prod-api.example.com/mcp",
            "headers": {"X-API-Key": os.getenv("PROD_API_KEY")}
        }
    }
else:
    servers = {
        "api": {
            "command": "python",
            "args": ["dev_server.py"],
            "env": {"DEBUG": "true"}
        }
    }

options = ClaudeAgentOptions(mcp_servers=servers)

async for msg in query(prompt="Query API", options=options):
    print(msg)

Server with Complex Environment

import os
from claude_agent_sdk import ClaudeAgentOptions, query

# Server that needs many environment variables
server = {
    "command": "python",
    "args": ["mcp_server.py"],
    "env": {
        "DATABASE_URL": os.getenv("DATABASE_URL"),
        "REDIS_URL": os.getenv("REDIS_URL"),
        "API_KEY": os.getenv("API_KEY"),
        "LOG_LEVEL": "debug",
        "CACHE_DIR": "/tmp/mcp-cache",
        "MAX_CONNECTIONS": "10"
    }
}

options = ClaudeAgentOptions(
    mcp_servers={"data": server}
)

async for msg in query(prompt="Query database", options=options):
    print(msg)

Combining SDK and External Servers

from claude_agent_sdk import (
    tool, create_sdk_mcp_server, ClaudeAgentOptions, query
)

# Fast in-process tools for simple operations
@tool("add", "Add numbers", {"a": float, "b": float})
async def add(args):
    result = args["a"] + args["b"]
    return {"content": [{"type": "text", "text": f"Sum: {result}"}]}

math_server = create_sdk_mcp_server("math", tools=[add])

# External server for file system access
filesystem_server = {
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/project"]
}

options = ClaudeAgentOptions(
    mcp_servers={
        "math": math_server,       # In-process, fast
        "files": filesystem_server  # External, isolated
    }
)

async for msg in query(prompt="Calculate sum and save to file", options=options):
    print(msg)

Server with Specific Working Directory

from claude_agent_sdk import ClaudeAgentOptions, query

# Server that should run in specific directory
server = {
    "command": "python",
    "args": ["./server.py"],  # Relative path
    "env": {
        "WORKSPACE": "/home/user/project"
    }
}

# Note: The server process will inherit the cwd from ClaudeAgentOptions
options = ClaudeAgentOptions(
    mcp_servers={"local": server},
    cwd="/home/user/project"  # Sets working directory for CLI and servers
)

async for msg in query(prompt="Use local server", options=options):
    print(msg)

Authenticated Remote Server

import os
from claude_agent_sdk import ClaudeAgentOptions, query

# SSE server with authentication
server = {
    "type": "sse",
    "url": "https://mcp-prod.example.com/stream",
    "headers": {
        "Authorization": f"Bearer {os.getenv('MCP_TOKEN')}",
        "X-Client-ID": "python-sdk",
        "X-Client-Version": "0.1.0"
    }
}

options = ClaudeAgentOptions(
    mcp_servers={"prod": server}
)

async for msg in query(prompt="Use production server", options=options):
    print(msg)

Development vs Production Servers

from claude_agent_sdk import (
    tool, create_sdk_mcp_server, ClaudeAgentOptions, query
)
import os

# Create appropriate server based on environment
if os.getenv("ENV") == "production":
    # Production: Use external server
    server = {
        "type": "http",
        "url": "https://api.example.com/mcp",
        "headers": {"X-API-Key": os.getenv("API_KEY")}
    }
else:
    # Development: Use SDK server
    @tool("dev_tool", "Development tool", {"input": str})
    async def dev_tool(args):
        return {"content": [{"type": "text", "text": f"Dev: {args['input']}"}]}

    server = create_sdk_mcp_server("dev", tools=[dev_tool])

options = ClaudeAgentOptions(
    mcp_servers={"main": server}
)

async for msg in query(prompt="Use appropriate server", options=options):
    print(msg)

MCP Config File Format

# Example: ~/.config/claude/mcp.json
"""
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-filesystem", "/home/user/data"]
    },
    "database": {
      "command": "python",
      "args": ["/path/to/db_server.py"],
      "env": {
        "DATABASE_URL": "postgresql://localhost/mydb"
      }
    },
    "remote": {
      "type": "sse",
      "url": "https://mcp.example.com/sse",
      "headers": {
        "Authorization": "Bearer token"
      }
    }
  }
}
"""

from pathlib import Path
from claude_agent_sdk import ClaudeAgentOptions, query

# Load from standard config location
config_path = Path.home() / ".config" / "claude" / "mcp.json"

options = ClaudeAgentOptions(
    mcp_servers=str(config_path)
)

async for msg in query(prompt="Use configured servers", options=options):
    print(msg)

Server with Timeout and Retry

from claude_agent_sdk import ClaudeAgentOptions, query

# Configure server with extra args for timeout/retry
server = {
    "command": "python",
    "args": [
        "mcp_server.py",
        "--timeout", "30",
        "--retry", "3"
    ],
    "env": {
        "REQUEST_TIMEOUT": "30"
    }
}

options = ClaudeAgentOptions(
    mcp_servers={"reliable": server}
)

async for msg in query(prompt="Use reliable server", options=options):
    print(msg)

docs

agent-definitions.md

agents.md

client.md

configuration-options.md

content-blocks.md

core-query-interface.md

custom-tools.md

error-handling.md

errors.md

hook-system.md

hooks.md

index.md

mcp-config.md

mcp-server-configuration.md

messages-and-content.md

messages.md

options.md

permission-control.md

permissions.md

query.md

transport.md

COMPLETION_SUMMARY.md

tile.json