{
...
"aud": "https://example.com/mcp",
"scope": "mcp:resources mcp:tools mcp:prompts"
...
}
There are currently four versions of the Model Context Protocol (MCP) specification:
2025-11-25 (latest version)
2025-06-18
2025-03-26
2024-11-05 (initial version)
The initial version (2024-11-05) does not cover authorization, as such is not covered in this guide.
This guide shows you the following:
Which MCP version Keycloak supports.
How to set up Keycloak as an authorization server in MCP.
However, the guide does not cover everything you need to know. Therefore, you are recommended to read the authorization section of the relevant MCP version as well.
According to the MCP specification, there are several standards regarding an authorization server in MCP. The following table shows:
Which MCP version requires an authorization server to support which standards in which level (MUST, SHOULD, MAY).
With which standards Keycloak complies.
| Standard | 2025-11-25 | 2025-06-18 | 2025-03-26 | Keycloak |
|---|---|---|---|---|
MUST |
MUST |
MUST |
Supported |
|
MUST |
MUST |
MUST |
Supported |
|
MUST |
MUST |
- |
Not supported |
|
MAY |
SHOULD |
SHOULD |
Supported |
|
SHOULD |
- |
- |
Not supported |
The MCP specification adopts OAuth 2.0 Protected Resource Metadata (RFC 9728). The standard is for an MCP server and not for an authorization server like Keycloak. Therefore, it is not included in the above table.
In this guide, as criteria for compliance, "Keycloak supports MCP" means that Keycloak meets all MUST and SHOULD requirements by MCP.
According to these criteria, the following table shows which MCP version Keycloak supports.
| MCP Version | Conformance |
|---|---|
Supported |
|
Partially Supported without Resource Indicators for OAuth 2.0 |
|
Partially Supported without Resource Indicators for OAuth 2.0 and OAuth Client ID Metadata Document |
To gain security benefit, the MCP specification requires an access token to be bound with its audience. In order to do so, the MCP specification requires the following:
An MCP client MUST include the resource parameter defined in Resource Indicators for OAuth 2.0 (RFC 8707) in an authorization request and token request. The parameter’s value MUST identify an MCP server that the MCP client intends to use the token with.
An MCP server MUST validate that tokens presented to them were specifically issued for their use.
The MCP specification does not describe how to do this binding. One method for the binding is to set a value of resource parameter to an aud claim in an access token. However, Keycloak cannot recognize resource parameter.
The Keycloak community is planning to support Resource Indicators for OAuth 2.0 (RFC 8707) to Keycloak to make Keycloak recognize and process the resource parameter as the MCP specification expects. Until this support is completed, you can use OAuth 2.0’s scope parameter instead of the resource parameter. To show the binding, please consider the following situation:
An MCP server’s URL is https://example.com/mcp
The MCP supports the following three scopes: mcp:tools, mcp:prompts and mcp:resources.
To get an access token for accessing the MCP server, an MCP client sends to Keycloak an authorization request whose resource parameter value is https://example.com/mcp and scope parameter includes any combination of the three scopes.
We want Keycloak to issue an access token whose aud claim’s value is MCP server’s URL, namely https://example.com/mcp.
To make Keycloak issue such the access token, we could configure Keycloak as follows:
Add a client scope mcp:tools whose type is Optional.
Add to the client scope a new Audience mapper whose Included Custom Audience field is https://example.com/mcp.
Add a client scope mcp:prompts whose type is Optional.
Add to the client scope a new Audience mapper whose Included Custom Audience field is https://example.com/mcp.
Add a client scope mcp:resources whose type is Optional.
Add to the client scope a new Audience mapper whose Included Custom Audience field is https://example.com/mcp.
Please not that the client scope’s Included Custom Audience field needs to be the same as the authorization request’s resource parameter value and the MCP server’s URL.
With the configuration, if the MCP client send to Keycloak an authorization request whose resource parameter value is https://example.com/mcp and scope parameter includes mcp:resources, mcp:tools and mcp:prompts, Keycloak can issue the following access token:
{
...
"aud": "https://example.com/mcp",
"scope": "mcp:resources mcp:tools mcp:prompts"
...
}
If you want to use MCP Inspector, an official debugging tools for MCP server, with Keycloak as an authorization server, you need to do an appropriate setup regarding CORS on Keycloak’s' client registration endpoint because MCP Inspector executes JavaScript downloaded from the MCP Inspector’s backend server to register an MCP client dynamically to Keycloak.
You need to do an appropriate setup for Client Registration’s anonymous access policies as follows:
Allowed Client Scopes: Needs to include scopes supported by an MCP server.
Allowed Registration Web Origins: Needs to include web origin of MCP inspector’s backend server.
Trusted Hosts: Needs to include hostname or IP address of the machine that sends a dynamic client registration request to Keycloak, namely the machine your browser runs on.
According to Client Registration Approaches section of the MCP specification, the following three client registration mechanisms are supported and you can choose based on your scenario:
Client ID Metadata Documents: When client and server have no prior relationship (most common)
Pre-registration: When client and server have an existing relationship
Dynamic Client Registration: For backwards compatibility or specific requirements
The Keycloak community is planning to support OAuth Client ID Metadata Document in the future. Until the support is completed, Keycloak can still accommodate an MCP client by pre-registration or Dynamic Client Registration.