Webhook Capture MCP
# webhook-capture-mcp
**Let your AI assistant see your webhooks.** A self-hosted [MCP](https://modelcontextprotocol.io)
server that captures incoming webhook/HTTP requests and lets Claude, Cursor, or VS Code
**inspect, wait for, and replay** them β so you can debug *"why isn't my webhook working?"* by
having the AI read the actual payload.
You're wiring up a Stripe event, a GitHub webhook, an n8n/Make callback. Something fires, but
you can't see what it sent. Instead of reaching for webhook.site and copy-pasting into chat,
point the webhook here and ask your assistant: *"what did that request contain?"*
## What it does
- π£ **Captures** every incoming request (method, path, query, headers, raw + parsed JSON body)
- π **Inspects** any captured request in full detail on demand
- β³ **Waits** for the next request β *"I'll wait, trigger your webhook now"*
- β»οΈ **Replays** a captured request to any URL (e.g. your local dev server)
- π **Self-hosted, zero infrastructure** β runs on your machine via `npx`, stores nothing in the cloud
## Install
Add it to your MCP host. It runs via `npx` β no separate install step.
**Claude Desktop / Claude Code** (`claude_desktop_config.json` or `.mcp.json`):
```json
{
"mcpServers": {
"webhook-capture": {
"command": "npx",
"args": ["-y", "webhook-capture-mcp"],
"env": { "WEBHOOK_CAPTURE_PORT": "4444" }
}
}
}
```
**Cursor** (`~/.cursor/mcp.json`) and **VS Code** (`.vscode/mcp.json`, Copilot agent mode) use
the same shape. Restart the host, and you'll see the `webhook-capture` tools.
## Use it
1. Ask your assistant to run **`capture_status`** β it prints the local capture URL
(`http://localhost:4444`) and how to expose it.
2. **Point a webhook at it.**
- *Local sender* (your own app, curl): hit `http://localhost:4444/anything` directly.
- *External sender* (Stripe, GitHubβ¦): run a tunnel on your machine and use its public URL:
```bash
ngrok http 4444
# or: cloudflared tunnel --url http://localhost:4444
```
Put the printed `https://β¦` URL in your provider's webhook settings.
3. Ask: *"wait for the next webhook and tell me what's in it"* β the assistant calls
`wait_for_request`, you trigger the event, and it reads back the full payload.
4. Ask: *"replay that to my local server at http://localhost:3000/webhook"* β `replay_request`.
## Tools
| Tool | Description |
|------|-------------|
| `capture_status` | Show the capture URL, count, and how to expose it via a tunnel |
| `list_requests` | List captured requests (newest first); filter by method / path |
| `get_request` | Full detail of one request by id |
| `wait_for_request` | Block until the next request arrives (or timeout) |
| `replay_request` | Re-send a captured request to a target URL, return the response |
| `clear_requests` | Empty the store |
## Configuration
| Env var | Default | Description |
|---------|---------|-------------|
| `WEBHOOK_CAPTURE_PORT` | `4444` | Port the capture listener binds to |
| `WEBHOOK_CAPTURE_HOST` | `127.0.0.1` | Bind address. Loopback by default (tunnels still reach it). Set to `0.0.0.0` for direct LAN senders. |
## Notes & limits (v0.1)
- **In-memory only** β keeps the last 100 requests; restarting clears them. (Persistence is planned.)
- **No auth on the capture endpoint.** It binds to loopback by default. If you expose it via a
tunnel, treat the tunnel URL as sensitive and shut it down when done.
- Bodies are capped at 5 MB.
## Run from source
```bash
git clone https://github.com/void-pulse/webhook-capture-mcp
cd webhook-capture-mcp
npm install && npm run build
node dist/index.js # speaks MCP over stdio
```
## License
MIT Β© Curtis Holmes
TDQS
Scored across 6 tools
Each tool targets a distinct aspect of webhook capture: status, listing, detail retrieval, waiting for new requests, replaying, and clearing. No two tools have overlapping purposes.
All tool names follow a consistent verb_noun snake_case pattern (capture_status, list_requests, get_request, wait_for_request, replay_request, clear_requests), making the set predictable and easy to navigate.
Six tools is a well-scoped count for a webhook capture server, covering essential operations without unnecessary bloat or gaps.
The set provides a complete lifecycle for captured requests: list, get, wait, replay, and clear. A minor gap is the lack of individual request deletion, but clear_requests covers bulk cleanup and the core workflow is fully supported.