Skip to main content
View as Markdown

Connecting a Client

Once MCP_ENABLED=true the app serves one JSON-RPC endpoint at MCP_MOUNT_PATHhttps://your-app.example.com/mcp unless you moved it. Any MCP-capable client can speak to it.

The Generic Configuration

Claude Desktop, Claude Code, Cursor and ChatGPT Dev Mode all read some form of an mcpServers block:

app.json
{
  "mcpServers": {
    "sovrium": {
      "url": "https://your-app.example.com/mcp",
      "transport": "http"
    }
  }
}

Where that block lives differs per client — a settings file, a project config, a UI panel — but the two values it needs are always the same: the URL and the transport.

Authenticating

There is no mode to pick. The header you send decides which verifier runs, and both are live at once. See Auth, RBAC & Rate Limiting for what each grants.

API key. The simplest option for a script or a CI job. Sign in as the user whose role the client should inherit, mint a key, and send it on x-api-key. The key acts as its owner, so demoting or banning that user takes effect on the next call without re-issuing anything.

code
x-api-key: <your-api-key>

OAuth. For a client that can run a browser sign-in. Register it once by dynamic client registration and then run the ordinary authorization-code flow. Registration needs a session — run it signed in as an admin, with your login cookie in $SOVRIUM_SESSION:

>_ terminal
curl -X POST 'https://your-app.example.com/api/auth/oauth2/register' \
  --header 'Content-Type: application/json' \
  --cookie "$SOVRIUM_SESSION" \
  --data '{
    "client_name": "Sovrium MCP — Claude",
    "redirect_uris": ["https://your-app.example.com/oauth/callback"],
    "grant_types": ["authorization_code", "refresh_token"],
    "token_endpoint_auth_method": "client_secret_post"
  }'

A call to the MCP endpoint without a credential answers 401 with a WWW-Authenticate: Bearer discovery header, so a compliant client can start the flow without being told how.

Local IDE over stdio

For a local integration there is no HTTP at all. Set MCP_TRANSPORT=stdio and the client launches the Sovrium binary as a child process, speaking MCP over stdin and stdout.

app.json
{
  "mcpServers": {
    "sovrium": {
      "command": "sovrium",
      "args": ["start", "./app.ts"],
      "env": { "MCP_ENABLED": "true", "MCP_TRANSPORT": "stdio" }
    }
  }
}

The /mcp HTTP route is not mounted in this mode. They are alternatives, not layers — pick one per process.

Verifying the Connection

Do not trust the client's green dot. The smallest useful check is tools/list:

>_ terminal
curl -X POST 'https://your-app.example.com/mcp' \
  --header 'x-api-key: <your-api-key>' \
  --header 'Content-Type: application/json' \
  --data '{ "jsonrpc": "2.0", "id": 1, "method": "tools/list" }'

The response lists exactly the tools your credential can call — the tables, actions and automations you marked with aiAccess, filtered by the role behind the credential.

That last clause is what makes this worth running. Run it with a key owned by an admin and one owned by a viewer in turn: two different lists is the proof that role filtering is live. One identical list means something is wrong with your credentials, not with your schema.

Last updated September 1, 2026

This documentation was written with AI, so errors or outdated content are possible. Sovrium is in beta. Contributions and corrections are welcome.

Built with Sovrium