You changed something in your Stripe webhook handler. To know if it works, you need to: open the Stripe CLI, run stripe listen, run stripe trigger checkout.session.completed, tab over to your terminal to read the response, scroll up to find the signature header, run a curl with that exact body and header to retry against your local server. Or stop and let Claude Code or Codex do it for you.
This post shows how to wire the webhooks.cc MCP server into Claude Code or Codex so the agent can spin up a webhook endpoint, send a signed Stripe event, verify your handler accepts it, and replay it on a fix — all from one chat message.
What the MCP server gives your agent
@webhooks-cc/mcp exposes the webhooks.cc API as a Model Context Protocol server. Once installed in Claude Code or Codex, the agent gains 25 tools covering the full webhook test loop. The ones that matter for Stripe testing:
| Tool | What it does |
|---|---|
create_endpoint | Create a temporary webhooks.cc endpoint, optionally storing the Stripe signing secret for server-side verification |
send_webhook | Send a signed Stripe template (payment_intent.succeeded, checkout.session.completed, invoice.paid) to the endpoint |
send_to | Send a signed Stripe payload straight to a localhost URL, bypassing the webhooks.cc receiver |
wait_for_request | Block until a captured request matches given criteria (method, header, body path) |
verify_signature | Re-verify a captured request's stripe-signature against your secret |
replay_request | Re-send a captured request to any target URL with the original signature preserved |
test_webhook_flow | Chained workflow: create → send → wait → verify → replay → cleanup in a single call |
list_provider_templates | List available templates for any of the 14 providers |
All of these are first-class MCP tools with Zod schemas. The agent reads the schema, fills in arguments from your prompt, and calls the tool. Each call is logged in the Claude Code transcript so you can see exactly what ran.
Install
Full install instructions live at webhooks.cc/docs/mcp — the short version:
npx @webhooks-cc/mcp setup claude-code --api-key whcc_your_keyBehind the scenes this runs claude mcp add -s user --transport stdio webhooks-cc -e WHK_API_KEY=... -- npx -y @webhooks-cc/mcp. The -s user flag installs it globally for your account — it's available in every project. Verify with claude mcp list.
Restart any open agent sessions to pick up the new server.
You need an API key to authenticate. Every registered webhooks.cc account gets one for free — sign up at webhooks.cc, then grab the key from Account → API Keys. No paid plan required to use the MCP server.
The minimum-viable test
Start your handler:
pnpm dev # Next.js at http://localhost:3000In Claude Code, paste:
Send a signed Stripe
checkout.session.completedevent to my local handler athttp://localhost:3000/api/webhooks/stripeand tell me whether it returned 200. The signing secret is inSTRIPE_WEBHOOK_SECRET.
Claude calls send_to with provider: "stripe", template: "checkout.session.completed", secret: process.env.STRIPE_WEBHOOK_SECRET, and the URL. The MCP server generates a real Stripe-shaped payload, signs it with the canonical t=<timestamp>,v1=<hex> format Stripe uses, POSTs it to your localhost, and returns the response.
If your handler returned 200, the agent says so. If it returned 400 with "Invalid signature," the agent now has a concrete error to debug — and it can do that without leaving the chat.
The chained test_webhook_flow tool
For more complete testing, test_webhook_flow runs the entire loop server-side in one call:
// Tool call Claude makes
{
"name": "test_webhook_flow",
"arguments": {
"provider": "stripe",
"event": "checkout.session.completed",
"secret": "whsec_...",
"targetUrl": "http://localhost:3000/api/webhooks/stripe",
"verifySignature": true,
"cleanup": true
}
}In one call the server creates a temporary endpoint (1-hour expiry), sends a signed Stripe event to it, waits for capture, verifies the signature, replays the captured request to your localhost handler, returns the result, and deletes the endpoint.
The agent gets a single JSON response with everything: endpoint slug, captured request, verification result, replay status code. No follow-up tool calls needed for a clean test run.
Useful prompts
Once the MCP is installed, these prompts work without further setup. Replace localhost:3000 and the secret env var to match your project.
Smoke-test a fresh handler
Use
test_webhook_flowto send apayment_intent.succeededevent tohttp://localhost:3000/api/webhooks/stripe. Verify the signature, then tell me the response status from my handler and whether the signature was valid.
Reproduce a production bug
The captured request
req_abc123broke our prod handler. Usereplay_requestto replay it tohttp://localhost:3000/api/webhooks/stripe. Show me the full response body if it isn't a 200.
Test idempotency
Replay request
req_abc123tohttp://localhost:3000/api/webhooks/stripefour times in a row. Confirm the first returns 200 and the next three return either 200 with no side effect or 409.
The last one matters: because replay_request preserves the exact body, headers, and stripe-signature byte-for-byte, the four replays are indistinguishable from a real Stripe retry storm. If your handler isn't idempotent, this is where it shows.
Test against a flaky downstream
Set up an endpoint that returns a 500 the first call and a 200 the second. Send a signed
invoice.paidevent to it from my handler and tell me if my retry code recovers.
Translates to: create_endpoint with mockStatus: 500, then send_webhook, then update_endpoint to switch the mock to 200, then send_webhook again. The agent does the orchestration; you read the result.
What the agent can't do
The MCP server is scoped to your API key's permissions. The agent can create and delete endpoints under your account, capture requests on those endpoints, and send to arbitrary URLs (including localhost). It cannot:
- Read endpoints owned by other accounts
- Touch billing, account settings, or team membership
- Persist data beyond what the webhooks.cc API persists
- Issue requests to URLs you didn't include in the prompt or the captured request history
The full tool schemas live in packages/mcp/src/tools.ts. Every tool the agent can invoke is registered there with a Zod schema; nothing else is callable.
When whk is still the right tool
The MCP is for agentic loops — the agent decides which tool to call next based on the response. For predictable, scripted flows the CLI is faster:
- Live tunnel for daily dev:
whk tunnel 3000/api/webhooks/stripe - One-off replay:
whk replay req_abc123 --to http://localhost:3000/api/webhooks/stripe - Watch live:
whk listen <slug>
Use the MCP when the loop is exploratory ("figure out why this handler fails") and whk when it's deterministic ("send this one event").
Install in other clients
The same MCP server also works in Cursor, Windsurf, VS Code, and Claude Desktop. The setup CLI has a target for each:
npx @webhooks-cc/mcp setup cursor --api-key whcc_...All six clients share the same tool surface — once your prompts work in one, they work everywhere.
MCP server reference
Full tool list, Zod schemas, and configuration options for the @webhooks-cc/mcp server.