Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ codex-runs/
__pycache__/
*.pyc
mcp-server/node_modules/
mcp-server/*.mcpb
209 changes: 133 additions & 76 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,52 +1,89 @@
# github-webhook-mcp

GitHub webhook receiver as an MCP server.
GitHub webhook receiver and local MCP extension for GitHub notification workflows.

Receives GitHub webhook events and enables Lin and Lay to autonomously handle PR reviews and issue management.
It supports two operating styles:
## Description

- MCP polling: store webhook events and let an AI poll lightweight summaries.
- Channel push: push new events into a Claude Code session in real-time via `claude/channel`.
- Direct trigger: run a command immediately for each stored event.
`github-webhook-mcp` receives GitHub webhook events, persists them to a local `events.json`, and exposes them to AI agents through MCP tools.
It is designed for notification-style workflows where an AI can poll lightweight summaries, inspect a single event in detail, and mark handled events as processed.

Detailed behavior, event metadata, trigger semantics, and file responsibilities live in [docs/0-requirements.md](docs/0-requirements.md).

## Quick Start
## Features

### 1. Install dependencies
- Receives GitHub webhook events over HTTPS and persists them locally.
- Exposes pending events to MCP clients through lightweight polling tools.
- Supports real-time `claude/channel` notifications in Claude Code.
- Supports direct trigger mode for immediate Codex reactions per event.
- Ships as a Node-based `.mcpb` desktop extension and as an `npx` MCP server.

```bash
pip install -r requirements.txt
## Installation

### Claude Desktop — Desktop Extension (.mcpb)

Download `mcp-server.mcpb` from [Releases](https://github.com/Liplus-Project/github-webhook-mcp/releases), then:

1. Open Claude Desktop → **Settings** → **Extensions** → **Advanced settings** → **Install Extension...**
2. Select the `.mcpb` file
3. Enter the path to your `events.json` when prompted

### Claude Desktop / Claude Code — npx

Add to your Claude MCP config (`claude_desktop_config.json` or project settings):

```json
{
"mcpServers": {
"github-webhook-mcp": {
"command": "npx",
"args": ["github-webhook-mcp"],
"env": {
"EVENTS_JSON_PATH": "/path/to/events.json"
}
}
}
}
```

### 2. Start webhook receiver for MCP polling
### Codex — config.toml

```bash
WEBHOOK_SECRET=your_secret python main.py webhook --port 8080 --event-profile notifications
```toml
[mcp.github-webhook-mcp]
command = "npx"
args = ["github-webhook-mcp"]

[mcp.github-webhook-mcp.env]
EVENTS_JSON_PATH = "/path/to/events.json"
```

### 3. Optional: start webhook receiver with direct Codex reactions
### Python (legacy)

Use the bundled Codex wrapper if you want the webhook to launch `codex exec` immediately.
Put `--trigger-command` last when a service manager splits the remaining tokens for you.
```json
{
"mcpServers": {
"github-webhook-mcp": {
"command": "python",
"args": ["/path/to/github-webhook-mcp/main.py", "mcp"]
}
}
}
```

## Configuration

### 1. Install receiver dependencies

```bash
python main.py webhook \
--port 8080 \
--event-profile notifications \
--trigger-command "python codex_reaction.py --workspace /path/to/workspace --output-dir /path/to/github-webhook-mcp/codex-runs"
pip install -r requirements.txt
```

If you want Codex to resume an existing app thread instead of writing markdown output:
### 2. Start the webhook receiver

```text
python codex_reaction.py --workspace /path/to/workspace --resume-session <thread-or-session-id>
```bash
WEBHOOK_SECRET=your_secret python main.py webhook --port 8080 --event-profile notifications
```

If you want webhook delivery to stay notification-only for a workspace, create a `.codex-webhook-notify-only`
file in that workspace. The bundled wrapper will skip direct Codex execution and leave the event pending.

### 4. Set up Cloudflare Tunnel
### 3. Set up Cloudflare Tunnel

```bash
cloudflared tunnel login
Expand All @@ -56,12 +93,12 @@ cp cloudflared/config.yml.example ~/.cloudflared/config.yml
cloudflared tunnel run
```

### 5. Configure GitHub webhook
### 4. Configure the GitHub webhook

- Payload URL: `https://webhook.yourdomain.com/webhook`
- Content type: `application/json`
- Secret: same value as `WEBHOOK_SECRET`
- Recommended event profile: choose these events to stay close to GitHub Notifications
- Recommended event profile:
- Issues
- Issue comments
- Pull requests
Expand All @@ -74,73 +111,93 @@ cloudflared tunnel run

If your webhook is temporarily set to `Send me everything`, start the receiver with `--event-profile notifications` and it will ignore noisy events such as `workflow_job` or `check_suite`.

### 6. Enable channel push notifications (optional)
### 5. Optional direct trigger mode

The Node.js MCP server supports Claude Code's `claude/channel` capability (research preview, v2.1.80+). When enabled, new webhook events are pushed into your session automatically — no polling needed.
Use the bundled Codex wrapper if you want the webhook to launch `codex exec` immediately.

```bash
python main.py webhook \
--port 8080 \
--event-profile notifications \
--trigger-command "python codex_reaction.py --workspace /path/to/workspace --output-dir /path/to/github-webhook-mcp/codex-runs"
```

If you want Codex to resume an existing app thread instead of writing markdown output:

```text
python codex_reaction.py --workspace /path/to/workspace --resume-session <thread-or-session-id>
```

If you want webhook delivery to stay notification-only for a workspace, create a `.codex-webhook-notify-only`
file in that workspace. The bundled wrapper will skip direct Codex execution and leave the event pending.

### 6. Optional channel push notifications

The Node.js MCP server supports Claude Code's `claude/channel` capability (research preview, v2.1.80+). When enabled, new webhook events are pushed into your session automatically.

```bash
claude --dangerously-load-development-channels server:github-webhook-mcp
```

Channel notifications are enabled by default. To disable, set `WEBHOOK_CHANNEL=0` in the MCP server env.
Channel notifications are enabled by default. To disable, set `WEBHOOK_CHANNEL=0` in the MCP server environment.

### 7. Configure MCP server
## Examples

#### Option A: Claude Desktop — Desktop Extension (.mcpb)
### Example 1: Check whether any GitHub notifications are pending

Download `mcp-server.mcpb` from [Releases](https://github.com/Liplus-Project/github-webhook-mcp/releases), then:
**User prompt:** "Do I have any pending GitHub webhook notifications right now?"

1. Open Claude Desktop → **Settings** → **Extensions** → **Advanced settings** → **Install Extension...**
2. Select the `.mcpb` file
3. Enter the path to your `events.json` when prompted
**Expected behavior:**

#### Option B: Claude Desktop / Claude Code — npx
- Calls `get_pending_status`
- Returns pending count, latest event time, and event types
- Uses that summary to decide whether more detail is needed

Add to your Claude MCP config (`claude_desktop_config.json` or project settings):
### Example 2: Review the latest pending PR-related event

```json
{
"mcpServers": {
"github-webhook-mcp": {
"command": "npx",
"args": ["github-webhook-mcp"],
"env": {
"EVENTS_JSON_PATH": "/path/to/events.json"
}
}
}
}
```
**User prompt:** "Show me the latest pending pull request event and explain what changed."

#### Option C: Codex — config.toml
**Expected behavior:**

```toml
[mcp.github-webhook-mcp]
command = "npx"
args = ["github-webhook-mcp"]
- Calls `list_pending_events` to find the newest relevant event
- Calls `get_event` only for the selected event
- Summarizes the PR metadata and payload without dumping every event

[mcp.github-webhook-mcp.env]
EVENTS_JSON_PATH = "/path/to/events.json"
```
### Example 3: Mark an event as handled after triage

#### Option D: Python (legacy)
**User prompt:** "I already handled event `EVENT_ID`. Mark it processed so it stops appearing."

```json
{
"mcpServers": {
"github-webhook-mcp": {
"command": "python",
"args": ["/path/to/github-webhook-mcp/main.py", "mcp"]
}
}
}
```
**Expected behavior:**

- Calls `mark_processed` with the event ID
- Marks the event as processed in the local event store
- Confirms success and, if applicable, reports how many processed events were purged

## Privacy Policy

This extension works with GitHub webhook event payloads that you choose to persist locally in `events.json`.
It may include issue titles, pull request metadata, discussion text, sender identities, and repository URLs inside that local event store.

### Data Collection

- Reads the local `events.json` file configured by the user
- Surfaces webhook metadata and payloads to the connected MCP client
- Can mark events as processed in the same local event store
- Does not send event contents to third-party services by itself beyond the webhook receiver and infrastructure you configure

### Submission Note

The extension-specific privacy policy is published at:

- https://smgjp.com/privacy-policy-github-webhook-mcp/

Keep the policy URL in `mcp-server/manifest.json` aligned with that public page before directory submission.

## Operator Notes
## Support

- For the recommended polling flow, MCP tool contracts, event profiles, and trigger metadata, see [docs/0-requirements.md](docs/0-requirements.md).
- For environment variable examples, see [.env.example](.env.example).
- For direct trigger usage, `codex_reaction.py` is the bundled helper.
- GitHub Issues: https://github.com/Liplus-Project/github-webhook-mcp/issues
- Requirements/specification: [docs/0-requirements.md](docs/0-requirements.md)
- Environment variable examples: [.env.example](.env.example)

## Related

Expand Down
32 changes: 28 additions & 4 deletions mcp-server/manifest.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,21 @@
{
"manifest_version": "0.3",
"name": "github-webhook-mcp",
"version": "0.3.0",
"display_name": "GitHub Webhook MCP",
"version": "0.3.1",
"description": "Browse pending GitHub webhook events. Pairs with a webhook receiver that writes events.json.",
"long_description": "GitHub Webhook MCP helps Claude review and react to GitHub notifications from a local event store. It surfaces lightweight pending-event summaries, exposes full webhook payloads on demand, and lets users mark handled events as processed without exposing the event file directly.",
"author": {
"name": "Liplus Project"
"name": "Liplus Project",
"url": "https://github.com/Liplus-Project"
},
"repository": {
"type": "git",
"url": "https://github.com/Liplus-Project/github-webhook-mcp.git"
},
"homepage": "https://github.com/Liplus-Project/github-webhook-mcp",
"documentation": "https://github.com/Liplus-Project/github-webhook-mcp#readme",
"support": "https://github.com/Liplus-Project/github-webhook-mcp/issues",
"license": "MIT",
"server": {
"type": "node",
Expand Down Expand Up @@ -51,10 +61,24 @@
}
],
"compatibility": {
"claude_desktop": ">=0.11.0",
"platforms": [
"win32",
"darwin",
"linux"
]
}
],
"runtimes": {
"node": ">=18.0.0"
}
},
"keywords": [
"github",
"webhook",
"notifications",
"mcp",
"claude"
],
"privacy_policies": [
"https://smgjp.com/privacy-policy-github-webhook-mcp/"
]
}
4 changes: 2 additions & 2 deletions mcp-server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mcp-server/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "github-webhook-mcp",
"version": "0.3.0",
"version": "0.3.1",
"description": "MCP server for browsing GitHub webhook events",
"type": "module",
"bin": {
Expand Down
Loading
Loading