Skip to content

0 requirements

Claude Lin & Lay edited this page Aug 6, 2026 · 7 revisions

github-webhook-mcp Requirements Specification

Purpose

GitHub Webhook イベントを Cloudflare Worker で受信・永続化し、MCP プロトコル経由で AI エージェントに提供する。 エージェントが GitHub の状態変化をリアルタイムに検知し、自律的に対応できるようにする。

Premise

  • GitHub Webhook は Cloudflare Worker に直接到達する(ローカルサーバー不要)
  • イベントは Durable Object 内の SQLite に永続化される
  • AI エージェントは MCP stdio トランスポート(ローカルブリッジ)または Streamable HTTP(リモート)で接続する
  • ローカルブリッジは Worker にツール呼び出しをプロキシし、WebSocket でリアルタイム通知を中継する

Architecture

GitHub ──POST──▶ Cloudflare Worker ──▶ TenantRegistry DO
                  │ 署名検証                    │ installation_id → account_id
                  │ UUID 付与                    │
                  │                             ▼
                  │                    WebhookStore DO (SQLite) [per-tenant]
                  │                             │
                  ├── /mcp (Streamable HTTP)     ├── WebSocket / SSE real-time stream
                  │    createMcpHandler          └── REST endpoints
                  │    [stateless, per-request]       /pending-status
                  │    └── tools → WebhookStore       /pending-events
                  │                                   /webhook-events
                  ├── /events (WebSocket/SSE)          /event
                  │    └── WebhookStore DO             /mark-processed
                  │
                  ├── /oauth/authorize ──▶ github.com/login/oauth/authorize
                  ├── /oauth/callback  ◀── github.com redirect_uri (Worker-hosted)
                  ├── /oauth/token (web_authorization_poll, refresh_token)
                  │
                  └── /webhooks/github (POST)
                       └── TenantRegistry → WebhookStore DO /ingest

                          ┌─────────────────────────────┐
                          │  Local MCP Bridge (.mcpb)    │
                          │  stdio ← Claude Desktop/CLI  │
                          │  → proxy tool calls to /mcp  │
                          │  → WebSocket listener → channel │
                          │  → browser: /oauth/authorize  │
                          │  → poll:    /oauth/token      │
                          └─────────────────────────────┘

システムは四つのコンポーネントで構成される:

  1. Cloudflare Worker — webhook 受信、署名検証、テナントルーティング
  2. TenantRegistry Durable Object — installation_id → account_id マッピング管理、テナント単位クォータ管理(単一インスタンス)
  3. WebhookStore Durable Object — SQLite によるイベント永続化、REST/WebSocket/SSE エンドポイント(テナント別インスタンス: store-{accountId}
  4. ステートレス MCP ハンドラ — MCP Streamable HTTP サーバー、ツール定義。プロトコル版 2026-07-28 でセッションが消えたため Durable Object ではなく、リクエストごとに createMcpHandler が組み立てる(#249)

ローカルブリッジ(mcp-server/)は Worker に対するプロキシであり、データを保持しない。

プロトコル版と単レーン切替(#249)

Worker は MCP プロトコル版 2026-07-28(ステートレスコア)のみを提供する。createMcpHandlerlegacy: "reject" を渡しており、2025 系のリクエスト(initialize を含む)は、この endpoint が提供する唯一の版を名指しした unsupported-protocol-version エラーで返る。

Worker のプロトコル版は、本 repo の 2 成果物(Worker と npx ブリッジ)のあいだの私的な契約である。mcp-server/server.json は stdio トランスポートのみを宣言しており、リモートトランスポートの宣言が無いため、第三者クライアントが Worker に直接到達する経路は存在しない。したがって Claude Desktop 側の対応状況は Worker 側移行の条件ではない。ブリッジは二面を持ち、両面は独立している:

実装
Claude Desktop に対してサーバー SDK v1 stdio(Server クラス) 2025 系
Worker に対してクライアント SDK v2(@modelcontextprotocol/client 2026-07-28 に pin

互換レーンは実装しない。 保守されないフォールバック経路は放置されて死にコード化する。畳む条件が観測可能(旧レーンへの到達がゼロになる)であっても、観測できることと観測しに行くことは別であり、運用上その判断は忘れられる。破断の吸収はコードではなく、minor リリース + README 注意書きという別チャネルで行う。

非対称の所在: Worker は全員共有の 1 デプロイなので一斉に飛ぶ。ブリッジは利用者ごとで、各自の MCP クライアント再起動で追随する(@latest 指定でも起動済みプロセスは古い版を保持する — #247 / #248)。版を固定している外部利用者は再起動しても復旧しない。この層の切り捨てを受け入れるというのが本決定である。

Functional Requirements

F1. Webhook 受信

ID 要件
F1.1 POST /webhooks/github で GitHub Webhook ペイロードを受信する
F1.2 X-Hub-Signature-256 ヘッダによる HMAC-SHA256 署名検証を行う
F1.3 署名不一致時は HTTP 403 を返す
F1.4 シークレット未設定時は署名検証をスキップする
F1.5 テナント単位クォータ超過時は HTTP 429 を返す(installation イベントはクォータチェックをスキップ)
F1.6 認証チェック順序: IP allowlist → per-IP rate limit → signature → tenant resolution → per-tenant quota → ingest

F2. イベント永続化

ID 要件
F2.1 イベントを UUID 付きで WebhookStore DO の SQLite に保存する
F2.2 各イベントは id, type, payload, received_at, processed フィールドを持つ
F2.3 trigger_status, last_triggered_at フィールドを保持する(将来の trigger 機能用)
F2.4 mark_processed 実行時に、processed=1 かつ received_at が保持期間(PURGE_AFTER_DAYS 日、既定 3)より古いイベントを自動削除する。処理済み死蔵行による DO ストレージ肥大を防ぐ(即時性のための補助経路。本質的な保証は F2.5 の Alarm sweep が担う)
F2.5 DO Alarm(ctx.storage.setAlarm + alarm() ハンドラ)による時間駆動の retention sweep を提供する。sweep は (a) processed=1 かつ received_atPURGE_AFTER_DAYS 日(既定 3)より古い処理済みイベントと、(b) processed=0 かつ received_atUNPROCESSED_PURGE_AFTER_DAYS 日(既定 90)より古い未処理イベントを、まとめて削除する。alarm() は実行後に次回 sweep を再スケジュールし、消費ゼロ(mark_processed が一度も呼ばれない放置テナント)でも周期実行(日次)される。未処理保持期間を処理済みより長く取るのは未読データ消失の安全域確保のため(3 日 / 90 日の非対称は意図的)。既知の限界(スコープ外): 時間窓は「古さ」を縛るが「量」は縛らないため、高頻度 × 無消費テナントは 90 日窓があっても Cloudflare の 1GB/DO 壁に先に到達しうる。量ベース hard cap は別 issue 候補

イベント構造:

{
  "id": "uuid",
  "type": "issues",
  "payload": {},
  "received_at": "ISO8601",
  "processed": false,
  "trigger_status": null,
  "last_triggered_at": null
}

F3. MCP ツール

ステートレス MCP ハンドラが以下のツールセットを提供する。ローカルブリッジはこれをプロキシする。

ID ツール名 引数 戻り値 要件
F3.1 get_pending_status なし pending_count, latest_received_at, types 未処理イベントの軽量スナップショットを返す
F3.2 list_pending_events limit (1-100, default 20) サマリー配列 未処理イベントのメタデータ一覧を返す(ペイロード含まず)
F3.3 get_event event_id 完全イベント or error UUID 指定で完全なペイロードを返す
F3.4 get_webhook_events limit (1-100, default 20) 未処理イベント配列 未処理イベントをフルペイロード付きで返す
F3.5 mark_processed event_id または event_ids (1-100) 単数形: success, event_id, purged/バッチ形: success, marked, failed, results (id 単位の判定), purged イベントを処理済みにマークし、保持期間超過の処理済みイベントを自動削除する。purged は今回削除された件数

F3.1 Local bridge shaping: The local bridge wraps get_pending_status results into the Claude Code UserPromptSubmit hook decision JSON shape (hookSpecificOutput.hookEventName="UserPromptSubmit" plus a natural-language summary of pending_count / types / latest_received_at in additionalContext). This is required so values returned via type: "mcp_tool" UserPromptSubmit hooks reach the AI prompt context; manual tool calls receive the same shape. The remote (Worker + DO) return contract is unchanged.

F3.1 Empty silent (#221): When pending_count == 0, the local bridge returns the remote payload untouched (no wrap). Claude Code silently discards JSON that does not match a decision schema, so hook callers receive nothing in additionalContext — eliminating the per-turn empty-reminder noise. Manual tool callers see the raw payload ({pending_count: 0, types: {}, latest_received_at: null}) and can interpret it directly.

F3.5 Batch form (#245): mark_processed accepted exactly one event per call, so consuming the 6-10 self-operation acknowledgement events a single PR generates cost one round trip each. event_ids: string[] is added so the round trips collapse while the caller still enumerates ids explicitly (filter-based bulk consumption is deliberately not offered: it can silently consume external events).

  • Backward compatibility: the existing singular event_id call is unchanged, response shape included. It still answers success: true for an id that was never ingested.
  • Per-id verdict: the batch form returns {event_id, success, error?} per id. not found (no store held that id) is the only value error takes at the tool surface — an empty id is rejected by the tool schema before it reaches a store, so it never turns into a misleading not found.
  • Partial failure: one failing id does not fail the call. Marks for the successful ids are already committed, so the caller retries only the failed ids. Partial failure is reported in the body, not as a tool error.
  • Multi-account: an event lives in exactly one store, so the same batch goes to every accessible store and an id marked by any store counts as marked. Only an id missed by every store failed.
  • Purge cadence: the retention purge runs once per batch call, not once per id.
  • MCP proxy: the static schemas (mcp-server/server/index.js / local-mcp/src/index.ts) must be updated. A new param is not picked up by reconnecting; the npm package has to be republished.

イベントサマリー構造:

{
  "id": "uuid",
  "type": "issues",
  "received_at": "ISO8601",
  "processed": false,
  "trigger_status": null,
  "last_triggered_at": null,
  "action": "opened",
  "repo": "owner/repo",
  "sender": "username",
  "number": 123,
  "title": "Issue title",
  "url": "https://github.com/..."
}

F4. リアルタイムイベント配信(WebSocket / SSE)

ID 要件
F4.1 GET /events で WebSocket および SSE ストリームを提供する(Upgrade ヘッダで切り替え)
F4.2 webhook ingest 時に接続中の全クライアントにイベントサマリーをブロードキャストする
F4.3 30 秒間隔でハートビート(WebSocket: ping、SSE: heartbeat コメント)を送信する
F4.4 クライアント切断時にクリーンアップする

F5. チャンネル通知(ローカルブリッジ)

ID 要件
F5.1 ローカルブリッジが Claude Code の claude/channel experimental capability を宣言する
F5.2 Worker の WebSocket エンドポイントに接続し、新規イベント検出時に notifications/claude/channel を送信する
F5.3 通知内容はイベントサマリー(type, repo, action, title, sender)を含む
F5.4 meta フィールドに chat_id, message_id, user, ts を付与する
F5.5 WEBHOOK_CHANNEL=0 環境変数でチャンネル通知を無効化できる(デフォルト: 有効)
F5.6 チャンネル通知は one-way(読み取り専用)で、reply tool は提供しない

F6. 推奨ポーリングフロー

ステップ 操作
1 get_pending_status() を 60 秒間隔でポーリング
2 pending_count > 0 なら list_pending_events() でサマリー取得
3 フルペイロードが必要なイベントのみ get_event(event_id) で取得
4 処理完了後 mark_processed でマーク。複数件をまとめて処理した場合は event_ids で 1 呼び出しに畳む

F7. OAuth 認証(Worker-hosted web OAuth)

Worker は GitHub の web OAuth flow をホストする独自実装を備える(v0.11.0 の device authorization grant は v0.11.1 で撤去。GitHub 標準のログイン + 2FA UX に回帰しつつ、v0.10.x の chronic auth loop 原因である localhost callback 依存と refresh rotation desync を構造的に解消する)。

ID 要件
F7.1 GET /.well-known/oauth-authorization-server で RFC 8414 メタデータを返す(authorization_endpoint / token_endpoint / grant_types_supported=[urn:ietf:params:oauth:grant-type:web_authorization_poll, refresh_token]
F7.2 POST /oauth/register で RFC 7591 dynamic client registration を行う(public client、secret 発行なし)
F7.3 GET /oauth/authorize?client_id=<cid>&state=<state>[&scope=...]web_auth_state:{state} レコードを pending として作成し、redirect_uri=https://<worker>/oauth/callback を固定して https://github.com/login/oauth/authorize に 302 リダイレクトする
F7.4 GET /oauth/callback?code=<gh_code>&state=<state> で GitHub authorization code を confidential client として access token に交換し、fetchGitHubProps() で user profile + installations を取得、Worker 独自 bearer token pair を発行して web_auth_stateapproved に遷移させる。ユーザにはタブを閉じるよう案内する HTML を返す
F7.5 POST /oauth/tokengrant_type=urn:ietf:params:oauth:grant-type:web_authorization_poll を処理する。pending400 authorization_pendingapproved200 で bearer pair を返し state レコードを消費、denied400 access_denied、期限切れ → 400 expired_token(RFC 8628 §3.5 のエラー形式を再利用)
F7.6 POST /oauth/tokengrant_type=refresh_token を処理し、access token と refresh token を rotate する(ブリッジ側 RC1 修正と組み合わせて desync を解消)
F7.7 保護対象 API ルート(/mcp, /events)は Authorization: Bearer <access_token> ヘッダによる独自 token 検証 middleware で認可する
F7.8 KV schema は自前設計: client:{client_id} / web_auth_state:{state} / token:{access_token} / refresh:{refresh_token} / grant:{grant_id}。device flow 時代の device: / user_code: キーは撤去
F7.9 ローカルブリッジは authorize URL を platform 既定のブラウザで自動オープンする。Windows は cmd /c start、macOS は open、Linux は xdg-open を使う。オープン失敗は fatal にしない(stderr に警告を残し、URL は応答と stderr で伝える)
F7.10 ローカルブリッジは初回ツール呼び出しで web flow が完了していない場合、polling をバックグラウンドに維持したまま、authorize URL と残り有効秒数を本文に含む isError: true の構造化ツール応答を即座に返す。2 回目以降の同一ツール呼び出しは、承認完了なら通常処理、未完了なら同じ auth-required 応答を返す(ポーリングは 1 本に serialize)
F7.11 ローカルブリッジは refresh 時に invalid_grant を受けた場合、直ちに全面 re-auth に遷移せず tokens file を再読み込みする。別プロセスが既に rotation を完了していれば、その最新 refresh_token を採用して再試行する(RC1: refresh desync の最小 fix。file lock は導入しない)

Dynamic Client Registration の位置づけ(#249 で確認、撤去は本 issue の範囲外):

MCP 2026-07-28 の deprecated レジストリ 6 件のうち本 repo に該当するのは Dynamic Client Registration(F7.2)のみ。移行先は Client ID Metadata Documents。最短撤去は 2027-07-28 以降の最初のリビジョンであり、しかも「最短撤去」は撤去が可能になる時点にすぎず、実際の撤去は Core Maintainer 判断でそれ以降にずれうる。仕様からの撤去は SDK に削除義務を課さない。

本移行では撤去しない。理由は相乗りの前提が成立しないこと — 本移行は OAuth の実装に一切触れておらず(ブリッジ側は transport の authProvider に繋ぎ直しただけ)、DCR 撤去は両面の認証設計変更になる。プロトコル切替と同一リリースに載せると、利用者が再起動して降りてくる先で破断面が二つ同時に開く。

該当しないもの: Roots / Sampling / Logging / includeContext(未使用)、HTTP+SSE トランスポート(Streamable HTTP のみを提供しているため未露出)。

GitHub App 前提条件:

  • 使用する upstream endpoint: https://github.com/login/oauth/authorize(web), POST https://github.com/login/oauth/access_token
  • GitHub App の設定で redirect_uri = https://<worker>/oauth/callback を登録する必要がある(smgjp.com プレビュー + self-host 例示)

Non-Functional Requirements

N1. セキュリティ

ID 要件
N1.1 Webhook シークレットは Cloudflare Worker の Secret(GITHUB_WEBHOOK_SECRET)で管理する
N1.2 HMAC-SHA256 による署名検証でスプーフィングを防止する
N1.3 ローカルブリッジは stdio トランスポートを使用し、ネットワーク露出しない
N1.4 Webhook エンドポイントは多層防御で DDoS/課金攻撃を防止する: IP allowlist → per-IP rate limit → signature → tenant resolution → per-tenant quota
N1.5 GitHub IP allowlist(api.github.com/meta の hooks フィールド)で非 GitHub IP を最外層でブロックする(github-ip.ts)
N1.6 Per-IP rate limit はインメモリ sliding window で Worker isolate 内に実装する(rate-limit.ts)
N1.7 Per-tenant quota は TenantRegistry DO で atomic check-and-increment により管理し、単一テナントの無制限ストレージ消費を防止する
N1.8 Cloudflare WAF カスタムルールによる外部 IP ブロックを推奨する(Worker 到達前にブロックし CPU 課金を削減)

N2. 構成

ID 項目 ソース デフォルト
N2.1 Worker URL WEBHOOK_WORKER_URL 環境変数 なし(必須)
N2.2 シークレット Cloudflare Secret GITHUB_WEBHOOK_SECRET なし(検証スキップ)
N2.3 チャンネル通知の有効/無効 WEBHOOK_CHANNEL 有効(0 で無効)
N2.4 カスタムドメイン github-webhook.smgjp.com Cloudflare Worker のカスタムドメインとして設定済み
N2.5 認証方式 Worker 自前認証 Cloudflare Access は使用しない。Worker が webhook secret + Worker-hosted web OAuth で認証を処理する
N2.6 プレビューインスタンス preview 環境 本番と同一構成の検証用インスタンス
N2.7 処理済みイベント保持期間 PURGE_AFTER_DAYS 環境変数(wrangler.toml [vars] 3(日)。mark_processed 時および DO Alarm sweep 時に保持期間超過の処理済みイベントを削除。0 で処理済みを即削除
N2.8 未処理イベント保持期間 UNPROCESSED_PURGE_AFTER_DAYS 環境変数(wrangler.toml [vars] 90(日)。DO Alarm sweep 時に保持期間超過の未処理イベントを削除。0 で未処理を即削除。処理済み(3 日)より長いのは未読データ消失の安全域(非対称は意図的)

GitHub Webhook 購読イベント:

イベント 状態
Discussion 有効
Discussion comment 有効
Issue comment 有効
Pull request review 有効
Pull request review comment 有効
Pull request review thread 有効
Workflow run 有効
Issues 削除済み(未購読)
Pull request 削除済み(未購読)
Sub issues 削除済み(未購読)

N3. 制約

ID 制約
N3.1 WebhookStore DO はテナント別インスタンス(idFromName("store-{accountId}"))で動作する。MCP 側にテナント別インスタンスは無い(2026-07-28 でセッションが消え、リクエストごとの props から store 名を解決する)。TenantRegistry DO は単一インスタンスで全テナントの installation-account マッピングを管理する
N3.4 Web OAuth callback 処理時に GET /user/installations で取得した accessible_account_ids(ユーザー + org)を GitHubUserProps に保存し、MCP ツールが複数 store を並列クエリして結果をマージする。これにより org インストールのイベントもメンバーからも参照できる。accessible_account_ids はリクエストごとの props から読む
N3.2 WebSocket / SSE 接続は DO のメモリ内で管理される(DO eviction 時に切断)
N3.3 Worker とブリッジのあいだにセッションは無い(2026-07-28 ステートレスコア、#249)。ブリッジが再利用するのは MCP クライアントとその transport であり、切断のコストは再接続一回に閉じる
N3.5 Worker は 2026-07-28 のみを提供し、2025 系リクエスト(initialize を含む)を legacy: "reject" で拒否する。互換レーンは持たない(#249 決定 1)。ブリッジのクライアント面も同じ版に pin する

Dependencies

Cloudflare Worker

パッケージ 用途
agents Cloudflare Agents SDK (createMcpHandler — Worker 向けステートレス MCP ハンドラ)
@modelcontextprotocol/server MCP SDK v2 サーバー(プロトコル版 2026-07-28。agents が非 optional peer として exact 2.0.0 を要求するため exact 固定)
zod スキーマバリデーション

OAuth 実装は自前(worker/src/oauth.ts + worker/src/oauth-store.ts)。@cloudflare/workers-oauth-provider は v0.11.0 で撤去済み。v0.11.1 で Worker-hosted web OAuth に切り替え(device authorization grant は撤去)。

ローカルブリッジ (mcp-server/)

パッケージ 用途
@modelcontextprotocol/sdk MCP SDK v1(Claude Desktop に対するサーバー面。Server クラス直接使用)
@modelcontextprotocol/client MCP SDK v2 クライアント(Worker に対するクライアント面。版 2026-07-28 に pin)

Node.js >= 18.0.0 が必要。

CI/CD

テスト(CI)

トリガー ジョブ 内容
PR to main / push to main test Node.js syntax check

デプロイ(CD)

トリガー ジョブ 内容
release published build-mcpb mcpb pack で .mcpb 生成
release published attach-mcpb gh release upload で .mcpb をリリースに添付(build-mcpb 後)
release published npm-publish npm レジストリに公開

リリースフロー:

  1. AI が gh release create でリリースを作成する(PAT 経由で release イベントが発火する)
  2. Release published イベントで CD ワークフローが発火: .mcpb 生成 → .mcpb リリース添付 → npm publish
  3. npm publish 時にリリースタグ名から自動でバージョンを同期する(package.json の手動更新不要)
  4. プレリリースタグ(- を含む)は next dist-tag で公開、正式リリースは latest で公開

注意: GITHUB_TOKEN で作成されたリリースは release イベントを発火しない(GitHub Actions の制限)。 そのため AI が PAT 認証済み gh CLI でリリースを作成する運用とする。

manifest.json のバージョンも一致させる。

配送鎖と完了条件

merge → gh release create → CD (npm-publish) → registry の latest 更新
      → 利用側 MCP クライアントの再起動 → npx が新版を解決 → 利用側に到達

後半 2 段は CD の外側にあり、リポジトリ側からは実行できない。npx がパッケージのバージョンを解決するの はプロセス起動時の一度きりであり(クライアント設定で @latest を指定していても同じ)、すでに起動して いるプロセスは registry がどう変わっても起動時のバージョンを保持し続ける(v0.11.9 のリリース直後に実 測: registry が 0.11.9 を返している間、稼働中のクライアントは 0.11.8 のままだった。0.11.9 に移ったの は Claude Desktop を再起動した時点である)。

したがって 「registry が新版を返す」はリリース完了の判定基準にならない。特にプロキシの静的ツール スキーマを変更したリリースは、利用側プロセスが再起動して初めて成果が現れる。リリース完了報告を registry の確認で締めると、届いていない状態を届いたと報告することになる。

registry の確認には --prefer-online を付ける。npm CLI は registry のメタデータをキャッシュするため、 publish 直後の npm view github-webhook-mcp version は旧版を返しうる(同じく v0.11.9 で実測)。

npm view github-webhook-mcp version --prefer-online

npx のキャッシュ解決挙動そのものは本リポジトリの管理外であり、規定できるのは 「再起動が要る」という事実と上記の確認手段までとする。

Distribution Channels

チャネル 用途 ステータス 要件
Anthropic Desktop Extensions Directory Claude Desktop ローカル mcpb 配布 申請済み(2026-04-02) 公開 GitHub リポジトリ、Node.js、manifest.json、推奨 MIT ライセンス
Anthropic Remote MCP Server Directory リモート MCP サーバー配布 未申請 OAuth 2.0、HTTPS、ツール安全性アノテーション
npm レジストリ CLI / Codex 向け npx 配布 稼働中 npm publish(CD で自動公開)
MCP Community Registry (registry.modelcontextprotocol.io) コミュニティ発見チャネル 将来 未定

申請フォーム:

各チャネルの申請経緯と詳細ステータスは tips issue #175 を参照。

Infrastructure

コンポーネント 用途
Cloudflare Worker webhook 受信 + MCP サーバー
Cloudflare Durable Objects イベント永続化 (SQLite) + WebSocket/SSE
GitHub Webhook イベント送信元
MCPB Claude Desktop 向けローカルブリッジ配布
npx CLI/Codex 向けローカルブリッジ配布

Files

パス 用途
worker/src/index.ts Cloudflare Worker エントリポイント
worker/src/mcp.ts MCP サーバー factory(ツール定義。リクエストごとに生成、テナントは props から解決)
worker/src/retired-do.ts 退役した WebhookMcpAgent クラス(過去 migration 制約のためだけに残す)
worker/src/store.ts WebhookStore DO(SQLite + SSE、テナント別インスタンス)
worker/src/tenant.ts TenantRegistry DO(installation-account マッピング、クォータ管理)
worker/src/oauth.ts Worker-hosted web OAuth 自前実装(metadata / register / authorize / callback / token / 独自 token 検証 middleware)
worker/src/oauth-store.ts OAuth KV schema helper(client / web_auth_state / token / refresh / grant レコード操作)
worker/wrangler.toml Worker デプロイ設定
shared/src/types.ts 共有型定義
shared/src/summarize.ts イベントサマリー生成
local-mcp/src/index.ts ローカルブリッジ(TypeScript、開発用)
mcp-server/server/index.js ローカルブリッジ(JS、.mcpb 配布用)
mcp-server/manifest.json MCPB マニフェスト
mcp-server/package.json npm パッケージ定義