Skip to main content

zencontrol-cloud-mcp

MCP server for ZenControl DALI-2 lighting control via the ZenControl Cloud API.

Python 3.11+ License: Apache 2.0

Overview

zencontrol-cloud-mcp enables AI assistants — such as Claude, Cursor, and other MCP-compatible clients — to discover and control ZenControl DALI-2 lighting systems through natural language.

Built on the Model Context Protocol (MCP) with FastMCP, the server supports two transports:

  • stdio — for local, single-user setups (Claude Desktop, Cursor, etc.)
  • StreamableHTTP — for hosted / multi-user deployments

Features

Tool Description
list_sites Discover accessible ZenControl sites
get_site_details Explore site hierarchy (floors, zones, gateways, tenancies)
list_groups List lighting groups by scope (site, floor, map, or gateway)
list_devices List devices and their ECGs by scope
control_light On/off, dim, set level (0–100 %), recall scenes, identify
set_colour Colour temperature (Kelvin) or RGBWAF control

Prerequisites

Quick Start

  1. Set your credentials:

    export ZENCONTROL_CLIENT_ID=your_client_id
    export ZENCONTROL_CLIENT_SECRET=your_client_secret
    
  2. Run with uvx:

    uvx zencontrol-cloud-mcp
    

    On first launch a browser window will open so you can log in to ZenControl. After that, tokens are cached and refreshed automatically.

Configuration

Claude Desktop (stdio mode)

Add the following to your Claude Desktop configuration file:

{
  "mcpServers": {
    "zencontrol": {
      "command": "uvx",
      "args": ["zencontrol-cloud-mcp"],
      "env": {
        "ZENCONTROL_CLIENT_ID": "your_client_id",
        "ZENCONTROL_CLIENT_SECRET": "your_client_secret"
      }
    }
  }
}

HTTP mode (hosted)

Start the server on a network port:

uvx zencontrol-cloud-mcp --transport streamable-http --port 9000

Then point your MCP client at the HTTP endpoint:

{
  "mcpServers": {
    "zencontrol": {
      "url": "http://localhost:9000/mcp"
    }
  }
}

Environment Variables

Variable Required Default Description
ZENCONTROL_CLIENT_ID Yes (stdio) — OAuth client ID
ZENCONTROL_CLIENT_SECRET Yes (stdio) — OAuth client secret
ZENCONTROL_REDIRECT_URI No http://localhost:9000/callback OAuth redirect URI
ZENCONTROL_PORT No 9000 HTTP server port
ZENCONTROL_PUBLIC_URL No — Public HTTPS URL for HTTP mode (e.g. https://mcp.example.com)
ZENCONTROL_SCOPE_SITE No — Lock operations to a site (UUID, tag, or name)

Authentication

The server uses OAuth 2.0 Authorization Code flow to authenticate with the ZenControl Cloud API.

  1. On first run the server opens your default browser so you can log in.
  2. Tokens are stored encrypted in a platform-appropriate location (via platformdirs).
  3. Tokens are refreshed automatically when they expire — you should rarely need to re-authenticate.

Usage Examples

Typical interactions with an AI assistant:

User: "What sites do I have access to?"
→ Calls list_sites

User: "Show me the structure of the Main Office site"
→ Calls get_site_details

User: "Turn on all lights in the Lobby group"
→ Calls control_light(target_type="group", target_id="...", action="on")

User: "Set the office lights to 50% brightness"
→ Calls control_light(target_type="group", target_id="...", action="set_level", level=50)

User: "Change the lobby to warm white (3000K)"
→ Calls set_colour(target_type="group", target_id="...", mode="temperature", kelvin=3000)

Core Tool Families

  • Site discovery: list_sites, get_site_details
  • Topology inventory: list_groups, list_devices, list_gateways, list_device_locations
  • Lighting control: control_light, set_colour, set_profile
  • Live telemetry: get_live_light_levels, get_sensor_readings, get_system_variables
  • Diagnostics: get_device_health
  • Scope controls: set_scope, get_scope, clear_scope

Safe Control Workflow

  1. Start with list_sites.
  2. Resolve a concrete target with get_site_details or list_groups.
  3. Prefer controlling groups over individual devices.
  4. Use moderate levels first (for example, 30-50%) before full output.
  5. Use scope controls to avoid cross-site mistakes in multi-site environments.

Troubleshooting

  • Required environment variable(s) not set:
    • Set ZENCONTROL_CLIENT_ID and ZENCONTROL_CLIENT_SECRET for stdio mode.
  • HTTP 401 on live endpoints:
    • Verify account entitlement for Live API and valid token scope.
  • HTTP 403 on diagnostics:
    • Account may not have access to diagnostics endpoints.
  • get_site_details parsing inconsistencies:
    • This server tolerates both label payload shapes ({"value": "..."} and plain strings).

Architecture

┌─────────────────────┐     stdio / StreamableHTTP     ┌─────────────────────┐
│     MCP Client      │ ──────────────────────────────▶ │ zencontrol-cloud-mcp│
│ (Claude, Cursor, …) │                                │   FastMCP Server    │
└─────────────────────┘                                └──────────┬──────────┘
                                                                  │
                                                    REST + Live API│
                                                                  ▼
                                                       ┌──────────────────┐
                            ┌──────────────────┐       │    ZenControl    │
                            │    Encrypted     │◀─────▶│    Cloud API     │
                            │   Token Store    │       └──────────────────┘
                            └──────────────────┘

Development

git clone https://github.com/oWretch/zencontrol-cloud-mcp.git
cd zencontrol-cloud-mcp
uv sync

# Lint & format
uv run ruff check src/
uv run ruff format --check src/

# Run tests
uv run pytest

# Generate full API docs (Markdown)
uv run python scripts/generate_docs.py

Generated documentation entry points:

  • docs/reference/api.md

See CONTRIBUTING.md for full guidelines.

API Payload Compatibility Notes

Some ZenControl payloads can represent labels in two shapes:

  • Wrapped sync field: { "value": "Office", "state": "OK", "error": null }
  • Plain string: "Office"

The server accepts both formats for label fields (for example, tenancy and floor labels) so tools such as get_site_details remain robust across mixed API responses.

License

This project is licensed under the Apache License 2.0.

Metadata

Release files for zencontrol-cloud-mcp 1.0.3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for zencontrol-cloud-mcp 1.0.3
File Size Uploaded Provenance
zencontrol_cloud_mcp-1.0.3.tar.gz 43.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for zencontrol-cloud-mcp 1.0.3
File Interpreter ABI Platform
zencontrol_cloud_mcp-1.0.3-py3-none-any.whl Python 3 none any Details

Total release size: 99.6 kB

Release files / zencontrol_cloud_mcp-1.0.3.tar.gz

Download URL zencontrol_cloud_mcp-1.0.3.tar.gz
Size 43.6 kB
Tags Source
SHA-256 checksum
How to use checksums
e2ef68ad5b998568c97923a6af3c36ccb01ff7921dc2e022c47f681812d57282
BLAKE2b-256 checksum
How to use checksums
0c1e1f50968792596e2d37c214f46e300f74c1f4e4ec9886f9eaa3092faf2927
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 5, 2026.

Transparency log

Release files / zencontrol_cloud_mcp-1.0.3-py3-none-any.whl

Download URL zencontrol_cloud_mcp-1.0.3-py3-none-any.whl
Size 56.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
0b150c942437bd78110bec88df4d377fa56fb62a491a0146a07ab3c4633de193
BLAKE2b-256 checksum
How to use checksums
fc7f4f44b68470206dc2b519e1a679581bd43b7ab4a278c7a6d80968730ef886
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 5, 2026.

Transparency log

Security for zencontrol-cloud-mcp 1.0.3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for zencontrol_cloud_mcp-1.0.3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 5, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page