Matter Web Controller
Allows Apple HomeKit bridges to control Matter devices through the Matter Web Controller, enabling integration with Apple Home for lights, sensors, climate, and more.
Enables Apple TV devices to act as occupancy sensors for the Matter home, with occupancy data streamed via SSE.
Enables macOS devices to act as occupancy sensors for the Matter home, with occupancy data streamed via SSE.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Matter Web Controller turn on the living room light"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Matter Web Controller
A fast REST + MCP API in front of your Matter home.
Overview
Matter Web Controller is the hub of a small Matter home. Schedulers, HomeKit bridges, dashboards, presence sensors, and LLMs all talk to this one service — and none of them have to speak Matter. It runs python-matter-server as a subprocess and holds the WebSocket session; state is cached and event-driven, so a read never blocks on a protocol round-trip.
Several instances federate over the same REST they serve. Register a peer and its devices appear here, with commands forwarded automatically — no embedded code, just HTTP.
It runs as your user. Matter operational traffic is ordinary IPv6 UDP, so there are no raw sockets and no sudo on macOS or most Linux. It is built for home use. It is not hardened for commercial deployment.
Related MCP server: matter-mcp-server
How it works
A single key, the X-API-Key header, authenticates every request — and federation between instances. GET /health and GET /version are the only open endpoints. Secrets like a peer's key or a pairing code travel in the JSON body, never the URL.
Devices are addressed by stable hash IDs derived from hardware UniqueID, like dev_a3f7c1b2. Aliases you set with /api/name are display-only and are not accepted as IDs.
Quick start
pip install matter-web-controller
export MATTER_SRV_KEY=$(openssl rand -hex 32)
matter-srv --fabric "My Home"
# In another terminal
curl -H "X-API-Key: $MATTER_SRV_KEY" http://127.0.0.1:8080/api/status
# Pair a device (code from its app, e.g. Aqara Home)
curl -H "X-API-Key: $MATTER_SRV_KEY" -H "Content-Type: application/json" \
-d '{"code":"2456-515-1552","name":"Living Room"}' \
http://127.0.0.1:8080/api/registerRequires Python 3.12+. The Matter WebSocket binds to the REST port + 1.
matter-srv flags: --port (8080), --host (127.0.0.1; 0.0.0.0 for LAN), --api-key / $MATTER_SRV_KEY, --fabric, --data-dir / $MATTER_DATA_DIR (caches + fabric storage; absolute path logged at startup), --insecure, --log-level / $MATTER_LOG_LEVEL. A non-loopback bind without a key is refused unless --insecure.
REST API
Errors map cleanly: 404 unknown device, 400 bad params, 401 auth, 405 a POST-only endpoint called with GET, 503 Matter bridge offline, 500 other.
Read (GET)
/api/status— counts: lights on/off, sensors active, ACs on/off, bridges, total devices, plusdevices_online/devices_offline/api/devices— raw states for every device, each with anonlineflag/api/identities,/api/identities?id— hardware identity per device (or one): vendor, product/model, node label, hardware/software versions, serial, unique id, and Matter device-type ids. The static counterpart to/api/devices; tells apart bridged children of one hub after a re-pairing, and with?iddecodes adev_*id back to itsnode_id/endpoint_id/api/lights— normalized brightness 0–1 and Kelvin; brightness is kept even when off,statecarries on/off,onlinereports reachability/api/sensors,/api/sensor?id— all sensors, or one/api/climate[?id]— temperature (°C) and humidity (%)/api/level?id,/api/mired?id— read raw brightness (0–254) or color temperature (mireds)/api/metadata— declarative capabilities (plusonline), used by federation peers/health,/version— unauthenticated
Control (POST)
/api/set{id, brightness 0–1, temperature Kelvin}— both optional/api/toggle{id}— flip on/off; also valid on ACs/api/level{id, level 0–254},/api/mired{id, mireds 153–500}(clamped)/api/batch{actions:[…]}— run in parallel
curl -H "X-API-Key: $MATTER_SRV_KEY" -H "Content-Type: application/json" \
-d '{"id":"dev_e3798593","brightness":0.8,"temperature":2700}' \
http://127.0.0.1:8080/api/setAC / Thermostat
GET /api/acs,GET /api/ac?id— list, or read onePOST /api/ac{id, on, mode, setpoint °C, fan_speed}system_mode: 0 Off, 1 Auto, 3 Cool, 4 Heat, 5 EmergencyHeat, 6 Precooling, 7 FanOnly, 8 Dry, 9 Sleep.on=trueresumes the last non-zero mode (default Cool);on=falsewrites mode 0;modeoverrideson(system_modeis a synonym). The setpoint routes to the heating setpoint in Heat/EmergencyHeat or the cooling setpoint in Cool/Precooling; a lone setpoint in Auto is rejected.fan_speed(0–100) applies only to logical-bridge ACs that report it, and is rejected on physical Matter ACs.
Management (POST)
/api/name{id, name},/api/name/remove{id, name}/api/register{code, name, ip}— commission by pairing code/api/unregister{node_id},/api/refresh
Federation (POST)
/api/bridge{ip, port, api_key}— register a remote matter-srv (key in body)/api/bridge/remove{ip, port}Only private/loopback IPs or LAN hostnames are accepted, and self-registration is rejected.
SSE — GET /api/subscribe?id streams occupancy as Server-Sent Events with a : keepalive comment every 15s. For a device on a remote logical bridge, it forwards that bridge's own stream; if the upstream drops, a synthetic occupancy:0 frame lets subscribers fall back to absent.
curl -N -H "X-API-Key: $MATTER_SRV_KEY" \
"http://127.0.0.1:8080/api/subscribe?id=dev_b503384e"
# data: {"id":"dev_b503384e","occupancy":1,"timestamp":"…"}
# : keepalive ← every 15sMCP
matter-mcp is a thin HTTP client over the same REST API — same key, same error model. About 23 tools mirror the endpoints: get_devices, get_identities, get_lights, get_sensors, get_sensor, get_climate, get_status, set_device, toggle, set_level, set_mired, batch_control, set_name, remove_name, add_bridge, remove_bridge, register_device, unregister_node, list_acs, get_ac, set_ac, get_metadata, refresh. The SSE stream is HTTP-only.
Flags: --host (localhost), --port (8080), --api-key, --transport (stdio | sse | http; stdio for local agents), --mcp-host (127.0.0.1), --mcp-port (7861), --log-level.
{
"mcpServers": {
"matter": {
"command": "matter-mcp",
"args": ["--host", "localhost", "--port", "8080"],
"env": { "MATTER_SRV_KEY": "your-key-here" }
}
}
}Verified hardware
Verified with the Aqara Hub M200 bridging Aqara sensors over Matter — Motion Sensor P1 (PIR + lux), Presence FP1E (mmWave single-zone), Presence FP2 (mmWave multi-zone, each zone its own dev_* ID), and Presence Multi-Sensor FP300 (mmWave + lux + temp/humidity) — plus the Aqara Climate Sensor W100 paired to an IR AC and bridged as a Matter Thermostat (cluster 0x0201), where writes become IR commands. Sensitivity, hold times, and FP2 zones are configured in the Aqara app, not over Matter, and Aqara does not bridge in-app Scenes. A Matter Rain Sensor (device type 0x0044) surfaces as capability rain.
Limitations
Only Matter devices already on the LAN. Non-Matter hardware (Casambi, Yeelight, and the like) needs an adapter that exposes this same REST surface.
BLE commissioning is off by default in
python-matter-serverbuilds; devices commission over mDNS.One fabric per instance.
Related projects
This service is the hub of a small constellation, all at github.com/dongnh:
light_programmer — circadian schedule brain with a rain override
matter-weather-sensor — weather as Matter temp/humidity/pressure/rain/illuminance sensors
yeelight_webcontrol — Yeelight bulbs on the same REST contract, including on-device colour-flow
matter-homekit-bridge and matter-homekit-ac — publish Matter devices and AC tiles into Apple Home
matter-mac-presence, matter-appletv-presence, mac-status-bridge — Macs and Apple TV as occupancy sensors
See CHANGELOG.md for release notes and CLAUDE.md for architecture rules.
License
MIT.
Available Tools
23 toolsadd_bridgeA
Register a remote logical bridge by IP and port. Optional api_key for authenticated peers (sent in the request body, never the URL).
Inputs: ip (required), port (required), api_key.
batch_controlA
Control multiple devices at once. Each action: {"id": "...", "brightness": 0.5, "temperature": 4000}.
Inputs: actions (required). Returns: result
get_acA
Get a single AC's state by device ID.
Inputs: id (required).
get_climateA
Read temperature (°C) and/or humidity (%) for every device that reports them
(Thermostat local_temperature + standalone temp/humidity sensors). If id is given,
return one device only. Each entry has kind = "thermostat" or "sensor".
Inputs: id. Returns: result
get_devicesA
List all devices (physical and logical) with their current states and aliases.
Inputs: no named parameters. Returns: result
get_identitiesA
Hardware identity for every device: vendor, product/model name, node label, hardware/software versions, serial number, unique id, and Matter device-type ids. Physical Matter devices carry the full set (from Basic / Bridged Device Basic Information); logical devices report id + names only. Use to tell apart bridged children of one hub (e.g. Aqara sensors) that changed IDs after a re-pairing. If id is given, return just that one device — i.e. decode a dev_ id back to its node_id/endpoint_id + identity (the id is a one-way hash, so this is the way back).
Inputs: id. Returns: result
get_lightsA
List lighting devices with normalized brightness (0.0-1.0) and color temperature (Kelvin).
Inputs: no named parameters. Returns: result
get_metadataB
Declarative bridge metadata (capabilities + states per device), as consumed by federation peers. HTTP-only on the REST side (/api/metadata).
Inputs: no named parameters.
get_sensorA
Get a single sensor's data by device ID.
Inputs: id (required).
get_sensorsA
List sensor devices with their metrics (illuminance, temperature, humidity, occupancy, etc.).
Inputs: no named parameters. Returns: result
get_statusA
Quick summary: how many lights on/off, active sensors, connected bridges, total devices.
Inputs: no named parameters.
list_acsA
List all ACs (Matter Thermostat endpoints) with on/off, system_mode, local temp, and setpoints in °C.
Inputs: no named parameters. Returns: result
refreshA
Force refresh all device states from Matter bridge and logical bridges.
Inputs: no named parameters.
register_deviceA
Commission a new Matter device using its pairing code (sent in the body, never the URL). Optionally specify IP and a name.
Inputs: code (required), ip, name.
remove_bridgeB
Remove a registered logical bridge.
Inputs: ip (required), port (required).
remove_nameC
Remove an alias from a device.
Inputs: id (required), name (required).
set_acA
Control an AC.
on=True turns on (resumes last non-zero SystemMode, defaulting to Cool=3); on=False turns off.
mode (overrides on): 0=Off, 1=Auto, 3=Cool, 4=Heat, 5=EmergencyHeat, 6=Precooling, 7=FanOnly, 8=Dry, 9=Sleep.
setpoint: in °C (e.g. 26.0); routed to the heating or cooling setpoint by mode.
fan_speed (0-100): forwarded to logical-bridge ACs that support it; rejected on physical Matter ACs.
Inputs: id (required), on, mode, setpoint, +1 more.
set_deviceC
Control a device. Brightness: 0.0 (off) to 1.0 (full). Temperature: Kelvin (e.g. 4000).
Inputs: id (required), brightness, temperature.
set_levelA
Set raw brightness level (0-254) for a device.
Inputs: id (required), level (required).
set_miredA
Set color temperature in mireds for a device.
Inputs: id (required), mireds (required).
set_nameB
Assign a display alias to a device. Aliases are for display only, not for ID resolution.
Inputs: id (required), name (required).
toggleB
Toggle a device on or off. If on, turns off. If off, turns on at full brightness.
Inputs: id (required).
unregister_nodeA
Unpair a fabric node by node_id (clean up phantom/duplicate entries).
Inputs: node_id (required).
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 23 tools
Some tools overlap in purpose: get_sensor/get_sensors/get_climate all report sensor-ish data, and set_device/set_level/set_mired/toggle/batch_control all control devices with slightly different parameters. Descriptions help but an agent could misselect between get_sensors and get_climate, or set_device versus set_level.
Most tools follow verb_noun with get_/set_ prefixes, but toggle, batch_control, refresh, and register_device/unregister_node deviate slightly (toggle lacks a noun, unregister_node uses 'node' vs 'device'). Overall pattern is discernible and consistent enough.
23 tools is at the high end for a controller but justified by diverse device types (lights, sensors, ACs, bridges). Still, it feels heavy; some tools could be consolidated (e.g., set_device overlapping with set_level/set_mired).
Covers core lifecycle: query (list, get, metadata), control (set, toggle, batch), naming, bridges, commissioning/unpairing, and refresh. Missing minor capabilities like updating device metadata or a generic get_device by ID, but agents can work around.
Maintenance
Related MCP Connectors
Discover MCP servers and A2A agents; verify, message, post, follow, react, and receive webhooks.
Connect MCP clients to 2,000+ AI models without managing provider API keys.
One MCP URL for all your connectors — scoped writes, enforced constraints, and a full audit trail.
Protocol-native energy infrastructure orchestration for AI data centers. Provides 46 MCP tools across 8 grid protocols (IEC-61850, DNP3, Modbus, OCPP, OpenADR, IEEE 2030.5, IEC 60870-5-104, ICCP) with 5 core API primitives: connect, dispatch, settle, comply, and intel. Enables AI agents to programmatically interact with substations, grid interfaces, and energy assets for real-time workload-grid coordination.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceA powerful MCP server that enables AI assistants to discover, commission, and control Matter-compatible smart home devices through a standardized interface.20 npm9MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to directly interact with Matter devices and protocol operations, including device commissioning, attribute read/write, commands, and event monitoring, through natural language.7MIT
- AlicenseBqualityDmaintenanceEnables control of ECHONETLite home automation devices like air conditioners and sensors via MCP, supporting HVAC management and real-time monitoring.141MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI agents to control Apple Home devices, scenes, and automations through MCP.11 npm39MIT