mcp.webhook.co, authenticate with a bearer token, and it can manage endpoints, read events, inspect deliveries, verify your audit chain — and subscribe to an endpoint so it can act on what lands there, with a cursor that survives restarts.
Connect
The server is a streamable-HTTP endpoint:whk_ API key or an OAuth access token in the Authorization header. No cookies, no CORS, no login form. Connect two ways: paste a whk_ key, or run the interactive OAuth sign-in from your client. See how authorization works for the two methods and the consent screen, connect from a client for a ready-to-paste config, and authentication for how to mint a key.
Every session id is HMAC-bound to the principal that initialized it. Replaying a captured session id under a different principal is rejected before any tool runs — a stolen session is not a usable session.
The 22 tools
The catalog is derived from the same capability contract the API, CLI, and dashboard bind — surfaces can’t drift, because there’s one definition per capability and one shared handler. Each tool is scope-gated by that handler (an MCP bearer has no edge to lean on, so the handler’s scope check is the sole gate). A fault becomes a clean, closed-taxonomy error result, and internals go to logs — never to the caller. One case is answered before the handler runs, and so sits outside that taxonomy: every tool advertisesadditionalProperties: false, so an argument the tool does not declare is rejected by the protocol layer as a JSON-RPC -32602 (invalid params) naming the offending key, rather than as a VALIDATION_ERROR result. That is deliberate — you find out you invented a field before the call does anything, not after. On the REST API the same request is a 400 VALIDATION_ERROR.
Endpoints (10)
endpoints.list · endpoints.get · endpoints.create · endpoints.update · endpoints.delete · endpoints.rotate · endpoints.revealIngestUrl · endpoints.addProviderSecret · endpoints.listProviderSecrets · endpoints.revokeProviderSecretEvents (4)
events.list · events.get · events.tail · events.deleteTriggers (4)
triggers.create · triggers.list · triggers.revoke · triggers.waitDeliveries (2)
deliveries.list · deliveries.getAudit (1)
audit.verifyUsage (1)
usage.getendpoints.create/update/delete/rotate, the reveal and provider-secret tools, triggers.create/revoke) require a write scope; the rest need only the matching read scope. events.delete is separate again: it takes events:delete, redacts and purges a single event, and does not reduce metered usage — deleting an event you were billed for does not un-bill it. A read-only key can browse and wait, but can’t mutate anything.
There’s also an identity tool, whoami, that returns your organization, user, and granted scopes — plus your name and email when the OAuth profile scope was granted (see how authorization works). It’s identity, not a scope-gated capability, so it isn’t counted among the 22.
What’s deliberately not here
Twelve capabilities that exist on other surfaces are held back from MCP on purpose — the parity contract records the reason for each:events.getPayload— no raw-payload retrieval over MCP. An agent reads event metadata viaevents.get; the payload bytes stay off this surface. (triggers.waitcan inline a bounded body when an agent needs the content to act — see trigger semantics.)events.replay— replay-to-localhost is intrinsic to the CLI; an agent has no localhost session to forward to.- all
replayDestinations.*andsubscriptions.*— these register and mutate where an org’s events get delivered. An agent must never be able to steer an org’s event stream to a destination of its choosing. Withholding them is the egress / confused-deputy guard: the outbound allowlist is not agent-writable.
Delivery reads —
deliveries.list and deliveries.get — are exposed. Watching where events
went is safe; deciding where they go is not.Next
Agent triggers
The flagship: a durable subscription your agent drains on its own cadence.
Connect from a client
Add
mcp.webhook.co to Claude, Cursor, VS Code, and friends.