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

> ## Agent Instructions
> For AgentScope Python, use https://docs.agentscope.io/stable/en/index for new projects. For existing projects, check the installed agentscope version and use matching versioned documentation.
> The /latest/ alias points to development documentation. Use it only with the matching development source. Do not mix AgentScope 1.x and 2.x APIs.
> State the AgentScope version when providing installation commands or code examples. ReMe uses its own continuously updated /reme/latest/ documentation.

# MCP

> 接入 MCP 服务并使用其工具

AgentScope 集成 [Model Context Protocol (MCP)](https://modelcontextprotocol.io/)，让智能体可以接入任意兼容 MCP 的工具服务。框架自动处理协议协商、工具发现与结果转换。

支持两种连接方式：

| 连接方式               | 传输协议         | 生命周期                             |
| ------------------ | ------------ | -------------------------------- |
| **有状态（Stateful）**  | STDIO 或 HTTP | 持久会话，需显式 `connect()` / `close()` |
| **无状态（Stateless）** | 仅 HTTP       | 每次调用临时建会话，无需生命周期管理               |

为了避免冲突，MCP 工具的命名空间为 `mcp__{server_name}__{tool_name}`；被标注 `readOnlyHint` 的 MCP 工具会被权限系统识别为只读（在 EXPLORE 与 ACCEPT\_EDITS 模式下自动放行；DEFAULT 模式下若没有 allow 规则命中，仍然会 ASK）。

## 注册 MCP 客户端

通过 `Toolkit(mcps=[...])` 接口可以注册多个 MCP 客户端，其中有状态的 MCP 客户端必须在构造 toolkit 之前完成连接。

<CodeGroup>
  ```python title="Stateful (STDIO)" theme={null}
  from agentscope.mcp import MCPClient, StdioMCPConfig
  from agentscope.tool import Toolkit

  client = MCPClient(
      name="filesystem",
      is_stateful=True,
      mcp_config=StdioMCPConfig(
          command="mcp-server-filesystem",
          args=["--root", "/my/project"],
      ),
  )

  await client.connect()

  toolkit = Toolkit(mcps=[client])
  ```

  ```python title="Stateful (HTTP)" theme={null}
  from agentscope.mcp import MCPClient, HttpMCPConfig
  from agentscope.tool import Toolkit

  client = MCPClient(
      name="weather",
      is_stateful=True,
      mcp_config=HttpMCPConfig(
          url="https://api.weather.com/mcp",
          headers={"Authorization": "Bearer xxx"},
      ),
  )

  await client.connect()

  toolkit = Toolkit(mcps=[client])
  ```

  ```python title="Stateless (HTTP)" theme={null}
  from agentscope.mcp import MCPClient, HttpMCPConfig
  from agentscope.tool import Toolkit

  client = MCPClient(
      name="search",
      is_stateful=False,
      mcp_config=HttpMCPConfig(url="https://api.search.com/mcp"),
  )

  toolkit = Toolkit(mcps=[client])
  ```
</CodeGroup>

## 筛选暴露的工具

如果希望只暴露 MCP 服务的部分工具，可以在客户端上配置 `enable_tools` 或 `disable_tools` 参数：

```python theme={null}
client = MCPClient(
    name="search",
    is_stateful=False,
    mcp_config=HttpMCPConfig(url="https://api.search.com/mcp"),
    enable_tools=["web_search", "image_search"],
)
```

## 运行时更新 HTTP header

`mcp_config` 中的 `headers` 在构造时就已固定。当鉴权令牌会在会话中途轮换时，对 Streamable HTTP 客户端调用 `set_runtime_headers()` 即可替换后续请求携带的 header，既不用重建客户端，也不用重新连接：

```python theme={null}
# 传入完整映射，整体替换运行时 header；传入空字典则清空，回到 mcp_config 中的静态 header
await client.set_runtime_headers({"Authorization": "Bearer new-token"})
```

使用时需要注意以下边界：

| 项目   | 说明                                                                                                                                    |
| ---- | ------------------------------------------------------------------------------------------------------------------------------------- |
| 适用范围 | 仅 Streamable HTTP 客户端，STDIO 与 SSE 客户端调用会抛出 `ValueError`                                                                               |
| 生效时机 | 下一个出站请求。已经在途的调用沿用它启动时的快照，Streamable HTTP 长连 GET 流的 header 在流建立时即固定                                                                    |
| 覆盖关系 | MCP 自己按请求设置的 header（`mcp-session-id`、`content-type` 等）始终优先；`connection`、`content-length`、`host`、`transfer-encoding` 由 HTTP 层所有，传入会被拒绝 |
| 持久化  | 运行时 header 是实例上的活跃状态，不参与 `model_dump`，也不会写入工作区持久化                                                                                     |

<Note>
  Docker 工作区中真正的 MCP 客户端跑在网关进程里，主机侧持有的是代理对象。对代理调用 `set_runtime_headers()` 会转发给网关，详见 [MCP 网关](/versions/2.0.9dev/zh/building-blocks/workspace/mcp-gateway)。
</Note>

## 在 Toolkit 之外使用 MCP 工具

需要在 `Toolkit` 之外直接调用 MCP 工具时，调用 `await client.list_tools()` 拿到 `MCPTool` 实例列表后，即可像普通 `ToolBase` 一样使用。
