# How to Configure MCP Servers with aisuite: A Complete Guide to Model Context Protocol Tool Calling

> Configure MCP servers with aisuite easily. Learn how to pass a Python dictionary to start server processes and expose tools to your LLM for seamless integration.

- Repository: [Andrew Ng/aisuite](https://github.com/andrewyng/aisuite)
- Tags: how-to-guide
- Published: 2026-07-27

---

**To configure MCP servers with aisuite, pass a Python dictionary with `"type": "mcp"` into the `tools` list of `client.chat.completions.create`, and the library will automatically validate the config, start the server process or HTTP connection, and expose discovered tools to the LLM.**

To configure MCP servers with aisuite, you use a plain Python dictionary that conforms to the `MCPConfig` TypedDict. The `andrewyng/aisuite` repository handles the entire server lifecycle—from validation to tool discovery—when it detects an MCP entry in the `tools` parameter.

## Understanding MCP Configuration in aisuite

aisuite integrates external tools via the **Model Context Protocol (MCP)** by accepting configuration dictionaries directly inside tool lists. These dictionaries follow the `MCPConfig` specification defined in [[`aisuite/mcp/config.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py)](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py).

### The MCPConfig TypedDict Structure

The `MCPConfig` TypedDict defines the expected shape of every MCP server configuration. At minimum, a config must include `"type": "mcp"` and a non-empty `"name"` field. The library then distinguishes between **stdio** and **HTTP** transports based on the presence of either a `"command"` or `"server_url"` key.

### Supported Transport Types

aisuite supports two transport mechanisms for MCP servers:

- **stdio transport**: Spawns a local process using the `"command"` field. You can optionally provide `"args"`, `"env"`, and `"cwd"` to control the execution environment.
- **HTTP transport**: Connects to a remote endpoint using the `"server_url"` field. You can optionally supply custom `"headers"`.

According to the source code in [`aisuite/mcp/config.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py), the `validate_mcp_config()` function enforces that **exactly one** of these transports is specified (see lines 95–100).

## How aisuite Consumes MCP Configurations

When a request reaches `client.chat.completions.create` in `aisuite`, the library inspects each entry in the `tools` list. If a dict has `"type": "mcp"`, aisuite routes it through the validation and instantiation pipeline:

```python

# Inside aisuite/client.py → chat.completions.create

if isinstance(tool_entry, dict) and tool_entry.get("type") == "mcp":
    cfg = validate_mcp_config(tool_entry)          # aisuite/mcp/config.py

    mcp = MCPClient.from_config(cfg)               # aisuite/mcp/client.py

    # Replace the dict with the callable tools provided by the MCP client

    tools.extend(mcp.get_callable_tools())

```

### Validation Rules in aisuite/mcp/config.py

The `validate_mcp_config()` function performs five critical steps:

1. **Ensures the config type is `"mcp"`** and verifies that a non-empty `"name"` is supplied.
2. **Detects the transport**—either stdio (`"command"`) or HTTP (`"server_url"`)—and confirms exactly one is present.
3. **Validates transport-specific fields**, such as ensuring `command` is a string and `server_url` starts with `http://` or `https://`.
4. **Applies defaults** for optional parameters, including `timeout_seconds` (default 30 seconds), `response_bytes_cap` (default 10 MiB), `use_tool_prefix`, and `lazy_connect` (defined at lines 42–46).
5. **Returns a normalized dictionary** (starting at line 86) that the MCP client consumes.

The normalized config is passed to `MCPClient.from_config()` in [[`aisuite/mcp/client.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/client.py)](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/client.py). This helper automatically starts the server process (for stdio), prepares the HTTP endpoint, discovers tools via `list_tools()`, and wraps each remote tool as a callable that the LLM can invoke through the standard tool-calling protocol.

## Essential MCP Configuration Fields

The following fields control how aisuite connects to and manages an MCP server:

- **`type`** — Must be `"mcp"` (required).
- **`name`** — Logical identifier for the server (required).
- **`command`** — Executable for stdio transport (e.g., `"npx"`).
- **`args`** — Argument list for the stdio command.
- **`env`** — Environment variables for the stdio process (optional).
- **`cwd`** — Working directory for the stdio process (optional).
- **`server_url`** — Base URL for HTTP transport (must start with `http://` or `https://`).
- **`headers`** — Additional HTTP headers for HTTP transport (optional).
- **`allowed_tools`** — Whitelist of tool names the LLM may call for security.
- **`use_tool_prefix`** — Prefixes tool names with `<name>__` to prevent collisions across multiple servers.
- **`timeout_seconds`** — Maximum wait time for a tool response (default 30).
- **`response_bytes_cap`** — Upper bound on response size in bytes (default 10 MiB).
- **`lazy_connect`** — Defer connecting until the first tool call if `True`.

## Code Examples for Configuring MCP Servers with aisuite

### Basic stdio-Based MCP Server (Filesystem Example)

The following example demonstrates how to configure a filesystem MCP server using the stdio transport. It is adapted from [[`examples/mcp_config_dict_example.py`](https://github.com/andrewyng/aisuite/blob/main/examples/mcp_config_dict_example.py)](https://github.com/andrewyng/aisuite/blob/main/examples/mcp_config_dict_example.py) (lines 23–38).

```python
import aisuite as ai
import os

client = ai.Client()

response = client.chat.completions.create(
    model="openai:gpt-4o",
    messages=[{"role": "user", "content": "List all Python files here"}],
    tools=[
        {
            "type": "mcp",
            "name": "filesystem",
            "command": "npx",
            "args": [
                "-y",
                "@modelcontextprotocol/server-filesystem",
                os.getcwd(),
            ],
        }
    ],
    max_turns=2,
)

print(response.choices[0].message.content)

```

### Restricting Available Tools for Security

Use the `allowed_tools` field to limit which remote tools the LLM can access. This prevents unintended operations from exposed servers.

```python
{
    "type": "mcp",
    "name": "filesystem",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", os.getcwd()],
    "allowed_tools": ["read_file"],  # only allow file reads

}

```

### Running Multiple MCP Servers with Tool Prefixing

When you connect to multiple MCP servers, enable `use_tool_prefix` to avoid name collisions. Tool names are prefixed with `<name>__` automatically.

```python
{
    "type": "mcp",
    "name": "temp_dir",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", temp_dir],
    "use_tool_prefix": True,  # tools become temp_dir__list_directory, …

}

```

### Mixing MCP Config Dicts with Native Python Functions

aisuite allows you to combine standard Python callables with MCP configuration dictionaries in the same `tools` list.

```python
def get_current_time():
    ...

response = client.chat.completions.create(
    model="openai:gpt-4o",
    messages=[{"role": "user", "content": "What time is it?"}],
    tools=[
        get_current_time,  # native Python function

        {  # MCP config dict

            "type": "mcp",
            "name": "filesystem",
            "command": "npx",
            "args": ["-y", "@modelcontextprotocol/server-filesystem", os.getcwd()],
        },
    ],
    max_turns=3,
)

```

## Summary

- aisuite configures MCP servers through Python dictionaries that follow the `MCPConfig` TypedDict in [`aisuite/mcp/config.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py).
- The `validate_mcp_config()` function enforces required fields, validates the transport type, and applies default values for timeouts and response caps.
- `MCPClient.from_config()` in [`aisuite/mcp/client.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/client.py) consumes the normalized config to spawn processes, discover tools, and present them as LLM-callable functions.
- You can secure tool access via `allowed_tools`, prevent naming collisions with `use_tool_prefix`, and mix MCP configs with native Python functions seamlessly.

## Frequently Asked Questions

### What is the MCPConfig TypedDict in aisuite?

The `MCPConfig` TypedDict is a structural definition in [`aisuite/mcp/config.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py) that specifies the required and optional fields for an MCP server configuration. It ensures that every config dict includes a valid transport type, a server name, and the correct parameters for either stdio or HTTP communication.

### How does aisuite validate MCP server configurations?

aisuite validates configurations through `validate_mcp_config()` in [`aisuite/mcp/config.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py). This function checks that the type is `"mcp"`, that a name is present, that exactly one transport is specified, and that transport-specific fields meet format requirements before applying defaults for optional settings.

### Can I mix MCP servers with regular Python functions in aisuite?

Yes. The `tools` parameter in `client.chat.completions.create` accepts a heterogeneous list. You can include native Python functions alongside MCP configuration dictionaries, and aisuite will resolve and invoke each tool through the appropriate path.

### What transport protocols does aisuite support for MCP servers?

aisuite supports **stdio** and **HTTP** transports. For stdio, you provide a `"command"` field with optional `"args"`, `"env"`, and `"cwd"`. For HTTP, you provide a `"server_url"` field with optional `"headers"`. The validator in [`aisuite/mcp/config.py`](https://github.com/andrewyng/aisuite/blob/main/aisuite/mcp/config.py) enforces that exactly one transport is present.