Skip to main content

Keycloak MCP Server

MCP server for Keycloak Identity and Access Management instances. Auto-generates 401 tools from the Keycloak OpenAPI specification using FastMCP.from_openapi(). Includes CodeMode for efficient AI interaction with large tool sets, and supports dual authentication modes (OAuth2 HTTP transport for user sessions, client_credentials for stdio service accounts).

Configuration

Authentication: Keycloak supports two modes depending on transport:

  • stdio (service account): Uses client_credentials or password grant to obtain tokens automatically
  • HTTP (user OAuth): Uses OIDC proxy to authenticate end-users via browser flow

Option 1: config.json

cp config.json.example config.json
# Edit config.json with your Keycloak credentials

Option 2: Environment Variables

export KEYCLOAK_HOST="keycloak.example.com"
export KEYCLOAK_REALM="master"
export KEYCLOAK_CLIENT_ID="admin-cli"
export KEYCLOAK_CLIENT_SECRET="your-client-secret"
# Or use password grant:
export KEYCLOAK_USERNAME="admin"
export KEYCLOAK_PASSWORD="admin-password"
export KEYCLOAK_VERIFY_SSL="true"
export KEYCLOAK_CA_CERT_PATH=""
export KEYCLOAK_TIMEOUT="30"

Authentication Modes

stdio Mode (Service Account)

For AI assistants connecting via stdio transport. The server acquires tokens automatically using either:

  • Client credentials grant: Set client_id + client_secret. Best for service-to-service.
  • Password grant: Set username + password. Falls back to admin-cli as client_id.

Tokens are cached and refreshed automatically before expiry.

HTTP Mode (User OAuth Flow)

For web-based access where end-users authenticate via browser:

python -m bibliocommons_mcp_keycloak --transport http --port 8000

Uses OIDC proxy with your Keycloak realm's well-known configuration. Users authenticate through the standard Keycloak login page.

Installation

uvx bibliocommons-mcp-keycloak

uvx runs the package directly from PyPI in an isolated environment. Install uv first if you don't have it:

curl -LsSf https://astral.sh/uv/install.sh | sh

Option 2: Using pip

pip install bibliocommons-mcp-keycloak

AI Client Setup

VS Code (with MCP Extension)

{
  "mcp.servers": {
    "keycloak": {
      "command": "uvx",
      "args": ["bibliocommons-mcp-keycloak"]
    }
  }
}

Claude Desktop

Configuration file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json
{
  "mcpServers": {
    "keycloak": {
      "command": "uvx",
      "args": ["bibliocommons-mcp-keycloak"]
    }
  }
}

Kiro IDE

{
  "mcpServers": {
    "keycloak": {
      "command": "uvx",
      "args": ["bibliocommons-mcp-keycloak"]
    }
  }
}

Kiro CLI

Create or edit ~/.kiro/settings/mcp.json:

{
  "mcpServers": {
    "keycloak": {
      "command": "uvx",
      "args": ["bibliocommons-mcp-keycloak"]
    }
  }
}

Configuration Notes

  • Add --config /path/to/config.json to the args array to use a specific config file
  • Add --read-only to the args array to disable destructive tools
  • After adding the configuration, restart your AI client for changes to take effect

For other AI clients (Amazon Q, GitHub Copilot, Cline, Zed, Cursor), see docs/ai-clients.md.

Docker

# Pull from Docker Hub (private)
docker pull bibliocommons/mcp-keycloak:latest

# Run in stdio mode
docker run -i --rm \
  -v /path/to/config.json:/config.json:ro \
  bibliocommons/mcp-keycloak:latest \
  --config /config.json

# Run in HTTP mode
docker run -d --rm \
  -v /path/to/config.json:/config.json:ro \
  -p 8000:8000 \
  bibliocommons/mcp-keycloak:latest \
  --config /config.json --transport http --port 8000

# Run in expanded mode
docker run -i --rm \
  -v /path/to/config.json:/config.json:ro \
  bibliocommons/mcp-keycloak:latest \
  --config /config.json --expanded

Standalone MCP Server

python -m bibliocommons_mcp_keycloak

CLI Flags

Flag Env Var Description
--config PATH KEYCLOAK_CONFIG Path to config.json
--read-only KEYCLOAK_READ_ONLY Exclude destructive tools (POST, PUT, DELETE, PATCH)
--expanded KEYCLOAK_EXPANDED Register all tools individually instead of gateway mode
--transport stdio|http KEYCLOAK_TRANSPORT Transport mode (default: stdio)
--port PORT KEYCLOAK_PORT HTTP port (default: 8000)
--version — Show version and exit

Gateway Mode (Default)

By default, the server exposes 2 tools instead of 401 individual tools:

Tool Purpose
keycloak_api Execute any Keycloak action by name with a params dict
keycloak_help Search available actions, parameters, and descriptions

The AI assistant calls keycloak_help to discover available actions, then calls keycloak_api(action="get_users", params={"realm": "master"}) to execute them.

To register all individual tools (previous behavior), use --expanded:

python -m bibliocommons_mcp_keycloak --expanded

Read-Only Mode

Disable all write operations (POST, PUT, DELETE, PATCH) for safe, audit-only operation:

# CLI flag
python -m bibliocommons_mcp_keycloak --read-only

# Environment variable
export KEYCLOAK_READ_ONLY=true

In read-only mode, only GET-based tools are exposed. All mutating operations are excluded.

OpenAPI Spec

A copy of the Keycloak OpenAPI spec (src/bibliocommons_mcp_keycloak/openapi.json) ships in the package, so the server starts without any download.

At startup it also asks keycloak.org whether a newer spec exists (5 second limit, conditional request, so an unchanged spec costs almost nothing). A newer spec is used straight away and kept in the user cache directory, ~/.cache/bibliocommons-mcp-keycloak/openapi.json ($XDG_CACHE_HOME is honoured). A cached spec is only used while it is newer than the bundled one, so upgrading the package is never undone by an old cache.

If the check fails (offline, a proxy, a timeout, an unexpected response) the server logs a warning and boots with the bundled or cached spec. It never fails to start because of it.

Variable Purpose
KEYCLOAK_SPEC_UPDATE=false Skip the check, for air-gapped hosts or reproducible runs
KEYCLOAK_SPEC_CACHE Path of the cache file (default above); use a writable path in read-only containers

To refresh the bundled copy before a release, run make update-spec and commit the result.

Security Notes

  • Create a dedicated service account in Keycloak for MCP access with minimal required roles
  • Never commit config.json with real credentials (excluded by .gitignore)
  • Use config.json.example as a template
  • Prefer environment variables for production and CI environments
  • Use --read-only mode when write access is not needed
  • Tokens are cached in memory only and never written to disk
  • Set verify_ssl=true in production; only disable for development with self-signed certificates

Metadata

Release files for bibliocommons-mcp-keycloak 1.4.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for bibliocommons-mcp-keycloak 1.4.1
File Size Uploaded Provenance Actions
bibliocommons_mcp_keycloak-1.4.1.tar.gz 50.7 kB Without provenance Details for bibliocommons_mcp_keycloak-1.4.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for bibliocommons-mcp-keycloak 1.4.1
File Interpreter ABI Platform Actions
bibliocommons_mcp_keycloak-1.4.1-py3-none-any.whl Python 3 none any Details for bibliocommons_mcp_keycloak-1.4.1-py3-none-any.whl

Total release size: 94.7 kB

Release files / bibliocommons_mcp_keycloak-1.4.1.tar.gz

Download URL bibliocommons_mcp_keycloak-1.4.1.tar.gz
Size 50.7 kB
Tags Source
SHA-256 checksum
How to use checksums
64fa198bdfba3f52eeb01cae515f708042db40d2f0601602123fdc729b02c3bb
BLAKE2b-256 checksum
How to use checksums
a268cc1a0419024012e85ea50e65d35aa271932d74a3063497cb421b4ee5cabe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.10

Release files / bibliocommons_mcp_keycloak-1.4.1-py3-none-any.whl

Download URL bibliocommons_mcp_keycloak-1.4.1-py3-none-any.whl
Size 44.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
421595aa52decea9eb905463d214d6b175692fcdc059957a5a0d79435e4d9d89
BLAKE2b-256 checksum
How to use checksums
39ccd58c9948ef106c2adb5215b4efb9921e2e24eec59755ac1e05a352e11e97
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.10

Security for bibliocommons-mcp-keycloak 1.4.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page