MCP server for the Keycloak Admin REST API — a strong ally for auth troubleshooting: inspect users, sessions, clients, and realm config through AI assistants.
- ✓Open-source license (MIT)
- ✓Actively maintained (<30d)
- ✓Clear description
claude mcp add keycloak-mcp -- python -m keycloak-mcp{
"mcpServers": {
"keycloak-mcp": {
"command": "python",
"args": ["-m", "keycloak-mcp"],
"env": {
"KEYCLOAK_URL": "<keycloak_url>",
"KEYCLOAK_CLIENT_SECRET": "<keycloak_client_secret>"
}
}
}
}KEYCLOAK_URLKEYCLOAK_CLIENT_SECRETMCP Servers overview
<!-- mcp-name: io.github.shigechika/keycloak-mcp -->
# keycloak-mcp
English | [日本語](README.ja.md)
An MCP (Model Context Protocol) server for the [KeyCloak](https://www.keycloak.org/) Admin REST API.
Authenticates via a Service Account (**Client Credentials Grant**), so no human password or TOTP is involved. Also Infinispan-safe — it never creates user sessions and never hits the userinfo endpoint.
## Features
### Users
| Tool | Description |
|------|-------------|
| `count_users` | Total user count in the realm |
| `search_users` | Partial-match search (username / email / name) |
| `get_user` | Full detail for an exact username |
| `reset_password` | Reset one user's password |
| `reset_passwords_batch` | Bulk reset from CSV (`username,password` per line; blank password is generated) |
| `get_user_sessions` | Active sessions for one user, timestamps in local time |
| `logout_user` | Kill all active sessions for one user |
| `set_user_enabled` | Enable or disable one user; disabling blocks all logins (custom attributes preserved) |
### MFA / Credentials
| Tool | Description |
|------|-------------|
| `get_user_credentials` | Credential types configured for one user; an `otp` entry means TOTP/HOTP is set up |
| `get_totp_users` | Realm-wide TOTP adoption: how many users have an `otp` credential, with percentage and (optionally) the user list. Enumerates users and reads each one's credentials (N+1; bound with `max_users`) |
### Groups
| Tool | Description |
|------|-------------|
| `list_user_groups` | Which groups a user belongs to |
| `list_users_by_group` | Members of a group |
### Security
| Tool | Description |
|------|-------------|
| `get_brute_force_status` | Whether a user is currently locked by brute-force detection |
| `get_realm_security_defenses` | Realm-level security policy: whether brute-force detection is enabled and its thresholds, the password policy, and browser security headers |
| `get_login_failures_by_ip` | Failure breakdown by source IP (site-labeled when `KEYCLOAK_SITES_INI` is set) |
| `get_ip_activity` | Exhaustive investigation of one source IP: success/failure counts, affected users/clients, timeline. Returns structured JSON. |
| `detect_login_loops` | Flag users who logged in too many times in a short window (redirect loops) |
### Events
| Tool | Description |
|------|-------------|
| `get_events` | Filter by type, username, client, IP, and date range. Username is resolved to user ID internally. Failure events include KeyCloak's `error` field (e.g. `invalid_user_credentials`). |
| `get_login_stats` | Login success/failure totals, paginated across all results |
| `get_login_stats_by_hour` | Logins bucketed by hour of day (local time) |
| `get_login_stats_by_client` | Logins bucketed by client / SP |
| `get_password_update_events` | `UPDATE_PASSWORD` history |
### Admin Events
`get_events` only sees *user* events. Actions driven by an admin — or by a service account writing custom attributes — don't show up there. The admin-event endpoint fills that gap.
| Tool | Description |
|------|-------------|
| `get_admin_events` | Filter by operation (CREATE / UPDATE / DELETE / ACTION), resource type (USER / CLIENT / ROLE / GROUP / …), resource path, and date range |
| `get_user_attribute_history` | UPDATE/ACTION events scoped to one user — handy for tracking when a custom attribute (e.g. `temp_password`) was written by an automated pipeline |
Both tools accept `max_repr` to control the representation payload: positive = truncate to N chars (default 500), `0` = omit, negative = include in full.
### Sessions & Clients
| Tool | Description |
|------|-------------|
| `get_session_stats` | Active session count per client |
| `get_client_sessions` | Active sessions for one client (SP) |
| `list_clients` | SAML and OIDC clients in the realm |
| `get_realm_roles` | Realm-level roles |
### Morning Patrol
| Tool | Description |
|------|-------------|
| `health_check` | Report the running server version and verify the KeyCloak backend is reachable and the service account can authenticate. Lightweight (one token request; no user/event/session scans). Returns a fixed-shape dict with `status` (healthy / degraded / error), `auth` (ok / error / missing-env), and the configured URL/realm. |
| `daily_brief` | One-shot morning health check: login stats, brute-force IPs, active sessions, password updates, and admin events in a single Markdown summary. IPs exceeding `ip_failure_threshold` failures (default 50) are flagged **WARNING**; API errors surface as **CRITICAL**. `since_hours` controls the look-back window (default 18 h). |
## Setup
```bash
# uv
uv pip install keycloak-mcp
# pip
pip install keycloak-mcp
```
From source:
```bash
git clone https://github.com/shigechika/keycloak-mcp.git
cd keycloak-mcp
# uv
uv sync
# pip
pip install -e .
```
## Configuration
| Variable | Description | Default |
|---|---|---|
| `KEYCLOAK_URL` | Base URL, e.g. `https://keycloak.example.com` | *required* |
| `KEYCLOAK_REALM` | Realm name | `master` |
| `KEYCLOAK_CLIENT_ID` | Service Account client ID | *required* |
| `KEYCLOAK_CLIENT_SECRET` | Client secret | *required* |
| `KEYCLOAK_SITES_INI` | INI file for IP-to-site labeling (see below) | *unset* |
| `KEYCLOAK_DEFAULT_DATE_FROM_HOURS` | Default look-back window for event tools when `date_from` is omitted. Set to `0` to scan full history (can hang on large realms). | `24` |
| `KEYCLOAK_DEADLINE` | Per-call wall-clock budget (seconds) for the heavy event/TOTP tools. When a wide window / large realm would exceed it, the tool stops and returns a **disclosed partial** (⚠️ warning) instead of running past the client's ~60s gateway timeout and hammering KeyCloak. `0` or negative disables. | `45` |
| `KEYCLOAK_MAX_EVENTS` | Per-pagination cap on events fetched by the event tools (also bounds how deep the slow high-offset pagination goes). Over the cap the result is a disclosed partial. `0` or negative disables. | `200000` |
| `KEYCLOAK_MAX_USERS` | Default cap on users scanned by `get_totp_users` when its `max_users` argument is `0` (each user costs one credential call). `0` or negative disables (whole realm, bounded only by `KEYCLOAK_DEADLINE`). | `5000` |
### KeyCloak client setup
1. Create a new client in the KeyCloak admin console.
2. Turn on **Client authentication** and **Service account roles**.
3. Give it `view-users`, `view-events`, `view-clients`, and — only if you need password reset — `manage-users`.
### Verify your setup
After setting the environment variables, run `--check` to confirm authentication works before wiring it into an MCP client:
```bash
export KEYCLOAK_URL=https://keycloak.example.com
export KEYCLOAK_REALM=my-realm
export KEYCLOAK_CLIENT_ID=keycloak-mcp
export KEYCLOAK_CLIENT_SECRET=your-secret
keycloak-mcp --check
# HTTP Request: POST https://keycloak.example.com/realms/my-realm/protocol/openid-connect/token "HTTP/1.1 200 OK"
# OK: authenticated to https://keycloak.example.com/admin/realms/my-realm
```
Exit codes: `0` success, `1` configuration error (missing variable), `2` authentication error.
### IP-to-site labeling (optional)
Point `KEYCLOAK_SITES_INI` at an INI file if you want IP addresses in tool output to be tagged with your site names. Tools like `get_user_sessions`, `get_events`, and `get_login_failures_by_ip` pick it up automatically; anything outside your declared ranges is labeled `external`. Leave the variable unset and IPs are shown as-is.
See [`sites.ini.example`](sites.ini.example). A minimal file:
```ini
[hq]
name = HQ (Tokyo)
ipv4 = 192.0.2.0/24, 198.51.100.0/24
ipv6 = 2001:db8:1::/48
[vpn]
name = VPN
ipv4 = 10.0.0.0/8, 172.16.0.0/12
```
One site per `[section]`. `name` is the display label (falls back to the section name). `ipv4` / `ipv6` take comma-separated CIDRs; a single host is `/32` or `/128`. Matching is first-match in file order — put specific ranges before broad ones.
## Usage
### Claude Code
In `.mcp.json`:
```json
{
"mcpServers": {
"keycloak-mcp": {
"type": "stdio",
"command": "keycloak-mcp",
"env": {
"KEYCLOAK_URL": "https://keycloak.example.com",
"KEYCLOAK_REALM": "my-realm",
"KEYCLOAK_CLIENT_ID": "keycloak-mcp",
"KEYCLOAK_CLIENT_SECRET": ""
}
}
}
}
```
### Claude Desktop
In `claude_desktop_config.json`:
```json
{
"mcpServers": {
"keycloak-mcp": {
"command": "keycloak-mcp",
"env": {
"KEYCLOAK_URL": "https://keycloak.example.com",
"KEYCLOAK_REALM": "my-realm",
"KEYCLOAK_CLIENT_ID": "keycloak-mcp",
"KEYCLOAK_CLIENT_SECRET": ""
}
}
}
}
```
### From a shell
```bash
export KEYCLOAK_URL=https://keycloak.example.com
export KEYCLOAK_REALM=my-realm
export KEYCLOAK_CLIENT_ID=keycloak-mcp
export KEYCLOAK_CLIENT_SECRET=your-secret
keycloak-mcp
```
### CLI
```bash
keycloak-mcp --version # Print version and exit
keycloak-mcp --help # Show usage and required environment variables
keycloak-mcp --check # Verify env vars and authentication, then exit
keycloak-mcp # Run the MCP STDIO server (default)
```
No-argument mode is the normal one — that's how MCP clients launch it.
## Development
```bash
git clone https://github.com/shigechika/keycloak-mcp.git
cd keycloak-mcp
# uv
uv sync --dev
uv run pytest -v
uv run ruff check .
# pip
python3 -m venv .venv
.venv/bin/pip install -e . && .venv/bin/pip install pytest pytest-cov respx ruff
.venv/bin/pytest -v
.venv/bin/ruff check .
```
## License
MIT
What people ask about keycloak-mcp
What is shigechika/keycloak-mcp?
+
shigechika/keycloak-mcp is mcp servers for the Claude AI ecosystem. MCP server for the Keycloak Admin REST API — a strong ally for auth troubleshooting: inspect users, sessions, clients, and realm config through AI assistants. It has 0 GitHub stars and was last updated today.
How do I install keycloak-mcp?
+
You can install keycloak-mcp by cloning the repository (https://github.com/shigechika/keycloak-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.
Is shigechika/keycloak-mcp safe to use?
+
Our security agent has analyzed shigechika/keycloak-mcp and assigned a Trust Score of 82/100 (tier: Trusted). See the full breakdown of passed checks and flags on this page.
Who maintains shigechika/keycloak-mcp?
+
shigechika/keycloak-mcp is maintained by shigechika. The last recorded GitHub activity is from today, with 6 open issues.
Are there alternatives to keycloak-mcp?
+
Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.
Deploy keycloak-mcp to your cloud
Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.
Maintain this repo? Add a badge to your README
Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.
[](https://claudewave.com/repo/shigechika-keycloak-mcp)<a href="https://claudewave.com/repo/shigechika-keycloak-mcp"><img src="https://claudewave.com/api/badge/shigechika-keycloak-mcp" alt="Featured on ClaudeWave: shigechika/keycloak-mcp" width="320" height="64" /></a>More MCP Servers
Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.
User-friendly AI Interface (Supports Ollama, OpenAI API, ...)
An open-source AI agent that brings the power of Gemini directly into your terminal.
The fastest path to AI-powered full stack observability, even for lean teams.
Real-time global intelligence dashboard. AI-powered news aggregation, geopolitical monitoring, and infrastructure tracking in a unified situational awareness interface
🕷️ An adaptive Web Scraping framework that handles everything from a single request to a full-scale crawl!