> ## 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

> Connect agents to MCP servers and use their tools

AgentScope integrates with [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) servers, letting an agent reach any MCP-compatible tool provider. The framework handles protocol negotiation, tool discovery, and result conversion automatically.

Two connection modes are supported:

| Mode          | Transport     | Lifecycle                                                               |
| ------------- | ------------- | ----------------------------------------------------------------------- |
| **Stateful**  | STDIO or HTTP | Persistent session with explicit `connect()` / `close()`                |
| **Stateless** | HTTP only     | Ephemeral session created per tool call, no lifecycle management needed |

MCP tools are namespaced as `mcp__{server_name}__{tool_name}` to avoid name collisions, and tools annotated with `readOnlyHint` are recognized as read-only by the permission system (auto-allowed in EXPLORE and ACCEPT\_EDITS modes; in DEFAULT they still ASK unless an allow rule matches).

## Register MCP Client

Build one or more `MCPClient` instances and pass them to `Toolkit(mcps=[...])`. Stateful clients must be connected before the toolkit is constructed.

<CodeGroup>
  ```python 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 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 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>

## Filter Exposed Tools

To expose only a subset of an MCP server's tools, set `enable_tools` or `disable_tools` on the client itself:

```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"],
)
```

## Update HTTP Headers at Runtime

The `headers` in `mcp_config` are fixed at construction. When an auth token rotates mid-session, call `set_runtime_headers()` on a Streamable HTTP client to replace the headers sent with subsequent requests — no rebuild and no reconnect:

```python theme={null}
# The map is replaced, not merged; an empty dict clears it and the static headers apply again
await client.set_runtime_headers({"Authorization": "Bearer new-token"})
```

The behaviour has a few boundaries worth knowing:

| Aspect               | Behaviour                                                                                                                                                                                             |
| -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Scope                | Streamable HTTP clients only; STDIO and SSE clients raise `ValueError`                                                                                                                                |
| When it takes effect | The next outbound request. A call already under way keeps the snapshot it started with, and the headers of a Streamable HTTP session's long-lived GET stream are fixed when the stream is established |
| Precedence           | Headers MCP sets per request (`mcp-session-id`, `content-type`, ...) always win; `connection`, `content-length`, `host` and `transfer-encoding` are owned by the HTTP layer and are rejected          |
| Persistence          | Runtime headers are live instance state, excluded from `model_dump` and from workspace persistence                                                                                                    |

<Note>
  In a Docker workspace the live MCP client runs inside the gateway process and the host holds a proxy. Calling `set_runtime_headers()` on the proxy relays the update to the gateway — see [MCP Gateway](/versions/2.0.9dev/en/building-blocks/workspace/mcp-gateway).
</Note>

## Use MCP Tools Outside a Toolkit

If you need to invoke MCP tools outside a `Toolkit`, call `await client.list_tools()` to retrieve a list of `MCPTool` adapters and use them like any other `ToolBase` instance.
