# Base URL of the Keycloak server. Keycloak >= 17 (Quarkus) has NO /auth prefix. # A pasted admin-console URL is trimmed for you. Legacy (< 17) servers: keep the # prefix, e.g. https://kc.example.com/auth KEYCLOAK_URL=https://keycloak.example.com # Realm the tools operate on by default. Every tool takes an optional `realm` # argument to override it per call. KEYCLOAK_REALM=master # Realm to AUTHENTICATE against — where the service-account client or the admin # user actually lives. Defaults to KEYCLOAK_REALM. Set it to `master` when using # a master-realm admin to manage OTHER realms. KEYCLOAK_AUTH_REALM= # ── Auth: pick ONE grant ───────────────────────────────────────────────────── # # (A) client_credentials — RECOMMENDED. Used automatically when a secret is set. # Create a client in KEYCLOAK_AUTH_REALM with: # Client authentication: ON (i.e. confidential) # Service accounts roles: ON # Standard flow / Direct access grants: OFF (not needed) # Then give its service account the admin rights it needs: # Clients -> -> Service account roles -> Assign role # -> Filter by clients -> `realm-management` -> pick: # read-only: view-realm, view-users, view-clients, view-events, # view-identity-providers, query-users, query-clients, query-groups # + writes: manage-users, manage-clients, manage-realm, # manage-identity-providers, manage-events # or simply: realm-admin (the composite that contains all of them) # To manage OTHER realms from one client, put it in `master` and assign the # `admin` realm role instead. KEYCLOAK_CLIENT_ID=mcp-keycloak KEYCLOAK_CLIENT_SECRET= # (B) password grant — convenient for local testing against a server you already # have console credentials for. `admin-cli` is a PUBLIC client, so leave # KEYCLOAK_CLIENT_SECRET empty and set KEYCLOAK_CLIENT_ID=admin-cli. # Note this runs as a human admin, with everything that account can do. KEYCLOAK_USERNAME= KEYCLOAK_PASSWORD= # Force a grant explicitly (client_credentials | password). Otherwise it is # inferred: a client secret means client_credentials, a username+password means # the password grant. KEYCLOAK_GRANT_TYPE= # ── Safety ─────────────────────────────────────────────────────────────────── # Set to 1 to register the WRITE tools (create/update/delete/logout/reset-password). # Off by default: only read tools exist, and `keycloak_request` is GET-only. # Destructive tools (delete realm/user/group/client/role/IdP/flow, logout-all, # clear-events) additionally require an explicit `confirm: true` on every call. KEYCLOAK_ALLOW_WRITES= # ── Optional tuning ────────────────────────────────────────────────────────── # Retry budget for 401 / 429 / 5xx responses. Defaults to 3. KEYCLOAK_MAX_RETRIES=3 # Refresh the access token this many seconds before it expires. Defaults to 30. # Keycloak access tokens are SHORT (60s by default), so this is clamped to half # the token's actual lifetime and rarely needs changing. KEYCLOAK_REFRESH_SKEW_SECONDS=30 # Set to 1 to log debug output to stderr. KEYCLOAK_DEBUG=