Every change Wellknown observed on this MCP server, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Added "doorman_create_hook", "doorman_delete_hook", "doorman_hubspot_map_forms" and 3 more; changed the definition of "doorman_create_form", "doorman_get_install_snippet" and "doorman_list_submissions" (19 tools before, 25 now)
⟨77 unchanged words⟩ submissions to","type":"string"},"inbound_platform":{"description":"Where the form lives when it stays on another tool (tally, typeform, jotform, netlify, webflow, framer, or json for any webhook). Remembered for the dashboard's setup steps.","enum":["tally","typeform","jotform","netlify","webflow","framer","json"],"type":"string"},"kind":{"description":"lead = contact/demo/quote/sales form ⟨133 unchanged words⟩
⟨41 unchanged words⟩ form already posts to the project's own backend. 'badge' is the optional 'Protected by Doorman' link for the site's footer (+25% submissions while it's live; save the page with PATCH /v1/account { badge_url }).
⟨36 unchanged words⟩ ,"elixir","webflow","framer","wordpress","tally","typeform","jotform","netlify","badge"],"type":"string"}},"required": ⟨4 unchanged words⟩
⟨61 unchanged words⟩ ,"other"],"type":"string"},"via":{"description":"Only submissions that came in through this form tool's webhook","enum":["tally","typeform","jotform","netlify","webflow","framer","json"],"type":"string"},"workspace_id":{"description":"Optional ws_...: only ⟨8 unchanged words⟩
POST every delivered, held or dropped verdict to a URL you run (one JSON POST per submission, the same object as GET /v1/submissions/{id} plus event; not signed, no retries; paused after 10 failures in a row; a 410 answer deletes it). For a signed webhook of real ones only, set webhook_url on the form instead.
Delete a hook subscription by id (hk_...). A Zap that used it receives nothing until it is turned off and on again.
Choose which HubSpot forms Doorman screens on a connected HubSpot account. Replaces the current list. form_id "new" makes a lead form named like the HubSpot form. Each submission's verdict is then written onto the HubSpot contact as doorman_verdict (Real, Held, Kept out).
For a demo form that is a HubSpot form: whether Doorman's HubSpot app is enabled, which HubSpot accounts are connected, which HubSpot forms Doorman screens (and into which Doorman form), whether archiving is on, and the HubSpot forms available to map. Connecting is a browser step: give the user connect_url.
For a form that stays on Tally, Typeform, Jotform, Netlify Forms, Webflow or Framer: the form's inbound webhook URL, its signing secret and the exact clicks in that tool. Tell the user the steps; the tool keeps every submission and Doorman forwards the real ones with a verdict. Use this instead of changing the form's action when the form lives on one of those tools.
The account's hook subscriptions (made with doorman_create_hook, the API or the Doorman Zapier app): url, event, form, failures and whether each is paused.
Added "doorman_alerts", "doorman_client_report", "doorman_create_workspace" and 3 more; changed the definition of "doorman_create_form", "doorman_label_submission", "doorman_list_forms" and 4 more (13 tools before, 19 now)
⟨16 unchanged words⟩ Authorization header.","type":"string"},"attachments":{"description":"Forward file attachments (a CV, a brief, a screenshot) with real submissions by email and webhook: up to 5 files, 5 MB each, 8 MB in all; no executables or archives (default true). Submissions list them under files, with a download url while one waits.","type":"boolean"},"email_to":{"description":"Comma-separated emails to forward ⟨37 unchanged words⟩ thank-you page)","type":"string"},"routes":{"description":"Per-type destinations (Business plan): { support: { email_to, slack_url, webhook_url }, job: {...}, partnership, press, investor, other }. A type with a rule goes only there; the rest, sales leads included, go to the form's email_to/slack_url/webhook_url. Pass {} to clear.","type":"object"},"site_context":{"description":"What the business sells ⟨18 unchanged words⟩ receives a signed JSON POST per real submission","type":"string"},"workspace_id":{"description":"Optional ws_...: put the form in this client workspace (its blank destinations use the workspace's defaults). \"\" ungroups it.","type":"string"}},"required": ⟨3 unchanged words⟩
Added "doorman_audit_rows" (12 tools before, 13 now)
Audit old submissions: the user has a CSV export of past form submissions (Webflow, Framer, HubSpot, Formspree, Netlify, Typeform or any tool). Parse it yourself and pass up to 200 rows; each is judged and you get a summary ("4 of 12 were pitches") and every row's verdict with the sentence that gave it away. With form_id the rows are imported into that form's inbox (source "audit": never forwarded, never counted as checks) so the user can check and rescue them; without it nothing is stored. Free, 3 audits an hour.
Certificate recorded, valid to 2026-12-28
Authorization not required
Unknown → Live
First tool surface recorded: 12 tools (server version 0.1.0)
https://withdoorman.com/mcp (mcp_streamable_http) — from mcp_registry, with the record
Showing the latest 8 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
⟨6 unchanged words⟩ if it was held or dropped) or spam. A label that disagrees with Doorman becomes one of the few examples the form's next checks are judged with.
{"properties":{"always":{"description":"Also add a rule: always deliver (real) or always drop (spam) this sender or its domain. Domain is refused for free-mail providers.","enum":["sender","domain"],"type":"string"},"api_key":{"description":"Doorman API key ( ⟨30 unchanged words⟩
⟨15 unchanged words⟩ no Authorization header.","type":"string"},"workspace_id":{"description":"Optional ws_...: only this client workspace's forms","type":"string"}},"type":"object"}
⟨6 unchanged words⟩ review=true for held ones waiting for a human. Attached files are listed under files (name, size, type, kept, and a download url with the API key while the file waits).
⟨35 unchanged words⟩ hold","drop"],"type":"string"},"type":{"description":"Only this enquiry type (lead forms): sales, support, job, partnership, press, investor, other","enum":["sales","support","job","partnership","press","investor","other"],"type":"string"},"workspace_id":{"description":"Optional ws_...: only this client workspace's forms","type":"string"}},"type":"object"}
⟨21 unchanged words⟩ "description":"f_...","type":"string"},"type":{"description":"Send the sample to the destinations a submission of this type would get","enum":["sales","support","job","partnership","press","investor","other"],"type":"string"}},"required":["form_id"],"type":"object"}
Change a form's settings: context, what's welcome, destinations, thresholds, watch mode, allow/blocklists.lists, per-type routing.
{"properties":{"alert_delivery":{"description":"Alert the owner when deliveries to a destination fail 3 times in a row or run out of retries (default true)","type":"boolean"},"alert_silent":{"description":"Alert when a form that normally gets submissions goes quiet, which usually means it broke (default true)","type":"boolean"},"alert_silent_days":{"description":"Days of quiet before that alert; 0 = auto, from the form's own rhythm (1 to 60)","type":"number"},"alert_slack":{"description":"Also post alerts to the form's Slack destination (default true)","type":"boolean"},"alert_spike":{"description":"Alert on a flood: more than this many submissions an hour (default 50; 0 turns it off)","type":"number"},"allow_list":{"description":"Emails or domains always ⟨23 unchanged words⟩ Authorization header.","type":"string"},"attachments":{"description":"Forward file attachments (a CV, a brief, a screenshot) with real submissions by email and webhook: up to 5 files, 5 MB each, 8 MB in all; no executables or archives (default true). Submissions list them under files, with a download url while one waits.","type":"boolean"},"block_list":{"description":"Emails or domains always ⟨56 unchanged words⟩ ,"comment"],"type":"string"},"learn":{"description":"Show the owner's rescues and spam marks on this form to the model as a few examples (default true)","type":"boolean"},"mode":{"description":"watch = deliver everything ⟨22 unchanged words⟩ after submit","type":"string"},"routes":{"description":"Per-type destinations (Business plan): { support: { email_to, slack_url, webhook_url }, job: {...}, partnership, press, investor, other }. A type with a rule goes only there; the rest, sales leads included, go to the form's email_to/slack_url/webhook_url. Pass {} to clear.","type":"object"},"site_context":{"description":"What the business sells ⟨13 unchanged words⟩ ,"webhook_url":{"description":"HTTPS webhook URL","type":"string"},"welcome":{"description":"Kinds of enquiry the owner welcomes; Doorman treats them as real instead of pitches. The full set: pass [] to clear.","items":{"enum":["partnerships","jobs","press","investors"],"type":"string"},"type":"array"},"welcome_note":{"description":"One line of extra context from the owner, e.g. 'We sell to agencies, so an agency asking about our product is a customer'","type":"string"},"workspace_id":{"description":"Optional ws_...: put the form in this client workspace (its blank destinations use the workspace's defaults). \"\" ungroups it.","type":"string"}},"required": ⟨3 unchanged words⟩
Account, plan and this month'susage.usage (checks used, and blocked_free: bots caught without reading, which don't count), and whether the account has accepted the data processing addendum (dpa).
Open problems on the user's forms: deliveries failing, a flood, a form gone quiet (probably broken). Call it when the user asks why leads stopped arriving or a webhook isn't receiving.
A client workspace's monthly report: what reached them, what was kept out, the worst catches (redacted), per form. Returns the numbers and the shareable url (a page the client can open or print to PDF).
Create a client workspace: one per client site an agency manages. Its email_to/slack_url/webhook_url are the defaults for every form in it whose own field is blank. Pro includes one, Business 50.
Invite a teammate (role 'member': every client, full access, no keys or billing) or a client (role 'client' with workspace_id: that workspace only, view-only). They get an email to set a password. Business plan.
List the account's client workspaces (an agency's clients): each one's default destinations, form count, this month's numbers and its monthly report link.
Change a client workspace: its name, site, default destinations, and its monthly report (report_monthly emails report_to on the 1st; addresses confirm once).