> ## Documentation Index
> Fetch the complete documentation index at: https://slide.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Integration

> Connect your agents to Model Context Protocol servers using declarative config

Model Context Protocol (MCP) is an open standard for connecting AI applications to external data sources and tools. Tyler has first-class support for MCP through declarative configuration based on the MCP `2025-11-25` stable framing: Streamable HTTP for remote servers, `stdio` for local servers, and SSE only for legacy compatibility.

**💻 Code Examples**

<CardGroup cols={2}>
  <Card title="Basic MCP" icon="rocket" href="https://github.com/adamwdraper/slide/blob/main/packages/tyler/examples/300_mcp_basic.py">
    Get started with MCP servers
  </Card>

  <Card title="Advanced MCP" icon="server" href="https://github.com/adamwdraper/slide/blob/main/packages/tyler/examples/301_mcp_advanced.py">
    Multiple servers with filtering
  </Card>
</CardGroup>

## Quick Start

### Python API

```python theme={null}
from tyler import Agent, Thread, Message

# Create agent with MCP config
agent = Agent(
    name="Tyler",
    model_name="gpt-4.1",
    tools=["web"],
    mcp={
        "servers": [{
            "name": "slide_docs",
            "transport": "streamablehttp",  # Mintlify uses streamablehttp
            "url": "https://slide.mintlify.app/mcp"
        }]
    }
)

try:
    # Connect to MCP servers (fail fast!)
    await agent.connect_mcp()

    # Use normally - MCP tools are now available
    thread = Thread()
    thread.add_message(Message(role="user", content="How do I create a Tyler agent?"))
    result = await agent.run(thread)
finally:
    await agent.cleanup()
```

### CLI (tyler-chat)

Add this to your `tyler-chat-config.yaml`:

```yaml theme={null}
name: "Tyler"
model_name: "gpt-4.1"

tools:
  - "web"

mcp:
  servers:
    - name: slide_docs
      transport: streamablehttp  # Mintlify uses streamablehttp
      url: https://slide.mintlify.app/mcp
```

Then run:

```bash theme={null}
tyler chat  # MCP servers connect automatically on startup!
```

## How It Works

1. **Agent Creation**: `Agent(mcp={...})` validates config schema immediately (fail fast!)
2. **Connection**: `await agent.connect_mcp()` connects to servers and discovers tools
3. **Tool Registration**: Discovered tools are namespaced (`servername_toolname`) and merged with built-in tools
4. **Usage**: Tools are available in `agent.run()` like any other tool
5. **Cleanup**: `await agent.cleanup()` disconnects MCP servers

## Configuration Reference

### Server Configuration

Each MCP server requires:

```python theme={null}
{
    "name": str,        # Required: Unique server identifier
    "transport": str,   # Required: "stdio", "streamablehttp", or "sse"
    
    # Transport-specific fields (choose based on transport):
    "url": str,         # Required for streamablehttp/sse
    "command": str,     # Required for stdio
    "args": List[str],  # Optional for stdio
    "env": Dict,        # Optional for stdio
    "cwd": str,         # Optional for stdio
    "encoding": str,    # Optional for stdio
    "encoding_error_handler": str,  # Optional for stdio: strict, ignore, replace
    
    # Optional fields:
    "headers": Dict,           # Custom HTTP headers (for streamablehttp/sse)
    "include_tools": List[str],  # Whitelist specific tools
    "exclude_tools": List[str],  # Blacklist specific tools
    "prefix": str,             # Custom namespace (default: server name)
    "fail_silent": bool,       # Continue if connection fails (default: true)
    "max_retries": int,        # Positive retry count (default: 3)
    "timeout_seconds": float,  # Connection/request timeout
    "sse_read_timeout_seconds": float,  # Stream read timeout
    "terminate_on_close": bool,  # Streamable HTTP session termination (default: true)
    "tool_timeout_seconds": float  # Per-tool execution/read timeout
}
```

### Transport Types

**Streamable HTTP** - For HTTP-based MCP servers (Mintlify, hosted servers):

```python theme={null}
{
    "name": "slide_docs",
    "transport": "streamablehttp",
    "url": "https://slide.mintlify.app/mcp"
}
```

**stdio** - For local process MCP servers:

```python theme={null}
{
    "name": "filesystem",
    "transport": "stdio",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/tmp"]
}
```

**SSE (Server-Sent Events)** - Legacy HTTP transport for backward compatibility:

```python theme={null}
{
    "name": "legacy_server",
    "transport": "sse",
    "url": "https://legacy.example.com/mcp"
}
```

## Advanced Usage

### Multiple Servers

Connect to multiple MCP servers simultaneously:

```python theme={null}
agent = Agent(
    mcp={
        "servers": [
            {"name": "docs", "transport": "streamablehttp", "url": "https://docs.example.com/mcp"},
            {"name": "db", "transport": "streamablehttp", "url": "https://db.example.com/mcp"},
            {"name": "files", "transport": "stdio", "command": "mcp-server-files"}
        ]
    }
)

try:
    await agent.connect_mcp()
finally:
    await agent.cleanup()
```

### Tool Filtering

Control which tools are registered:

```python theme={null}
{
    "name": "filesystem",
    "transport": "stdio",
    "command": "mcp-server-filesystem",
    "include_tools": ["read_file", "list_directory"],  # Whitelist
    "exclude_tools": ["write_file", "delete_file"]   # Blacklist (applied after include)
}
```

### Custom Namespace

Override the default namespace prefix:

```python theme={null}
{
    "name": "wandb_documentation_server",  # Long name
    "prefix": "docs",  # Short, clean prefix
    "transport": "streamablehttp",
    "url": "https://docs.wandb.ai/mcp"
}
# Tools: docs_search, docs_query (instead of wandb_documentation_server_search)
```

### Environment Variables

Use environment variables for secrets (recommended!):

```yaml theme={null}
mcp:
  servers:
    - name: api
      transport: streamablehttp
      url: https://api.example.com/mcp
      headers:
        Authorization: "Bearer ${API_TOKEN}"  # Substituted from env
```

Set the environment variable:

```bash theme={null}
export API_TOKEN=your_secret_token
tyler chat
```

### Graceful Degradation

Control failure behavior per server:

```python theme={null}
{
    "servers": [
        {
            "name": "critical_server",
            "url": "...",
            "fail_silent": False  # Fail startup if unavailable
        },
        {
            "name": "optional_server",
            "url": "...",
            "fail_silent": True  # Continue if unavailable (default)
        }
    ]
}
```

## Resource Management

### When to Use `cleanup()`

Use `try/finally` and call `await agent.cleanup()` whenever an agent connects to MCP servers. Cleanup disconnects SDK sessions and removes dynamically registered MCP tools from the agent so reconnects do not duplicate definitions.

**Long-running applications:**

```python theme={null}
# Web server creating agents per request
@app.post("/chat")
async def chat_endpoint(request):
    agent = Agent(mcp={...})
    try:
        await agent.connect_mcp()
        result = await agent.run(thread)
        return result
    finally:
        await agent.cleanup()
```

**Testing or batch processing:**

```python theme={null}
# Creating/destroying many agents
for task in tasks:
    agent = Agent(mcp={...})
    try:
        await agent.connect_mcp()
        await agent.run(thread)
    finally:
        await agent.cleanup()
```

<Note>
  Streamable HTTP uses asyncio task groups and remote sessions that especially need explicit cleanup. Using the same pattern for `stdio` and legacy `sse` keeps scripts and tests predictable.
</Note>

## Security Best Practices

<Warning>
  Never hardcode API keys or secrets in config files!
  Always use environment variable substitution (`${VAR}`).
</Warning>

**DO:**

```yaml theme={null}
mcp:
  servers:
    - name: api
      url: https://api.example.com/mcp
      headers:
        Authorization: "Bearer ${API_TOKEN}"  # ✓ Good
```

**DON'T:**

```yaml theme={null}
mcp:
  servers:
    - name: api
      url: https://api.example.com/mcp
      headers:
        Authorization: "Bearer sk-1234567890"  # ✗ Bad - secret exposed!
```

**Harden MCP usage:**

* Trust only reviewed MCP servers; local `stdio` servers run with the same privileges as the Tyler process.
* Treat MCP tool descriptions, annotations, icons, and `_meta` as advisory/untrusted unless the server is trusted.
* Prefer `include_tools` and `exclude_tools` so agents only see the tools they need.
* Avoid always-on large MCP server catalogs; connect narrow server sets per agent or workflow.
* Keep secrets in environment variables and use `${VAR}` substitution in config.

## Troubleshooting

### Connection refused

**Error:** `Failed to connect to MCP server 'xyz': Connection refused`

**Solutions:**

1. Verify the server URL is correct
2. Check if the MCP server is running
3. For stdio servers, verify the command path is correct
4. Check firewall settings

### Invalid config schema

**Error:** `Server 'xyz' with transport 'sse' requires 'url' field`

**Solution:** Ensure required fields are present for the transport type:

* streamablehttp/SSE: `url` required
* stdio: `command` required

### Tools not discovered

**Error:** MCP connects but no tools available

**Solutions:**

1. Verify the MCP server is functioning (check server logs)
2. Check if tools are being filtered out (remove `include_tools`/`exclude_tools`)
3. Try connecting to the server manually to verify it exposes tools

### Environment variable not substituted

**Error:** Connection fails with literal `${VAR}` in URL

**Solution:** Ensure the environment variable is set before running:

```bash theme={null}
export MY_VAR=value
python my_script.py
```

<Note>
  **Under the Hood:** Tyler uses the official MCP SDK's `ClientSessionGroup` to manage
  connections to MCP servers. The declarative config approach is recommended for all users.
  See the [API Reference](/api-reference/tyler-agent) for details.
</Note>

## Next Steps

<CardGroup cols={2}>
  <Card title="MCP Specification" icon="file-contract" href="https://modelcontextprotocol.io/docs">
    Read the full MCP specification
  </Card>

  <Card title="MCP Servers" icon="server" href="https://github.com/modelcontextprotocol/servers">
    Browse available MCP servers
  </Card>

  <Card title="Adding Tools" icon="wrench" href="/guides/adding-tools">
    Build custom tools for agents
  </Card>

  <Card title="Tyler CLI" icon="terminal" href="/apps/tyler-cli">
    Use MCP with tyler-chat CLI
  </Card>
</CardGroup>
