webhooks.xyz

MCP server

Your AI assistant can work your bins through the Model Context Protocol: list and create bins, search requests, read one with its deliveries, replay failures, add destinations (HTTP or Private Relay) and secrets, set a scenario, import and export, subscribe to vendor status feeds, add connections and actions, mail from o.webhooks.xyz, read the inbox, set the digest, ask the AI assistant with your own key, and see your quotas. Same token as the API. For signed-in users on every plan.

Endpoint

POST https://webhooks.xyz/mcp
Authorization: Bearer whx_…          # token from your account
Content-Type: application/json       # JSON-RPC 2.0, Streamable HTTP, JSON responses

Claude Desktop, Cursor, Windsurf (stdio clients)

Until the whx mcp bridge ships, use mcp-remote:

{
  "mcpServers": {
    "webhooks": {
      "command": "npx",
      "args": ["-y", "mcp-remote", "https://webhooks.xyz/mcp", "--header", "Authorization: Bearer whx_…"]
    }
  }
}

Clients that speak Streamable HTTP directly

{ "url": "https://webhooks.xyz/mcp", "headers": { "Authorization": "Bearer whx_…" } }

Tools

ToolWhat it does
list_binsList the bins in your account with their URLs and last activity.
create_binCreate a new request bin. Returns its id, capture URL and page URL.
search_requestsSearch stored requests of a bin. Query syntax: provider:stripe event:payment_intent verify:ok|failed|unchecked status:200 method:POST path:/orders delivered:yes|no|pending since:24h plus free text.
get_requestOne stored request with headers, body, verification result and deliveries.
list_deliveriesDeliveries of a bin to its destinations, optionally filtered by status (queued, delivered, failed).
replay_failedQueue every dead-lettered (failed) delivery of a bin again.
add_destinationForward every request of a bin, with retries: mode http to a public URL, or mode relay to a `whx relay` agent on a private network (url is then the private URL the agent forwards to).
list_destinationsThe destinations of a bin (url, mode http|relay, paused, delivery counts).
add_secretAdd a signing secret so requests from that sender get verified. scheme is a slug from list_schemes, or 'custom' with a custom spec (sig_header, algo sha256|sha1|sha512, encoding hex|base64, sig_prefix, message template with {body} {ts} {id}, ts_header, key raw|base64).
list_schemesSignature schemes the bin can verify (slug, name, which secret to paste).
set_scenarioChange what the bin answers: normal, timeout, fail (503 for fail_minutes) or echo (returns echo_field).
get_binOne bin: name, URLs, its inbound mail address (<id>@i.webhooks.xyz) and sender address (<id>@o.webhooks.xyz), scenario, counts, destinations, relay tokens.
set_bin_publicMake a bin public (anyone with its link sees the requests) or private (the default for account bins: only you and your team).
create_relay_tokenPrivate Relay: mint a token for `whx relay --token …` so an agent inside a private network delivers the bin's relay-mode destinations. The token is shown once.
list_relay_tokensRelay tokens of a bin with last-seen time and whether an agent is connected.
revoke_relay_tokenRevoke a relay token.
export_binFull export of a bin (settings without secrets, destinations, every request) in the webhooks.xyz JSON format that import_requests accepts.
import_requestsImport requests into a bin (or new bins). source: webhook-site (token = its URL or token, api_key optional), hookdeck (api_key), pipedream (api_key, source_id), svix-play (token = play URL), har (data = parsed HAR), json (data = a webhooks.xyz export or a list of requests).
list_importsPast imports of the account: source, bins created, counts, notes.
list_connectionsThe account's connections (Slack, Teams, Discord, email, mailout = Email from webhooks.xyz, Sentry, HTTP) with ids for actions and status feeds.
add_connectionAdd a connection. kind slack|discord|teams: config.webhook_url. mailout: config.to (recipient; your account address or one confirmed by mail), config.reply_to. email (your SMTP): host, port, username, password, from_addr, starttls. sentry: dsn. http: url, method, auth_header.
list_actionsActions and alerts of a bin (trigger, filter, connection, template, state).
add_actionAdd an action to a bin: when `trigger` fires (request, signature_failed, delivery_failed, delivery_dead, silence) and the optional filter matches, send `template` (with {{ field }} placeholders) through a connection. subject/recipient for mail kinds; threshold = N for delivery_failed/silence.
list_mail_recipientsAddresses that may receive mail from <bin>@o.webhooks.xyz for this account (verified, pending, blocked), plus today's use of the daily limit.
add_mail_recipientSend a confirmation link to an address so actions can mail it from o.webhooks.xyz. The account's own address needs no confirmation.
list_status_feedsStatus Feed Relay: the account's vendor status subscriptions and the curated vendor list (slug, name, feed URL).
add_status_feedSubscribe to a vendor's status page and post incidents to connections. Give vendor (a slug from list_status_feeds) or name + url (any RSS/Atom feed), or kind webhook for a vendor that pushes (returns the inbound URL).
delete_status_feedDelete a status feed subscription.
inboxNotifications Inbox: every mail we sent the account and in-app notices (alerts, bounces, digests). unread_only limits to unread; mark_read marks the returned items read.
set_digestUsage Digest by mail: off, weekly (Monday) or monthly (1st). Returns the current setting; omit period to only read it.
ai_askAI Assistant (BYOK, the account's own provider key): explain a request, write a handler (lang python|node|go|ruby|php|java|csharp|rust), suggest a filter, or ask a question about it.
ai_summaryAI Assistant (BYOK): summarise the last `hours` of a bin's traffic.
list_routesTransformations and Routing: the ordered routes of a bin (conditions, transformation, action, destinations, hits, last error).
add_routeAdd a route to a bin. conditions: one per line ('body.type starts charge.', 'header:x-github-event is push', 'body.amount > 5000'). action: forward (needs destination_ids), drop, or continue. transform_kind: none, js (a function (req) => req; null drops) or jsonata (expression over the body). A bin with routes forwards only what a route forwards.
test_routeDry run the bin's routes (or one unsaved draft route) against a stored request (default: the latest). Shows which route matched and the exact request a destination would get. Sends nothing.
delete_routeDelete a route of a bin.
list_schemasBinary Payloads: the Protobuf schemas of a bin (message types), its path map and the built-in types. MessagePack needs no schema.
add_schemaUpload .proto files to a bin so Protobuf bodies decode to JSON. files: {"acme/reading.proto": "syntax = ..."} (imports between the files work). Then set_schema_map chooses the message type per path.
set_schema_mapWhich Protobuf message type decodes which requests of a bin. One line per rule: '<path prefix or *> <message type>', e.g. '/telemetry acme.Reading\n* transit_realtime.FeedMessage'. A content-type parameter '; proto=pkg.Msg' on a request wins over the map.
delete_schemaRemove a Protobuf schema from a bin.
sql_schemaSQL Access: the tables and columns of your account's database (bins, requests, deliveries, destinations), row counts and limits. SQLite dialect; JSON functions work on requests.body.
sql_queryRun one read-only SELECT on your account's database. Example: SELECT day, provider, count(*) FROM requests GROUP BY 1, 2. Use json_extract(body, '$.field') for body fields and json_extract(headers, '$."x-github-event"') for headers. fresh=true rebuilds the snapshot first (it is at most 60 s old otherwise).
list_viewsPublished Views: the account's public pages (URL, JSON/CSV/RSS URLs, kind, columns, visibility, hits) and the account handle.
publish_viewPublish a page at /p/<handle>/<slug> with .json, .csv and .rss. kind search: bin_id + q (search syntax) + fields (public columns: received_at, method, path, provider, event, verify, size, resp_status, ip, id, body.<path>, header:<name>). kind request: bin_id + request_id (fields = body fields to show; show_headers). kind sql: one SELECT on the account database. visibility public or secret (link carries a key).
unpublish_viewRemove a published view; its address stops working at once.
list_workflowsWorkflows: the account's step graphs (trigger, steps, edges, enabled, last run). Workflows must be turned on at https://webhooks.xyz/workflows first.
get_workflowOne workflow with its trigger and graph.
save_workflowCreate a workflow (or update it with workflow_id). trigger = {type:'request', bin_id, filter}. graph = {start, steps:{id:{type:send|set|if|switch|join|foreach|wait|http|forward|notify|stop, ...}}, edges:[{from, port, to}]}; ports: out; then/else (if); case1..caseN/default (switch); each/done (foreach). Several edges from one port = parallel branches; join waits for them. A step reads earlier outputs as {{ steps.<id>.out.<field> }} and the request as {{ trigger.body.x }}, {{ trigger.headers.x-github-event }}. send: connection_id, template, subject, recipient, retry_if_unsure. set: vars {name: template}. if: conditions (one per line: '<reference> <op> <value>'). notify: subject, text. stop: status done|failed, note. switch: cases [{name, conditions}]. join: mode all|any. foreach: over '{{ trigger.body.items }}', max; the body reads {{ loop.item }} {{ loop.index }}; after the loop read {{ steps.<foreach>.out.items }}. wait: minutes. http: connection_id (an http connection), body, query; output ok/status/json/text. forward: destination_id (queues the trigger request). Saved paused unless enabled=true.
set_workflow_enabledTurn one workflow on or off.
delete_workflowDelete a workflow and its run history.
test_workflowDry run against the newest request of the trigger bin: shows every step's input-resolved output. Nothing is sent or stored.
list_workflow_runsRuns of a workflow (status, started, finished, note). Pass run_id for one run with every step's stored output.
list_teamTeams: the members of the account's team (email, role editor|viewer, accepted) and the teams this account is a member of.
invite_memberInvite a person by email to the account's team as editor (can change bins) or viewer (can only look). They get a mail with an accept link.
remove_memberRemove a member from the account's team.
audit_logThe audit log of the account: every change through the web, API or MCP (time, actor, summary, bin, address, IP).
list_short_urlsShort URLs: every bin answers at https://webhooks.in/<bin-id> and https://webhook.in/<bin-id>. Lists the account's short names (webhooks.in/<name>).
add_short_urlGive a bin a short name: https://webhooks.in/<alias> then captures for that bin. alias: 3-40 characters a-z, 0-9, '-'.
delete_short_urlRemove a short name.
list_domainsYour own domains: each with its purposes (web, mail_in, mail_out), the state of each purpose and the DNS records still to add.
add_domainAdd your own subdomain. purposes: web (https://<host>/<bin-id> captures; /p/<slug> serves published views), mail_in (<bin-id>@<host> becomes a request), mail_out (actions send from <bin-id>@<host>). Use one subdomain per purpose, or one for all (then web uses A/AAAA records). Returns the DNS records to add; call check_domain after adding them.
check_domainRead DNS for a domain now and return its states and the records still missing.
delete_domainRemove a domain from the account. Its addresses stop working.
list_mail_invite_formsVerify by Email: a visitor solves a captcha, gets an address that takes mail for 5 minutes, and sends one mail to it. DMARC pass = the address is proven. Lists the account's Verify by Email forms with their embed snippet.
create_mail_invite_formMake a Verify by Email form for a bin. domain: an active mail-in domain of the account (the bin's short name is then the local part; Team and Business only), empty = the shared mail domain (all plans). origins: web origins that may embed it (empty = any). Returns the embed snippet. Each mail to an invite address lands on the bin with body.invite.status = verified, failed, expired or used.
delete_mail_invite_formRemove a Verify by Email form. Its open invite addresses stop working.
list_outbound_appsOutbound webhooks (send webhooks to YOUR customers): the account's apps, endpoint and message counts, messages this month.
create_outbound_appCreate an outbound app (one per product or environment). Returns its id (app_...) and backing bin.
list_outbound_endpointsEndpoints of an outbound app, optionally for one tenant (your customer's id): URL, event types, signing secret, state.
add_outbound_endpointRegister an https endpoint of a tenant. event_types empty = all events. Returns the signing secret (whsec_...) your customer verifies with.
delete_outbound_endpointRemove an endpoint of an outbound app.
send_outbound_messageSend one message to a tenant: signed (Standard Webhooks), delivered to each of the tenant's endpoints that wants the event type, retried with backoff. event_id makes the call idempotent.
list_outbound_deliveriesDeliveries of an outbound app (optionally one tenant): status, attempts, response status, error, message id.
outbound_portal_linkA signed link (7 days) where one tenant manages their own endpoints, sees deliveries and replays them. Give it to your customer.
billing_statusThe account's plan, how it is paid, when it renews, and the plans it can move to with their prices.
quotasEvery limit of the service with the account's current use (per bin, mail, connections, AI, API).

Read-only tokens can call every tool that reads. Replay needs the deliver scope; everything that creates, changes or asks the AI needs write. Every feature of the service has its tool here; a feature ships with its tool.

Try it with curl

curl -s https://webhooks.xyz/mcp -H "Authorization: Bearer $WHX_TOKEN" -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"search_requests","arguments":{"bin_id":"k7f3abc","q":"verify:failed since:7d"}}}'