mcpField
W
Webhooks by Wakeshift

Webhooks by Wakeshift

リモート
try.wakeshift.ai開発ツール04 日前に更新
リポジトリ公式サイト

Webhooks by Wakeshift について

Webhooks by Wakeshift は、外部イベントで AI エージェントの会話を起動したい開発者向けに、監視可能な webhook URL を提供します。MCP ツールでイベントを購読し、POST、PUT、PATCH の受信を会話に通知します。

主な機能

  1. 01webhook リンクと受信 URL の作成
  2. 02イベントの購読と解除
  3. 03最近の投稿と webhook 情報の表示
  4. 04GitHub、Stripe、Linear の署名検証
  5. 05イベントと接続状態のライブ表示

活用シーン

  1. 01GitHub のワークフロー失敗時にエージェントを起動
  2. 02Stripe の決済イベントを受けて処理を開始
  3. 03Linear の更新をエージェントに通知

MCP 対応

Streamable HTTP の MCP サーバーとして、`watch`、`unwatch`、`recent_posts`、`webhook_info` を提供します。MCP クライアントは `webhook.received` を購読し、リクエスト受信時に会話を起動できます。

設定

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

エンドポイントhttps://try.wakeshift.ai/t/{link}/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 設定に貼り付けて再起動します。認可が必要なサーバーは初回接続時にログインを求めます。

ツール

詳細

Webhook

エージェントを起動する Webhook URL です。リンクを取得して、エージェント(Claude Code、Codex、Cursor、Antigravity、opencode、Copilot CLI、または任意の MCP クライアント)に追加し、監視するよう指示します。すると、Webhook URL への POST(curl、Postman、GitHub、Stripe、Linear、ご自身のアプリからの POST)ごとにエージェントが起動します。Wakeshift は try.wakeshift.ai で実行されます。TypeScript SDK の @wakeshift/sdk を基盤にしています。

仕組み

  • ステートレスリンク。 リンクのコードは TRY_SECRET で署名され、ランダムな Webhook ID と作成日時が指定されています。MCP URL(/t/<code>/mcp)、ページ(/l/<code>)、Webhook URL(/in/<token>、署名チェックごとに 1 つ)、署名シークレットはすべてこのコードから導出されます。何も保存されません。リンクは 7 日間使用されないと期限切れになります。最後に使用された日時はデータベースに保存されます(インスタンスごとに最大 5 分に 1 回書き込まれます)。期限切れになると、Wakeshift に Webhook を忘れるよう依頼します(Webhook ID を指定した forgetUser。その Webhook にとってはアプリのユーザーです)。これにより、そのワークスペース、それを監視していた会話、そのサブスクリプションと配信が削除されます。期限切れの処理では、リンク自身の行を削除するトランザクション内でデータベースにキューを追加し、各インスタンスが 10 分ごとにキューを処理します。失敗した場合は、Wakeshift が完了を返すまでバックオフ(1 分から始まり、最大 6 時間まで倍増)で再試行します。
  • SDK のユーザーは Webhook、投稿はイベントです。 webhook.received(引数:Webhook の ID。サブスクライブできるのは、その Webhook 自身の SDK ユーザー、つまりリンクを持つ人だけです)には、投稿内容が含まれます。summary、何が起きたかを示す 1 行、その後に解析済みの本文と送信者を示すヘッダーが続きます。各ツールは attached.events(wake.attach が返すハンドル)でラップされ、Wakeshift の引数は attached.inputs を通して受け取ります。watch は call.subscribe で呼び出し元の会話をサブスクライブし、unwatch は call.unsubscribe でサブスクリプションを終了します。ラッパーは各ツールの結果に Wakeshift のブロックを 1 つ追加します。ブロックには、サブスクライブ後に会話をどのように起動するか、保留中のメッセージ、またはそれ以外の場合は Codex スレッドのビーコンが含まれます。呼び出しが失敗すると、その呼び出しが作成したサブスクリプションは終了します。MCP Events に対応するクライアント(ChatGPT)は会話をサブスクライブしません。ブロックには、webhook.received を自分でサブスクライブするよう記載されています。投稿は event.emit になります。wake.attach は subscribe_events、unsubscribe_events、list_subscriptions を追加します。
  • MCP: セッションを使用する Streamable HTTP で、サインインは不要です(URL 内のコードが認証情報です)。インスタンスにはセッション情報を保存しません。initialize のクライアント名、バージョン、ケイパビリティは Mcp-Session-Id の下に保存され、各リクエストでは、保存された情報から MCP サーバーを新たに構築し、リクエストが到達したインスタンスで処理します(ステートレスモードの SDK トランスポート。セッション ID はここで検証され、不明な場合や別のリンクのものの場合は 404 を返します)。そのため、セッションは再起動後も維持され、スティッキーセッションは不要です。また、クライアント名とケイパビリティ(Cursor、opencode などをどのように起動するか、自分でサブスクライブするクライアントかどうかを決定します)は、どのインスタンスからも参照できます。再構築されたサーバーは、保存された initialize の情報から getClientVersion と getClientCapabilities に応答し、ラッパーはそれらを読み取ります。7 日間操作のないセッションは削除されます(クライアントは再度 initialize します)。ツール:watch、unwatch、recent_posts、webhook_info。
  • Webhook: /in/<token> への POST、PUT、または PATCH。本文は最大 64 KB です。イベントの text は何が起きたかを示します。GitHub の場合(X-GitHub-Event から)GitHub workflow_run completed: failure on main (tests) in acme/api、Stripe の場合 Stripe invoice.payment_failed: in_…, USD 49.00, open (evt_…, test mode)、Linear の場合 Linear Issue create: ENG-123 Checkout page 500s、それ以外の場合は POST to your webhook(空の本文だった場合は (empty body) 付き)となります。残りの情報は data に含まれます。text では本文を繰り返さないため、小さな投稿なら data の全体が Monitor の 1 行(480 バイト)に収まります。data には解析済みの本文(body または body_base64)、メソッド、コンテンツタイプ、送信者を示すいくつかのヘッダー(Linear-Event と Linear-Delivery を含みます。Authorization、Cookie、署名は含みません)、および Stripe と Linear の場合は source(イベントタイプと ID)が含まれます。再試行は 1 回の公開として扱います。重複判定には Idempotency-Key、X-GitHub-Delivery、Linear-Delivery、または Stripe イベントの evt_ ID を使います。GitHub、Stripe、Linear の URL では、そのサービス独自の ID のみを使います(Idempotency-Key は署名されないため、取得された配信を新しいキーで再送すると、エージェントが再び起動します)。Stripe URL では、署名済み本文内の evt_ ID のみを使います。GET は投稿方法を説明します。上限を 256 KB 超える本文は、読み込まずに接続を切断します。
  • 署名チェック: ページのタブにはチェックごとに URL が表示され、それぞれ異なるトークンを持つため、チェック済み URL をオープン URL に変えることはできません。オープン URL は、ユーザーが(下記のとおり)置き換えるまで、それを持つ人なら誰でも引き続き使えます。GitHub の X-Hub-Signature-256 と Authorization: Bearer には、Webhook ごと、チェックごとに導出したシークレット(try_gh_…、try_bearer_…)を使います。Stripe と Linear では、それぞれ独自のシークレットを作成します。ユーザーがそのシークレットをページに貼り付けると、その URL のトークンに封入されます(TRY_SECRET から導出したキーを使う AES-256-GCM)。保存されるのはこの形式だけです。リンクの期限が切れるまで、URL は Webhook のチェック済み URL として保持されます(下記参照)。Stripe の Stripe-Signature(t=…,v1=…、t.body の HMAC-SHA256)は 5 分以内でなければなりません。Linear の Linear-Signature(本文の 16 進数形式の HMAC-SHA256)では、webhookTimestamp が 1 分以内である必要があります。
  • 新しいオープン URL: オープンタブの「新しい URL を取得」(POST /l/<code>/rotate)はオープン URL を置き換えます。以降、そのトークンには Webhook のオープン URL 世代が含まれ、これはデータベースの Webhook ごとの hooks.open_gen に保存されます。世代が異なるオープン URL への投稿や GET は、すべてのインスタンスでただちに 410(replaced)になります。Webhook ID(SDK ユーザーであり、サブスクリプションを持ちます)、リンクと MCP URL、履歴、チェック済み URL はそのまま維持され、ライブビューには URL が変更されたことを示す行が表示されます。依頼できるのはリンクのコードだけです(Webhook URL は別の権限であり、依頼できません)。また、このサイトのページからのみ依頼できます。Origin または Sec-Fetch-Site に別のサイトから送信されたことが示されているリクエストは 403 になります。Webhook ごとに 1 時間あたり 10 回までで、それを超えると 429 になります。
  • エージェントに通知する URL: watch と webhook_info は、ユーザーが最後に選んだチェック済み URL(開いた GitHub または bearer タブ、作成した Stripe または Linear URL、またはサービスが最後に投稿した URL)を返し、使用するチェックの種類を示します。リンクが有効な間は保持されます。
  • 制限(データベースでアトミックにカウントするため、インスタンス間で適用されます。固定ウィンドウは 1 時間および UTC の 1 日です):Webhook の各 URL につき 1 時間あたり 60 件、1 日あたり 500 件の投稿(429 と Retry-After を返します)。これにより、オープン URL を持つ人がチェック済み URL の枠を使い切ることはありません。拒否された投稿(401、413)はカウントされません。再試行はカウントされます(いずれも Wakeshift へのリクエストであるため、同じ Idempotency-Key を再利用しても制限を回避できません)。すべての Webhook を合わせて 1 時間あたり 20,000 件、アドレスごとに 1 時間あたり新規リンク 30 件(IPv6 アドレスは /64 単位。アドレスは 1 時間、HMAC として保持されます)。TRY_PER_HOUR、TRY_PER_DAY、TRY_GLOBAL_PER_HOUR、TRY_LINKS_PER_HOUR で変更でき、利用規約とプライバシーポリシーに現在の制限が記載されています。
  • 過負荷: 1 インスタンスが同時に処理するリクエストは 256 件までです(そのうち投稿は 4 分の 3 までとし、ページやツール呼び出し用に余裕を残します)。開いているストリームは 900 件までです(ライブビュー、MCP GET、listen ストリーム)。1 つの Webhook につき、ライブビューは最大 20 件、これとは別にエージェントのストリームは 20 件までです。これにより、エージェントがページの接続枠を使い切ることはありません。1 つの MCP セッションにつき GET ストリームは 2 件までです(ライブビューはそれを超えると 429、GET ストリームは 405 になります)。上限を超えた場合や、データベースに接続できない場合、または接続数が上限に達した場合は、Retry-After と簡潔なメッセージを添えて 503 を返します(Webhook は JSON、MCP は JSON-RPC、ページはページ形式)。500 は返しません。データベースの応答が遅くても、リンクのページは履歴なしで表示されます。ライブビューは再試行し、その旨を表示します(下記参照)。公開時の Wakeshift 独自の 429 または 503 は、投稿元に Retry-After 付きの 503 として返されます。
  • ページのライブビュー は、このサーバーからの SSE(/l/<code>/live)です。各投稿(受信、拒否、レート制限、投稿内容の冒頭、配信先となった監視中の会話の数)、各 watch と unwatch が表示されます。行はデータベースに保存されます(Webhook ごとに直近 50 件)。Webhook のチャネル(try_<hook>)での NOTIFY によって、すべてのインスタンスのページに届きます。各インスタンスは、ページを開いている Webhook のみ LISTEN し、接続が切れて復旧するたびに直近の行を再生します。また、無言で切断されていることを検知できるよう、その接続に 30 秒ごとに ping を送ります。Webhook の拒否された投稿とレート制限された投稿については、署名不正の大量投稿で実際の投稿が押し出されないよう、インスタンスごとに 1 分あたり最大 10 行までです。それ以外は集計され、1 分が経過するかインスタンスが停止すると、各インスタンスがその件数を Webhook の 1 分ごとの行に加算し、ページ上でその行をその場で更新します。すべてのインスタンスの合計を示す行は 1 分に 1 回だけで、各インスタンスが Webhook ごとに最大 1 回書き込みます。書き込みに追いつけないライブビューは切断されます(EventSource が再接続します)。各行には seq を SSE ID として付与し、ライブビューは最後に受け取った番号より後の行を要求します(?after=<seq>、または EventSource の自動再接続時は Last-Event-ID)。そのため、間が空いても、その間に起きたことが表示されます(直近 50 件の範囲内)。サーバーから拒否された場合(429、503)、EventSource は再接続を諦めます。ページは 2 秒後に再試行し、その後最大 30 秒まで間隔を倍増させます(少しランダム化されます)。接続できると 2 秒に戻り、ページが再表示されたとき、ネットワークが復旧したとき、またはステータスポーリングが応答を受け取ったとき(page.ts の liveConnection)にはただちに再試行します。ページには watch の呼び出し元、「sent to N watching conversations」の投稿ごとの表示、エージェントが現在接続されているかどうかと接続方法(stream、hooks、polling)が表示されます。10 秒ごとに /l/<code>/status をポーリングし、Webhook ID を使って Wakeshift に webhook.received の状態を問い合わせます(読み取り専用の event.status)。

自分で実行する

  1. Wakeshift コンソールで Build → New app を開き、キー(wst_…)をコピーします。

  2. 空の Postgres データベースを作成します。Webhooks は起動時にテーブルを作成します(migrations/)。

  3. リポジトリのルートから、SDK、次に Webhooks をビルドします。

    (cd third_party/wakeshift-node && npm ci && npm run build)
    cd webhooks && npm ci && npm run build
    
  4. .env.example を .env にコピーして値を入力し、実行します。

    変数
    WAKESHIFT_KEY手順 1 のアプリのキー
    WAKESHIFT_COREWakeshift の URL(デフォルトは https://app.wakeshift.ai)
    TRY_SECRETリンクに署名します。32 バイト以上のランダムな値を指定してください。変更すると、すべてのリンクが無効になります
    TRY_DATABASE_URL手順 2 のデータベース。すべてのインスタンスで共有します
    TRY_DB_POOLインスタンスあたりの接続数(デフォルトは 3)。これに加えて、ライブビューのリッスン用に 1 接続を使用します
    PUBLIC_URLコピーの公開 URL(デフォルトは http://localhost:$PORT)
    PORTリッスンするポート(デフォルトは 8380)
    TRY_PROXY_HOPSX-Forwarded-For に値を追加する、手前にあるプロキシの数(Google のロードバランサーでは 2)。0 にすると、ソケットのアドレスを使用します
    TRY_PER_HOUR, TRY_PER_DAY, TRY_GLOBAL_PER_HOUR, TRY_LINKS_PER_HOURオプション:上記の制限
    set -a; . ./.env; set +a
    npm start
    
  5. PUBLIC_URL を開いてリンクを取得し、エージェントのタブに表示されるコマンドを実行します。

テスト

npm run lint
npm test     # unit tests; needs WAKESHIFT_TEST_DATABASE_URL, a Postgres URL for a role that can create databases

エンドツーエンドテストと負荷テストでは、Wakeshift サーバーに対して Webhooks を実行するため、Wakeshift 自体のリポジトリ内で実行します。

コントリビュート

このリポジトリは Wakeshift のメインリポジトリから生成されています。プルリクエストを歓迎します。変更はそちらに適用し、結果を公開します。CONTRIBUTING を参照してください。

コメント

MCP は初めてですか?

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

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