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

# MultiMCPHandler

> Connect to multiple MCP servers simultaneously

## Overview

`MultiMCPHandler` allows you to connect to multiple MCP servers at once, aggregating all their tools into a unified interface.

## Basic Usage

```python theme={null}
from upsonic import Agent, Task
from upsonic.tools.mcp import MultiMCPHandler

# Create multi-handler with multiple servers
multi_handler = MultiMCPHandler(
    commands=[
        "uvx mcp-server-sqlite --db-path /tmp/db1.db",
        "uvx mcp-server-sqlite --db-path /tmp/db2.db",
    ],
    timeout_seconds=60
)

# Create agent
agent = Agent(
    name="Multi-MCP Agent",
    role="Multi-database operations specialist",
    goal="Demonstrate MultiMCPHandler with multiple SQLite databases",
    tool_call_limit=10
)

# Create task
task = Task(
    description="""
    IMPORTANT: You have access to TWO separate SQLite databases.
    - Database 1: Use tools from the first MCP server connection
    - Database 2: Use tools from the second MCP server connection
    
    Step 1: Using Database 1, create a 'users' table with:
    - id (integer primary key)
    - username (text)
    - email (text)
    - created_at (text)
    
    Insert 3 sample users into Database 1.
    
    Step 2: Using Database 2, create a 'posts' table with:
    - id (integer primary key)
    - user_id (integer)
    - title (text)
    - content (text)
    - published (boolean)
    
    Insert 4 sample posts into Database 2.
    
    Step 3: Query Database 1 to show all users.
    Step 4: Query Database 2 to show all posts.
    """,
    tools=[multi_handler]
)

# Execute
result = agent.print_do(task)
print("Result:", result)
```

## Parameters

* `commands` (List\[str]): List of command strings for each server
* `server_params_list`: List of server parameter objects
* `timeout_seconds` (int): Connection timeout for all servers (default: 5)
* `include_tools` (List\[str]): Optional list of tool names to include from all servers
* `exclude_tools` (List\[str]): Optional list of tool names to exclude from all servers
* `tool_name_prefix` (str): Optional single prefix for all servers (becomes `prefix_0`, `prefix_1`, etc.)
* `tool_name_prefixes` (List\[str]): Optional list of specific prefixes for each server (must match number of servers)

## Features

* **Multiple Connections**: Connect to multiple servers simultaneously
* **Unified Interface**: All tools from all servers available in one place
* **Server Introspection**: Get information about each server and its tools
* **Automatic Cleanup**: Properly closes all connections after task completion

## Server Introspection

```python theme={null}
from upsonic.tools.mcp import MultiMCPHandler

multi_handler = MultiMCPHandler(
    commands=[
        "uvx mcp-server-sqlite --db-path /tmp/db1.db",
        "uvx mcp-server-sqlite --db-path /tmp/db2.db",
    ],
    timeout_seconds=60
)

# Get tools first (this triggers connection if needed)
tools = multi_handler.get_tools()

# Get server information
print(f"Server Count: {multi_handler.get_server_count()}")
print(f"Tool Count: {multi_handler.get_tool_count()}")
print(f"Tools by Server: {multi_handler.get_tools_by_server()}")

# Get detailed server info
server_info = multi_handler.get_server_info()
for info in server_info:
    print(f"Server {info['index']}: {info['server_name']} ({len(info['tools'])} tools)")
```

## Example with Structured Output

```python theme={null}
from upsonic import Agent, Task
from upsonic.tools.mcp import MultiMCPHandler
from pydantic import BaseModel

class MultiDatabaseReport(BaseModel):
    """Structured output for multi-database operations."""
    databases_used: int
    total_tables: int
    total_records: int
    operations_summary: str

# Create multi-handler
multi_handler = MultiMCPHandler(
    commands=[
        "uvx mcp-server-sqlite --db-path /tmp/companies.db",
        "uvx mcp-server-sqlite --db-path /tmp/employees.db",
    ],
    timeout_seconds=60
)

# Create agent
agent = Agent(
    name="Multi-MCP Structured Agent",
    role="Multi-database operations with structured reporting",
    goal="Demonstrate structured output with MultiMCPHandler",
    tool_call_limit=10
)

# Create task with structured output
task = Task(
    description="""
    IMPORTANT: You have access to TWO separate SQLite databases.
    - Database 1: Use tools from the first MCP server connection
    - Database 2: Use tools from the second MCP server connection
    
    Step 1: Using Database 1, create a 'companies' table with:
    - id (integer primary key)
    - name (text)
    - industry (text)
    - revenue (real)
    
    Insert 3 tech companies into Database 1.
    
    Step 2: Using Database 2, create an 'employees' table with:
    - id (integer primary key)
    - name (text)
    - position (text)
    - salary (real)
    - company_id (integer)
    
    Insert 5 sample employees into Database 2.
    
    Step 3: Provide a structured report with:
    - Number of databases used (should be 2)
    - Total tables created (should be 2)
    - Total records inserted (should be 8: 3 companies + 5 employees)
    - Operations summary describing what was done
    """,
    tools=[multi_handler],
    response_format=MultiDatabaseReport
)

# Execute
result = agent.print_do(task)
print("Databases Used:", result.databases_used)
print("Total Tables:", result.total_tables)
print("Total Records:", result.total_records)
print("Operations Summary:", result.operations_summary)
```

## Tool Name Prefixes

When connecting to multiple servers of the same type, tools may have identical names (e.g., both SQLite servers have `create_table`). Use prefixes to distinguish them:

### Using `tool_name_prefixes` (Recommended)

Specify exact prefixes for each server:

```python theme={null}
from upsonic import Agent, Task
from upsonic.tools.mcp import MultiMCPHandler

# Create multi-handler with specific prefixes for each server
multi_handler = MultiMCPHandler(
    commands=[
        "uvx mcp-server-sqlite --db-path /tmp/users.db",
        "uvx mcp-server-sqlite --db-path /tmp/orders.db",
    ],
    tool_name_prefixes=["users_db", "orders_db"],  # Must match number of servers
    timeout_seconds=60
)

# Create agent
agent = Agent(
    name="Multi-DB Agent",
    role="Multi-database operations specialist",
    goal="Work with multiple databases using prefixed tools"
)

# Create task with clear tool prefixes
task = Task(
    description="""
    IMPORTANT: You have access to TWO separate databases with prefixed tools.
    - Users database: Use tools prefixed with 'users_db_' (e.g., users_db_create_table, users_db_read_query)
    - Orders database: Use tools prefixed with 'orders_db_' (e.g., orders_db_create_table, orders_db_read_query)
    
    Step 1: Using users_db tools, create a 'users' table with id, name, and email columns.
    Insert 3 sample users.
    
    Step 2: Using orders_db tools, create an 'orders' table with id, user_id, and product columns.
    Insert 4 sample orders.
    
    Step 3: Query both databases to show all records.
    """,
    tools=[multi_handler]
)

result = agent.print_do(task)
print("Result:", result)
```

### Using `tool_name_prefix` (Auto-indexed)

Use a single base prefix that gets automatically indexed:

```python theme={null}
from upsonic.tools.mcp import MultiMCPHandler

# Single prefix becomes: db_0_create_table, db_1_create_table, etc.
multi_handler = MultiMCPHandler(
    commands=[
        "uvx mcp-server-sqlite --db-path /tmp/db1.db",
        "uvx mcp-server-sqlite --db-path /tmp/db2.db",
    ],
    tool_name_prefix="db",  # Becomes db_0_*, db_1_*, etc.
    timeout_seconds=60
)
```

### Prefix Benefits

* **Prevents Collisions**: Multiple servers with same tool names work together
* **Clear Identification**: Agents know exactly which server's tool to use
* **Better Instructions**: Task descriptions can reference specific prefixed tools

## When to Use

* Need to work with multiple MCP servers simultaneously
* Want to aggregate tools from different servers
* Need to coordinate operations across multiple databases/services
* Want unified tool interface for multiple connections
* Use prefixes when servers have overlapping tool names
