关于 github-webhook-mcp
github-webhook-mcp 是连接本地 MCP 客户端与 Cloudflare Worker 的 stdio 代理,适用于需要接收 GitHub Webhook 事件的工作流。它可转发工具调用,并可通过 WebSocket 推送事件通知。
主要功能
- 01通过 stdio 连接本地客户端
- 02将工具调用转发至 Worker
- 03通过 WebSocket 推送事件通知
- 04使用 Web OAuth 授权
- 05缓存并刷新访问令牌
适用场景
- 01在客户端查看待处理事件
- 02获取单个事件的完整载荷
- 03实时接收 GitHub 事件通知
- 04批量标记事件为已处理
MCP 相关
本地代理通过 stdio 与 MCP 客户端通信,并将工具调用转发到 Worker 的 Streamable HTTP MCP 端点。Worker 提供事件工具及可选的 WebSocket 实时通知。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y github-webhook-mcpWEBHOOK_WORKER_URLURL of your deployed Cloudflare Worker endpoint (default: https://github-webhook.smgjp.com)WEBHOOK_CHANNELSet to '0' to disable SSE channel notifications (default: enabled)本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
5收录的工具列表 · 更新于 2 周前
此工具无需参数。
详细介绍
github-webhook-mcp
Stdio MCP 代理,用于将本地 MCP 客户端(Claude Desktop、Claude Code、Codex 等)桥接到远程 github-webhook-mcp Cloudflare Worker。该 Worker 接收 GitHub webhook 投递,将其持久化到按租户划分的 Durable Object(SQLite)中,并通过 MCP 工具和实时 WebSocket 流提供访问。
此软件包仅包含客户端代理。Webhook 接收、租户路由、持久化和 MCP 服务本身均运行在 Worker 上。有关架构和自托管说明,请参阅主仓库。
重大变更:MCP 协议修订版 2026-07-28
从此版本起,Worker 仅提供 MCP 协议修订版 2026-07-28,不再兼容之前的修订版。
- 早于此版本的代理将停止工作。 它们会通过
initialize建立会话,而 Worker 不再响应此请求。故障不会明显显示:代理不会崩溃,而是将协议错误作为工具输出文本返回。 - 实时通道通知仍会到达,因此故障不易察觉。
/eventsWebSocket 流不属于 MCP,不受影响;所以过时的代理仍会推送事件摘要,但所有工具调用(包括mark_processed)都会失败。即使通知看起来正常,待处理队列也不会被清空。 - 重启 MCP 客户端以获取新版代理。
npx会在进程启动时解析@latest,因此已运行的 Claude Desktop、Claude Code 或 Codex 会继续使用启动时获取的版本,无论之后发布的版本有多新。请彻底退出后重新打开。 - 固定代理版本会让你无法继续使用。 如果 MCP 客户端配置固定了早于此版本的版本,重启也无济于事;请先移除版本固定(或更新到更高版本)。
代理的两个协议接口相互独立:它仍通过 stdio 向客户端提供 2025 年时期的 MCP 修订版。只有面向 Worker 的接口发生了变化。
此代理的作用
- 通过 stdio 在本地与客户端进行 MCP 通信。
- 将
tools/call转发到 Worker 的 Streamable HTTP MCP 端点(/mcp)。 - 可选地维护与 Worker
/events端点的 WebSocket 连接,并将收到的 webhook 事件重新作为 Claude Codeclaude/channel通知发出(实时推送,无需轮询)。 - 处理针对 Worker 的 由 Worker 托管的 Web OAuth 和动态客户端注册(RFC 7591)。不会使用 localhost 回调端口:GitHub 的
redirect_uri固定指向 Worker 本身,因此即使进程重启或客户端实例并发运行,流程也能可靠完成。 - 在
~/.github-webhook-mcp/下缓存访问令牌和刷新令牌(模式0600),并在令牌过期前静默刷新。刷新时遇到invalid_grant,代理会重新读取令牌文件,以采用同级进程执行的任何轮换;若仍无法解决,则执行完整的重新授权。
要求
- Node.js >= 18
- 可访问的 github-webhook-mcp Worker(公开预览版的默认地址为
https://github-webhook.smgjp.com;也可以指向你自己的部署) - Web 浏览器(用于通过代理打印的授权 URL 登录 GitHub;浏览器可以与运行 MCP 客户端的机器不同)
- 已安装在你希望接收其事件的账户/组织上的 GitHub App(OAuth 完成后,Worker 会自动解析你可访问的安装)
安装 / 运行
该代理已发布到 npm,并提供 github-webhook-mcp 二进制文件。
使用 npx 直接运行(无需全局安装):
npx github-webhook-mcp
或全局安装:
npm install -g github-webhook-mcp
github-webhook-mcp
首次运行时,代理会向 stderr 输出授权 URL,并尝试在默认浏览器中打开:
[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)...
登录 GitHub(2FA 照常使用),批准访问权限,并在出现“Authorization complete”页面后关闭标签页。令牌存储在 ~/.github-webhook-mcp/ 下,并会在过期前自动刷新。
从 v0.10.x / v0.11.0 迁移。 v0.10.x 使用基于浏览器的 localhost 回调流程;v0.11.0 使用 GitHub 设备代码流程。首次运行 v0.11.1+ 时,如果令牌文件中的流程标记与新的 Web 流程不匹配,代理会将其视为未激活状态,并透明地启动新的授权流程。需要重新授权一次;旧文件会保留,但不会使用。
为自托管的 GitHub Apps 配置回调 URL。 如果你使用自己的 GitHub App 自托管 Worker,请将
https://<your-worker>/oauth/callback注册为 Callback URL。否则,Worker 的/oauth/callback步骤会失败并显示“Authorization failed”,因为 GitHub 会拒绝重定向。不会使用 Device Flow,可以将其关闭。请参阅自托管指南,了解分步说明。
更新
npx 会在进程启动时解析一次软件包版本,包括客户端配置指定 @latest 的情况。已经运行的客户端会继续使用启动时的版本,因此新 npm 版本发布后,只有在替换该进程后才能使用:重启 MCP 客户端(Claude Desktop、Claude Code、Codex)以获取新版本。 重启后,客户端才会切换到新版本。
对于会更改代理所公布工具架构的版本,这一点尤为重要,因为这些架构来自代理自身的代码,而非从 Worker 获取——在进程重启之前,客户端看到的仍是旧工具定义。
使用 --prefer-online 验证注册表中的版本。npm CLI 会缓存注册表元数据,因此发布后不久,直接运行 npm view 可能会显示之前的版本:
npm view github-webhook-mcp version --prefer-online
客户端配置
Claude Desktop / Claude Code
将服务添加到 MCP 客户端配置中。Claude Desktop 的示例(claude_desktop_config.json):
{
"mcpServers": {
"github-webhook": {
"command": "npx",
"args": ["-y", "github-webhook-mcp"],
"alwaysLoad": true
}
}
}
要连接自托管的 Worker,请设置 WEBHOOK_WORKER_URL 环境变量:
{
"mcpServers": {
"github-webhook": {
"command": "npx",
"args": ["-y", "github-webhook-mcp"],
"alwaysLoad": true,
"env": {
"WEBHOOK_WORKER_URL": "https://your-worker.example.workers.dev"
}
}
}
}
alwaysLoad: true 要求 Claude Code v2.1.121 或更高版本。它会让此服务的工具不受工具搜索延迟加载机制的影响,因此每轮都能立即调用(推荐,因为该服务会在每轮通过 UserPromptSubmit hook 调用)。
Codex(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 会禁用 WebSocket 实时通道。对于不支持 claude/channel 通知的客户端(Claude Desktop、Codex),请将其设为 0。若要为 Claude Code 启用实时推送,请保留默认值。
实时通道通知(仅限 Claude Code)
启用 WEBHOOK_CHANNEL(默认值)后,代理会声明 claude/channel 实验性功能,并将新的 webhook 事件重新作为通道通知发出。要在 Claude Code 会话中查看这些通知,请加载该通道:
claude --dangerously-load-development-channels server:github-webhook-mcp
通知是单向的:其中包含事件类型、仓库、操作、标题、发送者和 URL。没有回复工具。
配置
| 变量 | 必需 | 默认值 | 说明 |
|---|---|---|---|
WEBHOOK_WORKER_URL | 否 | https://github-webhook.smgjp.com | Cloudflare Worker 的基础 URL,该 Worker 提供 MCP 端点、WebSocket 流和 OAuth 元数据。 |
WEBHOOK_OBSERVER | 否 | 0(已禁用) | 将其精确设置为 1,即可使用现有的已保存访问令牌,以非交互方式获取原始待处理状态并进行身份验证。 |
WEBHOOK_CHANNEL | 否 | 1(已启用) | 设置为 0 可禁用 WebSocket 连接和 claude/channel 通知。 |
OAuth 客户端注册信息和令牌存储在:
~/.github-webhook-mcp/oauth-client.json(动态客户端注册)~/.github-webhook-mcp/oauth-tokens.json(访问令牌 + 刷新令牌)
删除这些文件可强制重新进行授权流程。
默认 Worker URL 说明。
https://github-webhook.smgjp.com是供评估使用的预览实例,不提供 SLA,且可能变更或在未通知的情况下停止运行。用于生产环境时,请部署自己的 Worker(参阅主仓库的安装指南),并相应设置WEBHOOK_WORKER_URL。
被动观察者连接
在专用的桥接进程中设置 WEBHOOK_OBSERVER=1,即可在不启动身份验证界面的情况下观察待处理状态。请先使用单独的常规命令行进程完成身份验证。观察者每次获取凭据时都会读取已保存的令牌文件,因此外部登录后,下次调用即可恢复连接。凭据缺失、格式错误、过期或被拒绝时,会返回工具错误,包含 isError: true 以及相应的 JSON 文本 / structuredContent:
{"error":"auth_required","message":"Observer mode requires an existing valid token. Authenticate using a separate CLI process, then retry."}
观察者模式不会注册客户端、刷新令牌、打开浏览器或启动 OAuth 轮询。没有过期时间的已保存令牌会一直被接受,直到服务器拒绝它。身份验证失败会停止后台 WebSocket 重连;外部登录后,下次成功的工具调用会重新启动重连。WEBHOOK_CHANNEL 仍控制频道通知,并且 get_event 仍然可用。
使用 tools/list 检测此契约:只有观察者的 get_pending_status 条目会声明 _meta: {"io.github.Liplus-Project/github-webhook-mcp/pending-status-observer": 1}。其结果会保留 Worker 的原始 JSON 文本及任何 structuredContent,包括非零计数:
{"pending_count":3,"types":{"issues":3},"latest_received_at":"2026-10-19T00:00:00Z"}
types 将事件名称映射到计数。latest_received_at 是时间戳字符串或 null,涵盖最新的待处理事件,而非完整历史记录。状态读取不会消耗事件或调用 mark_processed。身份验证和网络故障会作为错误返回,而不是返回零计数。常规模式不会声明此元数据;其现有的非零状态钩子决策 JSON 和零计数原始响应保持不变。需要此常规行为的钩子调用方请使用单独的进程。
提供的工具
除 mark_processed 外,所有工具均为只读。
| 工具 | 说明 |
|---|---|
get_pending_status | 待处理(未处理)Webhook 事件的轻量快照:待处理数量、最新接收时间戳和事件类型。定期轮询时,请先使用此工具,再请求详细信息。 |
list_pending_events | 待处理事件的摘要列表(limit:1-100,默认 20)。仅返回元数据——id、type、action、repo、sender、number、title、url、received_at——不包含完整载荷。 |
get_event | 按 event_id 获取单个 Webhook 事件的完整载荷。 |
get_webhook_events | 获取包含完整载荷的待处理事件。轮询时优先使用 get_pending_status 或 list_pending_events;只有在确实需要全部信息时才使用此工具。 |
mark_processed | 将事件标记为已处理,使其不再出现在待处理查询中。对单个事件传入 event_id,或传入 event_ids(1-100)一次清除整批事件。必须使用此工具,以免待处理队列无限增长。 |
推荐的轮询流程
- 定期轮询
get_pending_status()(例如每 60 秒一次)。 - 如果
pending_count > 0,调用list_pending_events()获取摘要。 - 仅对需要完整载荷的事件调用
get_event(event_id)。 - 处理完事件后调用
mark_processed——event_ids: [...]可在一次调用中清除整个集合;如果一批事件是一起处理的,这是通常的做法。
如果启用了实时通道通知(Claude Code),则可以跳过第 1 步——Worker 收到事件后,代理会立即推送事件摘要。你仍需调用 mark_processed 来清空队列。
事件保留
Worker 会自动清除存储的事件,以确保 Durable Object 存储空间保持在有限范围内。基于时间的清理任务由 Durable Object Alarm(每天)运行,并会重新安排自身,因此即使从未调用 mark_processed,清理也会执行。
| 事件类别 | 保留期限 | Worker 环境变量 | 默认值 |
|---|---|---|---|
已处理(已调用 mark_processed) | 删除超过保留期限的事件 | PURGE_AFTER_DAYS | 3 天 |
| 未处理(从未标记) | 删除超过保留期限的事件 | UNPROCESSED_PURGE_AFTER_DAYS | 90 天 |
- 未处理事件的保留期限更长是有意为之——未处理意味着用户尚未看到,因此丢弃前会留出较长的缓冲时间(3 天与 90 天之间的不对称是设计如此)。
- 为及时清理,已处理事件也会在调用
mark_processed时立即清除;Alarm 清理任务则确保停止消费事件的租户也能得到清理。 - 两个保留期限均为 Worker 端配置(
worker/wrangler.toml[vars]);将值设为0,即可在清理时立即清除相应类别的事件。这些环境变量位于 Worker 上,而非此代理中。 - 已知限制:保留期限限制的是事件的时间,而非数量。事件速率较高且从未被消费的租户,仍可能在 90 天期限生效前达到 Cloudflare 对每个 DO 设定的 1 GB 上限。
身份验证流程
- 首次调用工具时(或启动时,如果存在缓存令牌),代理会从
${WEBHOOK_WORKER_URL}/.well-known/oauth-authorization-server获取 OAuth 元数据。 - 如果没有缓存的客户端,代理会执行动态客户端注册(RFC 7591),声明支持
urn:ietf:params:oauth:grant-type:web_authorization_poll和refresh_token授权类型(公共客户端,无密钥——Worker 本身使用自己的GITHUB_CLIENT_SECRET与 GitHub 通信)。 - 代理会生成一个随机
state,并在默认浏览器中打开${WEBHOOK_WORKER_URL}/oauth/authorize?client_id=<cid>&state=<state>。Worker 会存储待处理的 state 记录,并将请求通过 302 重定向到 GitHub 的标准地址https://github.com/login/oauth/authorize,其中redirect_uri固定为 Worker 自己的/oauth/callback(不使用 localhost)。 - 你在 GitHub 上登录并授权后,GitHub 会重定向回
${WEBHOOK_WORKER_URL}/oauth/callback?code=<code>&state=<state>。Worker 会使用该代码换取 GitHub 访问令牌(机密客户端),获取你的 GitHub 个人资料和安装信息,并签发一对与该授权绑定的、不透明的访问令牌和刷新令牌。浏览器标签页会显示“授权完成”。 - 与此同时,代理会使用相同的 state,向
${WEBHOOK_WORKER_URL}/oauth/token轮询grant_type=urn:ietf:params:oauth:grant-type:web_authorization_poll。在回调完成前,代理会收到authorization_pending;之后的下一次轮询会收到 Worker 签发的令牌对。 - Worker 会解析你可访问的 GitHub 安装(你的用户账户,以及已安装 GitHub App 的组织),并将它们绑定到 OAuth 会话,以便来自这些租户的事件都通过同一个 MCP 会话传递。
- 后续调用会重复使用访问令牌,并在到期前五分钟静默刷新。如果 Worker 返回
401,或刷新时出现invalid_grant,代理会先重新读取令牌文件(以防其他进程已轮换令牌),只有磁盘上没有更新的刷新令牌时,才会启动新的网页授权流程。
此流程的任何阶段都不会监听 localhost 端口。在无头主机上以及多个 MCP 客户端实例并发运行时,该流程同样适用。
故障排查
- 日志中始终未显示授权 URL。 检查 MCP 进程的 stderr 流(Claude Code 会将其显示为服务的日志)。查找
[github-webhook-mcp] OAuth authorization required.代码块。 OAuth state expired before approval. Re-run the client to retry.状态令牌约 10 分钟后过期。再次触发任意工具调用即可重新开始授权流程。- 浏览器显示“Authorization failed”(Worker 502)。 Worker 拒绝了 GitHub 代码交换请求。对于自托管环境,通常是因为 GitHub App 的 Callback URL 未包含
https://<your-worker>/oauth/callback,或者GITHUB_CLIENT_SECRET缺失或不正确。 Failed to reach worker. 检查WEBHOOK_WORKER_URL是否正确,以及能否从你的机器访问。- 每次工具调用都返回协议错误,但仍能收到频道通知。 当前运行的代理版本早于 Worker 现在提供的 2026-07-28 修订版。重启 MCP 客户端,让
npx获取当前版本;如果你的配置固定了较旧版本,请先更新固定版本。请参阅本页顶部的重大变更说明。 Authentication failed after retry. 缓存的令牌已被拒绝,且重新认证未成功。删除~/.github-webhook-mcp/oauth-tokens.json后重试。- 从 v0.10.x / v0.11.0 升级。 现有令牌文件会被忽略(流程标记不匹配),下一次工具调用时会生成新的 Web 流授权 URL。无需手动清理。
- 没有收到事件。 确认 GitHub App 已安装在目标账户或组织中,并在 GitHub App 的 Advanced → Recent Deliveries 页面确认 Webhook 投递成功。Worker 只能接收与你的已认证账户关联的安装所产生的事件。
- Worker 返回
429。 已超出每租户事件配额(默认 10,000)。使用mark_processed处理积压事件以释放空间。 - Claude Code 中未显示实时通知。 确保未将
WEBHOOK_CHANNEL设为0,并且 Claude Code 启动时使用了--dangerously-load-development-channels server:github-webhook-mcp。 - 凭据过期。 删除
~/.github-webhook-mcp/oauth-tokens.json(也可选择删除oauth-client.json)后重试。
链接
- 源代码和架构:https://github.com/Liplus-Project/github-webhook-mcp
- 自托管 Worker:docs/installation.md
- 需求规范:docs/0-requirements.md
- 问题跟踪:https://github.com/Liplus-Project/github-webhook-mcp/issues
许可证
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。