# How to Integrate MCP Tools into AgentScope Agents: Complete Implementation Guide

> Learn to integrate MCP tools into AgentScope agents using the Toolkit class. Follow our three-step guide for seamless async tool call implementation and enhance your agent's capabilities.

- Repository: [AgentScope-AI/agentscope](https://github.com/agentscope-ai/agentscope)
- Tags: how-to-guide
- Published: 2026-03-09

---

**AgentScope enables seamless integration of Model Context Protocol tools through its Toolkit class, which exposes external MCP server functions as native async tool calls via a three-step process of client instantiation, connection, and registration.**

The `agentscope-ai/agentscope` repository provides first-class support for Model Context Protocol (MCP), allowing your agents to invoke remote tool services as if they were local Python functions. This integration leverages the `Toolkit` registry and specialized MCP client abstractions to handle connection management, tool discovery, and execution semantics automatically.

## Architecture of MCP Integration in AgentScope

The integration relies on four core components working together to bridge external MCP servers with AgentScope's execution environment.

**Toolkit** ([`src/agentscope/tool/_toolkit.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/tool/_toolkit.py)) serves as the central registry for all tool functions, handling both local and MCP-provided tools. The `register_mcp_client` method (starting at line 817) manages middleware pipelines, name conflict resolution, and execution grouping.

**MCPClientBase** ([`src/agentscope/mcp/_client_base.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/mcp/_client_base.py)) defines the abstract interface for all MCP clients, specifying `get_callable_function` and content conversion utilities that transform MCP responses into AgentScope blocks.

**StatefulClientBase** ([`src/agentscope/mcp/_stateful_client_base.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/mcp/_stateful_client_base.py)) extends the base with connection lifecycle management (`connect`, `close`), tool caching, and persistent session handling for long-running MCP connections.

**MCPToolFunction** ([`src/agentscope/mcp/_mcp_function.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/mcp/_mcp_function.py)) wraps remote MCP tools into async callables that return standardized `ToolResponse` objects, handling result conversion via `MCPClientBase._convert_mcp_content_to_as_blocks`.

## Step-by-Step MCP Integration

Integrating MCP tools requires three sequential operations: client creation, connection establishment (for stateful clients), and Toolkit registration.

### Creating an MCP Client

AgentScope supports three transport implementations: HTTP stateless, HTTP stateful (via `HttpStatefulClient`), and StdIO. Choose based on your server's capabilities and your need for persistent sessions.

```python
from agentscope.mcp import HttpStatefulClient

mcp_client = HttpStatefulClient(
    name="my_mcp",
    transport="streamable_http",  # or "sse"

    url="http://127.0.0.1:8000/mcp",
    headers={"Authorization": "Bearer token"},
)

```

For stateless scenarios, use `HttpStatelessClient` ([`src/agentscope/mcp/_http_stateless_client.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/mcp/_http_stateless_client.py)) instead, which creates temporary sessions per call and requires no explicit connection management.

### Connecting Stateful Clients

Stateful clients require an explicit connection step to establish the underlying `ClientSession` and cache available tools.

```python
await mcp_client.connect()

```

This sets `client.is_connected = True`, which `Toolkit.register_mcp_client` validates before proceeding; otherwise, it raises a `RuntimeError`. Stateless clients auto-manage connections internally, skipping this step.

### Registering Tools with the Toolkit

The `await toolkit.register_mcp_client(...)` method pulls tool metadata from the server and injects callable functions into your Toolkit instance.

```python
from agentscope.tool import Toolkit

toolkit = Toolkit()

await toolkit.register_mcp_client(
    mcp_client,
    group_name="my_mcp_tools",
    enable_funcs=None,           # register all available tools

    disable_funcs=["ignore_me"], # exclude specific tools

    preset_kwargs_mapping={      # inject default arguments

        "search": {"max_results": 5},
    },
    postprocess_func=None,       # optional response transformer

    namesake_strategy="override", # handle duplicate names

)

```

This workflow enumerates available tools via `await mcp_client.list_tools()`, retrieves callables via `get_callable_function`, and stores them using `Toolkit.register_tool_function` with conflict resolution.

## Direct Tool Invocation Patterns

You can interact with MCP tools either through the Toolkit middleware pipeline or by retrieving direct callables.

### Toolkit-Based Execution

Use `Toolkit.call_tool_function` with a `ToolUseBlock` to execute MCP tools through the standard middleware chain:

```python
from agentscope.tool import ToolUseBlock

tool_use = ToolUseBlock(
    type="tool_use",
    name="search",
    input={"query": "agentscope"},
    id="tool_1",
)

async for chunk in await toolkit.call_tool_function(tool_use):
    print(chunk.content[0]["text"])

```

Each `chunk` is a `ToolResponse` instance streamed from the remote MCP server.

### Direct Callable Retrieval

For scenarios bypassing the Toolkit, retrieve functions directly from the client:

```python
from agentscope.mcp import HttpStatelessClient

client = HttpStatelessClient(
    name="stateless_mcp",
    transport="streamable_http",
    url="http://127.0.0.1:8001/mcp",
)

summarize = await client.get_callable_function(
    func_name="summarize",
    wrap_tool_result=True,  # returns ToolResponse; False returns raw mcp.types.CallToolResult

)

resp = await summarize(text="AgentScope makes LLM agents easy.")
print(resp.content[0]["text"])

```

## Advanced Configuration Options

The registration API provides granular control over tool behavior, naming, and response processing.

### Handling Name Conflicts

The `namesake_strategy` parameter in `register_mcp_client` resolves collisions between MCP tools and existing Toolkit entries:

- **`raise`**: Throws an error on conflict
- **`override`**: Replaces the existing tool
- **`skip`**: Ignores the conflicting MCP tool
- **`rename`**: Automatically renames the incoming tool

### Injecting Preset Arguments

Use `preset_kwargs_mapping` to bind default parameters to specific MCP tools at registration time. This ensures consistent behavior without modifying agent prompts.

```python
preset_kwargs_mapping={
    "database_query": {"timeout": 30, "return_metadata": True},
}

```

### Post-Processing Tool Responses

The `postprocess_func` hook allows transformation of `ToolResponse` objects before they reach downstream agents. The function receives the original `ToolUseBlock` and the generated response.

```python
async def add_metadata(tool_use, response):
    response.metadata["source"] = tool_use.name
    return response

await toolkit.register_mcp_client(
    mcp_client,
    postprocess_func=add_metadata,
)

```

## Summary

- **AgentScope's Toolkit** ([`src/agentscope/tool/_toolkit.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/tool/_toolkit.py)) exposes MCP server functions as native tools through `register_mcp_client`.
- **Stateful clients** require explicit `await client.connect()` before registration; **stateless clients** manage connections automatically.
- **Tool registration** supports filtering via `enable_funcs`/`disable_funcs`, argument injection via `preset_kwargs_mapping`, and response transformation via `postprocess_func`.
- **Name conflicts** are resolvable through `namesake_strategy` with options for raising, overriding, skipping, or renaming.
- **Execution** flows through `Toolkit.call_tool_function` for middleware support, or via `client.get_callable_function` for direct invocation.

## Frequently Asked Questions

### What is the difference between stateful and stateless MCP clients in AgentScope?

Stateful clients (`HttpStatefulClient`, `StdIOClient`) maintain persistent connections to MCP servers through `ClientSession` instances, requiring explicit `connect()` and `close()` calls. They cache tool definitions and support long-running sessions. Stateless clients (`HttpStatelessClient`) create temporary sessions per request, offering lower overhead for intermittent tool usage without connection management overhead.

### How do I resolve tool name conflicts when registering multiple MCP servers?

Pass the `namesake_strategy` parameter to `Toolkit.register_mcp_client`. Set it to `"override"` to replace existing tools, `"skip"` to ignore duplicates, or `"rename"` to automatically generate unique names. The default behavior raises a `RuntimeError` when conflicts occur.

### Can I use MCP tools without the Toolkit class?

Yes. Call `await client.get_callable_function(func_name="tool_name", wrap_tool_result=True)` on any MCP client to receive an async callable that executes directly against the remote server. This bypasses Toolkit middleware but returns identical `ToolResponse` objects.

### Where is the MCP registration logic implemented in the AgentScope source code?

The primary registration workflow resides in [`src/agentscope/tool/_toolkit.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/tool/_toolkit.py) within the `register_mcp_client` method (starting at line 817). Supporting implementations include [`src/agentscope/mcp/_client_base.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/mcp/_client_base.py) for the client interface, [`src/agentscope/mcp/_mcp_function.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/mcp/_mcp_function.py) for the tool wrapper, and [`src/agentscope/mcp/_stateful_client_base.py`](https://github.com/agentscope-ai/agentscope/blob/main/src/agentscope/mcp/_stateful_client_base.py) for connection lifecycle management.