Mcp Server For Deconz Server

Created By
marcinn2a day ago
MCP Server for deConz server developed by Dresden Elektronik (bridge between smart home automation platforms and wireless Zigbee networks)
Overview

deConz MCP Server

An MCP (Model Context Protocol) server that exposes the deCONZ REST API to AI assistants. Control Zigbee lights, sensors, groups, scenes, rules, and schedules through natural language.

Supports stdio, SSE, and Streamable HTTP transports. HTTP transports are protected by a configurable bearer token.


Requirements

  • Python ≥ 3.10
  • uv (recommended) or pip
  • A running deCONZ / Phoscon gateway with a ConBee or RaspBee adapter
  • A valid deCONZ REST API key (see Obtaining an API key)

Installation

# Clone the repository
git clone https://github.com/your-org/deconz-mcp.git
cd deconz-mcp

# Install with uv (creates an isolated virtual environment)
uv sync

# Or install with pip into your environment
pip install -e .

Obtaining an API key

  1. Open the Phoscon App in your browser (usually http://<gateway-ip>/pwa).
  2. Go to Menu → Settings → Gateway → Advanced.
  3. Click Authenticate app — this opens the network for 60 seconds.
  4. Within those 60 seconds, run:
curl -s -X POST http://<gateway-ip>/api \
  -H "Content-Type: application/json" \
  -d '{"devicetype": "deconz-mcp"}'

The response contains your API key:

[{"success": {"username": "YOUR-API-KEY-HERE"}}]

Store it as DECONZ_API_KEY.


Quick start

stdio (Claude Desktop)

DECONZ_HOST=192.168.1.10 DECONZ_API_KEY=abc123def deconz-mcp

Streamable HTTP with bearer auth

DECONZ_HOST=192.168.1.10 \
DECONZ_API_KEY=abc123def \
MCP_AUTH_TOKEN=my-mcp-secret \
deconz-mcp --transport streamable-http --host 0.0.0.0 --port 8080

Combined SSE + Streamable HTTP

DECONZ_HOST=192.168.1.10 \
DECONZ_API_KEY=abc123def \
MCP_AUTH_TOKEN=my-mcp-secret \
deconz-mcp --transport server --host 0.0.0.0 --port 8080

Environment variables

VariableRequiredDefaultDescription
DECONZ_HOSTYes*IP or hostname of the deCONZ gateway
DECONZ_PORTNo80HTTP port of the deCONZ gateway
DECONZ_API_KEYYes*deCONZ REST API key
DECONZ_TLSNofalseSet true to use HTTPS
MCP_AUTH_TOKENNo†Bearer token clients must send to this MCP server
MCP_BASE_URLNohttp://<host>:<port>Public base URL (used as OAuth issuer URL)

* Not required when using stdio and calling configure_deconz at runtime.
† Strongly recommended for HTTP transports exposed beyond localhost.


CLI reference

usage: deconz-mcp [--transport {stdio,sse,streamable-http,server}]
                  [--host HOST] [--port PORT]
                  [--log-level {DEBUG,INFO,WARNING,ERROR}]
                  [--auth-token TOKEN] [--base-url URL]
FlagDefaultDescription
--transportstdioTransport mode
--host127.0.0.1Bind address (HTTP transports)
--port8000Listen port (HTTP transports)
--log-levelINFOLogging verbosity
--auth-token$MCP_AUTH_TOKENMCP bearer token
--base-url$MCP_BASE_URLOAuth issuer URL

Transport modes

ModeEndpoint(s)Description
stdiostdin/stdoutPipe-based — for Claude Desktop and local use
sse/sse, /messages/Legacy SSE (MCP pre-2025-03-26)
streamable-http/mcpModern Streamable HTTP (MCP 2025-03-26)
serverall of the aboveSSE + Streamable HTTP on one port

Authentication

deCONZ API key

The deCONZ REST API key is a gateway credential that travels as part of the URL path (/api/<apikey>/...). It is configured server-side via DECONZ_API_KEY and is never exposed to MCP clients.

MCP bearer token

The MCP_AUTH_TOKEN / --auth-token option protects the MCP server itself. Every HTTP request from an MCP client must include:

Authorization: Bearer <token>

The token is verified with a constant-time comparison to prevent timing attacks. When running over localhost only (default bind 127.0.0.1), bearer auth is optional but recommended.


Tools

Connection / configuration

ToolDescription
configure_deconzPoint the server at a deCONZ gateway at runtime (host, port, API key)
get_gateway_configRead gateway name, firmware, Zigbee channel, IP, WebSocket port
set_permit_joinOpen the Zigbee network for new device pairing (0–255 seconds)

Lights

ToolDescription
list_lightsList all lights with on/off, brightness, and reachability
get_lightFull JSON details for a single light
set_light_stateControl power, brightness, hue, saturation, colour temp, xy, effect, alert
rename_lightRename a light
delete_lightRemove a light from the gateway

Groups

ToolDescription
list_groupsList all groups with member count and action state
get_groupFull JSON details for a single group
create_groupCreate a new group (optionally pre-populate with lights)
set_group_actionControl all lights in a group simultaneously
modify_groupRename a group or change its member lights
delete_groupDelete a group (lights remain)

Scenes

ToolDescription
list_scenesList all scenes for a group
get_sceneFull JSON details for a scene
create_sceneCreate a scene (captures current group state)
recall_sceneActivate a scene
store_sceneOverwrite a scene with the current group state
rename_sceneRename a scene
delete_sceneDelete a scene

Sensors

ToolDescription
list_sensorsList all sensors with latest readings and battery levels
get_sensorFull JSON details for a single sensor
rename_sensorRename a sensor
set_sensor_configUpdate sensor config (enabled, battery level, sensitivity)
delete_sensorRemove a sensor from the gateway

Rules (automations)

ToolDescription
list_rulesList all automation rules with status and trigger counts
get_ruleFull JSON details (conditions + actions) for a rule
create_ruleCreate a new rule with conditions and actions
set_rule_statusEnable or disable a rule
delete_ruleDelete a rule

Schedules

ToolDescription
list_schedulesList all timed schedules
get_scheduleFull JSON details for a schedule
create_scheduleCreate a new schedule with ISO 8601 time expression
set_schedule_statusEnable or disable a schedule
delete_scheduleDelete a schedule
ToolDescription
touchlink_scanStart a Touchlink scan (~10 s) to find nearby Zigbee devices
get_touchlink_resultsReturn results from the last Touchlink scan
touchlink_identifyMake a Touchlink device blink for identification
touchlink_resetFactory-reset a Touchlink device

Resources

Resources are read-only, cacheable snapshots that MCP clients can fetch without issuing tool calls.

URIDescription
deconz://configGateway configuration JSON
deconz://lightsAll lights with state JSON
deconz://groupsAll groups with action state JSON
deconz://sensorsAll sensors with state JSON
deconz://rulesAll automation rules JSON
deconz://schedulesAll schedules JSON
deconz://stateComplete gateway state (all resources combined)

Prompts

Prompts are pre-built conversation starters that guide the AI through common workflows.

PromptArgumentsDescription
home_overviewFull status report: all lights, sensors, reachability, anomalies
control_lightsroom (optional)Turn lights on/off, set brightness or colour
manage_scenesgroup_id (optional)Create, recall, update, or delete scenes
add_deviceStep-by-step guide to pair a new Zigbee device
setup_automationCreate a rule triggered by a sensor event
diagnose_devicedevice_name (optional)Diagnose unreachable or misbehaving devices
evening_routinebedtime (default 23:00)Activate an evening scene and schedule lights off

Claude Desktop configuration

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS):

{
  "mcpServers": {
    "deconz": {
      "command": "deconz-mcp",
      "env": {
        "DECONZ_HOST": "192.168.1.10",
        "DECONZ_API_KEY": "your-api-key-here"
      }
    }
  }
}

Or if installed in a virtual environment:

{
  "mcpServers": {
    "deconz": {
      "command": "/path/to/deconz-mcp/.venv/bin/deconz-mcp",
      "env": {
        "DECONZ_HOST": "192.168.1.10",
        "DECONZ_API_KEY": "your-api-key-here"
      }
    }
  }
}

HTTP client configuration

For Streamable HTTP transport:

{
  "mcpServers": {
    "deconz": {
      "url": "http://localhost:8080/mcp",
      "headers": {
        "Authorization": "Bearer my-mcp-secret"
      }
    }
  }
}

For legacy SSE transport:

{
  "mcpServers": {
    "deconz": {
      "url": "http://localhost:8080/sse",
      "headers": {
        "Authorization": "Bearer my-mcp-secret"
      }
    }
  }
}

Docker

A pre-built multi-platform image (linux/amd64 + linux/arm64) is published to the registry:

registry.mne.pl/deconz-mcp:latest
registry.mne.pl/deconz-mcp:0.1.0

A multi-stage Dockerfile is also included if you prefer to build locally. The builder stage uses the official uv image to install dependencies and compile the package as a wheel; the runtime stage is python:3.12-slim (57 MB total).

Pull

docker pull registry.mne.pl/deconz-mcp:latest

Build locally

# Single-platform (current machine)
docker build -t deconz-mcp:latest .

# Multi-platform push (requires a buildx builder with multi-platform support)
docker buildx build \
  --platform linux/amd64,linux/arm64 \
  --tag registry.mne.pl/deconz-mcp:latest \
  --tag registry.mne.pl/deconz-mcp:0.1.0 \
  --push .

Run — HTTP server (SSE + Streamable HTTP)

docker run -p 8000:8000 \
  -e DECONZ_HOST=192.168.1.10 \
  -e DECONZ_API_KEY=abc123def \
  -e MCP_AUTH_TOKEN=my-mcp-secret \
  registry.mne.pl/deconz-mcp:latest

Run — stdio

docker run -i \
  -e DECONZ_HOST=192.168.1.10 \
  -e DECONZ_API_KEY=abc123def \
  registry.mne.pl/deconz-mcp:latest --transport stdio

Docker Compose

A ready-to-use Compose file is in docs/docker-compose.yml. It defines two services:

ServiceTransportStarted by default
deconz-mcpserver (SSE + Streamable HTTP) on port 8000Yes
deconz-mcp-stdiostdioNo — requires --profile stdio
# Copy and edit the environment file
cp .env.example .env   # set DECONZ_HOST, DECONZ_API_KEY, MCP_AUTH_TOKEN

# Start the HTTP server
docker compose -f docs/docker-compose.yml up

# Run a one-shot stdio session
docker compose -f docs/docker-compose.yml --profile stdio run --rm deconz-mcp-stdio

Use the stdio service in Claude Desktop:

{
  "mcpServers": {
    "deconz": {
      "command": "docker",
      "args": ["compose", "-f", "/path/to/docs/docker-compose.yml",
               "--profile", "stdio", "run", "--rm", "deconz-mcp-stdio"],
      "env": {
        "DECONZ_HOST": "192.168.1.10",
        "DECONZ_API_KEY": "your-api-key-here"
      }
    }
  }
}

Kubernetes

The manifest at k8s/deployment.yaml contains all resources needed to run the server in a cluster:

ResourcePurpose
Namespacedeconz-mcp — isolates all resources
SecretDECONZ_API_KEY and MCP_AUTH_TOKEN (base64-encoded)
ConfigMapDECONZ_HOST, DECONZ_PORT, DECONZ_TLS, MCP_BASE_URL
Deployment1 replica, non-root, read-only root FS, resource limits
ServiceClusterIP on port 80 → pod 8000
IngressCommented-out template for nginx / cert-manager

Deploy

# 1. Encode your secrets
echo -n 'your-api-key'   | base64   # → paste into Secret.DECONZ_API_KEY
echo -n 'your-mcp-token' | base64   # → paste into Secret.MCP_AUTH_TOKEN

# 2. Edit the ConfigMap (DECONZ_HOST, MCP_BASE_URL) in k8s/deployment.yaml

# 3. Apply
kubectl apply -f k8s/deployment.yaml

# 4. Verify
kubectl -n deconz-mcp get pods
kubectl -n deconz-mcp logs -f deploy/deconz-mcp

Health check

kubectl -n deconz-mcp port-forward svc/deconz-mcp 8000:80
curl http://localhost:8000/health
# {"status": "ok", "deconz_configured": true}

The Deployment configures both a liveness probe and a readiness probe against /health, so Kubernetes automatically restarts the pod if the server becomes unresponsive.

Ingress (optional)

Uncomment the Ingress section at the bottom of k8s/deployment.yaml and set your hostname. TLS termination happens at the ingress controller; the pod always speaks plain HTTP internally.


Health check

HTTP transports expose a liveness probe:

curl http://localhost:8080/health
# {"status": "ok", "deconz_configured": true}

Project structure

deConz-mcp/
├── Dockerfile                      # Multi-stage image build
├── pyproject.toml                  # Package metadata and dependencies
├── uv.lock                         # Locked dependency versions
├── README.md
├── docs/
│   └── docker-compose.yml          # Compose services (HTTP + stdio)
├── k8s/
│   └── deployment.yaml             # Kubernetes: Namespace, Secret, ConfigMap,
│                                   #   Deployment, Service, Ingress (template)
└── src/
    └── deconz_mcp/
        ├── __init__.py
        ├── __main__.py             # CLI entrypoint and transport wiring
        ├── client.py               # Async deCONZ REST API HTTP client
        └── server.py               # FastMCP server: tools, resources, prompts

deCONZ API overview

The server covers these API categories:

CategoryEndpoints
ConfigGET /config, PUT /config (permit join)
LightsGET /lights, GET /lights/<id>, PUT /lights/<id>/state, DELETE /lights/<id>
GroupsGET /groups, POST /groups, PUT /groups/<id>/action, DELETE /groups/<id>
ScenesFull CRUD under /groups/<id>/scenes/<sid> incl. recall and store
SensorsGET /sensors, PUT /sensors/<id>/config, DELETE /sensors/<id>
RulesFull CRUD under /rules/<id>
SchedulesFull CRUD under /schedules/<id>
TouchlinkPOST /touchlink/scan, identify, reset

For the full API reference, see the deCONZ REST API documentation.


Data & Privacy

Preliminary assessment only — not legal advice. See full notes below.

Personal home use

When this server runs in a private household and is accessed only by the residents, processing of smart-home device data is likely covered by the household exemption (GDPR Recital 18). In that scenario the GDPR does not apply and no additional compliance steps are required.

Commercial or shared deployments

Deploying this server in offices, rental properties, hotels, co-working spaces, or any environment where you process data on behalf of other people takes you outside the household exemption. In those cases:

  • Presence and motion sensor data constitutes personal behavioral data (Art. 4(1) GDPR). Establish a documented lawful basis (Art. 6) before processing it.
  • Conduct a Data Protection Impact Assessment (Art. 35) if the deployment involves systematic monitoring of occupants on a large scale.
  • Provide a privacy notice to data subjects describing what is collected, for how long, and under what legal basis.

Security recommendations

RiskRecommendation
API key exposed in URL paths and server access logsRotate the deCONZ API key periodically; restrict access to gateway logs
Unencrypted transportEnable TLS for any network-facing deployment (DECONZ_TLS=true); use a reverse proxy with a valid certificate
MCP endpoint publicly accessibleAlways set MCP_AUTH_TOKEN when binding to a non-loopback address

What this software does NOT do

  • No data is sent to third parties, analytics services, or cloud providers.
  • No telemetry, tracking pixels, or consent libraries are present in this codebase.
  • All communication stays between the MCP client, this server, and the local deCONZ gateway.

This GDPR assessment was generated as a preliminary, exploratory evaluation. It does not constitute legal advice and does not replace a legal audit. For binding guidance, consult a qualified data protection lawyer in your jurisdiction.


License

Apache 2.0 — see LICENSE.

Disclaimer

This software is not affiliated with or endorsed by Dresden Elektronik. Use at your own risk. It does not come with any warranty of any kind. There is no liability for the developer. This software is a personal project that I maintain in my free time. Refer to the licence for more information.

Server Config

{
  "mcpServers": {
    "deconz": {
      "command": "deconz-mcp",
      "env": {
        "DECONZ_HOST": "192.168.1.10",
        "DECONZ_API_KEY": "your-api-key-here"
      }
    }
  }
}
Project Info
Created At
a day ago
Updated At
a day ago
Author Name
marcinn2
Star
-
Language
-
License
-
Category
Tags

Recommend Servers

View All
Tatsu55

14 hours ago
Wpnews

a day ago
PDFGate
@pdfgate

21 hours ago