Skip to main content
Glama
namiyama814

SwitchBot Plug Mini MCP

by namiyama814
README.md
# SwitchBot Plug Mini MCP

Remote [Model Context Protocol (MCP)](https://modelcontextprotocol.io/) server on [Cloudflare Workers](https://developers.cloudflare.com/workers/) that controls **SwitchBot Plug Mini (JP)** via the [SwitchBot Open API v1.1](https://github.com/OpenWonderLabs/SwitchBotAPI), with **GitHub OAuth** for client authentication.

## Tools (v1)

| Tool | Description |
|------|-------------|
| `list_plug_minis` | List Plug Mini (JP) devices (`deviceId`, `deviceName`, …) |
| `get_plug_status` | Get status (voltage, power usage, current, …) |
| `turn_on_plug` | Turn a plug on |
| `turn_off_plug` | Turn a plug off |
| `toggle_plug` | Toggle on/off |

Only GitHub users listed in `ALLOWED_GITHUB_USERS` can use these tools.

## Prerequisites

- Node.js 18+
- Cloudflare account + Wrangler
- SwitchBot app Open Token **and** Secret Key (app v6.14+)
- Two GitHub OAuth Apps (local + production), or one if you only deploy

## Setup

```bash
npm install
npm run cf-typegen
```

### 1. Create KV namespace

```bash
npx wrangler kv namespace create "OAUTH_KV"
```

Copy the returned ID into [`wrangler.jsonc`](wrangler.jsonc) (`kv_namespaces[0].id`).

### 2. GitHub OAuth App

Create an OAuth App at [GitHub Developer Settings](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app):

**Production**

- Homepage URL: `https://switchbot-mcp.<your-subdomain>.workers.dev`
- Authorization callback URL: `https://switchbot-mcp.<your-subdomain>.workers.dev/callback`

**Local development**

- Homepage URL: `http://localhost:8788`
- Authorization callback URL: `http://localhost:8788/callback`

### 3. Secrets

**Local** — copy [`.dev.vars.example`](.dev.vars.example) to `.dev.vars` and fill in:

```
GITHUB_CLIENT_ID=...
GITHUB_CLIENT_SECRET=...
COOKIE_ENCRYPTION_KEY=...   # e.g. openssl rand -hex 32
SWITCHBOT_TOKEN=...
SWITCHBOT_SECRET=...
ALLOWED_GITHUB_USERS=your-github-login
```

**Production**

```bash
npx wrangler secret put GITHUB_CLIENT_ID
npx wrangler secret put GITHUB_CLIENT_SECRET
npx wrangler secret put COOKIE_ENCRYPTION_KEY
npx wrangler secret put SWITCHBOT_TOKEN
npx wrangler secret put SWITCHBOT_SECRET
npx wrangler secret put ALLOWED_GITHUB_USERS
```

## Develop

```bash
npm start
# http://localhost:8788
```

Test with [MCP Inspector](https://modelcontextprotocol.io/docs/tools/inspector):

```bash
npx @modelcontextprotocol/inspector@latest
```

Connect to `http://localhost:8788/mcp` (Streamable HTTP) or `http://localhost:8788/sse` (legacy SSE). Complete the GitHub OAuth flow, then list tools.

## Deploy

```bash
npm run deploy
```

Endpoint: `https://switchbot-mcp.<your-subdomain>.workers.dev/mcp`

## Connect from Cursor / Claude Desktop

Remote MCP clients that need OAuth typically use `mcp-remote`:

```json
{
  "mcpServers": {
    "switchbot": {
      "command": "npx",
      "args": [
        "mcp-remote",
        "https://switchbot-mcp.<your-subdomain>.workers.dev/mcp"
      ]
    }
  }
}
```

On first connect, a browser window opens for GitHub login and consent.

## Architecture

- **OAuth**: `@cloudflare/workers-oauth-provider` — MCP client ↔ this Worker ↔ GitHub
- **MCP**: `McpAgent` Durable Object (`/mcp` Streamable HTTP, `/sse` legacy)
- **SwitchBot**: HMAC-SHA256 signed requests to `https://api.switch-bot.com/v1.1`

SwitchBot credentials are Worker secrets (one shared account), not per GitHub user.

## License

See [LICENSE](LICENSE).