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_credentialsorpasswordgrant 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 toadmin-clias 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
Option 1: Using uvx (Recommended — no install needed)
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.jsonto the args array to use a specific config file - Add
--read-onlyto 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.jsonwith real credentials (excluded by.gitignore) - Use
config.json.exampleas a template - Prefer environment variables for production and CI environments
- Use
--read-onlymode when write access is not needed - Tokens are cached in memory only and never written to disk
- Set
verify_ssl=truein 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)
| 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)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| 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.