Client Mode
Client mode is the mirror of server mode: instead of an outside assistant calling your data, your own agents call tools hosted elsewhere — web search, document fetch, whatever an external MCP server publishes.
Unlike server mode, this one requires AI_PROVIDER. Sovrium is the caller here, so a model has to run somewhere on your side to decide when a tool is worth invoking.
Declaring External Servers
The servers are operator configuration, not schema — a URL and a credential are deployment facts. MCP_CLIENT_SERVERS is a comma-separated list, and each entry's auth is configured by its 1-based position in that list:
MCP_CLIENT_SERVERS=https://search.example.com/mcp,https://docs.example.com/mcp
MCP_AUTH_TYPE_1=bearer
MCP_AUTH_TOKEN_1=sk-...
MCP_AUTH_TYPE_2=header
MCP_AUTH_HEADER_2=X-Api-Key
MCP_AUTH_TOKEN_2=...
| Variable | Values | Meaning |
|---|---|---|
MCP_CLIENT_SERVERS |
comma-separated URLs | The external servers. Unset means client mode is off. |
MCP_AUTH_TYPE_{N} |
bearer, header, none |
How to authenticate to server N. Defaults to none. |
MCP_AUTH_TOKEN_{N} |
string | The secret sent to server N. |
MCP_AUTH_HEADER_{N} |
header name | Which header carries it, when type is header. |
The index is positional, so reordering the list re-points your secrets. Inserting a server at the front of MCP_CLIENT_SERVERS shifts every subsequent _{N} suffix by one, silently sending server 1's token to a different origin. Append rather than insert, and re-check the numbering whenever the list changes.
Scoping an Agent
An agent's mcp block is an allowlist over the discovered tool catalog. It answers "which of these may this agent use", not "which servers exist".
agents:
- name: research-agent
role: analyst
systemPrompt: Research topics using approved external tools. Always cite sources.
tools:
tables: [findings]
actions: [record.create, record.read]
mcp:
allowedTools: [web-search]
| Property | Effect |
|---|---|
mcp.allowedTools |
External tool names this agent may invoke. Omitted means the whole catalog. |
Two allowlists are now in play and they do not overlap. tools scopes what the agent may do inside Sovrium — its tables and its actions. mcp.allowedTools scopes what it may reach outside. An agent can be read-only internally and still search the web, or the reverse.
An unrecognised tool name is dropped, not rejected. allowedTools is filtered against the discovered catalog, so a typo — web_search for web-search — silently yields an agent with no external tools rather than a validation error. Confirm the real names against /api/ai/mcp/client/tools before trusting an allowlist.
Inspecting What Is Available
Two read-only endpoints let you check the wiring without prompting a model. Both answer 404 with { "enabled": false } when MCP_CLIENT_SERVERS is unset, so "disabled" is distinguishable from "route missing".
curl https://your-app.example.com/api/ai/mcp/client/status
{
"enabled": true,
"servers": [
{ "url": "https://search.example.com/mcp", "authType": "bearer", "status": "connecting" }
]
}
Tokens are never echoed back — the summary carries the URL, the auth type, and the header name, and nothing secret.
curl https://your-app.example.com/api/ai/mcp/client/tools
The tool catalog seeds with web-search and document-fetch, and real tools/list discovery supersedes it once a configured server is reachable. Those seed names are what an allowedTools entry must match today.
Calling an Agent
POST /api/agents/{name}/chat forwards a message to the provider along with that agent's filtered tool catalog, and returns a { "reply": … } envelope. The runtime is deliberately tolerant: if an external server is unreachable or a tool call fails, the model still answers in text rather than the request erroring out. An agent that depends on a flaky server degrades to a worse answer, not to a 500.
Related Pages
- MCP Overview — server mode versus client mode.
- Agents Overview — the agents doing the calling.
- Tools — the internal allowlist this complements.
- AI Providers — the
AI_PROVIDERclient mode needs. - Server Mode — the opposite direction.
Last updated July 27, 2026
This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta — contributions and corrections are welcome.