Skip to main content
Glama
marcinn2

deConz MCP Server

by marcinn2

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)


Related MCP server: zont-mcp

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

Variable

Required

Default

Description

DECONZ_HOST

Yes*

IP or hostname of the deCONZ gateway

DECONZ_PORT

No

80

HTTP port of the deCONZ gateway

DECONZ_API_KEY

Yes*

deCONZ REST API key

DECONZ_TLS

No

false

Set true to use HTTPS

MCP_AUTH_TOKEN

No†

Bearer token clients must send to this MCP server

MCP_BASE_URL

No

http://<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]

Flag

Default

Description

--transport

stdio

Transport mode

--host

127.0.0.1

Bind address (HTTP transports)

--port

8000

Listen port (HTTP transports)

--log-level

INFO

Logging verbosity

--auth-token

$MCP_AUTH_TOKEN

MCP bearer token

--base-url

$MCP_BASE_URL

OAuth issuer URL

Transport modes

Mode

Endpoint(s)

Description

stdio

stdin/stdout

Pipe-based — for Claude Desktop and local use

sse

/sse, /messages/

Legacy SSE (MCP pre-2025-03-26)

streamable-http

/mcp

Modern Streamable HTTP (MCP 2025-03-26)

server

all of the above

SSE + 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

Tool

Description

configure_deconz

Point the server at a deCONZ gateway at runtime (host, port, API key)

get_gateway_config

Read gateway name, firmware, Zigbee channel, IP, WebSocket port

set_permit_join

Open the Zigbee network for new device pairing (0–255 seconds)

Lights

Tool

Description

list_lights

List all lights with on/off, brightness, and reachability

get_light

Full JSON details for a single light

set_light_state

Control power, brightness, hue, saturation, colour temp, xy, effect, alert

rename_light

Rename a light

delete_light

Remove a light from the gateway

Groups

Tool

Description

list_groups

List all groups with member count and action state

get_group

Full JSON details for a single group

create_group

Create a new group (optionally pre-populate with lights)

set_group_action

Control all lights in a group simultaneously

modify_group

Rename a group or change its member lights

delete_group

Delete a group (lights remain)

Scenes

Tool

Description

list_scenes

List all scenes for a group

get_scene

Full JSON details for a scene

create_scene

Create a scene (captures current group state)

recall_scene

Activate a scene

store_scene

Overwrite a scene with the current group state

rename_scene

Rename a scene

delete_scene

Delete a scene

Sensors

Tool

Description

list_sensors

List all sensors with latest readings and battery levels

get_sensor

Full JSON details for a single sensor

rename_sensor

Rename a sensor

set_sensor_config

Update sensor config (enabled, battery level, sensitivity)

delete_sensor

Remove a sensor from the gateway

Rules (automations)

Tool

Description

list_rules

List all automation rules with status and trigger counts

get_rule

Full JSON details (conditions + actions) for a rule

create_rule

Create a new rule with conditions and actions

set_rule_status

Enable or disable a rule

delete_rule

Delete a rule

Schedules

Tool

Description

list_schedules

List all timed schedules

get_schedule

Full JSON details for a schedule

create_schedule

Create a new schedule with ISO 8601 time expression

set_schedule_status

Enable or disable a schedule

delete_schedule

Delete a schedule

Tool

Description

touchlink_scan

Start a Touchlink scan (~10 s) to find nearby Zigbee devices

get_touchlink_results

Return results from the last Touchlink scan

touchlink_identify

Make a Touchlink device blink for identification

touchlink_reset

Factory-reset a Touchlink device


Resources

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

URI

Description

deconz://config

Gateway configuration JSON

deconz://lights

All lights with state JSON

deconz://groups

All groups with action state JSON

deconz://sensors

All sensors with state JSON

deconz://rules

All automation rules JSON

deconz://schedules

All schedules JSON

deconz://state

Complete gateway state (all resources combined)


Prompts

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

Prompt

Arguments

Description

home_overview

Full status report: all lights, sensors, reachability, anomalies

control_lights

room (optional)

Turn lights on/off, set brightness or colour

manage_scenes

group_id (optional)

Create, recall, update, or delete scenes

add_device

Step-by-step guide to pair a new Zigbee device

setup_automation

Create a rule triggered by a sensor event

diagnose_device

device_name (optional)

Diagnose unreachable or misbehaving devices

evening_routine

bedtime (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:

Service

Transport

Started by default

deconz-mcp

server (SSE + Streamable HTTP) on port 8000

Yes

deconz-mcp-stdio

stdio

No — 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:

Resource

Purpose

Namespace

deconz-mcp — isolates all resources

Secret

DECONZ_API_KEY and MCP_AUTH_TOKEN (base64-encoded)

ConfigMap

DECONZ_HOST, DECONZ_PORT, DECONZ_TLS, MCP_BASE_URL

Deployment

1 replica, non-root, read-only root FS, resource limits

Service

ClusterIP on port 80 → pod 8000

Ingress

Commented-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:

Category

Endpoints

Config

GET /config, PUT /config (permit join)

Lights

GET /lights, GET /lights/<id>, PUT /lights/<id>/state, DELETE /lights/<id>

Groups

GET /groups, POST /groups, PUT /groups/<id>/action, DELETE /groups/<id>

Scenes

Full CRUD under /groups/<id>/scenes/<sid> incl. recall and store

Sensors

GET /sensors, PUT /sensors/<id>/config, DELETE /sensors/<id>

Rules

Full CRUD under /rules/<id>

Schedules

Full CRUD under /schedules/<id>

Touchlink

POST /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

Risk

Recommendation

API key exposed in URL paths and server access logs

Rotate the deCONZ API key periodically; restrict access to gateway logs

Unencrypted transport

Enable TLS for any network-facing deployment (DECONZ_TLS=true); use a reverse proxy with a valid certificate

MCP endpoint publicly accessible

Always 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.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
1Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/marcinn2/deConz-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server