
Company News
AWS Security Hub Adds Socket for Supply Chain Security
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.
github-webhook-mcp
Advanced tools
Stdio MCP proxy that bridges local MCP clients (Claude Desktop, Claude Code, Codex, etc.) to a remote github-webhook-mcp Cloudflare Worker. The Worker receives GitHub webhook deliveries, persists them in a per-tenant Durable Object (SQLite), and exposes them through MCP tools and a real-time WebSocket stream.
This package is the client-side proxy only. Webhook ingestion, tenant routing, persistence, and the MCP server itself run on the Worker. See the main repository for architecture and self-hosting instructions.
tools/call to the Worker's Streamable HTTP MCP endpoint (/mcp)./events endpoint and re-emits incoming webhook events as Claude Code claude/channel notifications (real-time push, no polling).redirect_uri is pinned to the Worker itself, so the flow works reliably across process restarts and concurrent client instances.~/.github-webhook-mcp/ (mode 0600) and refreshes them silently before expiry. On invalid_grant during refresh, the proxy re-reads the tokens file to adopt any rotation performed by a sibling process before falling back to a full re-authorization.https://github-webhook.smgjp.com; you can also point at your own deployment)The proxy is published to npm and exposes a github-webhook-mcp binary.
Run directly with npx (no global install required):
npx github-webhook-mcp
Or install globally:
npm install -g github-webhook-mcp
github-webhook-mcp
On first run the proxy prints an authorize URL to stderr and tries to open it in your default browser:
[github-webhook-mcp] OAuth authorization required.
[github-webhook-mcp] Opening: https://github-webhook.smgjp.com/oauth/authorize?client_id=abc&state=xyz
[github-webhook-mcp] Approve in the browser window; the tab can be closed when done.
[github-webhook-mcp] Waiting for approval (state expires in 600s)...
Sign in on GitHub (2FA works as usual), approve access, and close the tab when the "Authorization complete" page appears. Tokens are stored under ~/.github-webhook-mcp/ and refreshed automatically before expiry.
Migrating from v0.10.x / v0.11.0. v0.10.x used a browser-based localhost callback flow; v0.11.0 used a GitHub device code flow. On first run with v0.11.1+, the proxy treats any tokens file whose flow marker does not match the new web flow as inactive and transparently starts the new authorization. One-time re-authentication is required; the legacy file is left in place but ignored.
Configure the Callback URL on self-hosted GitHub Apps. If you self-host the Worker with your own GitHub App, register
https://<your-worker>/oauth/callbackas the Callback URL. Without it, the Worker's/oauth/callbackstep fails with "Authorization failed" because GitHub will reject the redirect. Device Flow is not used and can stay off. See the self-hosting guide for step-by-step instructions.
Add the server to your MCP client configuration. Example for Claude Desktop (claude_desktop_config.json):
{
"mcpServers": {
"github-webhook": {
"command": "npx",
"args": ["-y", "github-webhook-mcp"],
"alwaysLoad": true
}
}
}
To target a self-hosted Worker, set the WEBHOOK_WORKER_URL environment variable:
{
"mcpServers": {
"github-webhook": {
"command": "npx",
"args": ["-y", "github-webhook-mcp"],
"alwaysLoad": true,
"env": {
"WEBHOOK_WORKER_URL": "https://your-worker.example.workers.dev"
}
}
}
}
alwaysLoad: true requires Claude Code v2.1.121 or later. It exempts this server's tools from tool-search deferral so they remain immediately callable every turn (recommended because the server is invoked every turn via the UserPromptSubmit hook).
config.toml)[mcp.github-webhook-mcp]
command = "npx"
args = ["-y", "github-webhook-mcp"]
[mcp.github-webhook-mcp.env]
WEBHOOK_WORKER_URL = "https://your-worker.example.workers.dev"
WEBHOOK_CHANNEL = "0"
WEBHOOK_CHANNEL=0 disables the WebSocket real-time channel. Set it to 0 for clients that do not support claude/channel notifications (Claude Desktop, Codex). Leave it at the default to enable real-time push for Claude Code.
When WEBHOOK_CHANNEL is enabled (the default), the proxy declares the claude/channel experimental capability and re-emits new webhook events as channel notifications. To make them visible in a Claude Code session, load the channel:
claude --dangerously-load-development-channels server:github-webhook-mcp
Notifications are one-way: they include event type, repo, action, title, sender, and URL. There is no reply tool.
| Variable | Required | Default | Description |
|---|---|---|---|
WEBHOOK_WORKER_URL | No | https://github-webhook.smgjp.com | Base URL of the Cloudflare Worker that exposes the MCP endpoint, the WebSocket stream, and OAuth metadata. |
WEBHOOK_CHANNEL | No | 1 (enabled) | Set to 0 to disable the WebSocket connection and claude/channel notifications. |
OAuth client registration and tokens are stored in:
~/.github-webhook-mcp/oauth-client.json (dynamic client registration)~/.github-webhook-mcp/oauth-tokens.json (access + refresh tokens)Delete these files to force a fresh authorization flow.
Note on the default Worker URL.
https://github-webhook.smgjp.comis a preview instance offered for evaluation. It has no SLA and may change or stop without notice. For production use, deploy your own Worker (see the main repository's installation guide) and setWEBHOOK_WORKER_URLaccordingly.
All tools are read-only except mark_processed.
| Tool | Description |
|---|---|
get_pending_status | Lightweight snapshot of pending (unprocessed) webhook events: pending count, latest received timestamp, and event types. Use this for periodic polling before requesting details. |
list_pending_events | Summary list of pending events (limit: 1-100, default 20). Returns metadata only — id, type, action, repo, sender, number, title, url, received_at — without the full payload. |
get_event | Full payload for a single webhook event by event_id. |
get_webhook_events | Pending events with full payloads. Prefer get_pending_status or list_pending_events for polling and only fall back to this when you really need everything. |
mark_processed | Mark events as processed so they no longer appear in pending queries. Pass event_id for one event, or event_ids (1-100) to clear a whole batch in a single call. Required to keep the pending queue from growing unbounded. |
get_pending_status() periodically (e.g. every 60 seconds).pending_count > 0, call list_pending_events() for summaries.get_event(event_id) only for events that need the full payload.mark_processed after handling the events — event_ids: [...] clears the whole set in one call, which is the normal case when a batch of events was handled together.If real-time channel notifications are enabled (Claude Code), step 1 can be skipped — the proxy will push event summaries as soon as the Worker receives them. You still need to call mark_processed to clear the queue.
The Worker purges stored events automatically so Durable Object storage stays bounded. A time-based sweep runs on a Durable Object Alarm (daily) and reschedules itself, so cleanup happens even when mark_processed is never called.
| Event class | Retention window | Worker env var | Default |
|---|---|---|---|
Processed (mark_processed called) | events older than the window are deleted | PURGE_AFTER_DAYS | 3 days |
| Unprocessed (never marked) | events older than the window are deleted | UNPROCESSED_PURGE_AFTER_DAYS | 90 days |
mark_processed for promptness; the Alarm sweep is the guarantee that covers tenants that stop consuming.worker/wrangler.toml [vars]); set a value to 0 to purge that class immediately on sweep. These env vars live on the Worker, not in this proxy.${WEBHOOK_WORKER_URL}/.well-known/oauth-authorization-server.urn:ietf:params:oauth:grant-type:web_authorization_poll and refresh_token grant types (public client, no secret — the Worker itself uses its own GITHUB_CLIENT_SECRET to talk to GitHub).state and opens ${WEBHOOK_WORKER_URL}/oauth/authorize?client_id=<cid>&state=<state> in your default browser. The Worker stores a pending state record and 302-redirects to GitHub's standard https://github.com/login/oauth/authorize, with redirect_uri pinned to the Worker's own /oauth/callback (no localhost).${WEBHOOK_WORKER_URL}/oauth/callback?code=<code>&state=<state>. The Worker exchanges the code for a GitHub access token (confidential client), fetches your GitHub profile + installations, and issues its own opaque access/refresh token pair bound to that grant. The browser tab shows "Authorization complete".${WEBHOOK_WORKER_URL}/oauth/token with grant_type=urn:ietf:params:oauth:grant-type:web_authorization_poll against the same state. It receives authorization_pending until the callback completes, then receives the Worker-issued token pair on the next poll.401 from the Worker or invalid_grant during refresh, the proxy first re-reads its tokens file (in case a sibling process has already rotated) and only falls back to a fresh web flow when no newer refresh token is on disk.No localhost port is listened on at any point. The flow works the same way on headless hosts and across concurrent MCP client instances.
[github-webhook-mcp] OAuth authorization required. block.OAuth state expired before approval. Re-run the client to retry. The state token expires after ~10 minutes. Trigger any tool call again to restart the flow.https://<your-worker>/oauth/callback, or GITHUB_CLIENT_SECRET is missing / wrong.Failed to reach worker. Check that WEBHOOK_WORKER_URL is correct and reachable from your machine.Authentication failed after retry. Cached tokens were rejected and re-authentication did not succeed. Remove ~/.github-webhook-mcp/oauth-tokens.json and retry.429 from the Worker. The per-tenant event quota (default 10,000) has been exceeded. Process the backlog with mark_processed to free space.WEBHOOK_CHANNEL is not set to 0 and that Claude Code was launched with --dangerously-load-development-channels server:github-webhook-mcp.~/.github-webhook-mcp/oauth-tokens.json (and optionally oauth-client.json) and retry.Apache-2.0. See the LICENSE and NOTICE files in the main repository.
FAQs
MCP server bridging GitHub webhooks via Cloudflare Worker
The npm package github-webhook-mcp receives a total of 193 weekly downloads. As such, github-webhook-mcp popularity was classified as not popular.
We found that github-webhook-mcp demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Company News
Socket is now in the AWS Security Hub Extended plan. Adopt it through AWS, apply committed spend, and block malicious open source packages.

Research
/Security News
Popular npm packages keyv and cacheable compromised.

Security News
A misconfiguration gave three Anthropic models internet access, and one, believing it was in a simulation, shipped a credential-stealing package to PyPI.