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

> How to declare an outbound MCP connection in an Atoti Java application through `spring.ai.mcp.client` — the accepted keys, the supported transports, sharing the `atoti.jwt.key` signing key, and the Spring properties and beans that name the server, replace the tool naming scheme, or withhold `getConnectedServers`.

<Info>
  ### Atoti Intelligence SDK

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

This guide explains how to connect an Atoti Java application to the Model Context Protocol (MCP)
servers of other Atoti Server instances, 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 Java project with the Atoti MCP Server already set up; see [How to set up the Atoti MCP Server](../setup/atoti-mcp-server-setup)
* A license including the Atoti Intelligence Extension tier, which itself requires Essentials

## How to declare a connection

Declare a connection under `spring.ai.mcp.client.streamable-http.connections.<name>`. Everything
about it goes on that one node. `url` and `endpoint` are Spring AI's own properties, documented in
the [Spring AI MCP Client Boot Starter reference](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html).
`authentication` is Atoti's own property.

Below, `pnl-server` is a peer Atoti Server in the same deployment, authenticating with a token minted
for the calling user. `sandbox` is an unsecured local server used during development: it names no
authentication mode, so it sends no credential.

```yaml theme={"languages":{"custom":["/engine/python-sdk/6.2/languages/pycon.tmLanguage.json"]}}
spring:
  ai:
    mcp:
      client:
        streamable-http:
          connections:
            pnl-server:
              url: https://pnl.example.com
              authentication: atoti-jwt
            sandbox:
              url: http://localhost:9090
```

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.

<Note>
  A connection accepts `url`, `authentication`, and `endpoint`, and nothing else. Any other key is flagged by the IDE as it is typed, and refused at startup with the connection and the offending key named. A misspelled `authentication` would otherwise bind to nothing, leaving the connection silently on `none`. On the wire, that looks exactly like a remote server refusing a correct credential.

  `authentication` belongs to the HTTP transports only. A connection declared under `spring.ai.mcp.client.stdio.connections` runs a local process and identifies itself by being that process. Writing `authentication` on one is refused at startup rather than ignored.
</Note>

<Warning>
  Streamable HTTP is the only transport Atoti supports for an outbound connection. The server-sent events transport is deprecated for removal in Spring AI 2.0.0. Declare every connection under `spring.ai.mcp.client.streamable-http.connections`. Set no `spring.ai.mcp.server.protocol` on the servers being connected to, which leaves them on Streamable HTTP.

  A connection declared under `spring.ai.mcp.client.sse.connections` is reported at startup as unsupported and gets none of the documented behavior. Its calls carry no credential whatever `authentication` says, and it is absent from `getConnectedServers`. Spring AI still builds a client for it, so nothing else says anything is wrong.
</Warning>

## How to authenticate with `atoti-jwt`

An `atoti-jwt` connection mints a token accepted by every server sharing the deployment's signing
key. Both servers must be configured with the same `atoti.jwt.key`. Against a session started from
the Atoti Python SDK, the same key pair must be passed to that session; see
[Connect to other MCP Servers in Python](./setup-python#how-to-authenticate-with-atoti-jwt).

<Warning>
  Declaring a connection states where a server is, never that it belongs to this deployment. Choose `atoti-jwt` only for servers under the same ownership.
</Warning>

## Which other properties and beans matter?

| To                                                                                 | Use                                                                                                                                                                                                                                                                                                                                    |
| ---------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Name the server running the chat                                                   | `spring.ai.mcp.server.name`, `spring.ai.mcp.server.version`, and `spring.ai.mcp.server.instructions`, which fill the `server`, `version`, and `instructions` fields of its `getConnectedServers` entry.                                                                                                                                |
| Report the right address behind a proxy                                            | `server.forward-headers-strategy`, set to `framework` or `native`. Spring trusts `X-Forwarded-*` headers only when that property tells it to, so without it the reported address is the proxy's back-end hop. `server.address` and `server.port` are not used: they name the interface the server bound, which no client can be given. |
| Replace the [remote tool naming scheme](./how-it-works#how-are-remote-tools-named) | An `McpToolNamePrefixGenerator` bean.                                                                                                                                                                                                                                                                                                  |
| Withhold `getConnectedServers` from an application that holds the Extension tier   | Exclude the `connectedServersTools` bean.                                                                                                                                                                                                                                                                                              |

<Note>
  Two properties are deliberately not needed. Spring AI's own `spring.ai.mcp.server.expose-mcp-client-tools` is a different mechanism: it publishes one fixed tool list assembled while the application starts, before any user has authenticated. It would therefore need a service account to enumerate the peers, and would then show every client that one account's list. Leave it unset.

  Remote tools are reported on this server's MCP endpoint over Streamable HTTP, the default. An application that switches its endpoint to the deprecated SSE transport with `spring.ai.mcp.server.protocol=SSE` keeps a working endpoint and its own tools, but not the remote ones.

  A chat run that carries no address reports its entry with no `url` rather than with an invented one. This happens only when the `chatExecutor` bean is replaced with one that does not propagate the address.
</Note>

## Related reading

* [How connecting to other MCP Servers works](./how-it-works) and [Connect to other MCP Servers in Python](./setup-python)
* [Migration notes](../../../releases-and-upgrades/migration-notes#spring-ai-mcp-client-defaults) for the Spring AI MCP client defaults this capability changes
* [Spring AI MCP Client Boot Starter reference](https://docs.spring.io/spring-ai/reference/api/mcp/mcp-client-boot-starter-docs.html) for the client properties Atoti builds on
* [How to set up the Atoti MCP Server](../setup/atoti-mcp-server-setup) and [How to add custom tools](../custom-tools)
