技術 約8分で読めます

SwitchBot公式CLI @switchbot/openapi-cli が登場、MCPサーバーとMQTTストリームでAIエージェントから家電操作

いけさん目次

SwitchBot Japan 公式アカウントが、SwitchBot OpenAPI 向けの CLI ツールを公開したと告知した。
リポジトリは OpenWonderLabs/switchbot-openapi-cli、npm 配布は @switchbot/openapi-cli
ライセンスは MIT、2026-04-17 に初コミットされたばかりで、書いている時点の GitHub スターは 88 ほど。

眺めてみると、Hub / Bot / カーテン / ロック / 各種センサー / プラグ / IR 家電を CLI から叩けるだけでなく、
MCP サーバーとしてそのまま Claude や Cursor に刺さる ようになっていて、想像よりだいぶ意欲的な作りだった。
雑にメモを残す。

どういうツールか

一言でいうと、SwitchBot の Cloud API v1.1 を叩くための公式 CLI。
Node.js ≥ 18 で動く TypeScript 実装で、npm install -g @switchbot/openapi-cli すると switchbot コマンドが生える。

READMEが「Human / Script / Agent」の 3 種類の使い手を想定している、という書き方をしているのが面白い。

  • Human: 色付きテーブル、エラー時のヒント、シェル補完、switchbot doctor での自己診断
  • Script: --json / --format=tsv/yaml/id--fields による列制御、安定した exit code、history replay、監査ログ
  • Agent: switchbot mcp serve(stdio MCP サーバー)、schema exportplan run、破壊的コマンドへのガード

同じバイナリで同じカタログ・キャッシュ・HMAC クライアントを共有しているので、使い分けはほぼゼロコスト、と書いてある。

セットアップ

SwitchBot アプリの「プロフィール → 設定 → 開発者向けオプション」からトークンとシークレットを取る。
あとはそれを CLI に食わせるだけ。

npm install -g @switchbot/openapi-cli

# ~/.switchbot/config.json に保存(パーミッションは 0600)
switchbot config set-token <token> <secret>

# 手元のデバイス一覧
switchbot devices list

# 操作
switchbot devices command <deviceId> turnOn

環境変数 SWITCHBOT_TOKEN / SWITCHBOT_SECRET が config ファイルより優先される。
CI に刺すならこっち。

よくある操作が全部生えている

主要なサブコマンドをざっと挙げておく。全部 --help で使い方が読める。

  • devices list / devices status / devices command / devices batch / devices watch
  • scenes list / scenes execute
  • webhook setup/query/update/delete(イベント送信先の URL 管理)
  • events tail(ローカルでポートを開いて webhook を受ける)
  • events mqtt-tail(SwitchBot の MQTT から直接イベントを流す)
  • plan run(JSON 記述の宣言的バッチ実行)
  • mcp serve(MCP stdio サーバー)
  • doctor / quota / history / catalog / schema / capabilities / cache / completion

個人的に「ちゃんとしてるな」と思った点をいくつか。

--dry-run で POST/PUT/DELETE を投げずに中身だけ出せる。
GET は普通に走るので、対象デバイスの現在の状態を見ながら破壊的操作を事前確認できる。
未知のデバイス ID やカタログにない不正コマンドは exit 2 で弾くので、pre-flight ゲートとしてそのまま使える。

devices expand は、setAll "26,2,2,on" みたいなパック済みの文字列を、--temp 26 --mode cool --fan low --power on のように読める形で組み立ててくれる。
エアコン / カーテン / ブラインドチルト / リレースイッチ用。
カンマ区切りの呪文を覚えなくていい。

devices explain は、カタログ上のメタ情報(サポートコマンド・パラメータ・ステータスフィールド)と現在のライブステータスを 1 回の API 呼び出しでまとめて返す。
Hub の場合は子デバイスも出る。
statusdescribe を別々に呼ぶ必要がない。

quota はアカウントあたり 10,000 req/day の制限に対して、ローカルの ~/.switchbot/quota.json でカウントを取る。
--no-quota でトラッキング停止も可。
429 retry は backoff 指定もできて、exponential / linear を選べる。

catalog は 42 種類の標準デバイスをオフラインカタログとして持っていて、~/.switchbot/catalog-overlay.json を置けばユーザー側で上書きや追加ができる。
API を叩かずにコマンドとパラメータの形を参照できるので、switchbot devices commands Bot みたいな引き方ができる。

events mqtt-tail が便利そう

個人的に一番刺さったのがこれ。
REST の webhook を立てなくても、REST のトークンだけで SwitchBot の MQTT に接続して、シャドー更新イベントをそのままストリームできる。
クライアント証明書は初回アクセスで自動プロビジョン。

# 全イベントを JSONL で tail
switchbot events mqtt-tail --json

# 30秒で自動終了
switchbot events mqtt-tail --for 30s --json

# トピックでフィルタ
switchbot events mqtt-tail --topic 'switchbot/#'

出力はこんな形で、1 行 1 イベントの JSONL。

{ "t": "2024-01-01T12:00:00.000Z", "topic": "switchbot/abc123/status", "payload": { } }

さらに --sink で出力先を選べる。file / webhook / openclaw / telegram / homeassistant に直接投げられるので、 たとえば Home Assistant の webhook trigger に流し込むだけで state 連動が完成する。

switchbot events mqtt-tail \
  --sink homeassistant \
  --ha-url http://homeassistant.local:8123 \
  --ha-webhook-id switchbot

ついでに各デバイスの最新状態は ~/.switchbot/device-history/<deviceId>.json にリングバッファ(最新 + 直近 100 件)で勝手に保存される。
これが後述の MCP の get_device_history ツールのデータソースになる。

MCP サーバー内蔵が本題

switchbot mcp serve で stdio の MCP サーバーとして動く。Claude Desktop / Cursor / Claude Code 等から設定を足せば、以下の 8 ツールと 1 リソースが見える。

  • list_devices
  • describe_device
  • get_device_status
  • send_command
  • list_scenes
  • run_scene
  • search_catalog
  • account_overview
  • リソース switchbot://events(リアルタイムのシャドー更新)

ポイントは、MCP モードでも CLI と同じカタログとキャッシュを共有していること。
なので、エージェントがコマンドを呼ぶ前に「このデバイスタイプは何ができるのか」を API 呼び出しなしで把握できる。
Smart Lock の unlock のような破壊的コマンドはガードが入っていて、エージェントが勝手に鍵を開けないようになっている、と README にも書いてある。

エージェントフレームワーク側に渡したいときは、

switchbot schema export
switchbot capabilities --json

でカタログと CLI マニフェストを JSON でぶちまけられる。 capabilities の各コマンドに {mutating, consumesQuota, idempotencySupported, agentSafetyTier, verifiability, typicalLatencyMs} のメタが付いていて、 エージェント側の tool 選択プロンプトに埋め込む想定っぽい。

plan(宣言的バッチ操作)

plan run plan.json で、command / scene / wait ステップを順に回せる。
途中で失敗したらデフォルトで止まる(--continue-on-error で全部走らせる指定もある)。
plan schema で JSON Schema が出るので、そのままエージェントに食わせれば LLM がプランを書ける。

switchbot plan schema                    # JSON Schema を出す
switchbot plan validate plan.json        # 実行せず検証だけ
switchbot --dry-run plan run plan.json   # GETは走る、mutationは止める
switchbot plan run plan.json --yes       # 破壊的ステップ許可

「朝 7 時にリビングを 50% にして 10 秒待ってからエアコン ON」みたいな処理を、シェルスクリプトではなく JSON で書いて plan run に渡す、という設計思想。
外部ランナー(cron / launchd / GitHub Actions)から叩く前提に寄っている。

落ち着いた作り

README を見るに、

  • Vitest 692 ケース、axios はモック、CI はネット未接続で通る
  • HMAC-SHA256 署名はちゃんと token + t + nonce → sign で作っている
  • --verbose で HTTP の req/res を stderr に吐ける
  • 監査ログ ~/.switchbot/audit.log に mutating コマンドが JSONL で残る
  • history replay <n> で過去の操作をそのまま再実行できる
  • エラーコード(151/152/160/161/171/190/401/429)を人間向けの英文にマップ

という感じで、運用を意識した作りになっている。

シェル補完も bash / zsh / fish / powershell まで揃っていて、

echo 'source <(switchbot completion zsh)' >> ~/.zshrc

で即補完が効く。

公式が MCP まで同梱してきたのは大きい

SwitchBot はずっと非公式ライブラリに頼るエコシステムだったので、公式が CLI + MCP + MQTT までまとめて出してきたのは普通に大きい。
特に MCP サーバーが同梱されているおかげで、

  1. switchbot mcp serve を Claude Desktop なりに足す
  2. 「リビングのエアコンを 26 度で冷房にして」と話しかける
  3. エージェントが search_catalog でコマンド形式を確認し、send_command で叩く

という流れが、追加のツール実装なしで完成する。
家のセンサー値を LLM に食わせて「そろそろ部屋暑いから AC つけて」みたいな自動化を組むハードルがかなり下がっている。

個人的には Home Assistant の webhook 連動と、events mqtt-tail --sink file での JSONL ログ収集を試してみたいところ。
既存の SwitchBot 非公式 API 叩きスクリプトを置き換えるかどうかは、実際にトークンをセットして触ってみてから判断する。

そういえば 1 月に AI と喋れる環境を作る(3)ついに喋れた編 を書いたとき、かなちゃんから SwitchBot の温湿度計を叩いて「今何度?」に答えさせたり、「電気消して」で照明を操作したりしていた。
あのときは自前で axios に HMAC 署名を載せて、最低限のエンドポイントだけ叩く薄いラッパを書いていた。
@switchbot/openapi-cli が出た今なら、署名生成も quota トラッキングも 429 リトライも CLI 側に寄せられるので、あの自作ラッパは丸ごと消して switchbot devices command の呼び出しに置き換えるだけでよさそう。
ついでに events mqtt-tail --sink file で温湿度と CO2 の JSONL を残しておけば、あとから Gemini に「昨日帰宅してからの室温の推移」を聞くような遊びもやりやすい。
あの頃のセットアップを組み直したくなってきた。


参考: README (OpenWonderLabs/switchbot-openapi-cli) / @switchbot/openapi-cli on npm / SwitchBot API v1.1 docs