Securing MCP Servers with Keycloak DCR

George Thomas George Thomas 5 min read

Introduction

In a previous article, I demonstrated how to secure an MCP Server using Keycloak with a pre-registered OIDC client. While that approach works well for known clients, it becomes less practical when dealing with anonymous AI agents that cannot be pre-registered in advance.

OIDC clients can be established using several approaches:

  • Pre-registered clients
  • OAuth Client ID Metadata Documents (OAuth CIMD)
  • Dynamic Client Registration (DCR)

For anonymous AI agents, pre-registration is often not feasible. An emerging recommendation is to use OAuth Client ID Metadata Documents (OAuth CIMD), where client metadata is retrieved from a published metadata URL instead of requiring manual client registration. As of Keycloak 26.6.1, OAuth CIMD is available as a preview feature.

In this article, we will explore Dynamic Client Registration (DCR), allowing MCP clients to dynamically register themselves with Keycloak and obtain the credentials required to interact with a secured MCP Server.

Overview

The environment used in this article consists of the following components:

  • Keycloak as the Authorization Server
  • An OIDC client in Keycloak used by the MCP Server for token introspection
  • MCP Server
  • MCP Client

In the MCP ecosystem, the AI application (such as Visual Studio Code) acts as the MCP Client, while the tool provider exposes functionality through an MCP Server. The MCP Client obtains tokens and invokes tools exposed by the MCP Server.

For this demonstration, we use Visual Studio Code as the MCP Client. Visual Studio Code supports both Dynamic Client Registration (DCR) and OAuth Client ID Metadata Documents (OAuth CIMD). Since OAuth CIMD is still a preview feature in Keycloak 26.6.1 and is disabled by default, we will use DCR in this article.

By default, Keycloak requires a valid access token to perform Dynamic Client Registration (DCR). Anonymous client registrations are blocked unless appropriate Client Registration policies are configured. Therefore, we must configure the Client Registration settings to allow DCR requests from trusted hosts.

Implementation Steps

Keycloak as Authorization Server

For testing purposes, I created a Keycloak instance using Docker.

A realm named acme is used throughout this article.

Create an OIDC client for the MCP Server

In this example, the MCP Server validates incoming access tokens using Keycloak’s Token Introspection endpoint.

Navigate to:

Clients → Create Client

Create a client with the following settings:

  • Client ID: mcp-server (or a name of your choice)
  • Client Authentication: Enabled
  • Access Type: Confidential

Complete the client creation process.

Make a note of the following values, as they will be required later when configuring the MCP Server:

  • Realm Name
  • Client ID
  • Client Secret

Configure scope and audience

The access token sent by the MCP Client to the MCP Server should contain the appropriate scope and audience.

Navigate to:

Keycloak Console → Client Scopes → Create Client Scope

Create a scope with the following configuration:

  • Name: mcp:tools
  • Include in Token Scope: ON

For simplicity, I marked this scope as a Default Client Scope.

Next, select the newly created scope and navigate to:

Mappers → Configure a New Mapper → Audience

Specify:

Configure Trusted Hosts for Dynamic Client Registration

By default, anonymous Dynamic Client Registration requests are not allowed.

Navigate to:

Clients → Client Registration → Trusted Hosts

Since Visual Studio Code will perform Dynamic Client Registration, we must add the appropriate trusted hosts.

For local testing, I configured the following values:

MCP Server

For testing, I used a sample TypeScript-based MCP Server implementation.

Before running the MCP Server, create a .env file with the following configuration

# Server host/port
HOST=localhost
PORT=3000

# Auth server location
AUTH_HOST=localhost
AUTH_PORT=8080
AUTH_REALM=<YOUR_REALM_NAME>

# Keycloak OAuth client credentials
OAUTH_CLIENT_ID=<YOUR_SERVER_CLIENT_ID>
OAUTH_CLIENT_SECRET=<YOUR_SERVER_CLIENT_SECRET>

Start the MCP Server after configuring the environment variables.

MCP Client

For this demonstration, we use Visual Studio Code as the MCP Client.

Perform the following steps:

  1. Open Visual Studio Code.
  2. Press Cmd + Shift + P (or Ctrl + Shift + P on Windows/Linux).
  3. Select MCP: Add Server.
  4. Choose HTTP.
  5. Enter the MCP Server URL:
http://localhost:3000
  1. Provide a name for the server.
{
	"servers": {
		"my-mcp-server-92bd9269": {
			"url": "http://localhost:3000",
			"type": "http"
		}
	},
	"inputs": []
}

When Visual Studio Code attempts to connect to the MCP Server, it will initiate the Dynamic Client Registration process.

You will be redirected to your browser and prompted to authenticate with Keycloak.

After successful authentication, you will be presented with a following screens

VS Code authentication prompt: MCP Server Definition my-mcp-server-92bd9269 wants to authenticate to MCP Demo Server; buttons: Allow, Cancel.
VS consent prompt

Consent screen requesting access to the mcp:tools scope.

Modal dialog: Grant Access to Visual Studio Code, asking to grant privileges for mcp:tools, with Yes and No buttons.
Consent prompt

Once consent is granted, Visual Studio Code can access the tools exposed by the MCP Server.

You can then invoke the available MCP tools directly from the Visual Studio Code Chat interface.

Verifying Dynamic Client Registration

One interesting observation is that Visual Studio Code dynamically registers a new OIDC client in Keycloak during the authentication flow.

If you inspect the clients in the Keycloak Administration Console, you will notice that a new client has been created automatically with a generated client ID.

Screenshot of admin console with 'Clients' highlighted in the left menu; right pane shows the Clients page with search, Create client button, Import/Refresh options, and a table of clients (first row: ID 13c...; Name Visual Studio Code; Type OpenID Connect).
Clients session

Selecting the newly created client allows you to inspect the client metadata and registration details generated during the DCR process.

For additional details on MCP server you may refer here.

Conclusion

In this article, we explored how Dynamic Client Registration (DCR) can be used to support anonymous MCP clients connecting to secured MCP Servers.

Using Keycloak, we configured trusted hosts, enabled Dynamic Client Registration, and allowed Visual Studio Code to dynamically create OIDC clients during the authentication process.

While Dynamic Client Registration works well for anonymous AI agents, OAuth Client ID Metadata Documents (OAuth CIMD) are emerging as a preferred approach because they depend on a published URL for fetching client data and provide a more controlled client metadata model. As support for OAuth CIMD matures in Keycloak, it is worth evaluating for production deployments.

About Skycloak

Skycloak is a fully managed Keycloak platform hosted in the cloud. It enables organizations to leverage the power of open-source Keycloak IAM without the operational overhead of installing, maintaining, and scaling production-grade Keycloak environments — delivered securely and cost-effectively.

If you’re new to Skycloak, visit the Skycloak Getting Started Guide to learn more

George Thomas
Written by George Thomas IAM Engineer

George is an IAM engineer with 23+ years in software engineering, including 14+ years specializing in identity and access management. He designs and modernizes enterprise IAM platforms with deep expertise in Keycloak, OAuth 2.0, OpenID Connect, SAML, and identity federation across cloud and hybrid environments. Previously at Trianz and a long-term contributor to Entrust IAM product engineering, George authors Skycloak's technical Keycloak tutorials.

Ready to simplify your authentication?

Deploy production-ready Keycloak in minutes. Unlimited users, flat pricing, no SSO tax.

© 2026 Skycloak. All Rights Reserved. Design by Yasser Soliman