Doorknock
Doorknock
Ein entfernter MCP-Server, der ein Unternehmen anhand seiner eigenen Domain recherchiert, es gegen ein von Ihnen geliefertes Lead-Profil bewertet und das Ergebnis in HubSpot schreibt.
Alles, was er berichtet, wurde live von der eigenen Website des Unternehmens oder seinen öffentlichen DNS-Einträgen gelesen und trägt die URL oder DNS-Abfrage, die es erzeugt hat. Er kauft nichts von einem Datenanbieter und leitet nichts über Umsatz, Mitarbeiterzahl oder Eigentümerschaft ab.
Live: https://doorknock-eight.vercel.app MCP-Endpunkt: https://doorknock-eight.vercel.app/mcp OpenAPI: https://doorknock-eight.vercel.app/openapi.json Health: https://doorknock-eight.vercel.app/health
Verbinden
claude mcp add --transport http doorknock https://doorknock-eight.vercel.app/mcpJeder MCP-Client, der Streamable HTTP spricht, kann dieselbe URL verwenden. Es ist nur POST: Der Server ist zustandslos, daher antworten GET und DELETE absichtlich mit 405.
Die Recherche-Tools benötigen überhaupt keine Anmeldeinformationen. Die HubSpot-Tools benötigen ein privates App-Token mit crm.objects.companies.read und .write, das als Header übergeben wird:
claude mcp add --transport http doorknock https://doorknock-eight.vercel.app/mcp \
--header "X-HubSpot-Token: pat-na1-..."Für alles, was nicht MCP spricht, sind die identischen Operationen unter /v1/<operation> verfügbar und werden durch /openapi.json beschrieben, das aus denselben Konstanten generiert wird, die der Router verwendet, sodass die beiden nicht auseinanderdriften können. Darauf sollte eine benutzerdefinierte GPT-Action oder ein n8n-HTTP-Knoten zeigen.
Related MCP server: HubSpot Extended MCP Server
Die sieben Tools
Tool | Was es tut |
| Liest die Startseite und die DNS. Gibt die Marketing- und CRM-Tools zurück, die auf der Seite geladen sind, welche Standardseiten existieren, wer deren E-Mail verwaltet und ob deren ausgehende E-Mail geschützt ist. |
| Führt die Recherche durch und bewertet sie dann anhand eines Profils, das Sie übergeben, und gibt eine Stufe mit der Begründung für jede Regel zurück. |
| MX, SPF und DMARC, in einfachen Worten gelesen. Hält „Wird meine E-Mail sie erreichen“ und „Kommt ihre E-Mail an“ getrennt, weil es unterschiedliche Fragen sind. |
| Das Vokabular, gegen das Profilregeln geschrieben werden: jede benannte Tatsache, was sie bedeutet und was ihr Fehlen beweist und nicht beweist. |
| Bestätigt, dass das Token funktioniert, und meldet das Portal und die Bereiche, bevor ein Schreibvorgang im schlimmsten Moment fehlschlägt. |
| Findet ein Unternehmen anhand der exakten Domain, damit eine Anreicherung kein Duplikat erzeugt. |
| Erstellt oder aktualisiert das Unternehmen und fügt optional eine Timeline-Notiz hinzu. |
Drei Entscheidungen, über die es sich zu streiten lohnt
Die Anmeldeinformationen berühren niemals das Modell. Das naheliegende Design ist ein token-Parameter für die HubSpot-Tools. Das legt das Geheimnis in den Prompt, in den Kontextfenster, in das Transkript des Clients und in jedes Protokoll, das Tool-Aufrufe aufzeichnet, und macht das Token zu etwas, das ein Modell dazu überredet werden kann, es woanders hinzuschicken. Hier reist es stattdessen in der HTTP-Anfrage, in einem X-HubSpot-Token-Header, und kein Tool-Schema hat ein Feld dafür. Das Modell kann eine Schreiboperation anfordern; es hat niemals die Anmeldeinformationen in der Hand. Eine der adversarischen Prüfungen existiert ausschließlich, um zu bestätigen, dass kein Tool-Schema jemals ein Anmeldefeld bekommen hat.
Die Regeln sind Daten, kein Code. Qualifikationsregeln kommen mit dem Aufruf und kommen mit der Antwort zurück, sodass die Logik, die ein Urteil erzeugt hat, immer sichtbar ist und die Änderung, wer als gutes Lead gilt, niemals eine Bereitstellung erfordert. Eine Regel, die ein Signal benennt, das nicht existiert, wird als unbekanntes Signal gemeldet, anstatt stillschweigend als Fehlschlag gezählt zu werden, und eine Regel, deren Signal nicht bestimmt werden konnte, blockiert die Stufe, anstatt sie fehlschlagen zu lassen, weil „wir konnten es nicht sagen“ und „nein“ ein Lead an verschiedene Orte schicken.
Abwesenheit wird als Abwesenheit gemeldet. Ein Tag kann über einen Tag-Manager geladen werden, hinter einem Consent-Banner sitzen oder nur auf einer inneren Seite leben. Die Antwort sagt also „auf der Startseite nicht erkannt“, niemals „sie verwenden HubSpot nicht“, und jedes Signal trägt einen Satz darüber, was sein Fehlen nicht beweist.
Lokal ausführen
npm install
npm run typecheck # tsc, no emit
npm run smoke # every operation against the real internet
npm run smoke:mcp # every endpoint over a real node:http server
npm run smoke:live -- https://doorknock-eight.vercel.app # the deployment, via the official client SDK
npm run adversarial -- https://doorknock-eight.vercel.app # tries to break it
npm run prove -- https://doorknock-eight.vercel.app # independent evidenceEs gibt nirgendwo Mocks. Ein gemockter Resolver beweist, dass mein Mock das zurückgibt, was ich ihm gesagt habe; die Fehler, die es sich zu fangen lohnt, sind eine sich ändernde Form des Upstreams, und kein Mock hat jemals einen gefangen.
npm run adversarial ist das, was Dinge findet. Es zielt auf den Cloud-Metadaten-Endpunkt, wirft feindselige Hostnamen, falsche Typen, 4000-Zeichen-Domains und fehlerhafte Protokollrahmen auf den bereitgestellten Server und behandelt eine selbstbewusste Antwort auf eine Frage, die der Server hätte ablehnen sollen, als die schlimmste Art von Fehler. Es fand drei echte Defekte beim ersten Lauf.
Überprüfen, ohne diesem Repository zu vertrauen
npm run prove existiert, weil das Bestehen meiner eigenen Tests jemandem, der sie nicht geschrieben hat, sehr wenig beweist. Es ruft den bereitgestellten Server über das offizielle MCP-Client-SDK auf, holt dann jeden DNS-Fakt von einem anderen Resolver als dem, den der Server verwendet hat, und holt die Seite direkt vom Unternehmen, vergleicht Feld für Feld und druckt jede Quell-URL.
Drei weitere Möglichkeiten, die nichts von hier benötigen:
# Anthropic's own inspector, not my code
npx @modelcontextprotocol/inspector --cli https://doorknock-eight.vercel.app/mcp --transport http --method tools/list
# raw JSON-RPC, no client, no session, because it is stateless
curl -s -X POST https://doorknock-eight.vercel.app/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
# let your own client run its health check against it
claude mcp add --transport http doorknock https://doorknock-eight.vercel.app/mcp
claude mcp listUnd die Version, die nur einen Browser benötigt. Öffnen Sie beide und vergleichen Sie:
https://doorknock-eight.vercel.app/v1/email-posture?domain=servicem8.com
https://dns.google/resolve?name=_dmarc.servicem8.com&type=TXT
Was kaputtging und was ich dagegen getan habe
Bisher sechs Defekte. Drei kamen vom adversarischen Skript beim ersten Lauf gegen die Bereitstellung, einer vom unabhängigen Verifikationsskript, und einer war in einem Test und nicht im Server.
1. Eine Ablehnung, die in einen Erfolg eingewickelt war. Die Frage an den Server nach 169.254.169.254 oder metadata.google.internal gab HTTP 200 mit einem Ergebnisobjekt zurück. Nichts leckte: Der Fetch-Guard lehnte die Anfrage korrekt ab, sodass keine interne Adresse jemals kontaktiert wurde. Aber der Recherche-Aufruf führt den Seitenabruf und die DNS-Lookups parallel aus, und die DNS-Hälfte machte fröhlich weiter, sodass der Aufrufer eine 200 um eine Ablehnung herum bekam. Defense in Depth hatte funktioniert, und der Antwortvertrag nicht. Die Adressregeln laufen jetzt in normaliseDomain, an der Eingangstür, sodass die gesamte Operation mit 400 ablehnt.
2. Redirects wurden von der Laufzeit verfolgt, die nichts prüfte. Die erste Version übergab redirect: 'follow' und validierte nur den ersten Hop. Ein öffentlicher Host, der mit 302 auf eine interne Adresse antwortet, wäre direkt durch den Guard gesegelt. Redirects werden jetzt von Hand verfolgt, maximal fünf, wobei jeder Hop neu aufgelöst und geprüft wird, bevor er genommen wird, und die Kette wird in der Antwort zurückgegeben, weil wohin eine Domain Sie schickt, selbst ein Befund ist.
3. Eine 4000-Zeichen-Domain wurde akzeptiert. Keine Längenprüfung irgendwo. DNS selbst stoppt bei 253 Zeichen und 63 pro Label, also kann alles Längere kein echter Name sein. Jetzt mit einer Erklärung abgelehnt.
4. MX-Einträge mit gleicher Priorität kamen bei jedem Aufruf in anderer Reihenfolge zurück. Gefunden vom unabhängigen Verifikationsskript, das einen Unterschied zwischen dem, was der Server sagte, und dem, was ein zweiter Resolver sagte, meldete. Die Einträge waren identisch; nur die Reihenfolge unterschied sich, weil Resolver Antworten mit gleicher Priorität rotieren und die Sortierung nur nach Priorität erfolgte, was keine totale Ordnung ist. Gleichstände werden jetzt nach Hostname aufgelöst, sodass dieselben Einträge immer dieselbe Ausgabe erzeugen.
5. Ein Test, der an etwas scheiterte, das er nie ansah. Das adversarische Skript kürzte jeden Antwortkörper auf 600 Zeichen, bevor es ihn prüfte, sodass die Assertion für unbekannte Signale nach einem Feld etwa vier Kilobyte in der Antwort suchte, es nie sah und den Server als defekt meldete, obwohl der Server korrekt war. Das kostete mehr Zeit als jeder der echten Defekte. Der Körper wird jetzt ganz behalten und nur beim Drucken gekürzt. Ein Test, der ein Bestehen oder Scheitern aus etwas entscheidet, das er nie tatsächlich gelesen hat, ist schlimmer als kein Test, weil ihm geglaubt wird.
6. Die Plattform übergibt dem Handler eine Node-IncomingMessage, keine Web-Request. Geerbt vom vorherigen Server, den ich so gebaut habe, und der Grund, warum npm run smoke:mcp einen echten node:http-Server aufstellt und über einen Socket mit ihm spricht, anstatt Request-Objekte im Speicher zu bauen. Ein Test, der seine eigene Request-Form baut, testet nur diese Form.
Grenzen, klar ausgesprochen
Es liest nur die Startseite. Ein Tag, das über einen Tag-Manager geladen wird oder auf einer inneren Seite lebt, wird übersehen, und die Antwort sagt das, anstatt zu implizieren, dass das Tool abwesend ist.
Es weiß nichts über Mitarbeiterzahl, Umsatz, Eigentümerschaft oder Kontaktnamen und wird keine Domain aus einem Firmennamen erraten.
DKIM wird nicht geprüft. Der Selektor kann nicht aus DNS entdeckt werden, also bedeutet das Prüfen Raten, und ein Fehlversuch sieht identisch aus wie eine Domain ohne DKIM.
Der Adress-Guard löst den Namen auf, prüft die Adressen und holt dann per Namen, sodass eine DNS-Änderung zwischen diesen beiden Schritten nicht vollständig geschlossen ist. Das Pinnen der Verbindung auf die geprüfte Adresse erfordert einen Agenten, den diese Laufzeit nicht bereitstellt. Die Abmilderung ist, dass kein Antwortkörper jemals roh zum Aufrufer gelangt, nur benannte übereinstimmende Signale, sodass ein erfolgreicher Rebind nichts Lesbares an denjenigen zurückgibt, der es versucht hat. Das steht auch im Code.
Wie es aufgebaut ist
src/core.ts the operations, shared by both front doors
src/mcpServer.ts the MCP tool surface
src/lib/guard.ts what this server is allowed to fetch
src/lib/dns.ts DNS over HTTPS, so every fact has a URL
src/lib/site.ts redirect-by-hand page fetching and reading
src/lib/fingerprints.ts the technology table, one literal string per entry
src/lib/email.ts MX, SPF and DMARC, read in plain words
src/lib/signals.ts the published vocabulary
src/lib/qualify.ts the rules engine
src/lib/hubspot.ts the CRM writes, with the caller's own token
api/ the four endpoints
scripts/ five suites, no mocksMIT-lizenziert.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- AlicenseAqualityDmaintenanceAn MCP server that provides AI agents with ICP Triangulation Framework™ for scoring prospects across firmographics, behaviors, and growth signals, plus RFM analysis and pipeline health scoring, with optional HubSpot integration.3Business Source 1.1
- FlicenseNot gradedqualityDmaintenanceA standalone MCP server that extends HubSpot functionality for post-call processing and pre-call preparation workflows.
- FlicenseNot gradedqualityBmaintenanceAn MCP server that uses a browser extension to interact with HubSpot through the logged-in browser, enabling reading, searching, creating, and updating HubSpot records without API tokens.9
- AlicenseNot gradedqualityBmaintenanceMCP-native sales intelligence server enabling prospect enrichment, LinkedIn scraping, and CRM push to HubSpot/Salesforce via natural language.80Mozilla Public 2.0
Related MCP Connectors
Remote MCP server to enrich company profiles with structured B2B data and confidence scores.
A paid remote MCP for hosted MCP server, built to return verdicts, receipts, usage logs, and audit-r
A paid remote MCP for Skybridge, built to return verdicts, receipts, usage logs, and audit-ready JSO
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Aa-ronJS/doorknock'
If you have feedback or need assistance with the MCP directory API, please join our Discord server