MCP server with tools to control an ESP32 bulb via MQTT (HiveMQ Cloud compatible).
- Exposes MCP tools for light control.
- Publishes MQTT commands to your broker (for example, HiveMQ Cloud).
- Lets your assistant map natural-language requests to MQTT actions.
Example intent mapping:
- "turn on my home light" ->
control_bulb("ON") - "turn off the bulb" ->
control_bulb("OFF")
-
Create and activate a virtual environment:
python3 -m venv .venv source .venv/bin/activate -
Install dependencies:
pip install -r requirements.txt
-
Copy env template and update values:
cp .env.example .env
-
Update
.env:MQTT_HOST= your broker hostMQTT_PORT=8883for TLSMQTT_USERNAME= broker usernameMQTT_PASSWORD= broker passwordMQTT_CONTROL_TOPIC= command topic (defaulthome/bulb/control)MQTT_STATUS_TOPIC= status topic (defaulthome/bulb/status)MQTT_USE_TLS=truefor cloud brokers
-
Run MCP server:
python server.py
-
Default transport is
stdio(good for local MCP clients). -
For cloud/web hosting (Render), use:
MCP_TRANSPORT=streamable-http python server.py
-
control_bulb(action)- Accepts
ONorOFF(case-insensitive) - Publishes to
MQTT_CONTROL_TOPIC - Use for natural-language light control requests
- Accepts
-
publish_raw(topic, payload, qos=1, retain=False)- Publishes any payload to any topic
-
get_config()- Returns non-sensitive runtime config summary
- Keep
.envprivate. Do not commit credentials. - Rotate broker password if it was shared publicly.
- ESP32 should subscribe to the same control topic configured here.
If Render shows "Application exited early", it usually means the server was
started in stdio mode and then exited (no stdio client attached).
Use Streamable HTTP mode on Render:
MCP_TRANSPORT=streamable-http- The app auto-binds to
0.0.0.0:$PORT
This is already configured in render.yaml.
