MCP Integration
The Model Context Protocol (MCP) is an open standard for connecting AI assistants to tools and data. Sovrium speaks MCP in both directions:
- Server mode — external AI clients (Claude Desktop, Claude Code, ChatGPT Dev Mode, Cursor) connect to Sovrium and call generated tools: table CRUD, manual-automation invocation, and action-template execution.
- Client mode — Sovrium agents call tools hosted on external MCP servers (web search, document fetch, code execution) as part of their workflows.
The two modes are configured independently and serve opposite roles.
| Mode | Controlled by | Where | LLM required on Sovrium? |
|---|---|---|---|
| Server | Operator (env) | MCP_ENABLED, MCP_TRANSPORT, … |
No — the LLM lives at the connecting client |
| Client | Schema author | An agent's mcp.allowedTools block |
Yes — AI_PROVIDER set |
Server mode needs no AI_PROVIDER. When Sovrium is the MCP server, the LLM runs at the connecting client. The platform only exposes tools; it does not call a model. AI_PROVIDER is only required for client mode (and the rest of the AI layer).
Server Mode
Enablement
The MCP server is disabled by default. The operator opts in via env vars; the server only mounts the /mcp route when MCP_ENABLED=true.
| Variable | Description | Default |
|---|---|---|
MCP_ENABLED |
Master switch — mounts the MCP route only when true. |
false |
MCP_TRANSPORT |
streamable-http for remote clients, stdio for local IDE integration. |
streamable-http |
MCP_MOUNT_PATH |
Route prefix when transport is streamable-http. |
/mcp |
MCP_AUTH_STRATEGY |
oauth2 (when app.auth is configured) or token. |
oauth2 when auth wired |
MCP_TOKEN_ADMIN |
Bearer token granting the admin role (≥32 chars; openssl rand -hex 32). |
— |
MCP_TOKEN_MEMBER |
Bearer token granting the member role (≥32 chars). | — |
MCP_TOKEN_VIEWER |
Bearer token granting the viewer role (≥32 chars). | — |
MCP_RATE_LIMIT_PER_MINUTE |
Per-token requests per minute. | 60 |
MCP_RATE_LIMIT_PER_DAY |
Per-token requests per day. | 5000 |
MCP_AUDIT_ENABLED |
Log every tool call to system.ai_tool_calls + the activity stream. |
true |
MCP_EXPOSE_INTERNALS |
Expose read-only auth/system tables to the admin role. | true |
MCP_CONFIRM_DESTRUCTIVE |
Compile destructiveHint=true onto delete tools and non-idempotent automations. |
true |
MCP_ENABLED=true
MCP_TRANSPORT=streamable-http
MCP_AUTH_STRATEGY=token
MCP_TOKEN_ADMIN=$(openssl rand -hex 32)
MCP_TOKEN_VIEWER=$(openssl rand -hex 32)
Exposed Surfaces
When mounted, the server generates tools from four surfaces — all gated by RBAC and aiAccess:
/mcp ─── tools/list ───▶ filtered by connecting role
│
┌────────┴───────────────────────────────────┐
│ 1. User tables {app}_{table}_{op} │ CRUD
│ 2. Manual automations {app}_automation_{name}│ invocation
│ 3. Action templates {app}_action_{name} │ execution
│ 4. Admin internals {app}_auth_*_read/_list │ read-only, denylisted secrets
└─────────────────────────────────────────────┘
│
Audit → system.ai_tool_calls Rate-limit → per token / OAuth client_id
Declaring AI-Eligible Entities
A schema author marks an entity eligible for MCP exposure with aiAccess. This declares intent; the operator still has to enable the server with MCP_ENABLED. aiAccess applies identically to app.tables[], manual-trigger app.automations[], and app.actions[].
It takes two forms — a boolean shorthand or a rich config object:
# Boolean shorthand — enable with defaults.
tables:
- name: contacts
aiAccess: true
# Rich config — supplying any object IS the enable signal (no `enabled` field).
tables:
- name: contacts
aiAccess:
description: Customer contacts. Use this when the user asks about people.
operations: [read, list, create, update]
fieldExposure: permissioned
annotations:
readOnly: false
destructive: false
| Property | Description |
|---|---|
description |
Hand-written tool description shown to the AI client — the biggest lever for steering AI behavior. |
operations |
Subset of read, list, create, update, delete to expose (tables default to all five). |
fieldExposure |
permissioned (default — only fields the role can read/write), all, or whitelist. |
whitelistFields |
Fields to expose when fieldExposure: whitelist (required and non-empty in that mode). |
annotations |
MCP risk hints — see below. |
requireConfirmation |
Force destructiveHint=true regardless of operation type (e.g. for email-sending automations). |
Tool Risk Annotations
Annotations compile into MCP tool definitions so clients can decide whether to auto-approve a call or require confirmation. They map directly to the MCP spec:
| Annotation | MCP hint | Meaning |
|---|---|---|
readOnly |
readOnlyHint |
Tool only reads data; safe to auto-approve. |
destructive |
destructiveHint |
Performs destructive operations; clients should require confirmation. |
idempotent |
idempotentHint |
Calling twice with the same args is safe (no duplicate side effects). |
openWorld |
openWorldHint |
Reaches outside the local app (external API, network call). |
Sensible defaults are derived from the operation type when annotations are unset.
Authentication
| Strategy | When | How |
|---|---|---|
token |
Default when app.auth is absent |
Static per-role bearer tokens (MCP_TOKEN_ADMIN/MEMBER/VIEWER). At least one must be set. |
oauth2 |
Default when app.auth is wired |
OAuth 2.1 against Better Auth's OAuth-server plugin. |
The connecting credential's role drives RBAC: a viewer token can only read/list even when an entity's aiAccess.operations allows writes. Startup validation rejects MCP_AUTH_STRATEGY=token with no token set, and oauth2 when app.auth is not configured.
RBAC, Audit & Rate Limiting
- RBAC — MCP clients are governed by the same role permissions and row-level rules as human sessions. There is no AI bypass.
- Audit — every tool call is logged to
system.ai_tool_callsand the activity stream whenMCP_AUDIT_ENABLEDistrue(the default). - Rate limiting — enforced per token (or OAuth
client_id); over-limit requests return429with standard rate-limit headers.
Admin Internals
When MCP_EXPOSE_INTERNALS=true (the default), the admin role gets read-only tools over the auth and system schema tables ({app}_auth_*_read/_list, {app}_system_*_read/_list), with secret columns denylisted. Set it to false to remove all internal tools from tools/list, even for admins.
Client Mode
Sovrium agents can consume tools from external MCP servers. An agent's mcp block defines the allowlist of external tool names it may invoke.
agents:
- name: research-agent
role: analyst
systemPrompt: Research topics using approved external tools.
mcp:
allowedTools: [web_search, fetch_url]
| Property | Description |
|---|---|
mcp.allowedTools |
External MCP tool names the agent is allowed to use. |
This complements the agent's internal tools allowlist: tools scopes what the agent can do inside Sovrium, while mcp.allowedTools scopes which external MCP tools it may call.
Related Pages
- AI Overview — the full AI ecosystem and config philosophy.
- AI Agents — agents that act as MCP clients.
- Tables Overview — the
aiAccesstable property. - Actions — action templates exposed as MCP tools.
- Roles & RBAC — the permissions MCP always enforces.
- Environment Variables — full
MCP_*reference.