Spec Driven Development
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Descripción del creador (original en inglés)
MCP server for controlling HomeMatic smart home devices via the CCU JSON-RPC API
Estos tres nunca se combinan en una sola puntuación: las opiniones, las mediciones y la popularidad son cosas distintas.
Todavía no escribimos un resumen sencillo para este. Abajo están los datos que leímos del registro.
Elige la app de IA que usas y copia la configuración.
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_LEVELLos valores marcados como secretos son llaves de tu cuenta. Nunca los compartas ni los pegues en un chat.
Necesitas
¿Qué app usas?
Elige tu app arriba. La recordamos, así que la próxima vez el botón dirá “Instalar en …”.
Abre Claude Desktop → Settings → Developer → Edit Config y pega esto en 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"
}
}
}
}Ejecuta esto en tu 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 --stdioCompleta los valores vacíos antes de ejecutarlo.
Pégalo en .cursor/mcp.json de tu proyecto, o en ~/.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"
}
}
}
}Tu navegador te pide permiso para abrir la app; luego la app muestra la configuración y te pide confirmar. Los valores de las claves quedan vacíos para que los completes tú.
Pégalo en .vscode/mcp.json de tu proyecto
{
"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"
}
}
}
}Tu navegador te pide permiso para abrir la app; luego la app muestra la configuración y te pide confirmar. Los valores de las claves quedan vacíos para que los completes tú.
Este se ejecuta en tu computadora, y ChatGPT solo puede conectarse a servidores en internet. Elige otra app.
Tu elección se guarda en una cookie en este dispositivo; no necesitas cuenta.
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 envEsta configuración se genera a partir de la ficha del creador en el registro. Si el README dice otra cosa, sigue el README.
Se ejecuta en tu computadora; la lista de herramientas aparece en tu app de IA después de instalarlo.
Revisamos información que cualquiera puede ver; no hemos leído el código. Las revisiones que no aplican no se cuentan. · Revisado el 7 nov 2026
El nombre en el registro se verificó con la cuenta de GitHub claymore666, dueña del repo
Todavía no hemos leído este repo en GitHub
Todavía no hemos leído este repo en GitHub
Este se ejecuta en tu computadora; no hay endpoint en internet
Se ejecuta en tu computadora y usa ajustes locales en su lugar
Se ejecuta en tu computadora; solo podemos leer listas de herramientas de endpoints en internet
Comparado con todos los servidores activos de esta categoría en el registro. Las estrellas solo cuentan cuando quien lo publica es dueño del repo.
Superó 1 de 1 revisiones básicas aplicables. No hemos leído el código. Antes de agregar una clave o un token, revisa qué acceso pide el servidor y usa una clave que tenga solo los permisos que necesitas.
Debes completar: CCU_HOST, CCU_PASSWORD
Se ejecuta en tu computadora. Tu app de IA lo inicia cuando hace falta, y los datos no pasan por los servidores del creador (a menos que el propio servidor llame a un servicio en línea).
El repo de GitHub cambió por última vez –, y la última versión (1.11.7) llegó al registro hace 13 días.
Las apps compatibles con MCP, como Claude Desktop, Claude Code, Cursor y VS Code. También necesitas Node.js en tu computadora.
En la misma categoría: Spec Driven Development, Remote Desktop Commander, OpenTakeoff
Servidores de la misma categoría hechos por otros creadores, ordenados por estrellas.
Cómo leer una tarjeta:★ Estrellas de GitHubiTres pilares: reseñas · revisiones · usoiActualizado = fecha en que se publicó la última versión en el registroi
MCP Server that facilitates spec-driven development workflows, not just Vibe Coding.
Remote Desktop Commander: use files, terminal and processes on your own computers from any AI app.
Construction takeoff for AI agents: load plans, set scale, measure, count, export with provenance.
Copiado tal cual del repo del creador. PopNx MCP no lo ha revisado ni lo respalda. Se quitaron HTML, imágenes y scripts. Los enlaces llevan fuera de este sitio.
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!
###
Solo se muestra el principio; lee el resto en el repo