Skip to main content
Glama
vinkurov
by vinkurov

hookshelf-mcp

Give your coding agent a real webhook endpoint. An MCP server that lets Claude Code, Cursor and any MCP client receive webhooks, inspect the exact bytes that arrived, send correctly signed test events for 7 providers, and replay any delivery — backed by a local hookshelf instance, so payloads never leave your machine.

CI license

The problem

Ask an agent to "integrate Stripe webhooks" and it writes the handler blind. It cannot receive a delivery, so it cannot see what Stripe actually sends, cannot check its signature verification against real bytes, and cannot find out whether its fix worked. The usual answer — a public tunnel and clicking around a provider dashboard — is exactly the part an agent cannot do.

With this server the agent closes the loop itself:

agent: create_endpoint(name: "stripe-dev", provider: "stripe", secret: "whsec_...")
  →  http://127.0.0.1:3000/in/f4080sjvz3v6tfd5

agent: send_test_event(endpoint_id: "f4080...")        # signed like the real thing
  →  { received: true, delivery: "a698af65..." }

agent: get_delivery(delivery_id: "a698af65...")
  →  headers as received, exact body, verification: "ok"

agent: send_test_event(endpoint_id: "f4080...", tamper: true)
  →  { error: "invalid_signature", delivery: "eb7c9d8e..." }   # failure path, also stored

Write handler → send signed event → read what arrived → fix → replay. No third-party service, no tunnel, no dashboard.

Related MCP server: hookray-mcp

Tools

Tool

What it does

create_endpoint

New endpoint with its inbound URL. Optional provider+secret for signature verification, optional forward URL.

send_test_event

Sends a webhook with a valid signature for the endpoint's provider: github, stripe, slack, shopify, standard-webhooks, paddle, telegram. tamper: true breaks the signature on purpose to test the failure path. Fixed event_id tests deduplication.

wait_for_delivery

Blocks until a new delivery arrives — "trigger, wait, inspect" without a polling loop.

get_delivery

One delivery whole: headers as received, exact body (UTF-8 or base64), verification result, forwarding attempts.

list_deliveries / list_endpoints / delete_endpoint

What they say.

replay_delivery

Queues a stored delivery again, byte for byte, pointing back at the original.

Twilio is verify-only: it signs the public request URL rather than the body, so only the real provider can produce a valid signature.

Setup

Two pieces: hookshelf (holds the deliveries) and this server (gives the agent hands).

# 1. hookshelf
git clone https://github.com/vinkurov/hookshelf.git && cd hookshelf
docker compose up -d        # dashboard on http://127.0.0.1:3000

# 2. this server
git clone https://github.com/vinkurov/hookshelf-mcp.git && cd hookshelf-mcp
npm install && npm run build

Claude Code.mcp.json in your project (or claude mcp add):

{
  "mcpServers": {
    "hookshelf": {
      "command": "node",
      "args": ["/path/to/hookshelf-mcp/dist/main.js"],
      "env": { "HOOKSHELF_URL": "http://127.0.0.1:3000" }
    }
  }
}

Cursor and Claude Desktop take the same command/args/env block in their MCP settings. HOOKSHELF_URL defaults to http://127.0.0.1:3000.

Not on npm yet — npx hookshelf-mcp will work once it is published; this README will say so when it does, rather than before.

Notes worth knowing

  • Signatures are generated from the same specifications webhook-kit verifies against, and every one is round-trip tested through webhook-kit's actual verifier — generation and verification can only drift if the tests break.

  • Secrets are held in memory only. hookshelf stores secrets write-only, so send_test_event works for endpoints created in the current session; for anything else the server says so instead of guessing.

  • A rejected delivery is still stored. That is hookshelf's defining behaviour: you cannot debug a request you threw away. The tool returns the delivery id either way, and the agent can inspect exactly what failed.

  • Timestamped schemes sign with unix seconds, not milliseconds — a millisecond timestamp produces a "valid" signature that fails the freshness check, which is the kind of bug this package exists to catch.

  • No auth on hookshelf: keep it bound to loopback (its compose file already does).

Development

npm test              # 37 tests: every signature round-trips through webhook-kit's verifier
npm run test:e2e      # 11 checks against a real hookshelf instance
npm run lint && npm run typecheck

The unit tests drive the server through a real MCP client over an in-memory transport, against a fake hookshelf whose responses are copied from the real handlers — and the e2e run then checks the copies against reality. It has already caught one drift: the fake deduplicated deliveries on capture-only endpoints, the real hookshelf only deduplicates when forwarding (there is nothing downstream to protect otherwise).

License

MIT — see LICENSE.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • A webhook inbox for agents: one call returns a live URL. Mock, verify, inspect and replay.

  • Fire-and-forget webhooks for agents with guaranteed, retried delivery and status polling. x402

  • Agent-first hosting: create apps, commit code, deploy, get HTTPS URLs. OAuth sign-in, no tokens.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vinkurov/hookshelf-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server