Keycloak Realm Inspector
Provides tools for inspecting a Keycloak realm: identifying the calling token's user and client, listing realm clients, and retrieving Keycloak's derived metadata for a client.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Keycloak Realm Inspectorwhat are the claims in my access token?"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Keycloak Realm Inspector
An MCP server that is purely an OAuth 2.0 protected resource, for a KeyConf 2026
talk on Client ID Metadata Documents
(draft-ietf-oauth-client-id-metadata-document-02).
It issues nothing — no /authorize, no /token, no client secret. Keycloak
issues tokens; this server validates them against Keycloak's JWKS, serves RFC
9728 discovery, and exposes three tools that make CIMD visible from inside the
resource server.
Three parties, deliberately kept apart
Keycloak | the authorization server. |
The MCP client | publishes its metadata document at a URL it controls. That URL is its |
This server | the protected resource. Port 9001 |
This server does not host, read or fetch the client's metadata document.
There is no /client-metadata.json route and no local copy. Keycloak fetches
that URL over the network during /authorize. In this codebase the URL only
ever appears as an opaque string arriving in the azp claim — which is the
entire point of the demo, and why the document is served by a separate process
on a separate port.
Related MCP server: Akeyless MCP Interop (OpenID AIIM)
Run
Keycloak is assumed to be up, with the realm created and the CIMD client policy
already applied. The client, its metadata document and the token helper live
alongside this repo in ../cimd-demo/auth-server/.
# terminal 1 — the client's document. Its own party, its own port.
cd ../cimd-demo/auth-server && python -m http.server 9000
# terminal 2 — the resource server
pip install -r requirements.txt
python server.py # http://localhost:9001
# terminal 3 — get a token, then point an MCP client at :9001/mcp
cd ../cimd-demo/auth-server && python get-token.pyThe flow
Client calls
/mcpwith no token, gets 401 withWWW-Authenticate: Bearer ..., resource_metadata="…".Client follows that to
/.well-known/oauth-protected-resource/mcpand learns which authorization server issues valid tokens.Client authenticates against Keycloak directly, using its metadata document URL as
client_id. Keycloak fetches that URL and materialises the client.Client retries
/mcpwith the bearer token.
RFC 9728 §3.1 puts the well-known segment between host and resource path, so
the discovery document lives at /.well-known/oauth-protected-resource/mcp. The
bare path is a 404.
Tools
whoami()—sub,preferred_username,azp,scope,exp,issfrom the caller's token, plusregistered_via_cimd. Reads the token only; no Keycloak call, so it works even if the admin credentials are wrong.list_clients(only_cimd=False)— realm clients, URL-shapedclient_ids sorted to the top so the calling client lands on the first line.get_client_metadata(client_id)— Keycloak's own representation of a client. This is Keycloak's derived view, not the published document.
CIMD is detected by client_id starting with http:// or https://. A
URL-shaped client_id is the tell.
get_client_metadata strips secret and registrationAccessToken before
returning. Both are live bearer credentials, and this output goes on a projector
and into a recording.
Two known gaps
RFC 8707 resource indicators. audience= is present but commented out on
JWTVerifier. Audience-restricting the token would require the client to send
resource on /authorize, and Keycloak 26.7's CIMD path does not honour it yet
(keycloak#45106, keycloak#45284). So the token carries Keycloak's usual
account audience and this server cannot audience-restrict. Visible on purpose.
No scope enforcement. required_scopes is unset, so any signature-valid,
unexpired token from the realm is accepted — including one from an admin-cli
password grant. That is useful on stage: run whoami() with an admin token
(azp is an opaque string) and again with the CIMD token (azp is a URL), same
tool, same server, the difference in one field. It also means you must be
certain which token you are holding.
Configuration
All os.getenv with localhost defaults.
Variable | Default |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
KEYCLOAK_ISSUER and KEYCLOAK_JWKS_URI are separately configurable rather
than derived from each other: in Kubernetes the issuer is the public URL, so
iss matches what clients see, while the JWKS fetch should go to the in-cluster
Service.
fastmcp is pinned exactly. The auth surface moves — resource_server_url
became base_url, AccessToken.claims arrived in 2.11.3 — and
allowed_client_redirect_uris is not a RemoteAuthProvider parameter in any
release, despite what the docs show. It belongs to OAuthProxy, which this
server does not use.
This server cannot be deployed
Maintenance
Related MCP Connectors
- SkycloakOAuthio.skycloak
Managed Keycloak from any MCP client: clusters, realms, apps, SSO, users, domains, audit events.
Remote MCP for A2A caller identity, scope policy, verdict receipts, and audit history.
Governed MCP gateway: one endpoint for your tools, with credential custody and audit log.
OAuth scope approvals and consent receipts for remote MCP servers.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceDemonstrates MCP remote authentication boundary with OAuth 2.0, Keycloak token introspection, audience and scope validation, and protected tools.-
- AlicenseNot gradedqualityCmaintenanceImplements an MCP server with OAuth 2.1 Protected Resource Metadata, enabling token-based authentication for MCP tools like ping.MIT
- AlicenseAqualityAmaintenanceEnables MCP-capable clients to inspect and manage Keycloak realms, users, clients, roles, and groups with layered security modes, realm allowlisting, protected realms, delete gating, dry-run, and audit logging.845 npm1MIT
- FlicenseBqualityBmaintenanceEnables MCP clients to authenticate through OIDC and call protected tools while rejecting unauthenticated requests.26-