Skip to main content
Glama
mrkutin

Sonoff MCP Server

by mrkutin
README.md
# Sonoff MCP Server

A [Model Context Protocol](https://modelcontextprotocol.io) server that lets AI
agents — Claude Code, claude.ai, or any MCP client — control **Sonoff smart-home
devices** through the eWelink Cloud API. Ask an agent to "turn on the heater" or
"what's the temperature in the nursery?" and it calls a real device.

Runs as a remote MCP connector over HTTPS with full OAuth 2.0, so it can be
attached to hosted AI clients, not just local ones.

## Architecture

```
AI client (Claude Code / claude.ai)
      │  HTTPS + OAuth 2.0 (Authorization Code + PKCE)
      ▼
  reverse proxy  ──▶  sonoff-mcp (FastMCP, streamable-http)
                            │  HTTPS
                            ▼
                    eWelink Cloud API (CoolKit Open Platform v2)
                            │
                            ▼
                    Sonoff devices (THR316D, MINIR4, SV, BASICR2, …)
```

- **Transport** — streamable-http (FastMCP), fronted by a reverse proxy for TLS
- **Auth** — OAuth 2.0 Authorization Code + PKCE between the AI client and the server
- **Upstream** — eWelink Cloud API v2 with its own OAuth token flow
- **SDK** — [FastMCP](https://github.com/modelcontextprotocol) (`mcp[cli]`), Python 3.12+, `aiohttp`

## Tools

| Tool | Description |
|------|-------------|
| `list_devices` | All devices with live state (on/off, online, temp/humidity for thermostats) |
| `get_device` | Detailed device info (model, firmware, power, thermostat mode) |
| `switch_device` | Turn a device on/off (disables auto mode on thermostats) |
| `get_sensor_data` | Current temperature and humidity from a sensor/thermostat |
| `set_thermostat` | Set thermostat mode (`heat` / `cool` / `dry` / `off`) with thresholds |

Devices are addressed by **name** (partial, case-insensitive match) or device ID,
so an agent can act on "living room lamp" without knowing internal identifiers.

## Running

```bash
cp .env.example .env      # eWelink app + MCP OAuth credentials
docker compose up -d
# then visit /ewelink/setup once to authorize your eWelink account
```

Configuration (`.env.example`):

- `EWELINK_APP_ID` / `EWELINK_APP_SECRET` — register at [dev.ewelink.cc](https://dev.ewelink.cc)
- `EWELINK_REGION` — eWelink data center region (`eu`, `us`, `as`, `cn`)
- `MCP_CLIENT_ID` / `MCP_CLIENT_SECRET` — OAuth credentials for the MCP client
- `SERVER_URL` — public base URL the connector is served from

## Notes

- Used in production as the smart-home action layer behind an
  [AI phone assistant](https://github.com/mrkutin/voice-assistant) — the LLM calls
  these tools to control devices from a phone call or SMS.
- The server capability-detects each device from its eWelink parameters, so
  switches, thermostats, and sensors are handled through a single unified model.