Doorknock
Doorknock
Un servidor MCP remoto que investiga una empresa desde su propio dominio, la evalúa según un perfil de cliente potencial que tú proporcionas y escribe el resultado en HubSpot.
Todo lo que informa se leyó en vivo desde el sitio web de la empresa o sus registros DNS públicos, e incluye la URL o la consulta DNS que lo produjo. No compra nada a un proveedor de datos ni infiere nada sobre ingresos, plantilla o propiedad.
Live: https://doorknock-eight.vercel.app Endpoint MCP: https://doorknock-eight.vercel.app/mcp OpenAPI: https://doorknock-eight.vercel.app/openapi.json Health: https://doorknock-eight.vercel.app/health
Conéctalo
claude mcp add --transport http doorknock https://doorknock-eight.vercel.app/mcpCualquier cliente MCP que hable Streamable puede usar la misma URL. Es solo POST: el servidor no tiene estado, por lo que GET y DELETE responden 405 por diseño.
Las herramientas de investigación no necesitan credenciales en absoluto. Las herramientas de HubSpot necesitan un token de aplicación privado con crm.objects.companies.read y .write, suministrado como cabecera:
claude mcp add --transport http doorknock https://doorknock-eight.vercel.app/mcp \
--header "X-HubSpot-Token: pat-na1-..."Para cualquier cosa que no hable MCP, las operaciones idénticas están en /v1/<operación> y descritas en /openapi.json, que se genera a partir de las mismas constantes que usa el enrutador, de modo que no pueden divergir. A eso debe apuntar una Acción GPT personalizada o un nodo HTTP de n8n.
Related MCP server: HubSpot Extended MCP Server
Las siete herramientas
Herramienta | Qué hace |
| Lee la página de inicio y el DNS. Devuelve las herramientas de marketing y CRM cargadas en la página, qué páginas estándar existen, quién gestiona su correo y si su correo saliente está protegido. |
| Ejecuta la investigación y luego puntúa según un perfil que tú pasas, devolviendo un nivel con la justificación adjunta a cada regla. |
| MX, SPF y DMARC, leídos en lenguaje claro. Mantiene separados "¿llegará mi correo?" y "¿llega su correo?", porque son preguntas diferentes. |
| El vocabulario contra el que se escriben las reglas de perfil: cada hecho nombrado, qué significa y qué demuestra o no su ausencia. |
| Confirma que el token funciona e informa del portal y los ámbitos, antes de que una escritura falle en el peor momento. |
| Busca una empresa por dominio exacto, para que un enriquecimiento no cree un duplicado. |
| Crea o actualiza la empresa y, opcionalmente, añade una nota a la cronología. |
Tres decisiones que merecen discutirse
La credencial nunca toca el modelo. El diseño obvio es un parámetro token en las herramientas de HubSpot. Eso pone el secreto en el prompt, en la ventana de contexto, en la transcripción del cliente y en cualquier registro que guarde las llamadas a herramientas, y hace que el token sea algo que se pueda engañar a un modelo para que envíe a otra parte. Aquí viaja en la petición HTTP, en una cabecera X-HubSpot-Token, y ningún esquema de herramienta tiene un campo para ella. El modelo puede pedir una escritura; nunca maneja la credencial. Una de las comprobaciones adversariales existe precisamente para afirmar que ningún esquema de herramienta ha tenido nunca un campo de credencial.
Las reglas son datos, no código. Las reglas de cualificación llegan con la llamada y vuelven con la respuesta, de modo que la lógica que produce un veredicto es siempre visible y cambiar quién cuenta como buen cliente potencial nunca requiere un despliegue. Una regla que nombre una señal que no existe se informa como señal desconocida, en lugar de contarse silenciosamente como fallo, y una regla cuya señal no pudo determinarse bloquea el nivel en lugar de hacerlo fallar, porque "no pudimos saberlo" y "no" envían a un cliente potencial a lugares diferentes.
La ausencia se informa como ausencia. Una etiqueta puede cargarse a través de un gestor de etiquetas, vivir en una página interna o aparecer solo tras un banner de consentimiento. Por eso la respuesta dice "no detectada en la página de inicio", nunca "no usan HubSpot", y cada señal lleva una frase sobre qué no demuestra su ausencia.
Ejecútalo localmente
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 evidenceNo hay mocks en ninguna parte. Un resolver simulado demostraría que mi simulación devuelve lo que yo le dije; los fallos que merece la pena cazar son un upstream que cambia de forma, y ningún mock ha cazado jamás uno.
npm run adversarial es el que encuentra cosas. Apunta al endpoint de metadatos de la nube, lanza hostnames hostiles, tipos equivocados, dominios de 4000 caracteres y tramas de protocolo malformadas contra el servidor desplegado, y trata una respuesta confiada a una pregunta que el servidor debería haber rechazado como el peor tipo de fallo. Encontró tres defectos reales en su primera ejecución.
Compruébalo sin confiar en este repositorio
npm run prove existe porque el hecho de que mis propios tests pasen demuestra muy poco a alguien que no los escribió. Llama al servidor desplegado a través del SDK oficial de cliente MCP, luego vuelve a recuperar cada hecho DNS desde un resolver diferente al que usó el servidor y vuelve a recuperar la página directamente desde la empresa, comparando campo por campo e imprimiendo cada URL de origen.
Tres formas más que no necesitan nada de aquí:
# 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 listY la versión que solo necesita un navegador. Abre ambos y compara:
https://doorknock-eight.vercel.app/v1/email-posture?domain=servicem8.com
https://dns.google/resolve?name=_dmarc.servicem8.com&type=TXT
Qué se rompió y qué hice al respecto
Seis defectos hasta ahora. Tres vinieron del script adversarial en su primera ejecución contra el despliegue, uno del script de verificación independiente y uno estaba en un test, no en el servidor.
1. Una negativa envuelta en un éxito. Preguntar al servidor por 169.254.169.254 o metadata.google.internal devolvía HTTP 200 con un objeto de resultado. Nada se filtró: el guardia de peticiones rechazó la solicitud correctamente, así que ninguna dirección interna fue contactada. Pero la llamada de investigación ejecuta la recuperación del sitio y las consultas DNS en paralelo, y la mitad DNS continuaba alegremente, de modo que quien llamaba recibía un 200 envolviendo una negativa. La defensa en profundidad había funcionado y el contrato de respuesta no. Las reglas de dirección ahora se ejecutan en normaliseDomain, en la puerta de entrada, de modo que toda la operación rechaza con 400.
2. Las redirecciones eran seguidas por el runtime, que no comprobaba nada. La primera versión pasaba redirect: 'follow' y validaba solo el primer salto. Un host público que respondiera 302 a una dirección interna habría atravesado el guardia sin problema. Las redirecciones ahora se siguen a mano, cinco como máximo, con cada salto re-resuelto y re-comprobado antes de darlo por tomado, y la cadena se devuelve en la respuesta, porque a dónde te envía un dominio es en sí mismo un hallazgo.
3. Se aceptaba un dominio de 4000 caracteres. No había ninguna comprobación de longitud en ninguna parte. El propio DNS se detiene en 253 caracteres y 63 por etiqueta, así que algo más largo no puede ser un nombre real. Ahora se rechaza con una explicación.
4. Los registros MX de igual prioridad volvían en orden diferente en cada llamada. Lo encontró el script de verificación independiente, que informó de una diferencia entre lo que decía el servidor y lo que decía un segundo resolver. Los registros eran idénticos; solo el orden difería, porque los resolvers rotan las respuestas de igual prioridad y la ordenación era solo por prioridad, que no es un orden total. Los empates ahora se rompen por nombre de host, de modo que los mismos registros producen siempre la misma salida.
5. Un test que fallaba por algo que nunca miraba. El script adversarial truncaba cada cuerpo de respuesta a 600 caracteres antes de comprobarlo, así que la aserción de señal desconocida buscaba un campo a unos cuatro kilobytes dentro de la respuesta, nunca lo veía e informaba de que el servidor estaba roto cuando el servidor estaba correcto. Eso costó más tiempo que cualquiera de los defectos reales. El cuerpo ahora se conserva entero y solo se trunca cuando se imprime. Un test que decide un aprobado o un suspenso a partir de algo que nunca llegó a leer de verdad es peor que no tener test, porque se cree.
6. La plataforma entrega al manejador un IncomingMessage de Node, no un Request web. Heredado del servidor anterior que construí de esta manera, y la razón por la que npm run smoke:mcp levanta un servidor node:http real y habla con él a través de un socket en lugar de construir objetos de petición en memoria. Un test que construye su propia forma de petición solo prueba esa forma.
Límites, expuestos con claridad
Lee solo la página de inicio. Una etiqueta cargada a través de un gestor de etiquetas o que vive en una página interna no se detecta, y la respuesta lo dice en lugar de dar a entender que la herramienta está ausente.
No sabe nada sobre plantilla, ingresos, propiedad o nombres de contacto, y no adivinará un dominio a partir del nombre de una empresa.
DKIM no se comprueba. El selector no puede descubrirse desde DNS, así que comprobarlo significa adivinar, y una suposición que falla se ve idéntica a un dominio sin DKIM en absoluto.
El guardia de direcciones resuelve el nombre, comprueba las direcciones y luego recupera por nombre, de modo que un cambio de registro DNS entre esos dos pasos no queda completamente cerrado. Fijar la conexión a la dirección comprobada necesita un agente que este runtime no expone. La mitigación es que ningún cuerpo de respuesta llega nunca al llamante en bruto, solo señales nombradas y coincidentes, así que un rebind exitoso no devuelve nada legible a quien lo intentó. Esto está escrito en el código además de aquí.
Cómo está organizado
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 mocksLicencia MIT.
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