All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
Full coverage of the documented webhook.site API. With WEBHOOK_SITE_API_KEY set you get what your plan pays for; without it everything still works on anonymous URLs.
list_webhooks,configure_webhook(all token settings:listen,request_limit,actions,clone_from,group_id, alias, expiry),get_request(latest or by id,raw),update_request(notes, dynamic responses),download_request_filemanage_custom_actions(list / create / update / delete / test / execute),manage_schedules(incl. run-now and logs),manage_global_variables,manage_groups,manage_templates,manage_databases(incl. SQL query),manage_usersexport_webhook_datapages through the requests list (the API caps a page at 100) and can return the account's CSV exportwait_for_request/wait_for_emaillisten onws.webhook.site(socket.io) and fall back to polling; results carrysource- Emails expose
sender,checks(spam, virus, SPF, DKIM, DMARC),email_truncatedandattachments; list results carrypagination - MCP tool annotations (
readOnlyHint,destructiveHint,idempotentHint) on every tool WEBHOOK_SITE_DEFAULT_EXPIRYfor operators who want new URLs to auto-expirelive_authtest tier that runs the real sign-up flow (create URL, send a verification-style email through a Custom Action,wait_for_email,follow_email_link) whenWEBHOOK_SITE_API_KEYis setFOLLOW_EMAIL_LINK_ALLOW_HOSTS: operator-configured hosts,*.suffixes, IPs or networks thatfollow_email_linkmay open although they are local or private (for testing your own sign-up flow onlocalhostor an intranet)follow_email_linkhonoursHTTPS_PROXY/HTTP_PROXY/NO_PROXY; proxied targets are checked before the request since the proxy makes the connectionfollow_email_linkreports a redirect refused after a completed public hop asblocked_redirect, with that hop's status, instead of failing the whole callmanage_custom_actions(action="script_reference"): every WebhookScript function with its signature and summary, generated from the docs and checked name-by-name against the live engine (two documented names do not exist there), plus language notes (var()is required, strict typing, regex literals)- Action-type reference corrections found in the frontend bundle and confirmed live:
set_variablemodesmathandrandom_number,conditionsoperatorsregex/nex/null/nnull(the singularconditionrejects them),text_mapoperator codes,databasetypewhdbwithdb_id, the editor's no-queue types - Custom actions carry a
name; updates keep it (the API drops it on a bare PUT). Schedules acceptrequire_cert_expiry(days before the HTTPS certificate expires) - Every
webhook_tokenaccepts an alias, a pastedhttps://webhook.site/...URL, the subdomain form, the inbox address or the DNSHook name; aliases resolve throughGET /token/{alias}(works live although the docs say otherwise) configure_webhookon an aliased token returnsalias_cache_note: webhook.site serves the previous settings on the alias URL for about two minutes after a change (measured), the UUID URL updates at oncesince/next_sinceonget_webhook_requestsandsearch_requests: asortingcursor that returns only what arrived after the previous call, without paging or de-duplicatingconfigure_webhook(alias="")removes an alias;get_webhook_inforeturnsforce_status_url(https://webhook.site/{token}/{status}answers with that status);search_requestsdocuments exclusion (-method:GET),_exists_:,note:and geo fields
-
The HTTP client expires idle keep-alive connections after 4 s and retries idempotent calls once after a dropped connection (webhook.site closes idle connections after a few seconds)
-
Documentation consolidated under
docs/: generated tool reference and README tables, verified webhook.site notes, testing and releasing guides; the stale publishing guide and manual test scripts are gone -
Email addresses use the current
{token}@emailhook.sitedomain (the oldemail.webhook.siteform still delivers) -
request_limitis no longer capped client-side at 10000; the API enforces the plan's ceiling (up to 100000 on Enterprise) -
Tool merges (no capability removed):
create_webhook_with_config+update_webhook->configure_webhook;get_webhook_url+get_webhook_dns-> fields ofget_webhook_info;get_latest_request->get_request;send_to_webhook+send_multiple_requests->send_requests;generate_ssrf_payload+generate_xss_callback+generate_canary_token->generate_oob_payloads -
Tokens created with an API key are permanent by default (pass
expiryor setWEBHOOK_SITE_DEFAULT_EXPIRYto change that) -
The HTTP client now raises
WebhookApiErroron failed DELETEs like every other verb, and every API error carries webhook.site's own validation message -
configure_webhookon an existing token no longer wipes the other settings:PUT /token/{id}replaces them, so a 2.xupdate_webhook(cors=true)silently reset the canned status, body and timeout. The current settings are merged in first -
Verified against the live API rather than the docs: notes and Set Response live on
/request/{id}(singular); updates of actions, schedules, templates, global variables, databases and users send the full record because the API replaces it (a value-only variable update would have wiped its name);run-nowanswers with a redirect;check_for_callbacksmatches the identifier anywhere in the captured request, not only in the body -
scripts/live_tool_check.pydrives the real server over stdio and exercises all 28 tools against the live API -
respond_to_next_request: hold the next request and answer it with a chosen status, headers and body, the mechanismwhcli forwarduses (tokenlistenset by PUT, socket listener, Set Response on the event). Verified live: the waiting caller received the reply in 0.2 s.listenis silently ignored byPOST /token, soconfigure_webhooknow applies it with a follow-up PUT -
Found by mapping the web app rather than the docs:
manage_queues(Queue Profiles at/queues, withqueue_idon custom actions), thedescriptionfield onconfigure_webhook, and the liveGET /variablesnames merged into the variables reference. Error log, providers, domains, API keys, notifications, roles and the form builder need a browser session and are not exposed -
docs/TOOLS.md, generated from the server's own catalogue (scripts/gen_tool_docs.py); CI fails when it or the README tool tables drift -
Real-socket tests for
follow_email_linkagainst a local web server and a local HTTP proxy (allowlist,HTTP_PROXY,NO_PROXY), no mocks involved -
server_statusdiagnostics tool (key, account, plan, socket, env, problems in plain words) -
Rate limits: a 429 with a short
Retry-Afteris waited out and retried once (WEBHOOK_MCP_RATE_LIMIT_MAX_WAIT, default 15 s); longer waits are reported with the exact wait instead of hanging. A socket dropped mid-wait switches the wait tools to fast polling -
Recorded-truth tests:
scripts/live_tool_check.py --recordcaptures every real HTTP exchange and tool result;tests/test_replay_recordings.pyreplays them through the real service code offline and expects the recorded results, so offline CI asserts on what webhook.site actually returned -
Built-in Custom Action reference:
manage_custom_actions(action="types")lists 63 action types (two of them,mockandvalidate_json, exist live but are missing from the API docs) with parameters, live-verified status and a working example;action="variables"lists the$request.*$variables checked live. Required parameters are validated before the API is called, including three the docs call optional but the API insists on. Regenerate withscripts/gen_action_types.pyand re-verify withscripts/verify_action_types.py -
Catalog token budget raised to 10000 for the 31-tool catalog
-
New dependency:
python-socketio[asyncio_client]
follow_email_linknow connects to the address it vetted (no DNS rebinding), also blocks cloud metadata and NAT64 / IPv4-mapped private addresses, resolves hosts without blocking the event loop, treats a 3xx withoutLocationas the final page, rejectsjavascript:and other non-http redirects cleanly, and reports the rankedauth_linksit chose from. When an environment proxy applies, the target is checked with the resolver before the request, because the proxy makes the connection and pinning cannot applyfollow_email_linkpicks the email that containsurl=, or the newest email with a verify / confirm / magic link, instead of the newest email with any login link- Link extraction ignores the raw quoted-printable message when decoded text or HTML exists, decodes
&in hrefs (but leaves®ion=-style query strings alone), handles IPv6-literal URLs, ranks verify / confirm links and "Verify your email" anchor text ahead of login links, and never returns unsubscribe or asset links asauth_links verification_codesunderstands "code is 512930", "code: 123 456", "G-847291 is your code" and "847291 is your code", ignores zip / promo / sort codes and order numbers, and no longer lists CSS colours ahead of the real OTP; markup stripping is linear on hostile input
2.2.2 - 2026-08-16
follow_email_linkopens a verify / magic / reset URL already captured in the inboxwait_for_emailandextract_links_from_requestnow returnverification_codes(OTP)- CI budget: the MCP tool catalog must stay under 5000 tokens
- List and wait tools omit HTML and truncate bodies; use
export_webhook_datafor the full dump - Default MCP install configs no longer mention an API key
2.2.1 - 2026-08-16
- Tool descriptions now say when to use each tool, including the sign-up / verify / magic-link / password-reset email flow
- README install examples pin
uvx webhook-mcp-server==2.2.1so clients do not keep 2.1.3
2.2.0 - 2026-08-16
- Migrated the MCP entry point to Python SDK 2.0
MCPServerwith typed@mcp.tool()handlers - Reuse one HTTP client for the process lifetime and read
WEBHOOK_SITE_API_KEYfrom the environment wait_for_requestandwait_for_emailnow wait for new events by default (addreturn_existing=truefor the old behavior)- SSRF output is split into
callback_payloadsandlocal_bypass_examples - Require
mcp>=2.0.0
- Server failed to start on MCP SDK 2.0 (
Server.list_toolsremoved) ToolResult.to_json()crashed whendatawasNone- Token UUID validation was skipped on several tools, including
get_webhook_dns - Tests called async
get_url/get_email/get_dnswithoutawait
- Offline unit tests and a GitHub Actions test workflow
- Official
server.jsonfor the MCP Registry - Cursor MCP config and authorized-use notes in the README
2.1.3 - 2026-01-27
- Smart waiting:
wait_for_emailandwait_for_requestnow check for existing items first- Returns immediately if matching email/request already exists (with
"waited": false) - Only polls if nothing exists yet
- Eliminates unnecessary 60-120 second waits when emails arrive before the wait call
- Returns immediately if matching email/request already exists (with
- Updated docstrings to document smart behavior
2.1.2 - 2026-01-26
- Removed
clone_webhooktool due to webhook.site API compatibility issues (24 → 23 tools)
- Updated README and badges to reflect 23 tools
2.1.1 - 2026-01-26
- Fixed
clone_webhookbug - was incorrectly calling.raise_for_status()on dict instead of Response object
2.1.0 - 2026-01-26
- 3 New Tools (21 → 24 total):
send_multiple_requests- Send batch of requests for load testingclone_webhook- Copy webhook with all settings to a new tokenexport_webhook_data- Export all requests to JSON format
post_raw()method in HTTP client for absolute URLs
- Updated README badge (21 → 24 tools)
- Added "Batch & Utility" tools section to README
2.0.7 - 2026-01-26
- Complete README rewrite with professional MCP-focused structure
- Updated tool count badge (16 → 21)
- Added natural language examples and use cases
- Improved documentation with JSON response examples
2.0.6 - 2026-01-26
- Removed 5 redundant script/test files (~800 lines)
- Removed unused
get_http_client()function - Removed unused
sanitize_identifier()function - Removed unused
WebhookInfoclass - Removed unused
WebhookRequestclass - Cleaned up unused imports across 5 files
LICENSEfile (MIT)CHANGELOG.md(this file)- Improvement plan documentation
2.0.5 - 2026-01-26
- Console script wrapper for proper uvx execution
- Entry point configuration for MCP server
2.0.4 - 2026-01-26
- F-string syntax error in request service
2.0.3 - 2026-01-26
- uvx compatibility for MCP server startup
- Module path resolution issues
2.0.2 - 2026-01-26
- Syntax error in request_service.py
- Import organization issues
2.0.1 - 2026-01-26
- Package structure and imports
- Build configuration
2.0.0 - 2026-01-25
- Complete rewrite with 21 MCP tools
- Webhook management tools (create, configure, update, delete)
- Request management tools (list, search, delete)
- Bug bounty payload generators (SSRF, XSS, canary tokens)
- Email and DNS endpoint support
- Real-time request waiting with SSE
- Link extraction from captured requests
- Comprehensive validation and error handling
- Async HTTP client with proper connection management
- Structured logging with configurable levels
- Migrated to MCP SDK 1.0.0
- Improved code architecture with service layer pattern
- Enhanced type hints throughout codebase
1.0.0 - 2026-01-24
- Initial release with basic webhook.site integration
- Core webhook creation and management
- Request capture and retrieval