How to Connect MCP Servers as Tools in aisuite: A Complete Integration Guide

aisuite converts any MCP (Model Context Protocol) server into callable Python tools that LLMs can invoke using the MCPClient class from aisuite/mcp/client.py and the wrapper system in aisuite/mcp/tool_wrapper.py.

The andrewyng/aisuite library provides native support for the Model Context Protocol, allowing you to connect MCP servers as tools in aisuite workflows. This integration bridges external tool ecosystems—whether local command-line utilities or remote HTTP APIs—into aisuite's unified interface for LLM interactions.

MCP Integration Architecture

The MCP implementation in aisuite relies on four specialized components that handle configuration, connection, and tool wrapping:

Component Source File Key Function
Configuration validation aisuite/mcp/config.py validate_mcp_config() parses transport settings and fills defaults
Connection management aisuite/mcp/client.py MCPClient class handles stdio processes or HTTP clients
Tool adaptation aisuite/mcp/tool_wrapper.py MCPToolWrapper converts MCP schemas into Python callables
Schema conversion aisuite/mcp/schema_converter.py Translates JSON-Schema into Python type annotations

When you connect MCP servers as tools in aisuite, the MCPClient discovers available remote tools via the MCP protocol, then wraps each tool using create_mcp_tool_wrapper() to produce Python functions compatible with aisuite's Tools class.

Transport Configuration: HTTP vs stdio

aisuite supports two transport mechanisms for MCP servers, validated in aisuite/mcp/config.py (lines 81-104):

HTTP Transport requires:

  • server_url: The endpoint hosting the MCP server
  • Optional: headers, timeout

stdio Transport requires:

  • command: The executable to spawn
  • Optional: args, env, cwd

The validate_mcp_config() function ensures exactly one transport type is specified and all required fields are present.


# HTTP transport configuration

http_config = {
    "type": "mcp",
    "name": "weather-api",
    "server_url": "http://localhost:8000/mcp/v1",
    "timeout": 30.0,
}

# stdio transport configuration  

stdio_config = {
    "type": "mcp", 
    "name": "filesystem",
    "command": "npx",
    "args": ["-y", "@modelcontextprotocol/server-filesystem", "/docs"],
}

Creating MCPClient Instances

You can instantiate MCPClient either from a configuration dictionary or directly with transport parameters.

Method 1: From Configuration Dictionary

Use MCPClient.from_config() (defined in aisuite/mcp/client.py, lines 71-77) when working with dict-based configs:

from aisuite.mcp import MCPClient

config = {
    "type": "mcp",
    "name": "api-server",
    "server_url": "http://localhost:8000/mcp/v1",
    "allowed_tools": ["get_weather", "forecast"],  # Optional filtering

}

mcp = MCPClient.from_config(config)

Method 2: Direct Instantiation

Create the client directly for stdio-based servers or when you need fine-grained control:

from aisuite.mcp import MCPClient

# stdio-based MCP server

mcp = MCPClient(
    command="python",
    args=["mcp_server.py"],
    name="local-tools",
)

# HTTP-based MCP server

mcp = MCPClient(
    server_url="https://api.example.com/mcp/v1",
    name="remote-api",
)

The constructor (lines 98-104 in client.py) automatically detects the transport type and calls _connect() to initialize the connection.

Discovering and Wrapping MCP Tools

Once connected, retrieve callable tool wrappers using get_callable_tools():


# Discover available tools

tools_list = mcp.list_tools()  # Returns raw MCP tool definitions

# Get Python-callable wrappers

callable_tools = mcp.get_callable_tools()  # Returns list of MCPToolWrapper instances

The get_callable_tools() method (lines 92-100 in client.py) internally calls create_mcp_tool_wrapper() from aisuite/mcp/tool_wrapper.py. This wrapper:

  1. Extracts parameter descriptions using extract_parameter_descriptions()
  2. Converts JSON-Schema to Python annotations via mcp_schema_to_annotations()
  3. Builds a proper inspect.Signature (lines 59-70 in tool_wrapper.py)
  4. Creates a callable that forwards invocations to MCPClient.call_tool()

Using MCP Tools in Chat Completions

Pass the wrapped tools directly to client.chat.completions.create():

import aisuite as ai
from aisuite.mcp import MCPClient

# Setup MCP client

mcp = MCPClient(server_url="http://localhost:8000/mcp/v1", name="weather-api")
tools = mcp.get_callable_tools()

# Use in chat completion

client = ai.Client()
response = client.chat.completions.create(
    model="openai:gpt-4o",
    messages=[{"role": "user", "content": "Give me tomorrow's forecast."}],
    tools=tools,
    max_turns=2,
)

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

Combining MCP Tools with Native Functions

Mix MCP tools with regular Python functions by unpacking the callable list:

import aisuite as ai
from aisuite.mcp import MCPClient
from datetime import datetime

def current_timestamp() -> str:
    """Return the current ISO-8601 timestamp."""
    return datetime.utcnow().isoformat()

mcp = MCPClient(server_url="https://api.example.com/mcp/v1", name="external-api")

client = ai.Client()
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "What time is it and what's the weather?"}],
    tools=[current_timestamp, *mcp.get_callable_tools()],
    max_turns=3,
)

Context Manager for Automatic Cleanup

Use the context manager protocol (implemented in client.py via __enter__ and __exit__) to ensure proper resource cleanup:

from aisuite.mcp import MCPClient
import aisuite as ai

with MCPClient(server_url="http://localhost:8000/mcp/v1", name="demo-api") as mcp:
    client = ai.Client()
    resp = client.chat.completions.create(
        model="openai:gpt-4o",
        messages=[{"role": "user", "content": "List available tools"}],
        tools=mcp.get_callable_tools(),
        max_turns=2,
    )
    print(resp.choices[0].message.content)

# mcp.close() called automatically

Advanced Configuration Options

The MCP integration supports several optional parameters in aisuite/mcp/config.py:

  • allowed_tools: whitelist specific tools by name when calling get_callable_tools()
  • use_tool_prefix: namespace tools with the MCP server name to avoid collisions
  • lazy_connect: defer connection until first tool invocation
  • timeout_seconds: set maximum wait time for tool responses
  • response_bytes_cap: limit response size to prevent memory issues

These options are processed during configuration validation and honored by the MCPClient initialization logic.

Summary

  • aisuite/mcp/client.py contains the MCPClient class that manages connections to both HTTP and stdio MCP servers
  • aisuite/mcp/tool_wrapper.py provides MCPToolWrapper to convert MCP tool schemas into Python callables with proper type hints and signatures
  • Use MCPClient.from_config() for dictionary-based configuration or direct instantiation for programmatic control
  • Call get_callable_tools() to retrieve wrapped tools ready for client.chat.completions.create(tools=...)
  • Transport types are validated in aisuite/mcp/config.py via validate_mcp_config()
  • Combine MCP tools with native Python functions by unpacking the callable list with *mcp.get_callable_tools()

Frequently Asked Questions

What is an MCP server and why use it with aisuite?

An MCP (Model Context Protocol) server exposes external capabilities—such as file system access, API calls, or database queries—through a standardized protocol. When you connect MCP servers as tools in aisuite, you extend LLM capabilities with these external resources without writing custom integration code for each service.

How do I choose between HTTP and stdio transport?

Choose stdio transport (command, args) when running local MCP server implementations as subprocesses, such as Node.js or Python scripts. Choose HTTP transport (server_url) when connecting to remote or already-hosted MCP endpoints. The validate_mcp_config() function in aisuite/mcp/config.py enforces that exactly one transport type is specified per configuration.

Can I filter which MCP tools are exposed to the LLM?

Yes. Pass the allowed_tools parameter in your configuration dictionary containing a list of tool names to whitelist. When get_callable_tools() executes, it only returns wrappers for tools matching the allowed list, preventing the LLM from accessing restricted functionality.

How does aisuite handle MCP tool schema conversion?

The MCPToolWrapper class in aisuite/mcp/tool_wrapper.py processes the MCP tool's JSON-Schema definition using utilities from aisuite/mcp/schema_converter.py. It converts schema types to Python type annotations, extracts parameter descriptions for docstrings, and constructs a proper inspect.Signature object so aisuite's tool introspection system can present the tool correctly to the LLM.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →