Ask any AI coding agent to write a Stripe webhook handler and it will produce something reasonable in thirty seconds. Ask it to verify that handler actually works and it hits a wall.
The problem isn't intelligence. It's plumbing. To debug a webhook you need to receive a real event on a public URL, check its signature, look at what actually arrived, fix your code, and run the same event again. Every step traditionally involves a human: clicking around a provider dashboard, copying a signing secret, pressing "resend event", eyeballing a request log in a browser.
An agent can do none of that. So it writes the handler, says "you should test this with a real event", and moves on. The one part of the integration that actually breaks in production is the one part the agent never touched.
The debugging loop for a webhook is mechanical: get an endpoint, trigger an event, inspect what arrived, verify the signature, fix the handler, replay the request. Every step is automatable. It just needs tools that speak exit codes and JSON instead of dashboards.
That's what I built. OtterKit is a tunnel plus webhook toolbox where each step is a command:
otterkit webhook
mints a public HTTPS endpoint and captures every request to a local logotterkit await
blocks until a matching request arrives, with exit codes for CIotterkit send stripe:payment_intent.succeeded localhost:3000/webhook --secret whsec_test
fires a correctly-signed synthetic event at your handler. No Stripe account needed. GitHub, Shopify, and Slack templates too.otterkit verify
answers the question that eats hours: is my signature check wrong, or is the payload malformed?otterkit replay --set data.object.amount=5000 --resign
re-sends a captured request with an edited body and a valid signatureEvery command takes a JSON output flag. And the whole surface is exposed as MCP tools (otterkit mcp
, published in the official MCP registry as io.github.useotterkit/otterkit), so an agent connected via MCP can run the entire loop: mint endpoint, send signed event, await it, verify, fix code, replay. No human in the loop.
Signed synthetic events turned out to be the sleeper feature. Building signature verification is miserable precisely because you need real events to test against, and real events require a configured provider account, a deployed endpoint, and something to actually trigger. Generating a correctly-signed event locally collapses all of that into one command. You can TDD a webhook handler now.
The second surprise: buffering. Webhooks fire whether or not your laptop is open. OtterKit's standby mode keeps the endpoint receiving while you're disconnected and delivers the buffered events when you reconnect, so the event that fired during your commute isn't gone.
There's a zero-signup demo at https://otterkit.com/try: you get an anonymous capture endpoint right in the browser (the browser itself is the tunnel client over WebSocket). If you want to keep it, otterkit webhook --claim
graduates it into a real session from the terminal.
The stack, for the curious: Cloudflare Workers and Durable Objects end to end. Each tunnel session is a Durable Object holding the WebSocket to your machine; captures buffer in DO storage. The CLI is TypeScript, and there's a macOS desktop app in Tauri.
I'd genuinely like to hear how others are handling webhook testing in CI or agent workflows. What's missing?