mcpField
W
Webhook Toolkit

Webhook Toolkit

リモート
webhook-toolkit.com開発ツール06 週間前に更新
リポジトリ公式サイト

Webhook Toolkit について

Webhook Toolkitは、Webhookの受信、転送、署名、検証、再送に使えるCLI、型付きライブラリ、MCPサーバーを提供します。Webhook連携をテストする開発者やハンドラーをデバッグするコーディングエージェント向けで、受信リクエストの確認と再送にも対応します。

主な機能

  1. 01公開Webhook URLの作成
  2. 02ローカルハンドラーへのリクエスト転送
  3. 03プロバイダー形式のペイロード署名と検証
  4. 04リクエストの記録、確認、再送
  5. 05テスト中の配信待機

活用シーン

  1. 01テストスイートでWebhook配信を検証
  2. 02Webhook署名エラーの原因調査
  3. 03記録したリクエストをローカルハンドラーへ再送
  4. 04コーディングエージェントによる受信イベントの確認

MCP 対応

MCPサーバーは、URL作成、配信の待機と確認、リクエストの再送、ペイロードの署名・検証、応答設定のツールを提供します。ホスト型エンドポイントもありますが、ローカルへの再送やlocalhostへの送信にはローカルサーバーが必要です。

設定

リモートサーバーはインストール不要です。クライアントを選んで設定をコピーするか、ワンクリックで導入できます。

エンドポイントhttps://webhook-toolkit.com/mcp
インストールコマンドをコピー
Claude CodeTerminal
Cursor.cursor/mcp.json
VS Code.vscode/mcp.json
Claude Desktopclaude_desktop_config.json
Windsurf~/.codeium/windsurf/mcp_config.json

コマンドはターミナルで実行し、JSON は各クライアントの MCP 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

すべてのエンドポイント
Streamable HTTPhttps://webhook-toolkit.com/mcp認証が必要
パッケージ
npmwebhook-toolkit0.1.1

ツール

10
パラメーター型必須説明
namestringいいえラベル。例:'stripe-test'

詳細

webhook-toolkit

ターミナル、テストスイート、AI エージェントから Webhook を受信、転送、署名、検証できます。 1 つのパッケージに、CLI(webhook-toolkit、エイリアスは whtk)、型付きライブラリ、MCP サーバーが含まれています。webhook-toolkit.com を基盤としています。

npm license node CI

クイックスタート

npx webhook-toolkit listen --forward http://localhost:3000/webhooks

これだけです。アカウントも設定も必要ありません。公開 URL が発行されるので、Stripe、GitHub、Shopify などの送信元に貼り付けてください。すべての Webhook がターミナルに表示され、ローカルのハンドラーに再送信されます。

  webhook-toolkit · listening

  Webhook URL   https://webhook-toolkit.com/r/l90c9MKIdo0o
  Inspector     https://webhook-toolkit.com/e/l90c9MKIdo0o
  Forwarding    → http://localhost:3000/webhooks
  Expires       in 7 days (2026-09-25 15:42)
                Anonymous URL. Run `webhook-toolkit login` to get a permanent one.

  Waiting for webhooks. Ctrl+C to stop.

  15:42:11  POST   /stripe  stripe checkout.session.completed  248 B
            ↳ 200 OK · 3 ms
  15:42:11  POST   /github  github push  269 B
            ↳ 500 Internal Server Error · 1 ms  {"error":"handler crashed: cannot read properties of undefined"}

各リクエストは Web インスペクターにも保存されます(ヘッダー、生の本文、再送信)。そのため、ハンドラーがクラッシュしても何も失われません。

目次

CLI

npm i -g webhook-toolkit     # or run any command with npx webhook-toolkit …
コマンド内容
whtk listen [--forward <url>]公開 URL と受信リクエストのライブストリームを提供し、必要に応じて localhost に再送信します。URL が有効な間は最後に使用した URL を再利用します(新しい URL を作成するには --new)。
whtk relay --to <url|port>実際のトンネルです。呼び出し元にはローカルアプリの応答が返されます。有料。
whtk sign <provider> --secret <s>有効な署名付き Webhook を作成します。ヘッダーとすぐに実行できる curl を出力するか、--send を指定して送信します。
whtk verify <provider> --secret <s> …署名を検証し、失敗した場合は理由を説明します。
whtk replay <token> <id> --to <url>キャプチャしたリクエストをマシンから再送信します(localhost も使用できます)。
whtk requests <token>キャプチャしたリクエストを一覧表示します(スクリプトでは --json を指定します)。
whtk endpointsアカウントの URL を一覧表示します。
whtk login / logout / whoamiAPI キーを保存、削除、または確認します。
whtk mcpstdio で MCP サーバーを起動します。

知っておくと便利な点:

  • サブパスとクエリ文字列は保持されます。 …/r/<token>/stripe?x=1 へのリクエストは http://localhost:3000/webhooks/stripe?x=1 に転送されるため、1 つの URL で複数のハンドラーにリクエストを送信できます。
  • ヘッダーは受信時のまま転送されます(ホップバイホップヘッダー、host、content-length を除く)。そのため、ハンドラーでの署名チェックは本番環境と同じように成功します。
  • --json は NDJSON を出力します(listening、request、forward イベント)。スクリプトで使用できます:whtk listen -f 3000 --json | jq .request.event。
  • 色の表示は NO_COLOR と FORCE_COLOR に従い、出力先がターミナルでない場合は無効になります。
署名付きテストイベントを送信する
# Prints the headers and a curl command, with a realistic sample event
whtk sign stripe --secret whsec_… --event checkout.session.completed

# Or send it straight to your handler
whtk sign github --secret my-secret --file push.json --send http://localhost:3000/api/github
whtk sign twilio --secret <auth token> --url https://example.com/sms --send 3000
「無効な署名」をデバッグする
whtk verify stripe --secret whsec_test_secret --body-file body.json \
  -H "Stripe-Signature: t=1726000000,v1=a530ce3d81556a0eced506e1d1cad777bc55bc1e408e54dd6bfef08e1dde216c"
✗ Invalid Stripe signature (body_trailing_newline_added)
  The signature matches the body without its trailing newline: a newline was appended after signing (proxy, logger, copy-paste). Verify the raw bytes exactly as received.
  expected  t=1726000000,v1=1e0085bf1054f89ac8882e2e5fcbfdf301b1d6445e8ed7a316120cd5dc651ba9
  received  t=1726000000,v1=a530ce3d81556a0eced506e1d1cad777bc55bc1e408e54dd6bfef08e1dde216c
  timestamp 1726000000 (738 days ago)

検証ツールはよくある間違い(シークレット内の空白、末尾の改行の追加または削除、CRLF への変換、期限切れのタイムスタンプ、Twilio の場合は http と https、ポート、クエリ文字列、末尾のスラッシュ、パラメーターの重複)を再現し、一致するものを伝えます。同じロジックはオンライン署名バリデーターでも使用されています。

テストスイートで Webhook をテストする

このライブラリを使うと、テストに実際の公開 URL と、届いたリクエストを待ち受ける方法を追加できます。匿名で利用できます。永続的な URL と高い上限が必要な場合は、CI で WEBHOOK_TOOLKIT_KEY を設定してください。

Vitest(または ESM モードの Jest)
import { expect, test } from "vitest";
import { WebhookToolkit, verify } from "webhook-toolkit";

const wt = new WebhookToolkit(); // anonymous, or reads WEBHOOK_TOOLKIT_KEY

test("creating an order notifies the customer's webhook", async () => {
  const endpoint = await wt.createEndpoint({ name: "ci-orders" });

  // The app under test sends its outgoing webhooks to the capture URL.
  await api.post("/settings/webhooks", { url: endpoint.url, secret: "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw" });
  await api.post("/orders", { sku: "tshirt", quantity: 2 });

  const req = await wt.waitForRequest(endpoint.token, {
    timeoutMs: 30_000,
    filter: (r) => JSON.parse(r.body).type === "order.created",
  });

  expect(JSON.parse(req.body).data.quantity).toBe(2);
  // Your outgoing signatures are correct, too:
  expect(verify("svix", { secret: "whsec_MfKQ9r8GKYqrTwjUPD8ILPZIo2LaLaSw", rawBody: req.body, headers: req.headers }).valid).toBe(true);
});

waitForRequest は、エンドポイントの作成後にすでに届いたリクエストを確認してから、timeoutMs までロングポーリングするため、「トリガー」と「待機」の順序は問いません。一致するものがなかった場合は、WebhookToolkitError(code: "timeout")を返して拒否します。

ネットワークを一切使わずにハンドラーをテストするには、ペイロードにローカルで署名します。

import { sign } from "webhook-toolkit";

const { headers, body } = sign("stripe", { secret: process.env.STRIPE_WEBHOOK_SECRET!, event: "checkout.session.completed" });
const res = await fetch("http://localhost:3000/api/webhooks/stripe", { method: "POST", headers, body });
expect(res.status).toBe(200);
Playwright
import { expect, test } from "@playwright/test";
import { WebhookToolkit } from "webhook-toolkit";

const wt = new WebhookToolkit();

test("'Send test event' reaches the configured URL", async ({ page }) => {
  const endpoint = await wt.createEndpoint();

  await page.goto("/settings/integrations");
  await page.getByLabel("Webhook URL").fill(endpoint.url);
  await page.getByRole("button", { name: "Save" }).click();
  await page.getByRole("button", { name: "Send test event" }).click();

  const req = await wt.waitForRequest(endpoint.token, { timeoutMs: 15_000 });
  expect(req.method).toBe("POST");
  expect(req.headers["content-type"]).toContain("application/json");
});

このパッケージは ESM 専用です。CommonJS のテストランナーは Node ≥ 20.19 / 22.12(ネイティブの require(esm))で動作します。Jest にはESM モードが必要です。

AI エージェントから使用する(MCP)

webhook-toolkit mcp はModel Context Protocol サーバーです。コーディングエージェントは、Webhook URL を作成し、トリガー後に配信を待ってペイロードを読み取り、コードを修正しながら、そのリクエストを再送するか、新たに署名したイベントをlocalhostのハンドラーに送信できます。

API キーは任意です。list_webhook_urls と explain_webhook_request 以外はすべて匿名で使用できます。

Claude Code

claude mcp add webhook-toolkit -- npx -y webhook-toolkit mcp
# with a key:
claude mcp add webhook-toolkit --env WEBHOOK_TOOLKIT_KEY=whk_… -- npx -y webhook-toolkit mcp

Cursor(.cursor/mcp.json)、Windsurf(~/.codeium/windsurf/mcp_config.json)、Claude Desktop(claude_desktop_config.json)

{
  "mcpServers": {
    "webhook-toolkit": {
      "command": "npx",
      "args": ["-y", "webhook-toolkit", "mcp"],
      "env": { "WEBHOOK_TOOLKIT_KEY": "whk_…" }
    }
  }
}

VS Code(.vscode/mcp.json)

{
  "inputs": [
    { "type": "promptString", "id": "webhook-toolkit-key", "description": "webhook-toolkit.com API key (optional)", "password": true }
  ],
  "servers": {
    "webhook-toolkit": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "webhook-toolkit", "mcp"],
      "env": { "WEBHOOK_TOOLKIT_KEY": "${input:webhook-toolkit-key}" }
    }
  }
}

Codex CLI(~/.codex/config.toml)

[mcp_servers.webhook-toolkit]
command = "npx"
args = ["-y", "webhook-toolkit", "mcp"]
env = { WEBHOOK_TOOLKIT_KEY = "whk_…" }

ChatGPT、Claude.ai、その他のリモート接続対応クライアント:ホストされたサーバーを指定するカスタムコネクターを追加します。インストールは不要です。

https://webhook-toolkit.com/mcp

(Streamable HTTP。Authorization: Bearer whk_… は任意です。)ホストされたサーバーからお使いのマシンにはアクセスできないため、localhost への再送と send_signed_webhook には、上記のローカルサーバーが必要です。

ツール用途
create_webhook_urlサードパーティーサービスやテスト対象のアプリから Webhook を受信するための公開 URL を取得します
wait_for_webhook配信が届くまで待機します(フィルター:プロバイダー、イベント、メソッド、パス、本文)。トリガー後に安全に呼び出せます
list_webhook_requests / get_webhook_request実際に送信された内容(ヘッダー、生の本文、検出されたプロバイダーとイベント)を確認します
replay_webhook_requestキャプチャしたリクエストを、ローカルマシンから http://localhost:3000/api/webhooks などに再送します
send_signed_webhook正しく署名されたイベント(Stripe、GitHub、Shopify、Slack、Twilio、Mailgun、Svix、Paddle、Discord)をハンドラーに POST します
sign_webhook_payload送信せずに署名ヘッダーと curl コマンドを生成します
verify_webhook_signatureハンドラーが署名を拒否する理由を説明します
set_webhook_responseURL の応答(ステータス、本文)を変更します。障害をシミュレートしたり、チャレンジに応答したりできます
list_webhook_urls既存の永続 URL を検索します(キーが必要です)
explain_webhook_requestペイロードの AI による説明、または生成されたハンドラーを取得します(有料、無料トライアル 3 回)

出力はコンパクトなテキストと主要な JSON です。20 KB を超える本文は切り詰められ、インスペクターへのリンクが注記されます。サーバーを独自のプロセスに組み込むには、import { createMcpServer } from "webhook-toolkit/mcp" を使用します。

署名と検証

sign() と verify() は node:crypto を使ってローカルで実行されるため、シークレットがマシンの外に出ることはありません。署名は webhook-toolkit.com signer とバイト単位で一致し、テストでは各プロバイダーが公開しているサンプル(GitHub、Slack、Twilio、Svix)と照合しています。

プロバイダーid署名アルゴリズムsecret
StripestripeStripe-Signaturet.body の HMAC-SHA256(16進数)エンドポイントのシークレット whsec_…
GitHub、Gitea、ForgejogithubX-Hub-Signature-256(および X-Hub-Signature)body の HMAC-SHA256(16進数)Webhook シークレット
ShopifyshopifyX-Shopify-Hmac-Sha256body の HMAC-SHA256(Base64)アプリのクライアントシークレット
SlackslackX-Slack-Signature、X-Slack-Request-Timestampv0:ts:body の HMAC-SHA256(16進数)署名シークレット
TwiliotwilioX-Twilio-SignatureURL とソート済みパラメーターの HMAC-SHA1(Base64。JSON の場合は bodySHA256)認証トークンと url
Mailgunmailgunbody 内の signature オブジェクトtimestamp + token の HMAC-SHA256(16進数)Webhook 署名キー
Svix / Standard Webhooks(Clerk、Resend)svixsvix-* と webhook-* ヘッダーid.ts.body の HMAC-SHA256(Base64)whsec_…
Paddle BillingpaddlePaddle-Signaturets:body の HMAC-SHA256(16進数)pdl_ntfset_…
Discord interactionsdiscordX-Signature-Ed25519、X-Signature-TimestampEd25519検証:アプリの公開鍵、署名:テスト用秘密鍵
import { sign, verify } from "webhook-toolkit";

// In an Express handler (use express.raw so the body stays byte-exact)
app.post("/webhooks/stripe", express.raw({ type: "*/*" }), (req, res) => {
  const result = verify("stripe", { secret: process.env.STRIPE_WEBHOOK_SECRET!, rawBody: req.body, headers: req.headers });
  if (!result.valid) return res.status(400).send(result.message);
  // …
});

verify() は { valid, reason?, message, expected?, received?, timestamp? } を返します。失敗理由は missing_signature、malformed_signature、missing_timestamp、missing_url、invalid_secret、timestamp_out_of_tolerance(デフォルトは 300 秒。toleranceSeconds: 0 で無効化)、signature_mismatch、secret_whitespace、body_trailing_newline_added、body_trailing_newline_removed、body_line_endings_changed、url_mismatch(Twilio)、body_hash_mismatch(Twilio JSON)です。比較は定数時間で行われます。

プロバイダーの検出

detectProvider(headers, body) は、データ駆動型のテーブル(DETECTION_RULES)から { provider, event } を返します。たとえば、{ provider: "stripe", event: "invoice.paid" } や { provider: "twilio", event: "message.received" } です。Stripe、GitHub、GitLab、Bitbucket、Shopify、WooCommerce、Slack、SendGrid、Twilio、Paddle、Svix(Clerk、Resend)、GoCardless、PayPal、Discord、Linear、Typeform、Calendly、Square、HubSpot、Zoom、Lemon Squeezy、Coinbase Commerce、Twitch、Mux、Vercel、Netlify、Sentry、Trello、Plaid、Mandrill、Jira、Postmark、Mollie、Adyen、Mailgun、Redsys に対応しています。追加するには、テーブルの項目とテスト用フィクスチャを追加します。

Relay:実際のトンネル(有料)

listen --forward は無料で、ほとんどの Webhook で問題なく使えますが、送信元が受け取るのはアプリの応答ではなく、キャプチャ URL の応答です。送信元に実際の応答を返す必要がある場合(Slack のスラッシュコマンド、Twilio TwiML、Shopify の必須応答、OAuth コールバック)は、Relay を使います。

whtk login               # once
whtk relay --to 3000
  webhook-toolkit relay · live

  Public URL  https://webhook-toolkit.com/relay/my-app  (any sub-path works)
  Forwarding  → http://localhost:3000

公開 URL へのリクエストは WebSocket 経由でマシンにプロキシされ、ローカルの応答(ステータス、ヘッダー、body)が呼び出し元に返されます。バックオフ付きで再接続します。Relay は 7-day Pass or Pro に含まれています。

無料プランと有料プラン

匿名無料アカウントPass(7 日間、€5・1 回限り)/ Pro(€9/月)
キャプチャ URL1 日あたり最大 30 個を新規作成でき、それぞれ 7 日間有効永続 URL 1 個永続 URL 25 個
履歴7 日間7 日間30 日間
CLI listen --forward、リプレイ、署名、検証、MCP✓✓✓
Relay(localhost への実際のトンネル)✓
AI による説明とハンドラーの生成無料トライアル 3 回無料トライアル 3 回✓

詳細と Business プランについては、webhook-toolkit.com/pricing をご覧ください。ローカルで実行されるすべての機能(署名、検証、検出、転送)は無料で、今後も無料です。

比較

  • smee.io は、GitHub Probot チームが提供する無料のオープンソースサービスで、クライアントを通じて Webhook を localhost に転送します。転送だけが必要なら、これで十分です。webhook-toolkit の listen --forward も同様に動作し、保存されたインスペクター、プロバイダー/イベントの検出、リプレイ、署名・検証ツール、テストスイート API、MCP サーバーが追加されています。
  • webhook.site は、カスタムレスポンスや有料の自動化機能を備えた、成熟したホスト型リクエストインスペクターです。webhook-toolkit は検査と応答の機能をカバーし、転送、署名付きテストイベント、署名の診断、テスト、エージェントといったローカル開発ループに重点を置いています。
  • ngrok は、ローカルのトラフィックインスペクターを備えた、あらゆる HTTP または TCP サービス向けの汎用トンネルです。アプリ全体を公開する場合に選んでください。webhook-toolkit の無料のワークフローではアカウントが不要で、有料リレーは Webhook に特化しています。

ライブラリリファレンス

import { WebhookToolkit, WebhookToolkitError, sign, verify, detectProvider, forwardRequest } from "webhook-toolkit";

const wt = new WebhookToolkit({ apiKey, baseUrl }); // both optional (env: WEBHOOK_TOOLKIT_KEY, WEBHOOK_TOOLKIT_URL)
メソッド戻り値
createEndpoint({ name? })Endpoint:{ token, url, inspectUrl, expiresAt, createdAt, response, … }
listEndpoints()Endpoint[](API キーが必要)
getEndpoint(token) / deleteEndpoint(token)Endpoint / void
updateEndpoint(token, { name?, response?: { status?, body?, contentType? } })Endpoint
listRequests(token, { limit?, after? })CapturedRequest[](新しい順)
getRequest(token, id) / clearRequests(token)CapturedRequest / void
waitForRequest(token, { timeoutMs?, after?, filter?, signal? })CapturedRequest(code: "timeout" で拒否されます)
stream(token, onRequest, { signal?, after?, onOpen?, onReconnect? })Promise<void>:ライブ SSE フィード。再接続し、受信し損ねたリクエストを取得します
replayRequest(token, id, url)サーバー側から公開 URL へのリプレイ
explainRequest(token, id, { mode?, language? })AI による説明またはハンドラー(有料、無料トライアル 3 回)
me()、listRelays()、createRelay()アカウント、プラン、リレー

forwardRequest(request, target) は、キャプチャしたリクエストをお使いのマシンから再送信します(listen --forward と replay が内部で使用するものと同じ関数です)。エラーは WebhookToolkitError で、status(HTTP ステータス。ネットワークエラーの場合は 0)、code(unauthorized、upgrade_required、plan_limit、expired、timeout、network_error など)、および 402 の応答時の upgradeUrl を持ちます。すべて型付けされており、型定義はパッケージに含まれています。

設定

変数用途
WEBHOOK_TOOLKIT_KEYAPI キー(whk_…)。ダッシュボードで作成します。保存済みのキーより優先されます。--key を指定すると、どちらよりも優先されます。
WEBHOOK_TOOLKIT_URLAPI のオリジン。セルフホストのインスタンスの場合は http://localhost:3000 などです。--base-url と同じです。
WEBHOOK_TOOLKIT_RELAY_TOKENwhtk relay 用のリレートークン。
NO_COLOR / FORCE_COLORターミナルの色。

whtk login はキーを ~/.config/webhook-toolkit/config.json(または $XDG_CONFIG_HOME/webhook-toolkit/config.json)に、モード 600 で保存します。同じファイルには、listen で最後に使用した URL も記録されます。

キャプチャ URL のトークンは、それを保持する誰もが送信されたリクエストを読み取れる機能です。機密情報を扱う場合はアカウントを使用してください。その場合、URL の変更や削除には所有者のキーが必要になります。

要件

Node.js 18.17 以降。実行時依存関係:@modelcontextprotocol/sdk と zod(MCP サーバー)、および ws(リレー)。

コントリビューション

Issue とプルリクエストを歓迎します。CONTRIBUTING.md をご覧ください。検出または署名に対応する新しいプロバイダーを追加するのが、最も手軽な貢献方法です。

ライセンス

MIT © 2026 Kipdev。ホスト型サービス:webhook-toolkit.com。

コメント

MCP は初めてですか?

プロトコルの概要から最初のサーバーの導入まで、よくある疑問にまとめて答えます。

AI アプリケーションが外部のツールやデータソースに統一的な方法で接続するためのオープンなプロトコルです。クライアントはモデルとの対話を担い、MCP サーバーはツール・リソース・プロンプトテンプレートを提供します。標準メッセージでやり取りするため、1 つのサーバーを複数のクライアントで再利用できます。