Tapo MCP について
Tapo MCPは、HTTPのMCPサーバーを通じてTP-Link Tapoのスマートホーム機器をAIエージェントに公開します。機器の検出、状態取得、操作に加え、カメラのスナップショットや対応するセンサー・電力データを利用できます。
主な機能
- 01Tapo機器の検出
- 02機器の状態と機能の取得
- 03対応する機器設定の操作
- 04カメラのスナップショット取得
- 05センサー・イベント・電力データの取得
- 06HTTP認証とホスト制御
活用シーン
- 01家庭内ネットワークの機器を検索
- 02照明のオン・オフや明るさ調整
- 03カメラ画像と検出イベントを確認
- 04温度や電力の記録を確認
MCP 対応
機器の検出、状態確認、操作、カメラのスナップショット取得をMCPツールとして提供し、`tapo://devices`リソースも公開します。MCPクライアントは各機器が対応する機能を利用でき、センサーや電力データも取得できます。
設定
ローカルサーバーの設定はどのクライアントでも共通です。コピーしてクライアントの MCP 設定ファイルに貼り付けてください。
docker run -i --rm -e TAPO_MCP_USERNAME -e TAPO_MCP_PASSWORD -e TAPO_MCP_CAMERA_USERNAME -e TAPO_MCP_CAMERA_PASSWORD -e TAPO_MCP_DISCOVERY_TARGET -e TAPO_MCP_API_KEY -e TAPO_MCP_ALLOWED_HOSTS -e TAPO_MCP_PUBLIC_URL -e TAPO_MCP_DISCOVERY_TIMEOUT -e TAPO_MCP_DISCOVERY_INTERVAL -e OTEL_EXPORTER_OTLP_ENDPOINT ghcr.io/mihai-dinculescu/tapo-mcp:0.6.0TAPO_MCP_USERNAMEシークレットTP-Link Tapo account emailTAPO_MCP_PASSWORDシークレットTP-Link Tapo account passwordTAPO_MCP_CAMERA_USERNAMEシークレットOptional camera account username; required for taking camera snapshotsTAPO_MCP_CAMERA_PASSWORDシークレットOptional camera account password; required for taking camera snapshotsTAPO_MCP_DISCOVERY_TARGETNetwork target for device discovery (e.g. 192.168.1.255)TAPO_MCP_API_KEYシークレットOptional Bearer token for API authenticationTAPO_MCP_ALLOWED_HOSTSOptional comma-separated Host header allowlist; replaces the loopback-only defaultTAPO_MCP_PUBLIC_URLOptional base URL clients reach the server at; enables short-lived snapshot linksTAPO_MCP_DISCOVERY_TIMEOUTDevice discovery timeout in seconds; must be between 1 and 60TAPO_MCP_DISCOVERY_INTERVALSeconds between background device discoveries that refresh the device list; must be at least TAPO_MCP_DISCOVERY_TIMEOUT and at most 86400 (one day); tool calls wait while a discovery runs, so a short interval delays them more oftenOTEL_EXPORTER_OTLP_ENDPOINTOptional OpenTelemetry collector endpoint for tracingローカルサーバーにはマシン上の実行環境(Node.js 18 以上など)が必要です。設定ファイルの場所はクライアントごとに異なります。
ghcr.io/mihai-dinculescu/tapo-mcp:0.6.0Streamable HTTPツール
ローカルサーバーのツールはマシン上で起動して初めて取得できます。メンテナーはまだツール一覧を提供していません。
詳細
tapo-mcp
Tapo スマートホームデバイスを、Model Context Protocol 経由で AI から呼び出せるツールおよびリソースとして公開する MCP サーバーです。
t apo クレートと rmcp SDK を基盤としています。HTTP サーバーとして動作します(Streamable HTTP トランスポート)。
プロンプトの例
「Tapo デバイスをすべて一覧表示して」
「オフィスのライトを消して」
「電源タップのスマートプラグ 4 をオンにして」
「オフィスのライトは点灯してる?」
「寝室のライトの明るさを 50% に設定して」
「リビングのライトをコーラルに変えて」
「ベビーモニターからスナップショットを撮って」
「キッチンの温度は?」
「リビングの温湿度センサーの過去 24 時間の温度を表示して」
「スマートボタンの直近 5 件のイベントを一覧表示して」
「今月、洗濯機のプラグは毎日どれくらい電力を使った?」
「過去 6 時間のテレビの消費電力を表示して」
ツール
| ツール | 説明 |
|---|---|
list_devices | ネットワーク上で利用可能な Tapo デバイスを一覧表示します(設定および取得の機能を含みます)。 |
check_device | デバイス ID が指定された IP に対応することを確認します。 |
get_device_state | デバイスの現在の状態(例:{"type": "DeviceInfo"})を取得します。機能のパラメーターを確認してから、check_device を実行します。 |
control_device | 設定機能を 1 ~ 12 個、順番に適用してデバイスを操作します。個数と値を確認してから、check_device を実行します。デバイスが対応していない機能がある場合、いずれも適用される前に失敗します。 |
take_snapshot | Tapo カメラから静止 JPEG スナップショット(約 640x360)を撮影します。デバイス ID、撮影時刻、サイズをテキストで返し、TAPO_MCP_PUBLIC_URL が設定されている場合は有効期間の短いリンクも返します(スナップショットリンクを参照)。最初に check_device を実行します。 |
リソース
| URI | 説明 |
|---|---|
tapo://devices | 検出された Tapo デバイスの JSON リストです。 |
機能
デバイスと子デバイスは、それぞれ対応する設定機能と取得機能のリストを公開します。子デバイスには独自の IP がなく、ip は親デバイスの IP です。子デバイスの id とともに親デバイスの IP を渡してください。
設定機能
| 機能 | 説明 |
|---|---|
Brightness | デバイスの明るさを設定します(1-100) |
Color | プリセット名を使ってデバイスの色を設定します |
OnOff | デバイスをオンまたはオフにします |
機能の取得
| 機能 | 説明 |
|---|---|
Detections | カメラの SD カードに保存された検出データと、検出されたイベント(人物、動きなど)を最大 24 時間分読み取ります(C120, C210, C220, C225, C325WB, C520WS, TC40, TC70) |
DeviceInfo | デバイスの現在の状態を読み取ります |
EnergyDataHourly | 1 時間ごとの消費電力量(Wh)を最大 8 日分読み取ります(P110, P110M, P115, P304M, P316M) |
EnergyDataDaily | 1 日ごとの消費電力量(Wh)を 1 年の 4 分の 1 の期間分読み取ります(P110, P110M, P115, P304M, P316M) |
EnergyDataMonthly | 1 か月ごとの消費電力量(Wh)を 1 年分読み取ります(P110, P110M, P115, P304M, P316M) |
PowerDataEvery5Minutes | 5 分ごとの消費電力(W)を最大 12 時間分読み取ります(P110, P110M, P115, P304M, P316M) |
PowerDataHourly | 1 時間ごとの消費電力(W)を最大 6 日分読み取ります(P110, P110M, P115, P304M, P316M) |
Snapshot | 静止 JPEG スナップショットを撮影します。専用の take_snapshot ツールから提供されます(バイナリ形式で、JSON の状態ではありません) |
TemperatureHumidityRecords | 15 分間隔で記録された過去 24 時間分の温度と湿度の記録を読み取ります(T310, T315) |
TriggerLogs | ハブの子センサー(S200, T100, T110, T300)からページ分割されたトリガーログを読み取ります |
設定
すべての設定は、TAPO_MCP_ がプレフィックスの環境変数を使用します。
| 変数 | 必須 | デフォルト値 | 説明 |
|---|---|---|---|
TAPO_MCP_USERNAME | はい | — | Tapo アカウントのメールアドレス |
TAPO_MCP_PASSWORD | はい | — | Tapo アカウントのパスワード |
TAPO_MCP_CAMERA_USERNAME | いいえ | — | カメラアカウントのユーザー名1。take_snapshot で必要です。 |
TAPO_MCP_CAMERA_PASSWORD | いいえ | — | カメラアカウントのパスワード1。take_snapshot で必要です。 |
TAPO_MCP_DISCOVERY_TARGET | はい | — | デバイス検出のネットワークターゲット(例:192.168.1.255) |
TAPO_MCP_HTTP_ADDR | いいえ | 127.0.0.1:3000 | サーバーがリッスンするアドレス |
TAPO_MCP_DISCOVERY_TIMEOUT | いいえ | 5 | 検出タイムアウト(秒)。1 以上 60 以下である必要があります2 |
TAPO_MCP_DISCOVERY_INTERVAL | いいえ | 600 | デバイスリストを更新するバックグラウンド検出の間隔(秒)。TAPO_MCP_DISCOVERY_TIMEOUT 以上、86400(1 日)以下である必要があります2 |
TAPO_MCP_API_KEY | いいえ | — | HTTP 認証用のベアラートークン(下記参照) |
TAPO_MCP_ALLOWED_HOSTS | いいえ | ループバックのみ | 許可する Host ヘッダーのカンマ区切りリスト(ネットワークへの公開を参照) |
TAPO_MCP_PUBLIC_URL | いいえ | — | クライアントがサーバーにアクセスするためのベース URL(例:https://tapo.example.com)。有効にすると、有効期間の短いスナップショットリンクを利用できます(スナップショットリンクを参照) |
認証
TAPO_MCP_API_KEY が設定されている場合、サーバーはすべての HTTP リクエストに Authorization: Bearer <key> ヘッダーを含めることを要求します。トークンがないか無効なリクエストには、401 Unauthorized レスポンスが返されます。
この変数が未設定(または空、空白文字のみ)の場合、サーバーは認証なしで動作します。
ネットワークへの公開
サーバーは、MCP Streamable HTTP の DNS リバインディング保護を適用します。デフォルトでは、ループバックの Host ヘッダー(localhost、127.0.0.1、::1)のみを受け付けます。これにより、悪意のあるウェブページが DNS リバインディングを利用して、ローカルで実行中のサーバーにアクセスするのを防ぎます。MCP エンドポイントへのリクエストで、これ以外の Host が指定されている場合は 403 Forbidden レスポンスが返されます。スナップショットリンクにはこのチェックは適用されません(「スナップショットリンク」を参照)。
LAN 経由または別のホストからサーバーにアクセスするには、クライアントが接続する正確なホスト名または host:port 形式のオーソリティを TAPO_MCP_ALLOWED_HOSTS に設定します。例:TAPO_MCP_ALLOWED_HOSTS="tapo-mcp.lan:3000,192.168.1.50:3000"。この設定はデフォルトのループバック許可リストを置き換えるため、引き続きループバックからもアクセスする必要がある場合は、ループバックのエントリーも含めてください。
認証なしでスマートホームを制御できる状態での提供を防ぐため、サーバーは TAPO_MCP_API_KEY が設定されていない状態で、ループバック以外のアドレス(例:0.0.0.0:3000)にバインドすると起動を拒否します。API キーを設定するか、ループバックアドレスにバインドしてください。
スナップショットリンク
MCP クライアントの中には、画像の結果をモデルに渡さないものもあれば、モデルに画像を表示しても、ユーザーに渡せるものを何も提供しないものもあります。TAPO_MCP_PUBLIC_URL を設定すると、take_snapshot は <TAPO_MCP_PUBLIC_URL>/snapshots/<token>.jpg を指す url(およびその expires_at)も返します。これにより、エージェントはリンクを共有したり、ファイルをダウンロードしたりできます。
- リンクは API キーなしで提供されるため、ブラウザーから直接開けます。また、
TAPO_MCP_ALLOWED_HOSTSのHost許可リストも適用されません。パス内のランダムなトークンだけが認証情報となり、リンクを持っている人は誰でも、有効期限が切れるまでそのフレームを表示できます。 - 各リンクの有効期間は 5 minutes です。スナップショットはメモリ内にのみ保持され、ディスクには書き込まれません。期限切れのスナップショットは 1 minute 以内に削除され、保持されるのは最新の最大 1024 件です。
- 認証を行うリバースプロキシ(Cloudflare Access など)の背後では、すでにプロキシにサインインしているブラウザーで開いたリンクは機能します。ブラウザー以外からの取得(
curlや、エージェントによるファイルのダウンロード)には、プロキシ独自の認証情報、または/snapshots/に対するポリシー例外が必要です。
TAPO_MCP_PUBLIC_URL が設定されていない場合、リンクは返されず、/snapshots/ ルートも提供されません。
OpenTelemetry
トレースをエクスポートするには、OTEL_EXPORTER_OTLP_ENDPOINT に、パスを含む OTLP/HTTP トレースエンドポイントの完全な URL(例:http://alloy.monitoring:4318/v1/traces)を設定します。OTEL_RESOURCE_ATTRIBUTES はリソース属性を追加します。RUST_LOG(デフォルトは tapo_mcp=info)も、どのスパンをエクスポートするかを決定します。
トレースの対象:
- ツール呼び出し。 各
tools/callリクエストは、OpenTelemetry MCP セマンティック規約に従い、呼び出し全体を対象とする、tools/call <tool>という名前のサーバースパンを1つ生成します。このスパンには、mcp.method.name、gen_ai.tool.name(サーバーが提供するツールの場合のみ)、gen_ai.operation.name、jsonrpc.request.id、mcp.session.id、mcp.protocol.versionのほか、ツールが受け取る場合はtapo.device.idとtapo.device.ipが記録されます。呼び出しが失敗すると、エラーステータスとerror.type(JSON-RPC エラーコード、またはtool_error)が記録されます。その中で、check_deviceはデバイスの検証を、get_capability、set_capability、またはcapture_snapshotはデバイスへのリクエストを対象とします。get_capabilityとset_capabilityにはtapo.capabilityが記録され、control_deviceには適用する各機能につき1つのset_capabilityスパンが記録されます。ステップが失敗すると、エラーステータスと、DeviceNotFoundやWrongDeviceTypeなどの失敗の種類を示すerror.typeが記録されます。 - バックグラウンドジョブ。 デバイス検出のたびに実行される
refresh_devicesと、期限切れのスナップショットリンクを一掃するたびに実行されるprune_snapshotsが対象です。
認証情報、API キー、画像データが記録されることはありません。ツールの引数も記録されませんが、id と ip、および失敗した呼び出しのエラーメッセージは例外です。エラーメッセージには、拒否された値が含まれる場合があります。
受信した W3C トレースコンテキストは尊重されます。リクエストの params._meta に traceparent(任意で tracestate)が含まれている場合、呼び出しをトレースする MCP クライアントから送られるコンテキストと同様に、ツール呼び出しのスパンはその子となり、そのトレースに参加します。呼び出しを含む HTTP リクエストに traceparent ヘッダーがある場合(たとえばトレース対応のリバースプロキシから送られた場合)、これはスパンリンクとして記録されます。_meta にコンテキストがない場合は、HTTP ヘッダーが親として使用されます。どちらもない場合は、新しいトレースが開始されます。
デプロイ
Docker
docker run --rm \
--network host \
-e TAPO_MCP_USERNAME="[email protected]" \
-e TAPO_MCP_PASSWORD="<YOUR_TAPO_PASSWORD>" \
-e TAPO_MCP_CAMERA_USERNAME="<YOUR_CAMERA_ACCOUNT_USERNAME>" \
-e TAPO_MCP_CAMERA_PASSWORD="<YOUR_CAMERA_ACCOUNT_PASSWORD>" \
-e TAPO_MCP_DISCOVERY_TARGET="192.168.1.255" \
-e TAPO_MCP_API_KEY="<YOUR_TAPO_MCP_API_KEY>" \
ghcr.io/mihai-dinculescu/tapo-mcp:latest
注: イメージは
0.0.0.0:3000にバインドするため、TAPO_MCP_API_KEYが必要です。これが設定されていない場合、サーバーはループバック以外のアドレスでは起動しません(ネットワークへの公開を参照)。ループバックではなくホスト名または LAN IP でサーバーに接続するには、TAPO_MCP_ALLOWED_HOSTSも設定してください。スナップショットリンクを利用するには、-e TAPO_MCP_PUBLIC_URL="https://tapo.example.com"を追加します。
注: コンテナがローカルネットワーク上の Tapo デバイスに UDP ブロードキャストで接続して検出できるようにするには、
--network hostが必要です。macOS と Windows では--network hostはサポートされていません。代わりに-p 3000:3000を使用できますが、Docker Desktop は LAN にアクセスできない VM 内でコンテナを実行するため、デバイス検出は機能しません。
Kubernetes
まず Secret と ConfigMap を作成します。
kubectl create secret generic tapo-mcp-secrets \
--from-literal=TAPO_MCP_USERNAME="[email protected]" \
--from-literal=TAPO_MCP_PASSWORD="<YOUR_TAPO_PASSWORD>" \
--from-literal=TAPO_MCP_CAMERA_USERNAME="<YOUR_CAMERA_ACCOUNT_USERNAME>" \
--from-literal=TAPO_MCP_CAMERA_PASSWORD="<YOUR_CAMERA_ACCOUNT_PASSWORD>" \
--from-literal=TAPO_MCP_API_KEY="<YOUR_TAPO_MCP_API_KEY>"
kubectl create configmap tapo-mcp-config \
--from-literal=TAPO_MCP_DISCOVERY_TARGET="192.168.1.255"
次に Deployment を適用します。
apiVersion: apps/v1
kind: Deployment
metadata:
name: tapo-mcp
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: tapo-mcp
template:
metadata:
labels:
app: tapo-mcp
spec:
hostNetwork: true
containers:
- name: tapo-mcp
image: ghcr.io/mihai-dinculescu/tapo-mcp:latest
env:
- name: TAPO_MCP_USERNAME
valueFrom:
secretKeyRef:
name: tapo-mcp-secrets
key: TAPO_MCP_USERNAME
- name: TAPO_MCP_PASSWORD
valueFrom:
secretKeyRef:
name: tapo-mcp-secrets
key: TAPO_MCP_PASSWORD
- name: TAPO_MCP_CAMERA_USERNAME
valueFrom:
secretKeyRef:
name: tapo-mcp-secrets
key: TAPO_MCP_CAMERA_USERNAME
- name: TAPO_MCP_CAMERA_PASSWORD
valueFrom:
secretKeyRef:
name: tapo-mcp-secrets
key: TAPO_MCP_CAMERA_PASSWORD
- name: TAPO_MCP_API_KEY
valueFrom:
secretKeyRef:
name: tapo-mcp-secrets
key: TAPO_MCP_API_KEY
- name: TAPO_MCP_DISCOVERY_TARGET
valueFrom:
configMapKeyRef:
name: tapo-mcp-config
key: TAPO_MCP_DISCOVERY_TARGET
注: UDP ブロードキャストによる検出には
hostNetwork: trueが必要です。これは Docker の--network hostと同様です。クライアントはループバックではなくノードの IP またはホスト名でサーバーに接続するため、TAPO_MCP_ALLOWED_HOSTSを適切に設定してください(ネットワークへの公開を参照)。スナップショットリンクを利用するには、ConfigMap と Deployment のenvにTAPO_MCP_PUBLIC_URLを追加します。
OpenClaw
OpenClaw エージェントからデプロイ済みの tapo MCP サーバーを簡単に利用できる、tapo スキルです。
次のコマンドでインストールします。
npx clawhub install tapo
コントリビューション
コントリビューションを歓迎します。ぜひご参加ください。/tapo-mcp/CONTRIBUTING.mdをご覧ください。
Footnotes
-
Tapo アプリで各カメラの「カメラ設定」>「詳細設定」>「カメラアカウント」から設定します。TP-Link クラウドアカウントとは別のものです。 ↩ ↩2
-
バックグラウンド検出の実行中は、デバイスに接続するツール呼び出しは検出が完了するまで待機し、検出は実行中の呼び出しが完了するまで待機します。1 回の実行には
TAPO_MCP_DISCOVERY_TIMEOUT秒に加え、デバイスへのログインに数秒かかります。デバイスの応答が遅い場合はさらに時間がかかります。間隔が短いと、この一時停止が頻繁に発生します。デフォルトのタイムアウトで間隔を15にすると、15 秒ごとに数秒間、ツール呼び出しが停止することがあります。list_devicesとtapo://devicesリソースは待機しません。 ↩ ↩2
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。