GitHub
GitHub’s official server lets AI read and manage code, issues and pull requests in your account. Use GitHub’s hosted version or run it locally with Docker.
Description from the maker (original English)
MCP server for controlling HomeMatic smart home devices via the CCU JSON-RPC API
These three are never merged into one score: opinions, measurements and popularity are different things.
We have not written a plain-language summary for this one yet. Below are the facts we read from the registry.
Pick the AI app you use, then copy the settings.
CCU_HOST, CCU_PASSWORD, CCU_USER, CCU_HTTPS, CCU_PORT, CACHE_DIR, MCP_ALLOWED_ORIGINS, MCP_ALLOWED_HOSTS, CCU_PROFILES, CCU_DEFAULT_PROFILE, CCU_TLS_VERIFY, CCU_TLS_FINGERPRINT, CCU_CA_CERT, CCU_TIMEOUT, CCU_SCRIPT_TIMEOUT, CACHE_TTL, CCU_RATE_LIMIT_BURST, CCU_RATE_LIMIT_RATE, RESOURCE_POLL_INTERVAL, LOG_LEVELValues marked secret are keys to your account. Never share them or paste them into a chat.
You need
Which app do you use?
Pick your app above. We remember it, so next time the button says “Install in …”.
Open Claude Desktop → Settings → Developer → Edit Config, and paste this into claude_desktop_config.json
{
"mcpServers": {
"ccu": {
"command": "npx",
"args": [
"-y",
"ccu-mcp",
"--stdio"
],
"env": {
"CCU_HOST": "your-value",
"CCU_PASSWORD": "your-value",
"CCU_USER": "your-value",
"CCU_HTTPS": "your-value",
"CCU_PORT": "your-value",
"CACHE_DIR": "your-value",
"MCP_ALLOWED_ORIGINS": "your-value",
"MCP_ALLOWED_HOSTS": "your-value",
"CCU_PROFILES": "your-value",
"CCU_DEFAULT_PROFILE": "your-value",
"CCU_TLS_VERIFY": "your-value",
"CCU_TLS_FINGERPRINT": "your-value",
"CCU_CA_CERT": "your-value",
"CCU_TIMEOUT": "your-value",
"CCU_SCRIPT_TIMEOUT": "your-value",
"CACHE_TTL": "your-value",
"CCU_RATE_LIMIT_BURST": "your-value",
"CCU_RATE_LIMIT_RATE": "your-value",
"RESOURCE_POLL_INTERVAL": "your-value",
"LOG_LEVEL": "your-value"
}
}
}
}Run this in your terminal
claude mcp add ccu --env CCU_HOST=your-value --env CCU_PASSWORD=your-value --env CCU_USER=your-value --env CCU_HTTPS=your-value --env CCU_PORT=your-value --env CACHE_DIR=your-value --env MCP_ALLOWED_ORIGINS=your-value --env MCP_ALLOWED_HOSTS=your-value --env CCU_PROFILES=your-value --env CCU_DEFAULT_PROFILE=your-value --env CCU_TLS_VERIFY=your-value --env CCU_TLS_FINGERPRINT=your-value --env CCU_CA_CERT=your-value --env CCU_TIMEOUT=your-value --env CCU_SCRIPT_TIMEOUT=your-value --env CACHE_TTL=your-value --env CCU_RATE_LIMIT_BURST=your-value --env CCU_RATE_LIMIT_RATE=your-value --env RESOURCE_POLL_INTERVAL=your-value --env LOG_LEVEL=your-value -- npx -y ccu-mcp --stdioFill in the empty values before running it.
Paste into .cursor/mcp.json in your project, or ~/.cursor/mcp.json
{
"mcpServers": {
"ccu": {
"command": "npx",
"args": [
"-y",
"ccu-mcp",
"--stdio"
],
"env": {
"CCU_HOST": "your-value",
"CCU_PASSWORD": "your-value",
"CCU_USER": "your-value",
"CCU_HTTPS": "your-value",
"CCU_PORT": "your-value",
"CACHE_DIR": "your-value",
"MCP_ALLOWED_ORIGINS": "your-value",
"MCP_ALLOWED_HOSTS": "your-value",
"CCU_PROFILES": "your-value",
"CCU_DEFAULT_PROFILE": "your-value",
"CCU_TLS_VERIFY": "your-value",
"CCU_TLS_FINGERPRINT": "your-value",
"CCU_CA_CERT": "your-value",
"CCU_TIMEOUT": "your-value",
"CCU_SCRIPT_TIMEOUT": "your-value",
"CACHE_TTL": "your-value",
"CCU_RATE_LIMIT_BURST": "your-value",
"CCU_RATE_LIMIT_RATE": "your-value",
"RESOURCE_POLL_INTERVAL": "your-value",
"LOG_LEVEL": "your-value"
}
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
Paste into .vscode/mcp.json in your project
{
"servers": {
"ccu": {
"type": "stdio",
"command": "npx",
"args": [
"-y",
"ccu-mcp",
"--stdio"
],
"env": {
"CCU_HOST": "your-value",
"CCU_PASSWORD": "your-value",
"CCU_USER": "your-value",
"CCU_HTTPS": "your-value",
"CCU_PORT": "your-value",
"CACHE_DIR": "your-value",
"MCP_ALLOWED_ORIGINS": "your-value",
"MCP_ALLOWED_HOSTS": "your-value",
"CCU_PROFILES": "your-value",
"CCU_DEFAULT_PROFILE": "your-value",
"CCU_TLS_VERIFY": "your-value",
"CCU_TLS_FINGERPRINT": "your-value",
"CCU_CA_CERT": "your-value",
"CCU_TIMEOUT": "your-value",
"CCU_SCRIPT_TIMEOUT": "your-value",
"CACHE_TTL": "your-value",
"CCU_RATE_LIMIT_BURST": "your-value",
"CCU_RATE_LIMIT_RATE": "your-value",
"RESOURCE_POLL_INTERVAL": "your-value",
"LOG_LEVEL": "your-value"
}
}
}
}Your browser asks to open the app, then the app shows the settings and asks you to confirm. Key values are left empty for you to fill in.
This one runs on your computer, and ChatGPT can only connect to servers on the internet. Pick another app.
Your choice stays on this device in a cookie; no account needed.
CCU_USER envCCU_HTTPS envCCU_PORT envCACHE_DIR envMCP_ALLOWED_ORIGINS envMCP_ALLOWED_HOSTS envCCU_PROFILES envCCU_DEFAULT_PROFILE envCCU_TLS_VERIFY envCCU_TLS_FINGERPRINT envCCU_CA_CERT envCCU_TIMEOUT envCCU_SCRIPT_TIMEOUT envCACHE_TTL envCCU_RATE_LIMIT_BURST envCCU_RATE_LIMIT_RATE envRESOURCE_POLL_INTERVAL envLOG_LEVEL envThese settings are generated from the maker’s registry entry. If the README says otherwise, follow the README.
Runs on your computer; the tool list appears in your AI app after you install it.
We check information anyone can see; we have not read the code. Checks that do not apply are left out of the count. · Checked Nov 7, 2026
The registry name was verified with the GitHub account claymore666, which owns the repo
We have not read this repo from GitHub yet
We have not read this repo from GitHub yet
This one runs on your computer; there is no internet endpoint
Runs on your computer and uses local settings instead
Runs on your computer; we can only read tool lists from internet endpoints
Compared with every active server in this category in the registry. Stars count only when the publisher owns the repo.
It passed 1 of 1 applicable basic checks. We have not read the code. Before adding a key or token, see what access the server asks for and use a key with only the permissions you need.
You need to fill in: CCU_HOST, CCU_PASSWORD
It runs on your computer. Your AI app starts it when needed, and data does not pass through the maker’s servers (unless it calls an online service itself).
The GitHub repo last changed –, and the latest version (1.11.7) reached the registry 13 days ago.
Apps that support MCP, such as Claude Desktop, Claude Code, Cursor and VS Code. You also need Node.js on your computer.
In the same category: GitHub, Desktop Commander, Cloudflare MCP
Servers in the same category from other makers, sorted by stars.
Reading a card:★ GitHub starsiThree pillars: reviews · checks · usageiUpdated = latest version published to the registryi
GitHub’s official server lets AI read and manage code, issues and pull requests in your account. Use GitHub’s hosted version or run it locally with Docker.
MCP server for terminal commands, file operations, and process management
Cloudflare MCP servers
Copied from the maker’s repo as written. PopNx MCP has not reviewed or endorsed it. HTML, images and scripts are removed. Links lead off this site.
Talk to your HomeMatic smart home from Claude, Cursor, or any MCP client.
ccu-mcp connects to the CCU's built-in JSON-RPC API and exposes your devices, rooms, programs, and system variables as MCP tools. No addons, no XML-API, no cloud — just a direct connection to the CCU on your local network.
Works with any HomeMatic CCU: debmatic (HomeMatic on Debian), a CCU3, or OpenCCU (formerly RaspberryMatic) — anything that exposes the standard /api/homematic.cgi endpoint.
Ask your AI assistant things like:
The MCP server handles device discovery, type resolution, session management, and value conversion — the AI just calls the tools.
export CCU_HOST=your-ccu-hostname-or-ip
export CCU_PASSWORD=your-ccu-admin-password npx ccu-mcp --stdio
If it prints server_ready to stderr, it's working. Press Ctrl+C to stop. Now set it up in your MCP client — see below.
A cache_save_failed … mkdir '/data' line alongside it is harmless here but worth fixing for real use: CACHE_DIR defaults to /data (the Docker layout), so outside a container the device-type cache and the CCU session are never persisted between runs. Point it somewhere writable: export CACHE_DIR="$HOME/.cache/ccu-mcp" (or the same key in your .env / env block).
Prefer a guided setup? npx ccu-mcp init probes your CCU, pins its TLS certificate, tests the login, writes a ready-to-use .env file, and prints the matching MCP client config — see Command-line flags.
There are two ways to run this: stdio (the server runs as a subprocess of your MCP client) or HTTP (the server runs standalone in Docker and clients connect over the network). Pick one.
This is the easiest setup. Your MCP client (Claude Code, Cursor, etc.) starts the server as a child process — no Docker, no network config, no auth tokens.
For Claude Code, create a .mcp.json file in your project directory (or any directory where you'll use Claude Code):
{
"mcpServers": { "ccu-mcp": { "command": "npx", "args": ["ccu-mcp", "--stdio"], "env": { "CCU_HOST": "your-ccu-hostname-or-ip", "CCU_PASSWORD": "your-ccu-admin-password" } } } }
Replace your-ccu-hostname-or-ip with your CCU's hostname (like homematic-ccu3) or IP (like 192.168.1.50), and your-ccu-admin-password with the password you use to log into the CCU WebUI.
Restart Claude Code. Run /mcp to check it connected. You should see ccu-mcp in the list.
Alternatively, use the Claude Code CLI:
claude mcp add ccu-mcp -- npx ccu-mcp --stdio
Use this if you want the server running independently — for example on a home server, accessible to multiple clients, or when your MCP client supports HTTP remotes.
1. Start the container. Images are published to GHCR for linux/amd64 and linux/arm64 (so a Raspberry Pi next to the CCU works), built natively on each architecture and attested — gh attestation verify oci://ghcr.io/claymore666/ccu-mcp:latest --repo claymore666/ccu-mcp proves the image came from this repository's release workflow.
docker pull ghcr.io/claymore666/ccu-mcp:latest
Every release also publishes its own X.Y.Z tag — pin that instead of latest if you'd rather upgrade deliberately. To build from source instead:
git clone https://github.com/claymore666/ccu-mcp.git && cd ccu-mcp
docker build -t ghcr.io/claymore666/ccu-mcp .
Then run it:
docker run -d \
--name ccu-mcp \ -e CCU_HOST=your-ccu-hostname-or-ip \ -e CCU_PASSWORD=your-ccu-admin-password \ -e MCP_ALLOWED_HOSTS=your-server-ip:3000 \ -v ccu-data:/data \ -p 3000:3000 \ ghcr.io/claymore666/ccu-mcp:latest
`MCP_ALLOWED_HOSTS` is required for remote clients. The server's
DNS-rebinding protection rejects any request whose
Hostheader isn't on
the allowlist — by default only
localhost/127.0.0.1/[::1]on the MCP
port. Set it to every name/IP clients will use to reach the server
(comma-separated,
host:port). Without it, the local health check works
but every remote MCP request gets 403 Invalid Host header.
2. Get the auth token. The server generates a random bearer token on first startup and saves it inside the container's data volume. You need this token to authenticate your MCP client. Grab it with:
docker exec ccu-mcp grep MCP_AUTH_TOKEN /data/.env
This prints something like MCP_AUTH_TOKEN=e96suzi1iG0H-GPif6K2.... The part after = is your token.
3. Configure your MCP client. If your client uses .mcp.json, add the HTTP server:
{
"mcpServers": { "ccu-mcp": { "url": "http://your-server-ip:3000", "headers": { "Authorization": "Bearer PASTE-YOUR-TOKEN-HERE" } } } }
To inject the token automatically (requires jq):
TOKEN=$(docker exec ccu-mcp grep MCP_AUTH_TOKEN /data/.env | cut -d= -f2)
jq --arg t "$TOKEN" '.mcpServers["ccu-mcp"].headers.Authorization = "Bearer " + $t' .mcp.json > .mcp.json.tmp && mv .mcp.json.tmp .mcp.json
This only updates the ccu-mcp entry — other servers in your .mcp.json are left alone.
4. Check it's healthy:
curl http://localhost:3000/health
By default the HTTP server sends no CORS headers, so a random web page can't drive a local instance. To let browser-based MCP clients like MCP Inspector connect directly, set MCP_ALLOWED_ORIGINS to a comma-separated allowlist of trusted origins (e.g. https://app.example,http://localhost:6274). A request whose Origin is on the list gets that exact origin reflected in Access-Control-Allow-Origin — never the wildcard *, which would let any site drive a local instance that controls real CCU hardware. A request from any other origin gets no CORS headers (the browser blocks it) and is rejected server-side by DNS-rebinding protection. Authentication is always enforced regardless: every MCP request needs the bearer token.
The HTTP transport also has DNS-rebinding protection on by default: it rejects requests whose Host header isn't localhost/127.0.0.1/[::1] on the configured port. If you reach the server under another hostname or IP (reverse proxy, container DNS name, the server's LAN address), list those hosts in MCP_ALLOWED_HOSTS or legitimate requests get a 403.
TLS. The bearer token travels in the request, so anything beyond loopback should be encrypted. You have two options: terminate TLS at a reverse proxy (Caddy/nginx) in front and bind the server to loopback (MCP_HOST=127.0.0.1), or let the server serve HTTPS itself by setting MCP_TLS_CERT and MCP_TLS_KEY to a PEM cert/key pair. Plain HTTP is still fully supported — it stays the zero-config default — but the server logs a warning at startup when it's serving the token over unencrypted HTTP on a non-loopback bind; set MCP_ALLOW_PLAINTEXT=true to acknowledge that and silence it.
Token rotation & expiry. By default the bearer token lives forever. Two optional, composable controls let you rotate it without dropping clients:
MCP_AUTH_TOKEN_TTL_DAYS (fractional days allowed) to give the generated token a lifetime. The server rotates it automatically at runtime shortly before it lapses (no restart needed; also on startup if it expired while the server was down), prints the new token on stderr, and keeps the just-replaced token validating for MCP_AUTH_TOKEN_GRACE_HOURS (default 24) so in-flight clients survive the swap. To force a rotation sooner, delete $CACHE_DIR/.env (or just its MCP_AUTH_TOKEN line) and restart.MCP_AUTH_TOKEN yourself, you own its lifetime (TTL doesn't apply). To rotate, put the new token in MCP_AUTH_TOKEN, move the old one to MCP_AUTH_TOKEN_PREVIOUS, and restart; both are accepted during the overlap. Drop MCP_AUTH_TOKEN_PREVIOUS and restart once every client is on the new token. Comparison stays timing-safe across every currently-valid token.Brute-force protection (fail2ban). The auto-generated token is 256 bits of randomness, so guessing it is infeasible. If you set MCP_AUTH_TOKEN yourself, make it long and random (e.g. openssl rand -base64 32) — a short or guessable token is the one case brute force matters. The server does not rate-limit or lock out failed logins in-process; that job belongs to a firewall-level tool like fail2ban, which bans the source IP before the request ever reaches the server. To make that easy, every rejected request logs a structured line to stderr:
{"ts":"2026-06-18T17:28:00.370Z","level":"warn","msg":"auth_failed","client":"203.0.113.7","hadToken":true}
Ready-to-use fail2ban config ships in fail2ban/: copy filter.d/ccu-mcp.conf to /etc/fail2ban/filter.d/ and the jail in jail.d/ccu-mcp.local to /etc/fail2ban/jail.d/ (it defaults to 5 failures in 10 minutes → 1-hour ban). The server logs to stderr, so point fail2ban at wherever you collect it — the journal (backend = systemd) when run as a unit, or a file when you redirect stderr/docker logs; both are spelled out in the jail file. Requires LOG_LEVEL=warn or lower (info, the default, is fine; error suppresses the line). Behind a reverse proxy the logged IP is the proxy's, so run fail2ban against the proxy's access log instead.
CORS support was first implemented by @marcinn2 in his fork marcinn2/debmatic-mcp — thanks!
###
Only the beginning is shown; read the rest in the repo