Atoti Intelligence SDK
This is part of the Atoti Intelligence SDK offer.To follow along, first declare a connection: see
Connect to other MCP Servers in Java or
Connect to other MCP Servers in Python. Both assume the Atoti MCP Server is already
set up; see How to set up the Atoti MCP Server.Connecting to other MCP Servers requires the Atoti Intelligence Extension tier, which itself
requires Essentials, like the rest of Atoti’s MCP surface.
What does connecting to other MCP Servers provide?
- A chat user on one Atoti Server can query cubes hosted on another, without duplicating tool logic across servers
- Remote tools appear alongside local cube tools and custom tools, wherever tools are offered to the model
- The remote cube’s own role-based data restrictions stay in force for every remote call
- Remote tools are reported on this server’s own MCP endpoint too. One server therefore shows an external MCP client the tools of the whole deployment, each client told what its own credential can reach
Which authentication modes are available?
Each connection names its own mode, in its own declaration.atoti-jwt mints its token from the authenticated principal rather than replaying one, so it works
whichever way the calling user authenticated: Basic, JWT, OIDC, or LDAP. Both servers must share the
signing key; see Java or
Python.
pass-through replays either kind of token this server accepts (an Atoti JWT, or an OAuth 2 access
token). This brings two limits. A user who authenticated with Basic or form login presents no bearer
token, so the call carries no credential and is rejected. A replayed OAuth 2 token also keeps the
audience it was issued for, so the remote server accepts it only when configured to trust tokens
issued for this server.
A connection that runs the remote server as a local process, over standard input and output,
identifies itself by being that process, so it accepts no authentication mode at all.
Why does the calling user’s identity carry through?
Every mode derives the outgoing credential from the calling user’s security context, evaluated on the caller’s own thread at the moment of the call. A remote tool therefore always runs under the identity of whoever triggered it. This is what keeps the remote cube’s role-based data restrictions in force: a user denied a measure or a member on the remote server gains nothing by asking through chat. Listing a remote server’s tools is an authenticated call of the same kind. Its result is cached per calling identity (the username together with its authorities), rather than once for the whole server. A remote server that varies its tool list by role therefore never has one user’s list served to another.How are remote tools named?
Atoti names every remote tool<connection name>_<tool name>; the server’s own tools stay
unprefixed. The prefix matters because every Atoti Server exposes the same cube tools. Unprefixed, a
second connected server’s tools collide with the first one’s, and only the first occurrence of
a name survives. Each remote tool’s description also states which server it runs on.
The connection name is first normalized to the alphabet tool names may use: a hyphen becomes an
underscore, and anything else outside letters, digits and underscores is dropped. fo ficc/server:1
becomes foficcserver1, and the run_mdx_query tool of a pnl-server connection becomes
pnl_server_run_mdx_query.
Two rules follow from that alphabet, and from the 64-character limit most model providers impose on a
tool name:
- Two names differing only by dropped characters normalize to the same prefix, for example
pnl-serverandpnl_server. Atoti checks the prefixes at startup and refuses to start rather than silently drop a server’s tools. The same check catches one name declared twice. Each transport has its own set of connections, and names are not compared across transports. - When a prefixed name exceeds 64 characters, the prefix is kept whole and the tool’s own name is shortened. A short hash is appended so two shortened names never collapse into one. A connection name of no more than 53 characters always keeps its prefix. Past that, the prefix is shortened instead, and
getConnectedServersthen reports notoolPrefixfor that connection rather than one its tools do not carry.
What does the getConnectedServers chat tool do?
A deployment of several connected servers gives the model tools from several cubes, and nothing in
those tools says which server each one reaches. getConnectedServers closes that gap: it lists the
server the chat runs on, then every connected server, whichever transport declares it. The model
calls it to name the servers available, to attribute an answer to one of them, or to check that one
is up.
It requires the Atoti Intelligence Extension tier, like the rest of this page, and can be withheld;
see Connect to other MCP Servers in Java.
What does the tool report?
The example below comes from a server namedfo-ficc-server, declaring the connections pnl-server
and sandbox, with sandbox down:
An entry describes a server; it is not a way to call one. The model reaches a connected server
through that server’s own prefixed tools, never through the reported URL.
The server running the chat always comes first, marked
current: true, and is the only entry
with no toolPrefix. This is what tells the model that its unprefixed tools are this server’s own.
A server that declares no connection still reports itself, so a question about the available servers
never gets an empty answer. Its url is the address the asking client used, up to and including the
context path, read from the request being served rather than from configuration. Two clients of one
server, one direct and one through an ingress, are therefore each told the address they used. Behind
a reverse proxy the server has to be told to trust the forwarded headers, or the reported address is
the proxy’s back-end hop; see
Connect to other MCP Servers in Java.
A connected server is reported with the URL its connection was declared with, whole and
unchanged, with no MCP endpoint appended: url: https://pnl.example.com is reported as
https://pnl.example.com, not https://pnl.example.com/mcp. What the report shows is the address a
person recognizes the server by, and can open.
Reachability is established per call and per user. The tool pings every connected server with the
calling user’s own credential, exactly as a remote tool call does, so a server is reported
reachable: false when it is down, when it rejects that credential, or when the user has no access
to it. Such an entry keeps its name and its URL, so the model can say which server is unavailable.
The pings run concurrently and the whole sweep is bounded to ten seconds, so an unreachable server
costs a chat turn a bounded wait rather than its transport’s full request timeout.
How do remote tools appear on this server’s own MCP endpoint?
On their own, alongside the local cube tools, for every client that connects. There is nothing to enable and no identity to configure. No LLM is required either: an LLM is only required for chat. Each client is told the tools its own credential can reach. An MCP client authenticates to this server first (an unauthenticated request is answered with a401 that starts the OAuth 2.1 flow),
so by the time it asks for tools there is a real user to ask on behalf of. Two clients logged in as
different users are therefore told different things. Calling a remote tool through this endpoint runs
it as the calling user, exactly as from chat.
How resilient is a connection to an unreachable remote server?
An unreachable remote server costs only its own tools. Atoti lists every connected server separately, so one that is down or that rejects the credential it received leaves the other servers’ tools untouched. The failure is not cached: that server is retried on the next request, and its tools reappear as soon as it answers. An unreachable peer never stops this server from starting, and never keeps its MCP endpoint from answering.Related reading
- Connect to other MCP Servers in Java and in Python
- Migration notes for the Spring AI MCP client defaults this capability changes
- What is the Atoti MCP Server? and How to add custom tools