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

# Connect to other MCP Servers in Python

> How to configure an Atoti session in Python to use the tools of other MCP Servers, with `AiConfig`, `McpClientConfig`, `StreamableHttpMcpServerConfig`, and `StdioMcpServerConfig` from `atoti_ai`, covering the server configuration parameters, invalid server names, and sharing a JWT key pair for `atoti-jwt`.

<Info>
  ### Atoti Intelligence SDK

  This is part of the Atoti Intelligence SDK offer.
</Info>

This guide explains how to connect an Atoti session started from Python to other Model Context
Protocol (MCP) servers, so that it uses their tools as its own. For what a connection then provides
(the authentication modes, identity propagation, remote tool naming, `getConnectedServers`, and
resilience), see [How connecting to other MCP Servers works](./how-it-works).

## Prerequisites

* An Atoti Python project
* A license including the Atoti Intelligence Extension tier, which itself requires Essentials

## How to install the package

```bash theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
uv add "atoti[ai]"
```

## How to declare a connection

Pass an `AiConfig` with an `mcp` attribute to [`SessionConfig`](https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.config.SessionConfig.html)
when starting the session. The `mcp` attribute takes a `McpClientConfig`, mapping the name the
session gives a server to that server's own configuration. Use `StreamableHttpMcpServerConfig` for a server
reached over Streamable HTTP, and `StdioMcpServerConfig` for one run as a local process.

Below, `pnl-server` is an Atoti Server reached over HTTP, authenticated with a token minted for the
calling user. `filesystem` is a local MCP Server started as a stdio process:

```python theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
import atoti as tt
from atoti_ai import (
    AiConfig,
    McpClientConfig,
    StdioMcpServerConfig,
    StreamableHttpMcpServerConfig,
)
mcp_config = McpClientConfig(
    servers={
        "filesystem": StdioMcpServerConfig(
            command="npx",
            args=["-y", "@modelcontextprotocol/server-filesystem", "/tmp"],
        ),
        "pnl-server": StreamableHttpMcpServerConfig(
            url="https://pnl.example.com",
            authentication="atoti-jwt",
        ),
    },
)
session_config = tt.SessionConfig(ai=AiConfig(mcp=mcp_config))
```

### `StreamableHttpMcpServerConfig` parameters

| Parameter        | Type                                           | Required | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| ---------------- | ---------------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `url`            | `str`                                          | Yes      | The address of the server, without the MCP endpoint. For example `"https://pnl.example.com"`.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `authentication` | `Literal["none", "atoti-jwt", "pass-through"]` | No       | How the session authenticates itself against the server. \* `"none"` sends no credential, for a server that is genuinely unauthenticated. \* `"atoti-jwt"` sends a JWT minted for the calling user, carrying their username and authorities, and requires the server to share this session's JWT signing key (see `JwtConfig`). .. warning:: Only choose this for servers operated by whoever operates this session. The token is handed to the server, which can then send it to any other server sharing the same signing key and be taken for the calling user there. \* `"pass-through"` forwards the calling user's own bearer token unchanged, for a server validating tokens against an external identity provider. |
| `endpoint`       | `str`                                          | No       | The path at which the server speaks the MCP protocol. Defaults to `"/mcp"`, which is the path Atoti Server serves it at.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |

See [Which authentication modes are available?](./how-it-works#which-authentication-modes-are-available)
for what each `authentication` value sends and when to choose it.

### `StdioMcpServerConfig` parameters

| Parameter | Type                      | Required | Description                                                                    |
| --------- | ------------------------- | -------- | ------------------------------------------------------------------------------ |
| `command` | `str`                     | Yes      | The executable to run, for example `"node"`.                                   |
| `args`    | `FrozenSequence[str]`     | No       | The arguments to pass to `command`.                                            |
| `env`     | `FrozenMapping[str, str]` | No       | The environment variables to give the process, on top of the ones it inherits. |

<Note>
  A server declared with `StdioMcpServerConfig` runs as a local process and identifies itself by being that process. It accepts no `authentication` parameter.
</Note>

## Which server names are invalid?

A server name cannot be empty and cannot contain a `.`, which would read as a separator between
configuration keys. Building the configuration refuses such a name. The name also prefixes every
tool taken from that server, after normalization. Two names normalizing to the same prefix make the
session refuse to start. See
[How are remote tools named?](./how-it-works#how-are-remote-tools-named) for the normalization rule
and the 64-character limit on tool names.

## Where do remote tools appear?

They are offered to the LLM in chat, alongside the session's own tools. They are also reported on
the session's own MCP endpoint at `f"{session.url}/mcp"`, per calling client. No LLM is required for
that: an LLM is only required for chat.

## How to authenticate with `atoti-jwt`

Both sessions must share a JWT signing key. From Python, pass the same
[`atoti.KeyPair`](https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti.KeyPair.html)
to both: `tt.SessionConfig(security=tt.SecurityConfig(jwt=tt.JwtConfig(key_pair=key_pair)))`. Against
a Java Atoti Server, that server's `atoti.jwt.key` property must match the same key pair; see
[Connect to other MCP Servers in Java](./setup-java#how-to-authenticate-with-atoti-jwt).

<Warning>
  Declaring a server states where it is, never that it belongs to this deployment. `atoti-jwt` mints a token accepted by every server sharing the deployment's signing key. Choose it only for servers under the same ownership.
</Warning>

## Related reading

* [How connecting to other MCP Servers works](./how-it-works) and [Connect to other MCP Servers in Java](./setup-java)
* [How to set up the Atoti MCP Server](../setup/atoti-mcp-server-setup) and [How to add custom tools](../custom-tools)
* [`atoti_ai.AiConfig`](https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti_ai.AiConfig.html), [`atoti_ai.McpClientConfig`](https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti_ai.McpClientConfig.html), [`atoti_ai.StreamableHttpMcpServerConfig`](https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti_ai.StreamableHttpMcpServerConfig.html), and [`atoti_ai.StdioMcpServerConfig`](https://docs.activeviam.com/products/atoti/python-sdk/latest/api/atoti_ai.StdioMcpServerConfig.html) API references
