Before you start
What your deployment and your account each need first.
Two separate things have to be true before a client can call a tool. One is a deployment question and one is an account question. They fail differently, so check them separately.
What the deployment needs
-
MCP switched on.
MCP_ENABLEDdefaults to false. While it is false there is no/mcproute at all, and a client gets a plain 404 rather than an authentication error. Source:services/runtime/src/runtime/config.py:522andservices/runtime/src/runtime/main.py:254-261. -
All four settings present.
KEYCLOAK_ISSUER,MCP_PUBLIC_BASE_URL,KEYCLOAK_MCP_RESOURCE_AUDIENCEandKEYCLOAK_MCP_REQUIRED_SCOPE. Enabling MCP with any of them empty makes the process refuse to start. It does not run in a degraded state. Source:services/runtime/src/runtime/config.py:561-580. -
The realm side configured. A public client using PKCE, and a client scope the MCP client can request. This lives in Keycloak, outside this repository. See Operator setup.
-
A reachable host.
MCP_PUBLIC_BASE_URLis what the discovery documents publish as this resource's own URL, so it has to be the address clients actually dial. Source:services/runtime/src/runtime/config.py:553-559andservices/runtime/src/runtime/mcp/well_known.py:35-40.
Nothing is deployed today
No public MCP host exists yet, so point 4 is currently unsatisfied everywhere.
What your account needs
-
An account the realm can sign in. The tools accept a bearer token issued by the configured issuer, and the identity in it is resolved to a helpdesk user before any tool runs. Source:
services/runtime/src/runtime/mcp/verifier.py:120-139. -
Membership of at least one workspace. An authenticated account with no membership is refused, with its own reason, and no tool can run. Source:
services/runtime/src/runtime/auth/workspaces.py:228-233. -
The right role in that workspace. Reading needs viewer. Writing needs editor. These are the same floors the equivalent HTTP routes apply. Source:
services/runtime/src/runtime/api/authz.py:131-132. -
MCP access not revoked in that workspace. An admin can cut off one member's MCP access in one workspace without touching anything else they do. See Workspace access. Source:
services/runtime/src/runtime/auth/mcp_access.py:67-91.
Which workspace a call acts in
Every tool takes an optional workspace_id.
- Belong to exactly one workspace: leave it out, and that one is used.
- Belong to several: name one, or the call is refused and asks you to.
- Name one you are not a member of: refused as not found, the same answer as a workspace that does not exist. The server does not confirm whether it exists.
Source: services/runtime/src/runtime/auth/workspaces.py:164-197 and
services/runtime/src/runtime/mcp/tools.py:132-166.