WhatsMCP について
WhatsMCPは、連携した通常のWhatsAppアカウントをAIエージェントから利用できるホステッド型MCPサーバーです。リモートHTTPエンドポイントでメッセージやアカウント管理のツールを提供し、SIP通話にも対応します。
主な機能
- 01メッセージの読み取りと送信
- 02連絡先とグループの管理
- 03メッセージへのリアクションと編集
- 04Webhookによる受信メッセージの取得
- 05メッセージ添付ファイルの取得
- 06SIP経由のWhatsApp通話転送
活用シーン
- 01エージェントによるWhatsAppチャットの確認と返信
- 02エージェントからの連絡先とグループの管理
- 03受信メッセージのWebhook配信
- 04WhatsApp通話の電話機またはPBXへの接続
MCP 対応
WhatsMCPは、ホステッド型のStreamable HTTPエンドポイントを通じて、WhatsAppのアカウントやメッセージを扱うツールをMCPクライアントに公開します。クライアントはOAuthまたはAPIキーで認証します。
設定
リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。
https://api.whatsmcp.com/mcpclaude mcp add --transport http whatsmcp-715771 https://api.whatsmcp.com/mcp{"mcpServers":{"whatsmcp-715771":{"type":"http","url":"https://api.whatsmcp.com/mcp"}}}Cursor で開く{"servers":{"whatsmcp-715771":{"type":"http","url":"https://api.whatsmcp.com/mcp"}}}VS Code で開く{"mcpServers":{"whatsmcp-715771":{"type":"http","url":"https://api.whatsmcp.com/mcp"}}}{"mcpServers":{"whatsmcp-715771":{"serverUrl":"https://api.whatsmcp.com/mcp"}}}コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。
ツール
詳細
WhatsMCP
エージェントに実際の WhatsApp アカウントを持たせましょう。
ホスト型のModel Context Protocolサーバーです。
一度電話番号を連携すれば、任意の MCP クライアントから 1 つの HTTPS エンドポイントに接続できます。SDK は不要で、
インストールもローカルでの実行も必要ありません。
クイックスタート · クライアントの接続 · ツール · ポーリング · Webhook · SIP トランク · セキュリティ
エージェントはチャットを読み、返信し、アドレス帳から相手を検索し、メッセージにリアクションしたり編集したりできます。また、グループを管理し、連絡先をブロックまたはブロック解除し、添付ファイルを取得して、Webhook で受信メッセージを受け取れます。同じ連携済み電話番号をSIP トランクにも接続できるため、WhatsApp 通話をデスクフォン、ソフトフォン、PBX で受けたり、内線からその番号で WhatsApp 通話を発信したりできます。SIP 経由の通話をご覧ください。
インストールもローカルでの実行も必要ありません。Streamable HTTP 経由のリモート MCP サーバーです。クライアントは https://api.whatsmcp.com/mcp に接続し、OAuth でサインインするか、API キーを提示します。
**WhatsApp Business API ではありません。**テンプレート、24 時間のセッション時間制限、メッセージの承認、会話ごとの課金はありません。スマートフォンで QR コードをスキャンして通常の WhatsApp アカウントを連携します。WhatsApp Web と同じ方法で、エージェントは連携済みデバイスとしてそのアカウントを使用します。
目次
- クイックスタート
- 登録
- WhatsApp 電話番号の連携
- API キーの作成
- クライアントの接続
- ツール
- 連絡先
- 受信メッセージの読み取り
- Webhook
- 送信
- グループとチャンネル
- SIP 経由の通話
- プランと上限
- 拒否とエラー処理
- セキュリティモデル
- ステータスとライセンス
- リンク
クイックスタート
1. Create a workspace → https://console.whatsmcp.com/register
2. Link a WhatsApp number → Console → Pair device (scan the QR with your phone)
3. Give your client → https://api.whatsmcp.com/mcp
…and sign in when it asks. No key to paste.
Claude Code の場合は、次の 2 つのコマンドを実行します。
claude mcp add --transport http wamcp https://api.whatsmcp.com/mcp
claude mcp login wamcp
次に、エージェントに 「WhatsApp アカウントの一覧を表示して、直近のメッセージをいくつか見せて」 と頼んでください。
サインインできないクライアント(curl、CI、OAuth を使えないものなど)は、代わりにヘッダーでキーを渡します。キーを作成してから、クライアントの接続をご覧ください。
登録
サインアップはセルフサービスで無料です。クレジットカードも営業担当との通話も必要ありません。
| アカウントを作成 | https://console.whatsmcp.com/register |
| サインイン | https://console.whatsmcp.com/login |
| 製品サイト | https://whatsmcp.com |
名前とメールアドレスを入力すると、確認リンクが届きます。そのリンクを開くと、パスワードを設定できます。確認が完了すると無料プランのワークスペース(テナント)が作成され、簡単なセットアップウィザードが表示されます。このウィザードでは、アカウントを使える状態にするための3つの手順、つまり電話番号をリンクする、キーを発行する、そして必要に応じてエンドポイントにWebhookを設定する方法を案内します。チェックリストを自分でチェックして進めるのではなく、実際に行った操作に応じて表示されるため、セットアップが完了すると消え、すべてのリンクを解除すると再び表示されます。
すべての操作はコンソールで行えます。
| コンソールのページ | 用途 |
|---|---|
| Fleet | リンク済みのすべての電話番号と接続状態 |
| Pair device | QRコードで新しいWhatsApp番号をリンク |
| API keys | キーの発行と取り消し、コピーして使える接続例 |
| Connections | OAuthでサインインしたクライアントと、クライアントごとの取り消しボタン |
| Webhooks | 受信データの配信先エンドポイントと最近の配信試行 |
| Usage | プランの上限に対する送信済みメッセージ数 |
| SIP | 電話番号ごとに、通話をホスト型SIP回線または独自のPBXに接続 |
| Help | お客様のワークスペースの接続情報と、プランに含まれるツール |
番号ごとのページ(Messages、Contacts、Calls、SIP)は、同じコンソール内の各アカウントから開けます。
WhatsApp番号をリンクする
WhatsMCPは、WhatsApp Webと同じ仕組みのリンク済みデバイスとして接続します。スマートフォンは引き続きメインデバイスとして使え、その後は手元に置いておく必要もありません。
コンソールから: Pair deviceを開き、スマートフォンでWhatsApp → Settings → Linked devices → Link a deviceに進んでコードをスキャンします。

コードは約20秒ごとに切り替わり、ページも自動更新されるため、期限切れのQRコードが表示されたままスキャンできなくなることはありません。下のステップ表示では一連の処理を確認できます。スマートフォンがコードを受け入れるとスキャン済みになり、デバイスがログインして履歴を取得すると同期中になり、その後に番号が使用可能な準備完了状態になります。
エージェントから、wa_pair_accountツールを使用します。
// 1. start pairing — returns a QR as a base64 PNG for the user to scan
wa_pair_account()
→ { "pair_id": "…", "state": "qr", "qr_png_base64": "iVBORw0…", "instructions": "…" }
// 2. the code rotates about every 20 seconds — poll for the current one
wa_pair_status({ "pair_id": "…" })
→ { "state": "qr", "qr_png_base64": "…" } // show the new image
→ { "state": "paired", "instructions": "Linked. …" } // done
stateがpairedになると、その番号がwa_list_accountsに表示され、使用できる状態になります。wa_unpair_accountを実行すると、再び接続が解除されます。
APIキーを作成する
任意です。 OAuthでサインインできるクライアントにはAPIキーは必要ありません。クライアントを接続するに進んでください。キーは、curl、CI、OAuthに対応していないクライアントで使用します。
Console → API keys → Create key。
キーはwamcp_live_XXXXXXXXXXXX_…のような形式で、表示されるのは一度きりです。保存するのはハッシュのみのため、紛失したキーは復元できず、新しいキーに置き換える必要があります。クライアントごと、または環境ごとにキーを1つ発行し、それぞれ個別に取り消してください。
キーはそのままワークスペースを表します。すべてのツールはそのワークスペースに限定されるため、渡すテナント引数はなく、あるワークスペースから別のワークスペースのメッセージにアクセスすることもできません。
クライアントを接続する
Streamable HTTP に対応した MCP クライアントならどれでも使用できます。エンドポイントは 1 つです。
| エンドポイント | https://api.whatsmcp.com/mcp |
認証方法は 2 つあります。
OAuth — 推奨方式です。以下の各クライアントではデフォルトでこの方式が使われます。 クライアントがサーバー自身のメタデータを読み取り、登録を行った後、承認のためにコンソールが開きます。どこかに貼り付けるものはありません。キーは作成されず、設定ファイルにも保存されません。また、他のクライアントには触れずに、コンソール → 接続から特定のクライアントだけを取り消せます。
API キー — Authorization: Bearer <your key>、または Authorization を自身で管理するトークン用に確保しているクライアントでは x-api-key: <your key> を使います。curl や CI、OAuth に対応していないクライアントで使用します。API キーを作成するをご覧ください。
Claude Code
claude mcp add --transport http wamcp https://api.whatsmcp.com/mcp
次に、Claude Code 内で /mcp を実行し、Authenticate を選んで、開いたブラウザーウィンドウでサインインします。シェルから claude mcp login wamcp を実行しても同じ操作ができます。その後、claude mcp list に wamcp が接続済みとして表示されます。
サインイン手順を使わずにキーで接続する場合:
claude mcp add --transport http wamcp https://api.whatsmcp.com/mcp \
--header "Authorization: Bearer YOUR_KEY"
Claude Desktop と claude.ai
Settings → Connectors → Add custom connector を開き、URL フィールドにエンドポイントを入力して、Authentication は OAuth のままにし、Claude の指示に従ってサインインします。ダイアログが接続手順を自動で検出します。
コネクターを追加した時点で、認証方式が固定されます。 ヘッダーまたは API キーを使って作成したコネクターは、後から OAuth に切り替わりません。削除して、もう一度追加してください。
ここでキーを使うには、Authentication を None に設定し、Additional request headers の下に次のエントリーを 1 つ追加します。
| ヘッダー名 | x-api-key |
| 値 | YOUR_KEY |
キーだけを貼り付けてください。先頭に Bearer は付けません。このダイアログでは Authorization は選択できません。Claude が自身で管理する OAuth トークン用に確保されています。ヘッダーの値は一度保存すると、再表示されません。そのため、コネクターが接続できない場合は、値を読み返そうとせず、ヘッダーを入れ直してください。キーが間違っている場合と、キーがない場合は、外部からは同じように見えます。
ダイアログではなく設定ファイルを編集する場合、この制限はありません。
{
"mcpServers": {
"wamcp": {
"type": "http",
"url": "https://api.whatsmcp.com/mcp",
"headers": {
"Authorization": "Bearer YOUR_KEY"
}
}
}
}
ChatGPT
Settings → Security and login で Developer mode をオンにします(利用できるかどうかは ChatGPT のプランによって異なります)。次に Plugins に移動し、+ を押して、エンドポイントを入力します。
ここで使えるのは OAuth のみです。 ChatGPT はカスタム API キーを MCP サーバーに送信できないため、このページに記載されているキーを使う方法は利用できません。キーを入力するヘッダーフィールドもありません。サインインの手順が設定のすべてです。
Codex
codex mcp add wamcp --url https://api.whatsmcp.com/mcp
codex mcp login wamcp
または、同じサーバーを ~/.codex/config.toml に直接記述できます。auth のデフォルト値は "oauth" です。
[mcp_servers.wamcp]
url = "https://api.whatsmcp.com/mcp"
auth = "oauth"
代わりにキーを使う場合は、ファイルに記述せず、環境変数に保存します。
[mcp_servers.wamcp]
url = "https://api.whatsmcp.com/mcp"
bearer_token_env_var = "WHATSMCP_API_KEY"
export WHATSMCP_API_KEY=wamcp_live_…
Codex はこれを Authorization: Bearer … として送信します。ヘッダーを自分で設定する場合は、固定値には http_headers を、環境変数から取得する値には env_http_headers を使います。
その他すべてのクライアント
クライアントによって設定の保存場所は異なりますが、必要なことは同じです。エンドポイントを リモート HTTP サーバーとして追加してください(stdio ではありません)。OAuth に対応しているクライアントなら、URL を設定するだけでサインインの手順を自動で検出します。OAuth に対応していないクライアントでは、Authorization にキーを設定する必要があります。Authorization を設定できない場合は、x-api-key を使ってください。
「実行するコマンド」しか指定できないクライアントは、リモートサーバーに対応していません。接続先として指定できるローカルプロセスはありません。
OAuth フローの仕組み
自分でクライアントを統合する場合や、エージェントが何に同意したのかを確認したい場合に読んでください。ここで使われているのは標準の OAuth 2.1 であり、独自のハンドシェイクはありません。
サーバーは 2 つのメタデータドキュメントを公開します。これにより、クライアントはエンドポイント URL だけで初期設定を行えます。
/.well-known/oauth-protected-resource | RFC 9728 — リソースを指定し、認可サーバーを示します |
/.well-known/oauth-authorization-server | RFC 8414 — 以下のエンドポイント、グラント、スコープを示します |
クライアントは Dynamic Client Registration(RFC 7591、/oauth/register)を使って登録するか、URL がクライアント ID となる Client ID Metadata Document を公開します。どちらもサポートされており、上記のベンダーはどちらか一方を使用しています。その後は、PKCE(S256 のみ)を使う通常の認可コードフローになります。console.whatsmcp.com/oauth/authorize の同意ページに移動して承認し、/oauth/token でコードを交換します。認可コードは 1 回限り有効で、リフレッシュトークンは使用するたびにローテーションされます。失効済みのリフレッシュトークンを再使用すると、新たなトークンが発行されるのではなく、グラント全体が取り消されます。トークンはこのリソースにバインドされ(RFC 8707)、/oauth/revoke で取り消せます(RFC 7009)。
7 つのスコープが公開され、各グラントに記録されます。
| スコープ | 対象 |
|---|---|
wa:accounts | 電話番号、プラン、サービスのバージョンの一覧表示 |
wa:read | メッセージ、チャット、連絡先、プロフィール、グループ、通話、メディア |
wa:send | メッセージの送信、リアクション、編集、グループやブロックリストの変更 |
wa:pair | 電話番号のリンクとリンク解除 |
wa:webhooks | 受信データ配信の登録と管理 |
wa:egress:socks5、wa:egress:wireguard | アカウントごとのエグレス設定 |
スコープは記録されますが、ツール層では適用されません。 グラントで実際に利用できるツールは、API キーの場合とまったく同じように、プランによって決まります。スコープ一覧は、接続の用途を示すものとして扱ってください。サンドボックスではありません。
グラントはコンソール → 接続で一覧表示および取り消しができます。ここでグラントを取り消すと、そのクライアントだけが切断されます。
手動で確認する
curl -s https://api.whatsmcp.com/mcp \
-H "Authorization: Bearer YOUR_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
エンドポイントを直接呼び出す際に、戸惑いやすい点が 2 つあります。
- 応答はサーバー送信イベント形式でフレーム化される場合があります — メッセージごとに
data:の行が 1 つあります。 - ツールの結果は、それ自体が JSON であるテキストです。そのため、2 回解析する必要があります。
エンドポイントはステートレスです(MCP 2026-07-28 でプロトコルセッションが廃止されました)。そのため、スティッキールーティングは不要で、どこからでも安全に呼び出せます。認証情報なしで呼び出すと、保護されたリソースのメタデータを示す WWW-Authenticate ヘッダーとともに 401 が返されます。これにより、OAuth 対応クライアントは自動的にフローを開始できます。
ツール
ツールは 36 個あります。tools/list に表示されるツールはプランによって異なります。プランに含まれていないツールは、存在して拒否されるのではなく、表示されません。コンソール → ヘルプには、お使いのワークスペースで利用できるツールが一覧表示され、プランに含まれるものが示されています。
まず wa_list_accounts を使ってください。 ほかのすべてのツールでは、ここから取得した account_id を指定します。また、アカウントは state が connected の間だけ使用できます。
アカウント、ペアリング、プラン
| ツール | 説明 |
|---|---|
wa_list_accounts | リンク済みの番号を一覧表示します。account_id、phone、push_name、state(pairing、connected、disconnected、logged_out、locked)が含まれます |
wa_pair_account | 新しい番号のリンクを開始します。base64 PNG 形式の QR コードを返します |
wa_pair_status | ペアリングの状態を確認します。待機中の場合は新しいコードを返します |
wa_unpair_account | リンク済みの番号を切断します |
wa_set_profile_photo | 自分の番号のプロフィール写真(すべての連絡先に表示される画像)を差し替えるか、削除します |
wa_get_plan | プラン、その上限、メッセージ数とアカウント数の上限に対する現在までの使用状況を確認できます。送信が拒否された理由や、残りの余裕を確認するには、このツールを呼び出してください |
メッセージング
| ツール | 説明 |
|---|---|
wa_send_message | 自分の番号からテキスト、画像、ドキュメント、音声を送信します |
wa_list_messages | アカウントをまたいでメッセージを古い順に読み込み、カーソルでページ分割します |
wa_get_chat | カーソルを使わず、1 つのアカウントの最近のメッセージを取得します。1 回限りの確認に使えます |
wa_get_message | WhatsApp ID またはカーソルで、保存済みのメッセージを 1 件取得します。たとえば、Webhook で通知されたメッセージを取得できます |
wa_get_media | message_id で受信した添付ファイルをダウンロードします(base64 + mime) |
メッセージ操作
以下の各ツールは既存のメッセージに対して操作するため、wa_list_messages から取得した message_id が必要です。
| ツール | 説明 |
|---|---|
wa_react | 絵文字でリアクションします。空のリアクションを指定すると、自分が送信したリアクションを削除します |
wa_edit_message | 自分が送信したメッセージを編集します。WhatsApp では送信から約 20 分以内の編集が受け付けられます |
wa_delete_message | 全員に対して削除します。WhatsApp に完全な削除機能はありません。この操作ではメッセージが取り消され、現在のすべてのクライアントで反映されます |
wa_set_presence | チャットに入力中(composing/paused)であることを通知するか、アカウントを available/unavailable に設定します。送信後の応答は待ちません。配信確認はありません |
連絡先とプロフィール
| ツール | 説明 |
|---|---|
wa_list_contacts | アカウントのアドレス帳をページ分割して表示します。または query を指定して名前や番号で検索できます。プロフィール写真も任意で取得できます |
wa_get_profile | 番号が WhatsApp に登録されているか、その公開名、自己紹介文、写真、ビジネスアカウントのカテゴリ、連絡先、営業時間を確認します |
上記の wa_list_contacts とは異なり、wa_get_profile はローカルストアではなく WhatsApp に問い合わせます。
自己紹介文または写真が空の場合、その相手がこのアカウントに対して共有していないことを意味し、情報自体がないとは限りません。
ブロックリスト
| ツール | 説明 |
|---|---|
wa_block_contact | 連絡先をブロックします。相手はこのアカウントに電話やメッセージを送れなくなります。または unblock: true を指定して、ブロックを解除します |
wa_list_blocked | このアカウントがブロックした相手をすべて表示します |
どちらのツールも番号だけでなく、相手が「誰か」も報告します。各エントリには、番号、このアカウントのアドレス帳に登録されている名前(電話に保存したことがない相手の場合は含まれません)、番号の国が含まれます。WhatsApp は連絡先がブロックされた日時を記録しないため、日付は取得できません。
グループとチャンネル
| ツール | 説明 |
|---|---|
wa_list_groups | アカウントが参加しているグループを一覧表示します。JID、名前、メンバー数が含まれます |
wa_list_channels | アカウントがフォローしているチャンネルを一覧表示します。JID、名前、登録者数が含まれます |
wa_join_group | 招待リンクからグループに参加します |
wa_follow_channel | リンクからチャンネルをフォローします |
wa_leave_chat | グループを退出するか、チャンネルのフォローを解除します |
wa_list_group_members | グループのメンバーを一覧表示します。各メンバーについて、JID、電話番号、管理者フラグが含まれます |
wa_create_group | グループを作成し、JID と招待リンクを返します |
wa_delete_group | 他のメンバー全員を削除してから退出します(WhatsApp に完全な削除機能はありません) |
グループ管理
以下の操作はいずれも WhatsApp 独自のルールに従います。管理者権限が必要な変更は、権限がない場合、何もせずに終了するのではなく失敗します。
| ツール | 機能 |
|---|---|
wa_update_participants | 電話番号または JID でメンバーを追加するか、メンバーを管理者に昇格、または管理者を降格します。action は add、promote、demote のいずれかです |
wa_remove_participants | グループからメンバーを削除します |
wa_update_group | グループの name、設定を変更できるのを管理者のみにするか(locked)、投稿できるのを管理者のみにするか(announce)を変更します。1 回の呼び出しで複数を変更できます |
wa_get_group_invite_link | 招待リンクを返します。reset を指定すると、現在のリンクを無効にして新しいリンクを発行します |
通話
| ツール | 機能 |
|---|---|
wa_list_calls | 通話履歴を古い順にページ分割して取得します。方向、相手、answered、seconds、reason、codec が含まれます |
Webhook (有料プラン)
| ツール | 機能 |
|---|---|
wa_set_webhook | 受信メッセージ用の HTTPS エンドポイントを登録します。署名シークレットは一度だけ表示されます |
wa_get_webhook | エンドポイント、有効かどうか、最後に配信が成功した日時を表示します |
wa_enable_webhook | エンドポイントやシークレットを変更せずに、配信を一時停止または再開します |
wa_delete_webhook | 配信を停止します。メッセージは引き続きツールから読み取れます |
配信をしばらく停止したいだけなら、削除して再作成するのではなく wa_enable_webhook を使ってください。削除すると新しいシークレットが発行され、古いシークレットを使っているものはすべて機能しなくなります。
連絡先
エージェントが、あなたをアドレス帳代わりにする必要はありません。wa_list_contacts はアカウントがリンクされている電話から同期された連絡先を読み取るため、エージェントは 「Alice にメッセージを送って」 という指示を自分で電話番号に変換できます。
アカウントのローカル連絡先ストアを読み取ります。WhatsApp との通信は行われません。ネットワークへの検索は実行されず、問い合わせてもプランの通常のリクエスト制限を除き、レートコストはかかりません。(以下の wa_get_profile は WhatsApp に接続する唯一のツールです。)
wa_list_contacts — アドレス帳全体
wa_list_contacts({ "account_id": "acct_…", "limit": 500 })
→ {
"contacts": [
{ "phone": "447700900111", "name": "Alice Perreira", "name_source": "saved",
"jid": "[email protected]" },
{ "phone": "447700900222", "name": "Bakery", "name_source": "business", "jid": "…" },
{ "phone": "447700900333", "name": "dave", "name_source": "push", "jid": "…" }
],
"total": 482,
"next_cursor": "447700900333",
"has_more": true
}
| フィールド | 意味 |
|---|---|
phone | 国際形式の数字のみの番号です。そのまま wa_send_message に渡せます。このアカウントに番号が一度も伝えられたことのない LID 形式の連絡先では空になります |
name | 利用可能な最適な表示名 |
name_source | saved — アカウント所有者が自分のアドレス帳に登録した名前 · business — 認証済みのビジネス名 · push — 連絡先本人が名乗っている名前。第三者による確認はありません |
jid | WhatsApp 独自の識別子 |
total | ページ上限を適用する前に一致した連絡先の数です。モデルは現在のページがアドレス帳全体かどうかを判別できます |
next_cursor / has_more | has_more が false になるまでページを取得すると、すべての連絡先を読み取れます |
ページ分割には安定した順序(電話番号順)でカーソルを使用するため、行が重複したり飛ばされたりすることはありません。デフォルトのページサイズは 500、最大は 2000 です。
query で検索 — 1 人を見つける
query を渡すと、同じツールが一覧表示ではなく検索を実行します。
wa_list_contacts({ "account_id": "acct_…", "query": "+44 7700 900111" })
大文字と小文字は区別せず、電話番号の句読点は無視して照合します。そのため、"+44 7700 900111" を指定すると、447700900111 として保存された連絡先が見つかります。保存名、ビジネス名、連絡先本人が公開している名前、電話番号を検索します。結果が空の場合は一致なしを意味し、エラーではありません。
include_pictures でプロフィール写真を取得
include_pictures: true を設定すると、各連絡先に picture_url が含まれます。この場合、ローカルストアを読むのではなく、ページ内の各連絡先を WhatsApp で検索するため、ページ上限は 10 となり、最大で 30 秒ほどかかることがあります。すばやく一覧を取得したい場合は無効のままにしてください。picture_url が空の場合は、このアカウントから見える写真が連絡先にないことを意味し、検索に失敗したということではありません。
知っておくと便利なこと
- リンクしたばかりのアカウントのアドレス帳は空です。 リンク後まもなく、アプリ状態の同期によって電話から連絡先が届きます。そのため、ペアリング直後に「連絡先がありません」と表示される場合、通常は「まだ同期されていません」という意味です。エージェントが連絡先を500件登録しているユーザーに対して「連絡先がありません」と報告しないよう、ツールはその旨を
noteで伝えます。 - 連絡先として認識されるのは、電話本体に保存されている番号のみです。 チャットしたことがあっても保存していない相手は、アドレス帳には登録されていません。ただし、
wa_list_messagesではpeerとして表示されます。 - アカウントがオフラインの場合、 読み取りは
account_not_connectedと再試行までの待ち時間を返して拒否されます。「知り合いが誰もいない」と受け取られかねない空のアドレス帳を返すことはありません。 - 目で確認したい場合は、コンソールの Contacts で、番号ごとに同じアドレス帳を表示できます。
受信メッセージの読み取り
サーバーがエージェントにメッセージをプッシュすることはありません。 メッセージの到着によってモデルの動作が中断されることはないため、エージェントは自分のスケジュールで読み取ります。これを確実にするのが カーソル です。
wa_list_messages はメッセージを古い順に返します。各メッセージには cursor があり、ページには next_cursor と has_more も含まれます。カーソルを after_cursor として渡せば、その後に届いたメッセージだけを取得できます。同じミリ秒に届いた2件のメッセージでも、タイムスタンプでは保証できない欠落や重複が発生しません。
after = 0
repeat:
r = wa_list_messages(after_cursor = after)
for m in r.messages:
if m.direction == "inbound":
handle(m) # e.g. reply with wa_send_message
after = r.next_cursor # advance — only newer rows next time
if not r.has_more:
sleep(a while) # caught up; poll again later
各行には、送信者と送信先が示されます。
| フィールド | 意味 |
|---|---|
direction | inbound(受信)または outbound(送信) |
peer | 相手の番号。グループまたはチャンネルでは、会話相手ではなく個々の送信者を示します |
chat | 会話の JID。グループは …@g.us、チャンネルは …@newsletter です |
chat_kind | dm、group、channel、broadcast のいずれか |
kind / text | コンテンツの種類と本文(本文を含むのはテキストのみです。それ以外は wa_get_media で取得してください) |
at、message_id | RFC3339 形式のタイムスタンプと WhatsApp の ID |
返信するには、DM では相手の番号を to に指定します。グループまたはチャンネル では chat の JID を to に指定します。個々の相手を指定すると、代わりにプライベートチャットが開始されます。
Claude Code では、
/loopコマンドでこれを自動化できます。一定間隔でポーリングし、メッセージが表示されたら処理して停止します。実行中のループは/tasksで確認できます。
ポーリングではなく、単一アカウントのメッセージを一度だけまとめて確認する場合は、wa_get_chat を使うとカーソルなしで最近のメッセージを取得できます。
Webhook
ポーリングを使わない場合は、wa_set_webhook を使うと、受信した各メッセージを HTTPS エンドポイントに配信できます(有料プラン)。
{
"event": "message.inbound",
"delivery_id": "01JB…",
"tenant_id": "01JA…",
"account_id": "01J9…",
"account_phone": "447700900000",
"message_seq": 48210,
"message_id": "3EB0…",
"chat_jid": "[email protected]",
"peer": "447700900111",
"kind": "text",
"body": "are you open on Sunday?",
"at": "2026-09-02T14:21:07Z"
}
account_phone は、メッセージを受信した自分の番号です。ルーティングルール、CRM、サポートキューなどで通常、キーとして使用されます。message_seq は wa_list_messages が使用するものと同じカーソルなので、配信を受け取れなかったコンシューマーは推測に頼らず、照合できます。
各リクエストには次の情報が含まれます。
| ヘッダー | 値 |
|---|---|
X-WAMCP-Signature | t=<unix>,v1=<hex hmac-sha256> |
X-WAMCP-Delivery | 冪等性のための配信 ID |
X-WAMCP-Event | イベント名。本文を解析せずにルーティングできます |
署名を検証してください — HMAC-SHA256(secret, "<unix>" + "." + <raw body>) を再計算し、一定時間比較を行い、古いタイムスタンプを拒否します。
import hashlib, hmac, time
def verify(secret: str, header: str, body: bytes, tolerance: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
ts, sig = parts["t"], parts["v1"]
if abs(time.time() - int(ts)) > tolerance:
return False
mac = hmac.new(secret.encode(), f"{ts}.".encode() + body, hashlib.sha256)
return hmac.compare_digest(mac.hexdigest(), sig)
受信を確認するには 2xx を返してください。1回の試行は最大10秒です。失敗した場合は、最大8回まで指数バックオフで再試行されます。410 Gone を返すと、そのメッセージの配信は恒久的に停止します。これは、エンドポイントが今後復旧しないことを示す応答です。最近の試行とその結果は、Console → Webhooks で確認できます。
送信
wa_send_message({
"account_id": "acct_…",
"to": "447700900111", // international form, digits only — or a …@g.us / …@newsletter JID
"text": "on my way"
})
→ { "status": "sent", "message_id": "3EB0…", "request_id": "01JB…" }
添付ファイルも同じツールで送信されます。適用できる場合、text はキャプションになります。
| 引数 | 上限 | 備考 |
|---|---|---|
image_base64 + image_mime | デコード後 5 MiB | JPEG または PNG |
document_base64 + document_mime + document_filename | デコード後 20 MiB | 任意のファイル。受信者に表示されるのはファイル名です |
audio_base64 + audio_mime (+ audio_seconds, audio_ptt) | デコード後 16 MiB | audio_ptt: true を指定するとボイスメッセージを送信します。音声にはキャプションがありません |
返された status を確認してください。3 つの値はそれぞれ意味が異なります。
status | 意味 |
|---|---|
sent | WhatsApp に配信済みです。message_id が設定されています |
queued | 受け付けられましたが、まだ確認されていません。届く可能性があります — 再送信しないでください。 後で request_id を使って wa_list_messages で照合してください |
refused | 送信されていません。refusal.reason に再試行が有効かどうかが示されます |
queued を失敗として扱うエージェントは、顧客に同じメッセージを 2 回送信してしまいます。
グループとチャンネル
グループとチャンネルの一覧表示は読み取り機能に含まれます。参加、退出、メッセージ送信、グループ管理を行うには、ブリッジでアカウントがグループおよびチャンネルのメッセージ送信を許可されている必要があります — 番号の機能を有効にするにはお問い合わせください。有効になっていない場合、アカウントはこれらの呼び出しを拒否し、その理由を一般的なエラーではなく、そのままの文言で返します。
グループ管理(wa_create_group、wa_update_participants、wa_remove_participants、wa_update_group、削除)は WhatsApp 独自のルールに従います。管理者権限が必要な変更は、権限がなければ失敗します。WhatsApp には実際の削除機能がないため、wa_delete_group は他のメンバーを全員削除してから退出します。
SIP 経由の通話
ベータ版。 WhatsMCP はWhatsApp の音声通話を双方向で SIP に接続します。リンク済みの番号への WhatsApp 通話は、通常の INVITE として SIP 電話または PBX に着信します。E.164 形式の WhatsApp 番号に発信する内線からは、WhatsApp で相手に接続でき、発信者番号にはお客様の番号が表示されます。これは Meta Business Calling API ではなく、ビジネス認証も分単位の課金もありません。
番号ごとに コンソール → SIP で設定でき、接続方法は 2 つあります。
ホスト型 SIP 回線 — PBX 不要
電話システムは当社が運用します。番号には当社サーバー上の SIP アカウントが割り当てられ、任意の SIP 電話、ソフトフォン、ブラウザーを登録できます。コンソールにはサーバー、ユーザー名、パスワード(表示、コピー、新しいパスワード)と、お使いの電話および WhatsApp ブリッジが現在それぞれ登録されているかどうかが表示されます。
この回線の電話の種類を選択してください。2 つの種類で同じエンドポイントを共有することはできません。
| 電話の種類 | 対象 | 接続方法 | メディア |
|---|---|---|---|
| SIP 電話 | 卓上電話、ソフトフォン、PBX | SIP サーバーに TLS(ポート 5061) で接続 — TLS に対応していない電話に限り、通常の UDP 5060 を使用 | SRTP(SDES)。電話で有効にしてください。電話が対応していない場合は通常の RTP |
| ブラウザー(WebRTC) | コンソールに組み込まれたダイヤラー、または独自の WebRTC クライアント | コンソールに表示される WebSocket URL(wss、ポート 8089) | DTLS-SRTP。ブラウザーが自動的に処理します |
ブラウザーを選択すると、SIP ページにダイヤラーが表示されます。ブラウザーで回線にサインインし、WhatsApp 番号に発信するか着信を待ち、マイクを通して通話できます — ハードウェアは一切不要です。
ホスト型回線で登録できるのは一度に 1 台、通話も一度に 1 件です。同じ回線に 2 台目のデバイスがサインインすると、最初のデバイスの登録が置き換わるため、1 回線につき電話は 1 台にしてください。回線ページの接続履歴には、電話とブリッジが登録された日時と、どちらかの接続が切断された日時が表示されます。
独自の PBX または CRM 電話システム
ブリッジは通常の SIP 内線としてレジストラーに発信登録するため、シグナリング用に受信ファイアウォールルールを開く必要はありません。次の情報を入力します。
| フィールド | |
|---|---|
| レジストラー | host または host:port — ポートの既定値は、UDP の場合は 5060、TLS の場合は 5061 です |
| トランスポート | UDP(ほとんどの PBX が初期設定のまま受け付けます)またはシグナリングを暗号化する TLS — TLS を使う場合、PBX はそのホスト向けに公的に発行された証明書を提示する必要があります。現時点では、PBX への通話音声は暗号化されていない RTP です |
| ユーザー名/パスワード | PBX の内線またはトランクアカウントです。パスワードは暗号化して保存され、保存後に再表示されることはありません |
| 呼び出す内線 | WhatsApp の着信先です。既定値は 101 です。発信者の番号をダイヤルプランに渡すには caller または 9:caller を指定します |
認証情報は保存前にレジストラーで検証され、接続をテストでは必要に応じて再度ダイヤルし、応答した内容を知らせます。内線から発信する場合は、E.164 形式の WhatsApp 番号を先頭の + なしでダイヤルします。
コーデック
WhatsApp は通話ごとに独自のコーデック(Opus、またはネットワークが制限されている場合は Meta の低ビットレートコーデックである MLow)を選択し、通話中に切り替えることがあります。ブリッジがこれをデコードし、お客様側の形式に再エンコードするため、PBX が MLow の存在を認識する必要はありません。
| お客様側 | |
|---|---|
| G.722 | 最初に提示されます。広帯域(16 kHz)で、WhatsApp が使用する帯域幅と同じです |
| G.711 µ-law (PCMU) | すべての SIP 電話と PBX が対応するフォールバックです。狭帯域(8 kHz)です |
| G.711 A-law (PCMA) | お客様側が優先する場合に受け付けられます |
トランクで g722 を許可すると、通話は最初から最後まで広帯域のままになります。G.711 のみ対応する電話でも、固定電話と同等の音質で利用できます。
音声プラン
SIP 通話は音声プランの対象で、メッセージングプランとは別に回線ごとに課金されます。番号で利用できる通話方向(着信のみ、または着信と発信)が決まり、利用可能な内容は SIP ページに表示されます。プランに含まれない方向の通話は、接続が不完全な状態になるのではなく、拒否されます。料金は回線ごとの月額定額で、通話時間に応じた料金はありません。whatsmcp.com/sipをご覧ください。
SIP かどうかを問わず、すべての通話は番号の通話履歴に記録されます。履歴には方向、相手、応答の有無、通話時間、終了理由、コーデックが含まれ、コンソールと wa_list_calls ツールから確認できます。
まずは音声をお試しください。 SIP ページにはライブデモ番号があります。 WhatsApp でメッセージを送ると、折り返し電話がかかってきます。
トランク専用(端末なし)の番号や、複数回線が必要ですか?お問い合わせください。
プランと制限
すべてのワークスペースは無料プランで開始します。このプランでも番号をリンクし、エージェントから操作できます。有料プランでは上限が引き上げられ、機能が追加されます。
| プランで決まる内容 | |
|---|---|
| アカウント | 同時にリンクできる WhatsApp 番号の数 |
| メッセージ | 1 時間あたりおよび 24 時間あたりの送信上限 |
| 履歴 | 保存されたメッセージ本文が削除されるまでの期間 — wa_list_messages で読み戻せる範囲も、この期間と同じです |
| Webhook | 受信配信。有料機能であり、4 つの wa_*_webhook ツールを利用するための条件です |
| 送信経路 | アカウントのブリッジを独自の WireGuard トンネルまたは SOCKS5 プロキシ経由でルーティングする機能 |
| 音声 | 回線ごとの別の音声プランにより、番号の通話を SIP で利用できます。SIP 経由の通話をご覧ください |
プランに含まれない機能は、失敗するツールとして表示されるのではなく、tools/list にまったく表示されません。そのため、モデルが最初から失敗する通話を提案することはありません。
数値については、このページではなくサービスに問い合わせてください。wa_get_plan はプラン、制限、現在までの利用状況を返します。コンソール → 使用状況でも同じカウンターを確認できます。
拒否とエラー処理
ツールが処理を拒否しても、プロトコルエラーは発生しません。構造化された拒否を返すため、 モデルがその内容を読み、次の対応を判断できます。
{
"refused": true,
"reason": "account_not_connected",
"message": "this account's bridge is not currently connected, so its contacts cannot be read; it reconnects on its own",
"retry_after_seconds": 30
}
reason | 意味 |
|---|---|
invalid_request | 引数が不正または不足しているか、ワークスペースに存在しない ID です |
account_not_connected | 番号がオフラインです。自動的に再接続されるため、再試行してください |
account_locked | WhatsApp によってこのアカウントがロックされています。理由は message に記載されています |
quota_exceeded | ご利用プランの期間内における送信上限です |
plan_required | この機能を利用するには、より上位のプランが必要です |
throttled | リクエストが多すぎるか、アカウントが時間内に応答しませんでした。再試行してください |
retry_after_seconds がない場合、または 0 の場合、再試行しても解決しません。
トランスポートレベルでは、無効または失効した認証情報に対して 401 を返します(500 は返しません。そのため、クライアントが無効な認証情報で延々と再試行することはありません)。また、エンドポイントは送信元アドレスごとにレート制限されます。
セキュリティモデル
- 認証情報が ID になります。 API キーも OAuth の許可も、最終的には同じもの、つまりワークスペースを示します。どのツールも実行される前に、エッジでワークスペースが決定されます。認証情報はリクエストコンテキストを通じて渡され、ツールの引数には含まれないため、あるワークスペースが別のワークスペースを指定できるフィールドはありません。
- 他のワークスペースの ID は「そのようなアカウントは存在しません」として扱われます。 これにより、探りを入れても情報は得られません。
- キーはハッシュ化して保存され、作成時に一度だけ表示され、個別に失効させることができます。
- OAuth の許可は、コンソール → 接続からクライアントごとに失効させることができます。 認可コードは一度しか使用できず、更新トークンはローテーションされます。失効済みのトークンを再利用すると、新たなトークンが発行されるのではなく、許可が取り消されます。
- Webhook の本文には、タイムスタンプ付きのペイロードに対する HMAC-SHA256 署名が付与されます。
- WhatsApp アカウントは引き続きご自身のものです。WhatsMCP はリンク済みデバイスとして動作し、端末の 設定 → リンク済みデバイスから、または
wa_unpair_accountを使って、いつでも削除できます。
ステータスとライセンス
WhatsMCP は稼働中で、セルフサービスで利用できます。ここで説明するサービスは本番環境で稼働しており、誰かとやり取りすることなく、今日から登録して利用できます。
このリポジトリは、そのホステッドサービスに関する公開ドキュメントです。サーバーのソースコードは公開されておらず、このリポジトリの内容に関するライセンスも付与されていません。閲覧は公開されていますが、再利用や再配布は許可されていません。
WhatsMCP は非公式の連携サービスです。Meta または WhatsApp との提携、認可、推奨を受けているものではありません。
リンク
| 製品サイト | https://whatsmcp.com |
| ドキュメント | https://whatsmcp.com/docs/mcp |
| アカウントを作成 | https://console.whatsmcp.com/register |
| サインイン | https://console.whatsmcp.com/login |
| コンソール | https://console.whatsmcp.com |
| ヘルプ(ご利用のワークスペース固有の接続情報) | https://console.whatsmcp.com/help |
| MCP エンドポイント | https://api.whatsmcp.com/mcp |
| SIP ↔ WhatsApp 音声ブリッジ | https://whatsmcp.com/sip |
| SIP コンソール | https://console.whatsmcp.com/sip |
| エンジニアリングブログ | https://whatsmcp.com/blog |
| Model Context Protocol | https://modelcontextprotocol.io |
| GitHub の組織 | https://github.com/whatsmcp |
| プライバシーポリシー | https://whatsmcp.com/privacy |
| 利用規約 | https://whatsmcp.com/terms |
| お問い合わせ/サポート | https://whatsmcp.com/contact |
ご質問、グループメッセージを有効にする必要がある番号、規模を検討中の SIP トランク、またはご希望に合わないプランについては、 issue を作成するか、上記のお問い合わせリンクを利用するか、 コンソールからご連絡ください。
WhatsMCP — エンドポイントは 1 つ、リンクする番号は 1 つ。エージェントが WhatsApp を利用できます。
コメント
AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。