vonage-mcp-server
Provides tools for sending SMS messages, bulk SMS from CSV, making voice calls, retrieving call status, and generating JWT tokens via the Vonage API.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@vonage-mcp-serversend an SMS to +81345438093 with message 'Test'"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Vonage MCP Server
English | 日本語
VonageのSMS送信と音声通話を AIエージェントから安全に使うための MCP (Model Context Protocol) サーバーです。
利用者が自分の環境にコンテナを立て、自分の Vonage 資格情報を設定して使う OSS のリファレンス実装です。このプロジェクトがあなたの資格情報を預かることはありません。
このプロジェクトの前提
脅威モデル — エージェントを信頼できる主体として扱わない
攻撃者はプロンプトインジェクションによって AI エージェントを操れるものとします。
SMS 送信と音声通話は取り消せず、課金が発生し、相手にも迷惑がかかりうる操作です。「エージェントが正しく使えば安全」という前提は置けません。このサーバーのガードレールは、エージェントが敵対的に振る舞っても被害が上限内に収まることを目指しています。
そのため、既定ではツールが1つも公開されません。 使う機能を環境変数で明示的に有効にしてください。
対象範囲
項目 | 範囲 |
規制上の案内 | 日本国内での利用を対象とします |
発信先 | 海外番号も許容しますが、既定では日本(国番号 81)のみ有効です |
提供形態 | 利用者が自環境にデプロイします。1デプロイ = 1 Vonage アプリケーション |
対応クライアント | MCP 仕様準拠。stdio と Streamable HTTP の2形態 |
規制に関する記載は法的助言ではありません。 このプロジェクトが案内するのは日本国内での利用を対象とした事項に限られます。他地域で利用する場合は、その地域の規制・キャリア仕様・Vonage の利用規約をご自身で確認する責任を負います。 日本国内での利用についても、日本向け SMS の利用条件に挙げた事項はサーバー側で判定できないため、遵守は利用者の責任です。
単一インスタンスで動かしてください。 レートリミット・配信ステータス・Webhook のリプレイ検出はすべてプロセス内のメモリに保持されます。複数インスタンスで動かすと、
レートリミットが実効的にインスタンス数倍に緩みます(
RATE_LIMIT_PER_HOUR=5を3インスタンスで動かせば毎時15件)Webhook がインスタンス A に届いて
get_sms_statusが B で処理されると、配信ステータスを取得できませんWebhook のリプレイ検出がインスタンスをまたげません
Cloud Run なら --max-instances=1 を指定してください。外部ストア対応は現時点のスコープ外です。
Related MCP server: twilio-mcp
対応プラットフォーム
本サーバーは MCP 仕様に準拠した stdio と Streamable HTTP の2形態を実装しており、プラットフォーム固有の分岐は持ちません。以下は各基盤の公開ドキュメントに基づく対応状況です。
凡例: ✅ 実機で確認済み / 📄 ドキュメント上は対応(未検証)/ ⚠️ 制約あり
プラットフォーム | 接続方法 | 送れる認証 | ツール実行前の承認 | 状態 |
stdio / MCPB | 不要 | あり(読み取り系にも出ます) | ✅ | |
stdio / HTTP |
| あり | 📄 | |
Streamable HTTP 全般(Cloud Run 等) | Streamable HTTP | Bearer / 上流 IAM | クライアント次第 | ✅ |
Streamable HTTP | OAuth、または静的ヘッダ(beta・組織管理者が設定) | あり | 📄 | |
Streamable HTTP | OAuth 2.0 か「認証なし」のみ | あり(既定で必ず出る) | ⚠️ | |
Streamable HTTP | 任意ヘッダで Bearer | あり(ADK の | ✅ | |
Streamable HTTP(SSE は使いません) | API キープロバイダで任意ヘッダに Bearer。IAM SigV4 は使えません(下記) | 無し | ✅ | |
Streamable HTTP(SSE は使いません) | 任意ヘッダで Bearer | 無し。 Workflow に Human Input ノードを置けば可 | ✅ | |
HTTP Streamable / stdio | Bearer / 任意ヘッダ / OAuth2 | AI Agent ノードで有効化すれば可 | 📄 |
「📄」はまだ実機で確認していないという意味です。各基盤のドキュメント上は接続できるはずですが、動作報告をいただけると助かります。
Claude Desktop は 2026-08-24 に v1.34493 で確認しました。 MCPB のインストール、capability トグル、ALLOWED_NUMBERS によるブロック、SMS の実配信と音声通話の実発信、通話ステータスの取得、実行前の承認プロンプトまで動作しています。
ただし readOnlyHint は尊重されず、get_sms_status や get_call_status のような読み取り専用ツールでも承認プロンプトが出ます(安全側の挙動なので実害はありません)。
Streamable HTTP(Cloud Run)も同日に確認しました。 Bearer 認証(未認証は 401)、ALLOWED_NUMBERS によるブロック、SMS と音声通話の実行に加えて、
get_sms_status が delivered を返すこと(Status Webhook 経由)と、get_call_status が通話時間・料金を返すことを確認しています。
配信ステータスは stdio では取得できません。 受け取るには HTTP で待ち受け、Vonage に Status URL を登録する必要があります。
Dify Cloud(Sandbox プラン)は 2026-08-31 に確認しました。 カスタムヘッダでの Bearer 認証、tools/list の取り込み、dry_run、SMS の実送信と音声の実発信、get_sms_status の delivered、get_call_status の料金・通話時間まで動作しています。detail: ok / sip_code: 200 も返っており、Event Webhook 経由の失敗理由の伝達もこの経路で動いています。 手順は docs/dify.md。
ただし Dify には実行前の承認 UI がありません。 Agent アプリはエージェントの判断だけでツールを実行し、destructiveHint は無視されます。Agent アプリで使うなら ALLOWED_NUMBERS が唯一の防御です(Workflow なら Human Input ノードを置けます)。
AWS Bedrock AgentCore Gateway は 2026-08-31 に ap-northeast-1 で確認しました。 API キープロバイダによる Bearer 認証、ターゲット作成時の自動同期、**Strands + Bedrock のエージェントが自分でツールを選んでの SMS 実送信(delivered)と音声実発信(completed / sip_code: 200 / detail: ok)**まで動作しています。手順は docs/agentcore.md。
IAM SigV4 の outbound はこのサーバーでは使えません。 Gateway は署名するだけで、ターゲット側が SigV4 を検証できる必要があり、対応するのは API Gateway / Lambda Function URLs / AgentCore Runtime です。Cloud Run は含まれません。
Gateway は API であって UI ではないため、承認は一切ありません。 ここでも ALLOWED_NUMBERS が唯一の防御です。また ツール名に <ターゲット名>___ が前置されるので、ツール名を名指しする指示文はそのままでは使えません。
ツール実行前の承認について
send_sms / make_voice_call には、MCP のツール注釈で destructiveHint: true を付けています。これを解釈する基盤(Gemini Enterprise など)では、実行前に確認が表示されます。get_sms_status / get_call_status は readOnlyHint: true なので確認は省かれます。
注釈は仕様上ヒントであり、強制ではありません。 無視する基盤もあり、「常に許可」を選べる基盤もあります。実測でも、Claude Desktop は readOnlyHint を尊重せず、読み取り専用ツールにも承認プロンプトを出しました。
上の表で承認が「無い」基盤を使う場合は、ALLOWED_NUMBERS と RATE_LIMIT_PER_HOUR を必ず設定してください。承認UIもプロンプトも、実効的な防御にはなりません。
インストール方法
方法1: MCPB Bundle(推奨 - ワンクリックインストール)
Claude Desktopで簡単にインストールできます:
MCPBファイルのダウンロード
vonage-mcp-server.mcpb をダウンロード
Claude Desktopで開く
.mcpbファイルをダブルクリック、またはClaude Desktopにドラッグ&ドロップ
環境変数の設定
Claude Desktopのインストールダイアログで以下を入力:
VONAGE_APPLICATION_ID: Vonage Application IDVONAGE_PRIVATE_KEY_PATH: 秘密鍵ファイルのパス(例:/Users/your-name/vonage/private.key)VONAGE_VOICE_FROM: 音声通話用の電話番号(E.164形式、例:81345438093)
インストール完了
Claude Desktopを再起動すると、Vonage MCPサーバーが利用可能になります
方法2: 手動セットアップ
セットアップ
依存関係のインストール
npm installVonage設定
Vonageアカウントの作成
日本国内でご利用の場合は 日本語での申し込みページ から作成できます(詳細)
海外の場合は Vonage Developer Portal から作成します
アプリケーションを作成し、Application IDを取得
秘密鍵の準備
Vonage Developer Portalで秘密鍵(private.key)をダウンロード
プロジェクトルートに
private.keyとして保存
環境変数の設定
cp .env.example .env.envファイルを編集して以下を設定:VONAGE_APPLICATION_ID=your_application_id_here VONAGE_PRIVATE_KEY_PATH=./private.key VONAGE_VOICE_FROM=14155550100 # Voice通話用のFROM番号
機能の有効化(capability トグル)
このサーバーは、既定ではツールを1つも公開しません。 使う機能だけを環境変数で明示的に有効にしてください。電話とSMSは実際に課金が発生し、相手にも迷惑がかかりうる操作なので、「気づかないうちに使える状態になっていた」を避けるための設計です。
環境変数 | 有効になるツール | 既定 |
|
| OFF |
|
| OFF |
# SMSの単発送信だけを使う場合
ENABLE_SMS=true無効なツールは tools/list の結果に含まれません。エージェントが存在しないツールを呼ぼうとして迷走せず、使わないツールの定義がコンテキストを消費することもありません。
v1.3.0 の破壊的変更: generate_jwt ツールを削除しました。
Vonage API を直接叩ける署名済みクレデンシャルを呼び出し側に渡すツールで、受け取った相手にはこのサーバーのガードレール(宛先制限・レートリミット・capability トグル)が一切効きません。既定 OFF にしても、一度有効化した後にプロンプトインジェクションで長寿命のトークンを生成させられる余地が残ります。
AIエージェントから Vonage を使いやすくするという本サーバーの目的に対して汎用の JWT 発行は主要な用途ではないため、迂回路を残さない判断をしました。JWT が必要な場合は Vonage 公式のサーバーSDK を直接お使いください。
有効な値はtrue / false のみで、大文字小文字を区別します。ENABLE_SMS=True や ENABLE_SMS=1 は起動エラーになります。無効にしたつもりの false が truthy と判定されて機能が公開される事故を防ぐため、曖昧な値は推測せずに落とす方針です。
capability を有効にした場合、VONAGE_APPLICATION_ID は必須になります。ENABLE_VOICE=true の場合はさらに VONAGE_VOICE_FROM が必要で、いずれも未設定なら起動時にエラーになります(実行して初めて失敗するより、起動時に気づけるほうが安全なため)。
安全機能(Guardrails)の環境変数
AIエージェント(Gemini Enterprise / Claude 等)から利用する際の、意図しない課金・スパム送信を防ぐための設定です。すべて任意で、未設定でも動作します。
環境変数 | デフォルト | 説明 |
|
| 送信・架電を許可する国番号(カンマ区切り、 |
|
|
|
| (未設定=制限なし) | 送信・架電を許可する宛先番号のホワイトリスト(カンマ区切り)。設定すると、これ以外の番号へのリクエストはエラーになる。表記ゆれ( |
|
| 1時間あたりの送信・架電件数の上限( |
| (未設定= | SMS だけをさらに絞りたい場合の上限。 |
| (未設定=制限なし) | 1時間あたりのセグメント数の上限。課金と直結する唯一の設定。 |
|
| 1通のSMSに許すセグメント数( |
| (未設定= | 架電だけをさらに絞りたい場合の上限。 |
|
|
|
| (未設定) | Status Webhook の署名検証に使う Vonage の Signature Secret。推奨。Vonage Dashboard の Settings → API settings で取得できる。 |
| (案内文) | 音声の着信時に読み上げる文面。このサーバーは着信を処理しないため、既定では「お受けしておりません」という案内を読み上げて切る。1000文字以内(発信の読み上げと同じ上限)。着信は誰でも掛けられるため、長い案内文はそのまま通話時間と音声合成の課金になる。超過すると起動時にエラーで止まる。 |
| (未設定) | 署名検証が使えない環境向けの代替。設定すると |
|
| 署名付き Webhook の |
# 検証中は自分の番号だけに送信を許可する例
ALLOWED_NUMBERS=+819012345678,+819087654321
RATE_LIMIT_PER_HOUR=3
VONAGE_API_SIGNATURE_SECRET=your_signature_secret_here日本向け SMS の利用条件
ここに書いているのは法的助言ではありません。Vonage の利用規約およびキャリアの仕様として公開されている事項を、利用者が確認すべき論点として整理したものです。最新の条件は Vonage のサポート記事と契約書をご確認ください。 このプロジェクトの規制案内は日本国内での利用を対象としています。他地域の利用者はご自身で確認する責任を負います。
守るべき利用条件
項目 | 内容 |
マーケティング目的の送信 | 受信者からのオプトイン同意が必須 |
P2P(個人間)トラフィック | 禁止 |
禁止コンテンツ | 政治 / 宗教 / 未承諾プロモーション / ギャンブル |
これらはサーバー側では判定できません。 本文の内容や同意取得の有無はサーバーからは分からないため、利用者の責任で遵守してください。
配信の不確実性 — もっとも注意が必要な点
日本のネットワークでは、URL を含むメッセージがフィッシング SMS 対策として配信されないことがあります。拒否基準は非公開です。 問題は、API が成功を返すのに実際には届かないことです。AIエージェントは失敗を検知できないため、放っておくと「送信できました」とユーザーに報告してしまいます。
このサーバーはこう扱います。
ブロックはしません。 正当な用途がありますし、拒否基準が非公開である以上こちらで判定しきれません
日本宛で URL を含む本文の場合、
dry_runと成功レスポンスにdelivery_warningを添えますsend_smsの description に「成功レスポンスは配信保証ではない」と明記しています
重要な連絡に SMS を使う場合は、get_sms_status で配信結果を確認し、別の手段も併用してください。
文字数
Unicode 連結メッセージの上限は Docomo / KDDI / Softbank が 670文字、Rakuten が 660文字です。このサーバーは安全側の 660文字を絶対上限とし、実際の制限はセグメント数で掛けています。
content_id / entity_id について
Vonage Messages API には「特定国の規制要件を満たすためのパラメータ」として content_id / entity_id がありますが、これらはインドの DLT(Distributed Ledger Technology)登録制度のためのものです。entity_id が DLT に登録した Principal Entity ID、content_id が承認済みテンプレート ID にあたります。
日本宛の送信では不要なため、このサーバーでは使用していません。
送信者ID(sender ID)のルール
SMS の from には Vonage 公式ルールが適用されます。**英数字1〜11文字(A-Z a-z 0-9)**で、先頭文字と最小長の制限はありません。2FA や AB も有効です。
日本宛には、これに加えて日本の携帯キャリア固有の制限がかかります。
種別 | 日本宛 | 挙動 |
英数字(例: | ✅ 使用可 | そのまま表示される |
電話番号(例: | ❌ 使用不可 | 拒否します |
汎用語( | ❌ 使用不可 | 拒否します |
日本宛で電話番号を送信元に指定しても、Vonage 側で別の送信者IDに上書きされます。
このサーバーは、これを「送れる」と応答せずに拒否します。通してしまうと、dry_run が「この番号から送ります」と答えてユーザーが承認したのに、実際にはまったく別の送信者IDで届くからです。承認した内容と届く内容が食い違うのが、いちばん避けたい失敗の形です。
日本以外が宛先の場合、これら2つの制限は適用されません(自社の発信元電話番号を送信元に使えます)。
宛先のガードレール
宛先には、緩められるものと緩められないものの2種類の制限がかかります。
対象 | 挙動 | 緩められるか |
緊急通報番号( | 常にブロック | 不可 |
高額課金番号( | 既定でブロック |
|
国番号 | 既定で日本( |
|
個別の番号 | 未設定なら制限なし |
|
これらは AND で効きます。ALLOWED_NUMBERS に載せた番号でも、国番号が許可されていなければブロックされます。判定はすべて dry_run: true の時点で行われるので、「dry_run は通ったのに本番で弾かれた」は起きません。
ALLOWED_COUNTRY_CODES は IRSF(国際収益分配詐欺)に対する主防御にはなりません。
国番号と国は一対一ではありません。+1 は米国・カナダに加えてカリブ海の多数の国が共有しているため、「米国宛だけ許可」というポリシーはこの仕組みでは表現できません。米国宛のつもりで 1 を追加すると、同じ +1 配下の高リスク地域も同時に開きます。
実効的な防御は以下の併用です:
ALLOWED_NUMBERSによる宛先の個別指定(もっとも確実)Vonage アカウント側の地域制限・利用額上限・アラート(サーバーを迂回されても効く唯一の層)
RATE_LIMIT_PER_HOURによる被害額の上限
短縮番号(110 や海外の 911 / 112 など)は、E.164 の桁数要件を満たさないため一律で拒否されます。日本の緊急通報番号については、桁数検証とは独立した明示的なブロックも入れています(桁数の扱いが将来変わっても効き続けるようにするため)。
レートリミットの数え方
「ツール呼び出し回数」ではなく「送信件数」で消費されます。 どのツールを使ったかではなく、何件送ったかで枠が減ります。
ただしSMS の課金はセグメント単位です(SMS の課金単位)。件数の枠は「操作の回数」を抑えるもので、費用そのものを抑えたい場合は segments の枠を使ってください。
枠はツールごとではなく、次の2層で管理されます。
バケット | 消費単位 | 対象 | 環境変数 |
| 件数 | SMS・架電のすべて |
|
| 件数 |
|
|
| 件数 |
|
|
| セグメント数 | SMS のみ |
|
1回の送信は該当するバケットを同時に消費します。どれか1つでも足りなければどれも消費せずエラーになるので、「送っていないのに枠だけ減る」ことはありません。エラーレスポンスの exceeded_bucket に、どのバケットで不足したかが入ります。
SMS の課金単位 — セグメント
SMS の課金は通数ではなくセグメント単位です。 1セグメントに入る文字数はエンコーディングで変わります。
エンコーディング | 1通の場合 | 連結時(1セグメントあたり) |
GSM-7(英数字のみ) | 160文字 | 153文字 |
UCS-2(日本語などを含む) | 70文字 | 67文字 |
非ASCII文字が1文字でも混ざると、本文全体が UCS-2 になります。 英数字159文字+日本語1文字で、1セグメントから3セグメントに跳ねます。
RATE_LIMIT_PER_HOUR=5 は「1時間に5通まで」であって「5通分の課金まで」ではありません。
日本語で160文字のSMSは3セグメント=3通分の課金になるため、5通送ると実際の課金は約15通分です。
費用そのものを抑えたい場合は SMS_SEGMENT_LIMIT_PER_HOUR を設定してください。これがセグメント数を直接数える唯一の設定です。
設定しない場合の最悪ケースは RATE_LIMIT_PER_HOUR × SMS_MAX_SEGMENTS セグメント(既定なら 5 × 3 = 15)です。
本文の上限はセグメント数で指定します(SMS_MAX_SEGMENTS、既定 3)。文字数で縛っても課金と対応しないためです。既定の3セグメントは、日本語なら約200文字、英数字なら約450文字に相当します。
dry_run のレスポンスに encoding と segments が含まれるので、送信前にユーザーへ提示してください。
RATE_LIMIT_PER_HOUR=5 は「1時間に合計5件まで」を意味します。
ツールごとに別枠ではありません。送信手段を変えて上限を超えることはできません。
v1.3.0 の破壊的変更: SMS 本文の上限が「160文字」から「3セグメント」に変わりました。 英数字だけなら約450文字まで送れるようになり(従来より緩和)、日本語では約200文字までになります(従来の160文字より緩和)。ただし絵文字や記号を多用すると従来より厳しくなる場合があります。 文字数で縛っても課金と対応しないためです。同じ160文字でも、英数字なら1通分、日本語なら3通分の課金でした。
v1.3.0 の破壊的変更: RATE_LIMIT_PER_HOUR=0 の意味が反転しました。
v1.2.1 以前は 0 が「無制限」でしたが、v1.3.0 以降は「すべて拒否」になります。緊急停止のつもりで 0 を設定した管理者が、逆に無制限にしてしまう事故を防ぐためです。
無制限にしたい場合は DISABLE_RATE_LIMIT=true を明示的に設定してください。
環境変数は起動時に厳格に検証されます。解釈できない値があると、サーバーは警告を出して動き続けるのではなく、エラーメッセージを表示して起動に失敗します(fail-fast)。
真偽値(
ENABLE_*/DISABLE_RATE_LIMIT)に指定できるのはtrue/falseのみです。大文字小文字を区別し、1/yes/on/Trueはすべてエラーになります。Falseのような値を truthy と誤判定して、無効にしたつもりの設定が有効になる事故を防ぐためです数値(
RATE_LIMIT_PER_HOUR/SMS_MAX_SEGMENTS)は10進整数のみです。小数・指数表記・負数・範囲外はエラーになります問題はまとめて報告されます。1つ直すたびに再起動する必要はありません
ALLOWED_NUMBERS を設定しているのに有効な電話番号が1件も解釈できない場合(例: ALLOWED_NUMBERS=,)、「制限なし」ではなくすべて拒否として扱います。設定ミスを安全側に倒すためです。制限が不要な場合は環境変数自体を削除してください。
VONAGE_API_SIGNATURE_SECRET と VONAGE_WEBHOOK_SECRET のどちらも未設定の場合、Status Webhook エンドポイントは 503 を返して無効化されます。未認証で受け付けると、誰でも任意の message_id の配信ステータスを偽装できてしまうためです。
署名付き Webhook では、署名の一致だけでなく payload_hash / iat / jti をすべて検証し、いずれかが欠けていれば 401 で拒否します。
署名が正しいことは「Vonage が一度発行した」ことしか意味しません。claim が無ければ検証をスキップする実装だと、攻撃者は claim を外した JWT を作るだけで検証を無効化できます。有効な JWT が一度でもログやプロキシから漏れた場合に、無期限に、任意のボディと組み合わせて再利用されるのを防ぐための措置です。
payload_hash: このボディに対して発行された署名かiat/exp:WEBHOOK_MAX_AGE_SECONDS以内に発行されたものか(未来方向のずれも拒否)jti: 同じ JWT の使い回しでないか(受理済みのjtiは許容時間内は記憶される)
VONAGE_API_SIGNATURE_SECRET を設定した場合、共有シークレット認証にはフォールバックしません。
両方を設定していても、署名検証に失敗したリクエストは x-webhook-secret が正しくても 401 になります。フォールバックすると、攻撃者は Authorization ヘッダーを外すか壊すだけで弱いほうの方式を選べてしまうためです(ダウングレード攻撃)。
レートリミットはオンメモリ管理のため、プロセスを再起動するとカウントはリセットされます。
開発用依存関係のインストール
npm install --save-dev @types/node typescript ts-node開発
開発サーバーの起動
npm run dev:startTypeScriptのコンパイル
npm run buildコンパイルされたコードの実行
# 環境変数ファイル(.env)を使用して実行(推奨・Node.js v22以降)
npm start
# 環境変数ファイルを使用せずに実行(従来方式)
npm run start:legacyファイル監視モード(コンパイル)
npm run devビルドファイルのクリーンアップ
npm run cleanテストの実行
npm testテストの監視モード
npm run test:watchカバレッジ付きテスト
npm run test:coverageClaude Desktopでの利用
このMCPサーバーをClaude Desktopで利用するための設定方法を説明します。
方法1: MCPB Bundle(推奨 - ワンクリックインストール)
.mcpbファイルを使用すると、Claude Desktopに簡単にインストールできます。
インストール手順
MCPBファイルの作成
mcpbCLI が必要です(未インストールなら一度だけ)。npm install -g @anthropic-ai/mcpbnpm run build:mcpbこれにより
vonage-mcp-server.mcpbファイルが作成されます。Claude Desktopで開く
作成された
.mcpbファイルをダブルクリックまたは Claude Desktop にドラッグ&ドロップ
環境変数の設定 Claude Desktop のインストールダイアログで以下を入力:
Vonage Application ID: Vonage Application ID
Private Key Path: 秘密鍵ファイルの絶対パス(例:
/Users/your-name/vonage/private.key)Voice Call From Number: 音声通話用の電話番号(E.164形式、例:
81345438093)
インストール完了 Claude Desktop を再起動すると、Vonage MCP サーバーが利用可能になります。
MCPBファイルの配布
作成した .mcpb ファイルは他のユーザーと共有できます:
GitHub Releases で配布
直接ファイルを共有
方法2: 手動セットアップ
1. サーバーのビルドと起動
# プロジェクトをビルド
npm run build
# サーバーを起動(Node.js v22以降、推奨)
npm start
# または従来方式で起動(環境変数ファイルを使用しない場合)
npm run start:legacy2. Claude Desktopの設定
Claude Desktopの設定ファイル claude_desktop_config.json に以下の設定を追加します:
{
"mcpServers": {
"vonage-mcp-server": {
"command": "node",
"args": ["--env-file=.env", "dist/index.js"],
"cwd": "/Users/your-username/path/to/vonage-mcp-server"
}
}
}または環境変数を直接指定する方法もあります:
{
"mcpServers": {
"vonage-mcp-server": {
"command": "node",
"args": ["/Users/your-username/path/to/vonage-mcp-server/dist/index.js"],
"env": {
"VONAGE_APPLICATION_ID": "your-application-id",
"VONAGE_PRIVATE_KEY_PATH": "/Users/your-username/path/to/vonage-mcp-server/private.key"
}
}
}
}設定ファイルの場所
macOS:
~/Library/Application Support/Claude/claude_desktop_config.jsonWindows:
%APPDATA%\Claude\claude_desktop_config.jsonLinux:
~/.config/Claude/claude_desktop_config.json
設定手順
上記のパスにある
claude_desktop_config.jsonを開くmcpServersセクションに上記の設定を追加ファイルを保存
Claude Desktopを再起動
3. 利用可能な機能
設定完了後、Claude Desktopで以下の機能が利用できます:
ツール
すべてのツールは軽量なJSONを返します(Vonage APIの生レスポンスは返しません)。詳細は ツールのレスポンス形式 を参照してください。
send_sms: 単発SMS送信ツール
入力:
to(必須): 送信先の電話番号(E.164形式+819012345678または日本の国内形式09012345678)message(必須): 送信するメッセージ(最大3セグメント — 日本語なら約200文字、英数字なら約450文字。SMS の課金単位を参照)from(オプション): 送信元。英数字1〜11文字(A-Z a-z 0-9)。省略時は'VonageMCP'。dry_runの時点で検証される。送信者ID(sender ID)のルールを参照dry_run(オプション):trueで送信せず検証のみ(デフォルト:false)
機能:
日本の電話番号(0から始まる)は自動的にE.164形式に変換
{"status":"success","message_id":"...","to":"+81..."}を返却
make_voice_call: 音声通話ツール
入力:
to(必須): 発信先電話番号(E.164形式または0ABJ形式)message(必須): 読み上げるメッセージ(最大1000文字)voice(オプション):女性または男性(デフォルト: 女性)dry_run(オプション):trueで発信せず検証のみ
機能:
指定番号に発信してメッセージを音声で読み上げ
日本語音声対応(女性・男性)
NCCO(Nexmo Call Control Object)を使用
通話時間の自動見積もり。見積もりから通話の強制切断時間(
length_timer)を決めるため、dry_runで提示した時間を大きく超えて課金されることはないdry_runはestimated_duration_seconds(見積もり)とmax_duration_seconds(実際に適用される上限)の両方を返す
get_call_status: 通話ステータス取得ツール
入力:
call_id(必須): 取得する通話のCall ID(UUID形式)
機能:
Vonage Voice APIから通話のステータス情報を取得
call_status(通話ステータス)、start_time、price、rate、duration_secondsを返却環境変数から自動的にApplication IDとPrivate Keyを読み込み
get_sms_status: SMS配信ステータス取得ツール
入力:
message_id(必須):send_smsが返した message_id
機能:
delivery_status(submitted/delivered/failed等)を返却Vonage Messages APIは配信ステータスを同期取得できないため、HTTPサーバー版の Status Webhook(
POST /webhooks/message-status)で受信した結果を参照するWebhook未設定時・stdio版では
submittedのまま(noteフィールドで明示される)記録はオンメモリで24時間保持(プロセス再起動でクリア)
ツールのレスポンス形式
status | 意味 | 例 |
| 実行成功 |
|
| 検証のみ成功(API呼び出しなし) |
|
| 失敗 |
|
エラー時は必ず reason(原因)と suggestion(AIが次に取るべき行動)が含まれます。再試行が無意味なケースでは suggestion にその旨が明記されるため、AIエージェントの無限リトライを防げます。
4. 使用例
Claude Desktopで以下のような質問ができます:
単発SMS送信
「090XXXXYYYYに「これはVonage MCPサーバーを使って送信しています。」とSMSを送ってください」
→ send_smsツールを使用してSMS送信音声通話
「090XXXXYYYYに女性の声で『会議は明日の10時からです』と電話をかけて」
→ make_voice_callツールを使用して発信・音声読み上げ
「080XXXXYYYYに男性の声で『システム障害が発生しました。至急対応をお願いします』と電話で伝えて」
→ make_voice_callツールを使用して緊急連絡通話ステータス取得
「Call ID ca6b7710-3423-4c8d-b630-7b981ec4b2c2 の通話ステータスを取得してください」
→ get_call_statusツールを使用して通話情報を取得
「先ほどの通話の料金と時間を教えてください」
→ get_call_statusツールで通話詳細を確認Voice通話機能
機能概要
Voice APIを使用して自動音声通話を発信し、指定されたメッセージを日本語で読み上げます。
主な特徴
自動発信: 指定番号への自動発信
日本語音声: 女性・男性音声による自然な読み上げ
NCCO制御: Nexmo Call Control Objectによる通話フロー制御
通話時間見積: メッセージ長から自動的に通話時間を算出し、通話の強制切断時間に連動させる
通話時間には絶対上限(300秒)があります。
v1.2.1 以前は Vonage へ length_timer: 7200(2時間)を送っていました。dry_run が「約N秒」と提示してユーザーが承認しても、NCCO の挙動や機械検出の結果によっては最大2時間まで課金され得る状態でした。音声は分課金なので、SMS と違って金額の跳ね方が大きい点が問題です。
現在は「見積もり + 30秒の余裕」を上限として送り、どんな場合も 300 秒を超えません。dry_run の max_duration_seconds が実際に適用される値です。
音声オプション
音声タイプ | 性別 | 言語 | 特徴 |
女性 | 女性 | 日本語 | 自然で聞き取りやすい(デフォルト) |
男性 | 男性 | 日本語 | 落ち着いた男性音声 |
使用例
// 会議リマインダー
make_voice_call({
to: "090-1234-5678",
message: "明日の会議は10時から会議室Aで行います。資料をご準備ください。",
voice: "女性"
})
// 緊急連絡
make_voice_call({
to: "080-9876-5432",
message: "システム障害が発生しました。至急対応をお願いします。",
voice: "男性"
})通話ステータス取得機能
機能概要
Vonage Voice APIを使用して、過去の通話のステータス情報を取得します。通話の詳細(ステータス、料金、レート、通話時間)を確認できます。
主な特徴
詳細情報取得: 通話のステータス、料金、レート、通話時間を一度に取得
自動設定読み込み: 環境変数から自動的にApplication IDとPrivate Keyを取得
エラーハンドリング: 存在しないCall IDに対する適切なエラーメッセージ
パラメータ
パラメータ | 型 | 説明 |
call_id | string | 取得する通話のCall ID(UUID形式)。必須 |
返却される情報
status: 通話のステータス(completed, answered, busy, failed など)
start_time: 通話開始時刻(ISO 8601形式)
price: 通話料金(数値形式)
rate: 通話レート(1分あたりの料金)
duration: 通話時間(秒単位)
使用例
// Call IDを指定して通話ステータスを取得
get_call_status({
call_id: "ca6b7710-3423-4c8d-b630-7b981ec4b2c2"
})
// 結果例:
// ステータス: completed
// 開始時刻: 2025-12-10T03:53:19.000Z
// 料金: 0.06287850
// レート: 0.13973000
// 通話時間: 27秒5. トラブルシューティング
サーバーが起動しない場合
npm run buildが正常に完了しているか確認npm startでエラーが出ないか確認Node.jsバージョンが20.6.0以降であることを確認(
node -v)
Claudeデスクトップでのエラー
JSON解析エラー「Unexpected token 'd', "[dotenv@17."... is not valid JSON」が表示される場合:
claude_desktop_config.jsonのargsに--env-file=.envが含まれていることを確認サーバーコードがdotenvを使用していないことを確認(最新のコードではdotenvは使用していません)
MCPサーバーを再起動
Claude Desktopで認識されない場合
claude_desktop_config.jsonの設定が正しいか確認作業ディレクトリ(cwd)のパスが正しいか確認
Claude Desktopを再起動
機能が利用できない場合
サーバーのログを確認(Claude Desktopの設定画面で確認可能)
サーバーを再起動
Voice通話機能のトラブルシューティング
Voice通話が発信されない場合:
VONAGE_VOICE_FROM環境変数が正しく設定されているか確認VonageアプリケーションでVoice機能が有効になっているか確認
FROM番号がVonageアカウントに登録されているか確認
通話は繋がるが音声が再生されない場合:
NCCOパラメータの音声設定を確認
音声オプション(女性/男性)が正しく指定されているか確認
プロジェクト構造
vonage-mcp-server/
├── src/ # TypeScriptソースコード
│ ├── index.ts # stdio版エントリーポイント
│ ├── http-server.ts # HTTP版エントリーポイント・Webhook受信
│ ├── tools.ts # MCPツール定義の共通レジストリ(stdio/HTTP共用)
│ ├── guardrails.ts # 電話番号検証・ホワイトリスト・レートリミット
│ ├── toolResponse.ts # 軽量JSONレスポンスの整形
│ ├── messageStatusStore.ts # SMS配信ステータスのオンメモリ保持
│ ├── webhookAuth.ts # Vonage署名付きWebhookの検証
│ ├── vonage.ts # Vonage SMS送信機能
│ ├── voiceCall.ts # Voice通話機能・NCCO生成
│ └── callStatus.ts # 通話ステータス取得機能
├── tests/ # テストファイル
│ ├── index.test.ts # メイン機能のテスト
│ ├── utils.test.ts # ユーティリティのテスト
│ ├── callStatus.test.ts # 通話ステータス取得のテスト
│ ├── tools.test.ts # ツールレジストリ・ガードレール統合のテスト
│ ├── guardrails.test.ts # ホワイトリスト・レートリミットのテスト
│ ├── messageStatusStore.test.ts # 配信ステータス保持のテスト
│ ├── http-server.test.ts # HTTPラッパーのテスト
│ └── integration.test.ts # 統合テスト
├── docs/
│ ├── deployment.md # デプロイ手順
│ ├── setup-guide.md # セットアップガイド (PDF の元原稿)
│ ├── gemini-enterprise-adk.md # Gemini Enterprise (ADK 経路) の手順
│ ├── dify.md # Dify から使う手順
│ ├── agentcore.md # AWS Bedrock AgentCore Gateway の手順
│ └── gemini_system_instruction.md # Gemini Enterprise向けSystem Instruction
### HTTPラッパー (Dify / 外部アプリ用)
HTTPラッパーを使用してサーバーを実行することで、外部アプリケーション(Difyなど)からHTTP POSTリクエスト経由でMCPツールを呼び出すことができます。
```bash
npm run start:httpこれにより、ポート3000(デフォルト)でHTTPサーバーが起動します。
認証
MCP エンドポイント (/mcp) は Bearer トークンで認証します。
# 32バイトのランダムな値を生成して設定する
MCP_AUTH_TOKEN=$(openssl rand -hex 32)curl -X POST http://localhost:3000/mcp \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $MCP_AUTH_TOKEN" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'環境変数 | 既定 | 説明 |
| (未設定) |
|
|
|
|
| 認証があれば | 待ち受けアドレス。 |
|
| 待ち受けポート。 |
| (未設定=すべて拒否) | CORS で許可するオリジン(カンマ区切り)。ブラウザから |
| ループバック運用なら | 許可する |
CORS は既定で閉じています。
Bearer トークン認証があっても、ブラウザ側がトークンを持つ構成(ブラウザ拡張や Web 版の MCP クライアント)では、CORS が開いていると悪意ある Web ページが /mcp を呼び、レスポンスまで読み取れます。ツールのレスポンスに含まれる宛先や配信状況も読み取られます。
MCP クライアントの多くはブラウザではないため、開ける必要があるのは例外的なケースだけです。必要な場合のみ ALLOWED_ORIGINS に列挙してください。
ループバック運用では Host ヘッダーを検証します(DNS rebinding 対策)。
攻撃者が自分のドメインを 127.0.0.1 に解決させると、ブラウザからは同一オリジンに見えるため CORS では防げません。このとき Host ヘッダーには攻撃者のドメインが入るので、そこで 403 を返します。
外部アドレスに bind する場合、正しい Host は運用者のドメインでありサーバー側からは分かりません。推測して塞ぐと正規のリクエストまで落ちるため、ALLOWED_HOSTS が明示されるまで検証しません。インターネットに公開する場合は ALLOWED_HOSTS の設定を推奨します。
v1.3.0 の破壊的変更: X-API-KEY による認証を廃止しました。
v1.2.1 以前は X-API-KEY ヘッダを VONAGE_APPLICATION_ID と比較していました。Application ID は秘密情報ではありません — Vonage に送る JWT の claim に入る公開識別子です。これを認証に使うと、Application ID を知っている者は誰でも、そのデプロイの持ち主の課金で SMS 送信や架電ができてしまいます。MCP_AUTH_TOKEN に移行してください。
認証を設定しない場合、HTTPサーバーは 127.0.0.1 でのみ待ち受けます。
認証なしで BIND_HOST に外部アドレスを指定すると、起動時にエラーで停止します。
リクエストごとに接続元が localhost かを判定する方式は採っていません。Cloud Run やリバースプロキシの配下では、アプリから見た接続元が 127.0.0.1 になり、外部からのリクエストが全部「localhost」と判定されて無認証で通るためです。bind するアドレスならプロキシの有無に左右されません。
推奨構成: 認証は手前の層に置く
もっとも堅いのは、Cloud Run IAM や API Gateway をこのサーバーの手前に置く構成です。認証の実装をこのサーバーから切り離せるうえ、鍵のローテーションや監査ログもプラットフォーム側の仕組みに乗せられます。
その場合は TRUST_UPSTREAM_AUTH=true を設定してください(起動のたびに警告が出ます)。手前で認証していない環境でこれを有効にすると完全に無防備になります。
# Cloud Run IAM で認証する例(--allow-unauthenticated は付けない)
gcloud run deploy vonage-mcp-server \
--set-env-vars TRUST_UPSTREAM_AUTH=true,ENABLE_SMS=true \
--no-allow-unauthenticatedAPIエンドポイント
経路 | 認証 |
| 不要 |
| Bearer トークン( |
| Vonage の署名検証 |
ALL /mcp
MCP の Streamable HTTP エンドポイントです。POST (JSON-RPC) / GET (SSE) / DELETE (セッション終了) を MCP SDK の StreamableHTTPServerTransport が処理します。手書きの JSON-RPC 実装ではないので、仕様の追加に追従できます。
仕様どおり、クライアントは POST に Accept: application/json, text/event-stream を付ける必要があります(欠けていると 406 になります)。
curl -X POST http://localhost:3000/mcp \
-H "Authorization: Bearer $MCP_AUTH_TOKEN" \
-H "Accept: application/json, text/event-stream" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'セッションを持たないステートレス構成です。 リクエストごとにサーバーとトランスポートを生成し、Mcp-Session-Id を発行しません。
セッションを持つとその状態がプロセスのメモリに載るため、Cloud Run のように複数レプリカへ分散する環境では、同じセッションが別のレプリカに届いた時点で壊れます。スティッキーセッションを前提にすると、動く基盤が減ります。このサーバーのツールはどれも1リクエストで完結し、サーバー起点の通知も送らないため、セッションを持つ理由がありません。
同じ理由で POST の応答は SSE ではなく通常の JSON で返します(仕様上どちらでも構いません)。SSE はプロキシやゲートウェイにバッファされることがあり、環境依存の不具合を持ち込みやすいためです。
エラーは2種類に分かれます。
種類 | 返り方 | 例 |
スキーマ違反 | JSON-RPC エラー ( | 電話番号の形式が |
ガードレール違反・実行時エラー |
|
|
前者は MCP SDK が inputSchema で検証して弾くため、ハンドラに到達しません(エラーメッセージにはスキーマに書いた説明がそのまま入ります)。後者は原因が reason、次に取るべき行動が suggestion に入ります。
無効化されているツール(capability トグルが OFF)は登録されないため、tools/call では「存在しないツール」として扱われます。tools/list に出さない以上、これが MCP としての正しい表現です。どの環境変数を設定すべきかは起動ログと本 README を参照してください。
v1.3.0 の破壊的変更: POST /mcp-invoke と GET /mcp-tools を削除しました。
MCP と等価な機能を独自のインターフェースで二重に公開していたためです。/mcp だけ認証やガードレールを直しても、こうした別経路が残っていればそこから全部迂回できます。ツールの実行経路は /mcp の1本に絞りました。
既存の呼び出しは JSON-RPC の tools/call に置き換えてください。
{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"send_sms","arguments":{"to":"09012345678","message":"hello"}}}POST /webhooks/message-status
Vonage Messages API の Status Webhook(配信結果 / DLR)の受信エンドポイントです。Vonage から呼ばれるため Bearer トークン認証の対象外ですが、別途Webhook認証が必須です。
受信した配信結果はオンメモリに24時間保持され、get_sms_status ツールから参照できます。
このサーバーが送信した記録のない message_id は、配信ステータスの保持対象になりません。
同じ Vonage Application を別のシステムと共用していると、そちらが送信したメッセージの DLR もこのエンドポイントに届きます。それをそのまま保持すると、保持件数の上限(1000件)から自分のレコードが押し出され、get_sms_status が使えなくなります。
ただし、まれに DLR が送信 API のレスポンスより先に届くことがあります。これを取りこぼさないよう、未知の ID は 5 分間だけ別の小さなバッファに保持し、対応する送信が記録された時点で取り込みます。レスポンスの pending: true はこの状態を表します。Vonage Dashboard の Application 設定で Status URL に https://<host>/webhooks/message-status を登録してください。
認証は以下の優先順位で行われます。
VONAGE_API_SIGNATURE_SECRETが設定されていれば、Authorization: Bearer <JWT>の署名(HS256)と、ボディを束縛するpayload_hashクレームを検証する(推奨)VONAGE_WEBHOOK_SECRETが設定されていれば、x-webhook-secretヘッダーと照合するどちらも未設定なら 503 を返してエンドポイントを無効化する
状況 | HTTPステータス |
取り込み成功 |
|
再送・順序逆転で古い通知が届いた |
|
認証情報なし・不正な署名・ |
|
|
|
Webhook認証が未設定 |
|
# 共有シークレット方式の例
curl -X POST http://localhost:3000/webhooks/message-status \
-H "Content-Type: application/json" \
-H "x-webhook-secret: $VONAGE_WEBHOOK_SECRET" \
-d '{"message_uuid":"abc-123","to":"819012345678","status":"delivered","channel":"sms"}'POST /webhooks/inbound
受信メッセージ用のスタブ(常に 200 を返す)。Vonage側の設定必須項目を満たすために用意しています。
POST /webhooks/voice/answer
音声の着信に対して NCCO を返すエンドポイントです。このサーバーは発信専用で、着信を処理する機能を持ちません。 案内を読み上げて通話を終了します(文面は VOICE_INBOUND_MESSAGE で変更できます)。
それでも用意しているのは、Vonage の番号をアプリケーションにリンクすると、その番号への着信がアプリに向くためです。Answer URL が無いと、発信者は無言のまま切られます。
Vonage 側で Answer URL の HTTP メソッド(answer_method)を POST に変更してください。 既定は GET ですが、署名付き Webhook の検証はリクエストボディのハッシュ(payload_hash)を必要とするため、ボディの無い GET は受け付けません。GET で呼ばれた場合は 405 と対処法を返します。
POST /webhooks/voice/event
通話イベントの受信エンドポイントです。受信した内容はオンメモリに24時間保持され、get_call_status ツールのレスポンスに detail と sip_code として重ねて返されます。
通話が失敗した理由が届くのは、この Webhook だけです。 Voice API の GET /v1/calls/{uuid} は status しか返さず detail は常に null です。設定しておくと、原因調査が推測ではなく事実になります。
detail は status ごとに意味が異なります(公式リファレンス)。まとめて「宛先が悪い」と解釈しないでください。
status | detail | 意味 | 掛け直す意味があるか |
|
| 宛先がこのアカウントで未対応、またはブロック。相手の状態とは無関係 | ない |
|
| 宛先の番号自体が使われていない(番号の確認が要る) | ない |
|
| Vonage 側の内部エラー。宛先については何も分からない | 時間をおけばある |
|
| 番号が無効、キャリアまたは着信者が拒否 | 同じ条件では期待できない |
|
| 相手が一時的に応答できない | 時間をおけばある |
get_call_status は、接続できなかった通話にこの分類に沿った note を添えます。
detail が空でも、Webhook が未設定だとは限りません。 通知が届く前に確認した、Vonage が detail を付けなかった、サーバーが再起動した、24時間の保持期間を過ぎた——どれも同じ「空」に見えます。このサーバーからは原因を判別できないため、note も断定しません。
理由が「まだ届いていない」のか「届きようがない」のかで、正しい対処は正反対です。 届きようがない構成は2つあり、note はそれぞれを名指しして再確認を勧めません。
stdio 版 — Webhook を待ち受けるプロセスがありません。別プロセスの HTTP 版に Event URL を向けても、記録はそちらのメモリに入るだけで stdio 側の結果は変わりません(
get_sms_statusが stdio でsubmitted止まりなのと同じ理由)Webhook の認証が未設定 —
VONAGE_API_SIGNATURE_SECRETもVONAGE_WEBHOOK_SECRETも無い場合、エンドポイントは fail-closed で 503 を返し続けます。HTTP で動いていても記録は永久に埋まりません
受信したイベントはオンメモリに24時間保持されます(最大1000件)。このうち、このサーバーが発信していない通話(着信レグや、同じ Application を共用する別システムの通話)には専用枠 200 件を設けています。 枠を分けないと、着信が多い環境で get_call_status から引ける記録のほうが押し出されるためです。
busy が返っても「相手が通話中」と断定はできません。 実測で、アプリケーション側の設定が不十分なときに rate 0 / 0秒の busy が返り、同じ発信元から携帯宛は繋がる、という状態が起きました。detail が無いまま結論を出さないでください。
どちらのエンドポイントも認証は /webhooks/message-status と同じです(署名付きJWT を推奨、未設定なら 503 で無効化)。
古い Vonage アプリケーションでは、署名付き Webhook が既定で無効です。 その場合このサーバーは 401 を返し続けるので、Vonage Dashboard でアプリケーションの署名付き Webhook を有効化してください。
VONAGE_WEBHOOK_SECRET(共有シークレット)は、この経路の代替にはなりません。Vonage のアプリケーション設定で指定できるのは URL と HTTP メソッドだけで、x-webhook-secret ヘッダーを付ける手段がないためです。 この方式が使えるのは、手前に置いたゲートウェイなどがヘッダーを付与する構成に限られます。
Vonage Dashboard の Application 設定で、次のように登録します。
設定項目 | URL | メソッド |
Answer URL |
| POST |
Event URL |
| POST |
Gemini Enterprise などのAIエージェントから利用する
AIエージェントに設定すべき System Instruction(承認フロー、dry_run の使い方、エラー対処方針)を docs/gemini_system_instruction.md にまとめています。そのまま貼り付けられる形式です。
あわせて、サーバー側で ALLOWED_NUMBERS と RATE_LIMIT_PER_HOUR を設定することを強く推奨します。System Instruction はプロンプトインジェクションで破られる前提で読んでください。 実効的な防御はサーバー側の設定だけです。
⚠️ Gemini Enterprise のカスタム MCP サーバーコネクタを使う場合
公式ドキュメントによれば、このコネクタが送れる認証は 「認証なし」と「OAuth 2.0」の2つだけで、任意のヘッダを設定する欄がありません。つまり MCP_AUTH_TOKEN はこの経路では使えません。
かつコネクタは、MCP サーバーが公開インターネット上の HTTPS エンドポイントで到達可能であることを要求します。
ここで「認証なし」を選ぶと、課金を発生させられるサーバーが無認証で全世界に公開されます。 選ばないでください。
取りうる構成は次の2つです。
構成A: 上流で OAuth 2.0 を終端する
API Gateway や Identity-Aware Proxy をこのサーバーの手前に置いて OAuth 2.0 を処理し、本サーバーには TRUST_UPSTREAM_AUTH=true を設定します。認証の実装をこのサーバーから切り離せるうえ、監査ログもプラットフォーム側の仕組みに乗せられます。詳しくは推奨構成: 認証は手前の層に置くを参照してください。
構成B: ADK でエージェントを書く(実機で確認済み・推奨)
コネクタを使わず、Agent Development Kit の McpToolset から StreamableHTTPConnectionParams で接続します。任意のヘッダを送れるので MCP_AUTH_TOKEN がそのまま使えます。
ツール実行前の承認も ADK の require_confirmation で取れます。 Gemini Enterprise の Apps に承認ウィンドウが表示され、承認するまで送信されません(2026-08-25 に dry_run → 承認 → 実送信 → delivered まで確認しました)。
手順は Gemini Enterprise の Agent Apps から使う(ADK 経由) にまとめています。
import os
from google.adk.tools.mcp_tool import McpToolset
from google.adk.tools.mcp_tool.mcp_session_manager import StreamableHTTPConnectionParams
# 完全な実装では Secret Manager から解決する(下記リンク先を参照)
MCP_AUTH_TOKEN = os.environ["MCP_AUTH_TOKEN"]
def confirm_unless_dry_run(**kwargs) -> bool:
"""dry_run: true 以外の呼び出しに承認を要求する。"""
return kwargs.get("dry_run") is not True
# 課金対象のツールだけを、承認を必須にして渡す
sending = McpToolset(
connection_params=StreamableHTTPConnectionParams(
url="https://your-server.example.com/mcp",
headers={"Authorization": f"Bearer {MCP_AUTH_TOKEN}"},
),
tool_filter=["send_sms", "make_voice_call"],
require_confirmation=confirm_unless_dry_run,
)require_confirmation を省くと、課金対象のツールが承認なしで実行されます。 require_confirmation の callable にはツール名が渡らないため、読み取り専用のツールは別の McpToolset として渡してください(承認を掛けると不要な確認が毎回出ます)。
このサンプルは要点だけです。トークンをシリアライズに含めない書き方まで含めた完全な実装は ADK 経由の手順 にあります。
プロジェクト構造(続き)
├── dist/ # コンパイルされたJavaScript
├── package.json # プロジェクト設定
├── tsconfig.json # TypeScript設定
├── jest.config.js # Jest設定
├── .env.example # 環境変数設定例
├── private.key # Vonage秘密鍵(要設定・リポジトリには含めない)
├── LICENSE # Apache License 2.0
├── SECURITY.md # セキュリティポリシー
├── CONTRIBUTING.md # コントリビューションガイド
└── README.md # このファイル依存関係
主要パッケージ
@vonage/server-sdk- Vonage SMS機能@vonage/voice- Voice通話機能専用SDK@vonage/jwt- Webhook の署名検証@modelcontextprotocol/sdk- MCP Server実装zod- スキーマ検証zod-to-json-schema- ZodスキーマからJSON Schemaを生成(HTTP版のtools/list用)express/cors- HTTPラッパー
Vonage アカウントについて
このサーバーを使うには Vonage の Application ID と秘密鍵が必要です。
日本国内でご利用の場合は、日本語での申し込みページ からのお申し込みをご検討ください。日本語でのサポートと請求に対応しています。
海外からご利用の場合は Vonage Developer Portal から直接開設してください。
このサーバーはどちらの経路で開設したアカウントでも同じように動作します。 特定の経路を強制することはありません。
提供元
このプロジェクトは 株式会社KDDIウェブコミュニケーションズ が Vonage のリセラーとして開発・公開しています。
私たちはこのサーバーをサービスとして運営していません。 OSS のリファレンス実装として提供しており、利用者の資格情報を預かることはありません。
ライセンス
Copyright 2026 KDDI Web Communications Inc.
関連ドキュメント
セキュリティポリシー — 脆弱性の報告方法と脅威モデル
Gemini Enterprise の Agent Apps から使う(ADK 経由) — 実機で確認済みの手順
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections. Dates show when Glama detected each change.
No tool schema history has been recorded yet.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
MCP server for Vonage API documentation, code snippets, tutorials, and troubleshooting.
The Mobile Text Alerts SMS MCP server enables your AI to send SMS messages & manage contacts
Hosted MCP server for the Wavix telecom platform: SMS, voice, 2FA, SIP, numbers, 10DLC, CDRs.
MCP server for Text-to-Speech
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceMCP Server that integrates various Vonage APIs as MCP tools, to make it easier for developers to work with and create Vonage applications.353Apache 2.0
- AlicenseNot gradedqualityCmaintenanceMCP server for Twilio communications, enabling SMS/MMS sending, message listing, outbound calls, and phone number lookup.MIT
- FlicenseAqualityDmaintenanceMCP server for sending SMS messages via SmsManager.cz HTTP API, supporting high, economy, and low delivery gateways.1-
- AlicenseBqualityBmaintenanceMCP server for sending SMS via the SMSPM API. Send transactional SMS from Claude Desktop, Cursor, Windsurf, Cline, or any MCP client.148MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/mobilebiz/vonage-mcp-server'
If you have feedback or need assistance with the MCP directory API, please join our Discord server