Generect MCP
Generect MCP conecta tu base de datos de leads en vivo directamente a modelos de IA como OpenAI o Claude sin exportaciones ni demoras. Transmite datos de contacto enriquecidos y actualizados (cargos, firmografía, señales) directamente a los prompts para que los LLMs puedan personalizar, puntuar y recomendar leads automáticamente en tiempo real.
Documentación
Servidor MCP de Generect API
Datos de empresas y leads B2B para agentes de IA: búsqueda, vista previa, enriquecimiento, consulta de correos electrónicos y teléfonos a través de la API de Generect.
Diseñado para que un agente pueda trabajar sin gastar el saldo del cliente: dimensionar una audiencia es gratis, cada herramienta indica de antemano si tiene costo, y cada respuesta informa lo que realmente se cobró.
Obtén tu clave de API
Regístrate y obtén tu clave de API en https://app.generect.com
Servidor MCP remoto (OAuth - Recomendado)
Este servidor MCP implementa la autorización OAuth 2.1 según lo especificado por el Protocolo de Contexto de Modelo.
Usa nuestro servidor MCP alojado con cualquier cliente MCP compatible con OAuth:
{
"mcpServers": {
"generect": {
"url": "https://mcp.generect.com/mcp",
"type": "http"
}
}
}
Cuando te conectes por primera vez, el cliente iniciará un flujo OAuth:
- Serás redirigido a la página de autorización
- Ingresa tu token de API de Generect desde app.generect.com
- Autoriza al cliente para acceder a tu API
- El cliente recibe un token de acceso y ahora puede usar las herramientas MCP
Endpoints OAuth
| Endpoint | Descripción |
|---|---|
/.well-known/oauth-protected-resource | Metadatos de recurso protegido (RFC 9728) |
/.well-known/oauth-authorization-server | Metadatos del servidor de autorización (RFC 8414) |
/.well-known/jwks.json | Conjunto de claves JSON Web para verificación de tokens |
/oauth/authorize | Endpoint de autorización (inicio de sesión + consentimiento) |
/oauth/token | Endpoint de token |
/oauth/register | Registro dinámico de clientes (RFC 7591) |
Clave de API directa (sin OAuth)
Si tu cliente MCP no puede completar el flujo OAuth, puedes pasar la clave de API directamente mediante el encabezado Authorization. El servidor acepta cualquiera de:
Authorization: YOUR_API_KEY
Authorization: Bearer YOUR_API_KEY
Authorization: Token YOUR_API_KEY
Authorization: Bearer Token YOUR_API_KEY (legacy)
Ejemplo para mcp-remote:
{
"mcpServers": {
"generect": {
"command": "mcp-remote",
"args": [
"https://mcp.generect.com/mcp",
"--header",
"Authorization: Bearer YOUR_API_KEY"
]
}
}
}
Instalación local (alternativa)
Para desarrollo local o cuando no se necesita OAuth:
-
Requisitos: Node >= 18
-
Configura el entorno:
GENERECT_API_BASE=https://api.generect.com
GENERECT_API_KEY=Token <api-key>
GENERECT_TIMEOUT_MS=300000
JWT_SIGNING_KEY=<your-secret-key-for-jwt-signing>
TOKEN_ENCRYPTION_KEY=<32-byte-hex-key-for-token-encryption>
- Desarrollo local (opcional)
npm install
npm run dev:http
- Compilar e iniciar (servidor stdio)
npm run build && npm start
Registro de eventos
El servidor emite una línea de registro JSON estructurado por evento en stderr (stdout está reservado para el protocolo MCP stdio). El registro de metadatos está activado por defecto; establece MCP_LOG=0 para desactivarlo por completo.
Privacidad: los payloads están redactados por defecto. Los payloads de solicitud/respuesta pueden contener datos personales de prospectos (nombres, dominios de empresas, correos generados). Por defecto, estos valores no se registran textualmente: cada uno se reduce a un marcador de forma no identificable (p. ej., "first_name": "<str:4>"), para que puedas ver qué campos se enviaron sin registrar los datos en sí. Establece MCP_LOG_PAYLOADS=1 para registrar payloads textualmente, pensado para depuración de corta duración, con el consentimiento del propietario de los datos.
Eventos:
event | Cuándo | Campos clave |
|---|---|---|
tool_call | El LLM invoca una herramienta | reqId, tool, input (redactado a menos que MCP_LOG_PAYLOADS=1) |
api_request | Llamada saliente a la API de Generect | url, method, body (redactado a menos que MCP_LOG_PAYLOADS=1; nunca el token) |
api_response | La API de Generect respondió | url, status, ms |
tool_result | Resultado devuelto al LLM | reqId, tool, ms, output (redactado a menos que MCP_LOG_PAYLOADS=1) |
tool_error / api_error | Fallo | reqId/url, error, ms |
reqId correlaciona un tool_call con su tool_result. Establece MCP_DEBUG=1 para obtener salida adicional detallada.
El servidor alojado se ejecuta bajo PM2 (no Docker). Consulta los registros en el host con:
pm2 logs generect-mcp # live
pm2 logs generect-mcp --err # errors only
grep tool_call ~/.pm2/logs/generect-mcp-out.log # only LLM tool inputs
Modo de prueba
La API de Generect selecciona el modo real o de prueba según la clave, no la URL, por lo que este servidor no necesita una implementación separada ni una herramienta adicional. Pega una clave de prueba (test_…, creada en app.generect.com/settings/api) en la misma configuración y cada herramienta responderá con datos ficticios, a la velocidad del endpoint real, mostrando el precio que habría costado la llamada real, sin cobrar nada.
{
"mcpServers": {
"generect": {
"command": "mcp-remote",
"args": ["https://mcp.generect.com/mcp", "--header", "Authorization: Bearer test_YOUR_TEST_KEY"]
}
}
}
Cada resultado de una clave de prueba incluye test_mode: true y un aviso que indica al modelo que las personas son ficticias. Eso no es decoración. Un agente que recibe doce prospectos inventados sin marcador los resumirá como doce prospectos, y la persona que lee el resumen no tiene forma de saberlo: el fallo más probable del modo de prueba en un canal de agente es un informe confiado sobre personas que no existen. El marcador se agrega de forma centralizada, por lo que ninguna herramienta puede olvidarlo.
Consulta Modo de prueba para conocer las entradas mágicas que fuerzan un 402, un 429 o un tiempo de espera bajo demanda.
Herramientas
Cada herramienta indica en su propia descripción si es gratuita o facturable, y cada respuesta incluye un bloque cost con el importe que la API realmente cobró. Las herramientas aceptan timeout_ms.
Gratuitas: comienza aquí
| Herramienta | Qué hace |
|---|---|
count_leads | Cuántos leads coinciden con un ICP y cuánto cuesta el siguiente paso a tus tarifas. Ejecútala antes de search_leads. |
count_companies | Lo mismo, para empresas. |
get_balance | Saldo, precios reales por operación de esta cuenta, más include_usage opcional (gasto por operación) y include_token_analytics (qué token hizo qué llamadas). |
get_bulk_job | Consulta un trabajo por lotes (el trabajo se facturó al enviarlo). |
manage_webhooks | Listar/crear/actualizar/eliminar/probar endpoints de webhook. |
health | Verificación de actividad y credenciales contra un endpoint gratuito. Seguro para monitores. |
Facturables
| Herramienta | Facturado |
|---|---|
search_leads | por fila devuelta |
search_companies | por fila devuelta |
preview_leads | por fila devuelta (la forma más económica de ver personas reales); count_only: true es gratuita y es una segunda opinión sobre count_leads, ya que la vista previa y la búsqueda en caché son índices diferentes |
enrich_lead / get_lead_by_url | por registro encontrado |
resolve_profile | por perfil resuelto: la llamada más económica aquí; una referencia no resoluble es gratuita |
enrich_company | por registro encontrado |
generate_email | por correo electrónico válido encontrado |
validate_email | por correo enviado: cada dirección, sea cual sea el veredicto |
find_phone | por teléfono encontrado: la operación más cara aquí |
start_bulk_job | por registro, reservado al momento del envío |
database vs realtime
Cada búsqueda/enriquecimiento se ejecuta contra la base de datos en caché (subsegundo, más económica, recuentos gratuitos) o una búsqueda en vivo de LinkedIn (5–60 s, más cara, recuentos facturables, todos los filtros). Las herramientas aceptan mode: "auto" | "database" | "realtime":
auto(predeterminado) intenta la vía económica y escala solo si la API indica que un filtro que pasaste no existe allí. La escalada se informa en la respuesta, nunca en silencio.databasenunca escala: si un filtro no es compatible, obtienes un error, no una factura mayor.- El recuento es la excepción: un recuento en tiempo real cuesta dinero, por lo que
count_leads/count_companiesse niegan a ejecutarlo a menos que solicitesmode: "realtime"explícitamente. En su lugar, te indican qué filtros forzaron esa elección.
Vocabularios de filtros: léelos, no adivines
Medidos contra la API en vivo, los endpoints de búsqueda v1 validan sus filtros de forma inconsistente:
| Filtro | Valor desconocido |
|---|---|
locations, company_headcounts, company_types | HTTP 400 que nombra el campo |
company_industries, seniorities | aceptado: 0 resultados, $0, sin error |
Esa segunda fila es la peligrosa. company_industries: ["Fintech"] no es una industria de LinkedIn y devuelve un recuento de cero perfectamente exitoso, que se lee exactamente como "esta audiencia no existe".
Por lo tanto, el servidor verifica estos valores por sí mismo, antes de enviar cualquier cosa:
- una industria, un rango de tamaño de empresa o un tipo de empresa desconocido se rechaza localmente con los nombres válidos más cercanos (
Fintech→Financial Services,50-200→51-200), y no se envía ni se cobra nada; - un valor simplemente mal escrito o con mayúsculas incorrectas se corrige (
software development→Software Development): la coincidencia es exacta, por lo que enviarlo tal como estaba escrito habría devuelto cero; - una antigüedad o función desconocida es una advertencia, no un rechazo: el motor sí coincide de forma flexible (
Ownerencuentra personas aunque la etiqueta canónica seaOwner / Partner); allow_unlisted_values: trueanula la verificación si la instantánea de este servidor se queda atrás de la API.
Los vocabularios completos se exponen como recursos, para que un cliente pueda leerlos una vez y dejar de adivinar:
generect://vocabulary/industries 434 names, with parents
generect://vocabulary/seniorities
generect://vocabulary/functions (realtime only)
generect://vocabulary/company-types
generect://vocabulary/headcounts
generect://vocabulary/follower-ranges (realtime only)
generect://account/pricing this account's real per-operation prices
generect://account/balance balance and month-to-date usage
Se regeneran a partir de los propios datos de filtros del backend con node scripts/gen-vocabulary.mjs <api_parser checkout>: nunca se editan a mano.
Prompts
Los prompts de flujo de trabajo se incluyen con el servidor y aparecen como comandos de barra en los clientes que los admiten: size_an_audience, build_prospect_list, enrich_my_list, spend_report. Cada uno comienza desde el paso gratuito.
Límite de gasto
Un límite de filas acota los resultados, no el dinero. Cualquier llamada cuyo peor caso supere MCP_MAX_SPEND_PER_CALL (predeterminado $5) se rechaza con la cifra exacta y debe repetirse con confirm_spend_usd establecido al menos en ese importe. Esto se verifica antes de que start_bulk_job envíe, porque un trabajo por lotes reserva todo su costo al momento del envío y no se puede deshacer.
Flujo seguro para el presupuesto
count_leads (free) → preview_leads (cheap) → search_leads (per row)
→ generate_email on the ids you kept
get_balance antes y después de un lote te da una cifra de gasto exacta para informar.
Habilidad del agente
Las herramientas dan a un agente la capacidad de llamar a Generect; una habilidad le da el procedimiento. skills/generect-lead-workflows documenta los flujos anteriores para que un agente autónomo los siga sin que se le indiquen cada vez:
npx skills add generect/generect_mcp --skill generect-lead-workflows
Consulta skills/README.md. Proceso de publicación y la lista completa de lugares donde debe aterrizar una versión: RELEASING.md.
Integración con Cursor (extracto de settings.json)
{
"mcpServers": {
"generect-liveapi": {
"command": "node",
"args": ["./node_modules/tsx/dist/cli.mjs", "src/server.ts"],
"env": {
"GENERECT_API_BASE": "https://api.generect.com",
"GENERECT_API_KEY": "Token YOUR_API_KEY",
"GENERECT_TIMEOUT_MS": "300000"
}
}
}
}
Configuración de Claude Desktop (MCP)
Agrega a ~/.claude/claude_desktop_config.json (o mediante UI → Servidores MCP). Recomendado: ejecutar mediante npx para que los usuarios no instalen nada globalmente.
{
"mcpServers": {
"generect-api": {
"command": "npx",
"args": ["-y", "generect-ultimate-mcp@latest"],
"env": {
"GENERECT_API_BASE": "https://api.generect.com",
"GENERECT_API_KEY": "Token YOUR_API_KEY",
"GENERECT_TIMEOUT_MS": "300000",
"MCP_DEBUG": "0"
}
}
}
}
Nota para macOS: si Claude muestra "spawn npx ENOENT" o inicia una versión anterior de Node mediante nvm, establece command en la ruta absoluta de npx y/o anula PATH:
{
"command": "/usr/local/bin/npx",
"env": { "PATH": "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin" }
}
Alternativa sin npx:
npm i -g generect-ultimate-mcp
Luego usa:
{ "command": "/usr/local/bin/generect-mcp", "args": [] }
Implementación (producción, PM2)
El servidor alojado (https://mcp.generect.com) se ejecuta bajo PM2 como mcp_user en el host, con nginx (TLS) al frente, definido por ecosystem.config.cjs.
Las implementaciones son automáticas. Una ejecución verde de ci en main activa deploy-prod.yml, que llega al host mediante SSH con una clave que puede ejecutar exactamente una cosa: deploy/remote-deploy.sh y verifica el endpoint público después. El script:
- solo lleva al host a la punta de
main(nunca a una confirmación anterior); - se niega a implementar sobre ediciones no confirmadas en el host, o a iniciar una segunda instancia de pm2;
- reinicia con el entorno que pm2 ya tiene (
reload, no--update-env); - revierte automáticamente a lo que estaba ejecutándose si la nueva compilación no aparece con la versión esperada en 60 s.
deploy/sandbox-test.sh ejercita todo eso contra una copia desechable del repositorio con su propio pm2: ejecútalo después de tocar el script de implementación. La configuración única del host es deploy/bootstrap-chronos.sh (como root).
Solo una instancia. El estado de OAuth (clientes registrados, códigos de autorización) y las sesiones MCP se mantienen en memoria, por lo que el servidor debe ejecutarse como una sola instancia. El escalado horizontal requiere un almacén compartido (p. ej., Redis) primero: consulta ecosystem.config.js.
Secretos requeridos (cierre ante fallos). En producción (NODE_ENV=production), el servidor se niega a iniciar a menos que JWT_SIGNING_KEY esté establecido en un valor fuerte y no predeterminado; nunca recurre a un valor predeterminado codificado ni a una clave efímera. TOKEN_ENCRYPTION_KEY, si se establece, debe tener exactamente 64 caracteres hexadecimales (32 bytes).
Docker
Docker es compatible para ejecuciones locales/alternativas. Compila localmente:
docker build -t ghcr.io/generect/generect_mcp:local .
Ejecuta el servidor en un contenedor (nota: se requieren los mismos secretos de producción: un valor predeterminado inseguro hará que el contenedor salga al inicio):
docker run --rm \
-e NODE_ENV=production \
-e GENERECT_API_BASE=https://api.generect.com \
-e GENERECT_API_KEY="Token YOUR_API_KEY" \
-e JWT_SIGNING_KEY="a-strong-random-secret" \
-e TOKEN_ENCRYPTION_KEY="0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef" \
-e OAUTH_BASE_URL=https://your-domain.com \
-p 3000:3000 \
ghcr.io/generect/generect_mcp:local
Remoto por SSH (avanzado)
Algunos clientes MCP permiten iniciar el servidor mediante SSH, usando stdio a través de la sesión SSH. Configuración de ejemplo:
{
"mcpServers": {
"generect-remote": {
"command": "ssh",
"args": [
"user@remote-host",
"-T",
"node",
"/opt/generect_mcp/dist/server.js"
],
"env": {
"GENERECT_API_BASE": "https://api.generect.com",
"GENERECT_API_KEY": "Token YOUR_API_KEY",
"GENERECT_TIMEOUT_MS": "300000"
}
}
}
}
Utilidades de prueba locales
Las tres usan por defecto solo llamadas gratuitas a la API — una prueba de humo nunca debería facturar silenciosamente a quien la ejecute.
- Verificación de salud (cuenta, libro de precios, recuento gratuito en caché):
npm run health -- <api-key>
- Qué filtros admite ahora mismo el índice gratuito en caché (solo recuentos gratuitos):
npm run probe -- <api-key>
- Llamar a las herramientas mediante un cliente MCP local. Herramientas gratuitas por defecto;
--paidañade una búsqueda de 3 filas y una consulta de correo electrónico, y la ejecución imprime lo que ha gastado:
npm run mcp:client -- <api-key>
npm run mcp:client -- <api-key> --paid
Notas de seguridad
- Los tokens OAuth son JWT firmados por el servidor y contienen tu token de API cifrado
- El cifrado de tokens usa AES-256-GCM con una clave de
TOKEN_ENCRYPTION_KEY(o derivada deJWT_SIGNING_KEY) - Secretos con cierre ante fallos — en producción, el servidor se niega a arrancar si falta
JWT_SIGNING_KEYo si tiene un valor predeterminado conocido, y nunca publica material de clave simétrica en el JWKS - Tokens acotados y renovables — los tokens de acceso caducan (30 días por defecto,
ACCESS_TOKEN_TTL_SECONDS) y se renuevan mediante una concesiónrefresh_token; los tokens de refresco se rotan al usarse y se pueden revocar enPOST /oauth/revoke(RFC 7009). Los tokens emitidos antes de este cambio siguen siendo válidos (sin reautenticación forzada) - PKCE es obligatorio para todos los flujos de código de autorización (método S256) y se vuelve a comprobar tanto en el POST de consentimiento como en la redirección inicial — un código interceptado por una aplicación maliciosa que reclame el mismo esquema de URI es inútil sin el verificador
- Registro dinámico de clientes permite que cualquier cliente MCP se autorregistre, pero ahora está limitado por IP (
MCP_REGISTER_RATE_MAX, 60/hora por defecto) y el almacén de clientes está acotado (MCP_MAX_CLIENTS, 5000 por defecto, expulsión LRU que nunca elimina un cliente en uso) - URIs de redirección: abiertas por defecto, para que cualquier cliente pueda conectarse (
MCP_REDIRECT_POLICY=open). Se aceptan: cualquier URLhttps,httpsolo en direcciones de bucle local/privadas, y el esquema de URI de uso privado de una aplicación (cursor://…,vscode://…,com.example.app:/cb— RFC 8252 §7.1). Se rechazan independientemente de la política:httpen texto claro hacia un host público,#fragments, credenciales incrustadas, URIs excesivamente largas y esquemas ejecutables por el navegador (javascript:,data:,file:, …) — esa URI se navega desde nuestro propio origen, así que serían XSS. Las devoluciones de bucle local coinciden en todo excepto el puerto (RFC 8252 §7.3), ya que el listener de una aplicación nativa recibe uno efímero. EstableceMCP_REDIRECT_POLICY=strictpara volver a la lista de permitidos de primera parte (*.generect.com,claude.ai,linear.app, másMCP_ALLOWED_REDIRECT_DOMAINS/MCP_ALLOWED_REDIRECT_SCHEMES) - Obtención de metadatos protegida contra SSRF — el flujo del documento de metadatos del ID de cliente (
MCP_ENABLE_CIMD, activado por defecto) solo obtiene URLshttpsque se resuelven exclusivamente a IPs públicas, sin seguir redirecciones, con un tiempo de espera estricto y un límite de tamaño de respuesta (bloquea objetivos de bucle local / RFC1918 / enlace local / metadatos de nube) - La validación de tokens falla con cierre — si Generect no puede confirmar un token durante el inicio de sesión (error ascendente), el servidor se niega a emitir un token de acceso en lugar de asumir su validez
- Fijación de audiencia y algoritmo garantiza que los tokens solo se usen con este servidor MCP y solo mediante el algoritmo de firma esperado
Configuración (variables de entorno relevantes para la seguridad)
| Variable | Valor predeterminado | Efecto |
|---|---|---|
ACCESS_TOKEN_TTL_SECONDS | 2592000 (30d) | Vida útil del token de acceso |
REFRESH_TOKEN_TTL_SECONDS | 7776000 (90d) | Vida útil del token de refresco |
MCP_MAX_CLIENTS | 5000 | Límite del almacén de clientes DCR en memoria |
MCP_REGISTER_RATE_MAX | 60 | Máximo de llamadas /oauth/register por IP por ventana |
MCP_REGISTER_RATE_WINDOW_MS | 3600000 (1h) | Ventana de límite de velocidad |
MCP_ENABLE_CIMD | true | Permitir ID de cliente como URL de metadatos (protegido contra SSRF) |
MCP_REDIRECT_POLICY | open | open = cualquier cliente puede registrar su devolución de llamada; strict = solo lista de permitidos de primera parte |
MCP_ALLOWED_REDIRECT_DOMAINS | — | Hosts de redirección adicionales permitidos, solo strict (separados por comas) |
MCP_ALLOWED_REDIRECT_SCHEMES | — | Esquemas de URI de uso privado adicionales permitidos, solo strict (separados por comas, p. ej. cursor,vscode) |
MCP_ALLOW_ANY_HTTPS_REDIRECT | — | Heredado: abre devoluciones de llamada https bajo strict (implícito en open) |
- Privacidad de registros — las cargas útiles de prospectos se redactan de los registros por defecto (
MCP_LOG_PAYLOADS=1para optar por incluirlas)
Consentimiento intermediado: qué UI del producto aprueba la conexión
/oauth/authorize no pide contraseña. Deriva a una página del
producto donde el usuario ya ha iniciado sesión, y esa página publica un
token de API recién emitido de vuelta a /oauth/broker. Dos variables de entorno deciden qué página es,
y deben cambiarse juntas:
| Variable | Efecto |
|---|---|
MCP_CONSENT_URL | Dónde /oauth/authorize redirige al usuario (…/authorize/mcp?handoff=…&mcp=…) |
MCP_CONSENT_ORIGIN | El único Origin autorizado para llamar a /oauth/broker. Por defecto es el origen de MCP_CONSENT_URL — pero producción lo establece explícitamente en .env, así que el valor predeterminado no te salva |
Mover el consentimiento de un host a otro editando solo MCP_CONSENT_URL
hace que el intermediario rechace la nueva página con
403 {"error":"forbidden","error_description":"Origin not allowed to broker consent."},
después de que el usuario ya haya hecho clic en Aprobar. Cambia ambas líneas y luego demuéstralo:
# expect 400 invalid_handoff (origin accepted), NOT 403 forbidden
curl -s -X POST https://mcp.generect.com/oauth/broker \
-H 'Content-Type: application/json' -H "Origin: <the new consent origin>" \
-d '{"handoff":"nonexistent-probe","deny":true}'
CORS no es el control aquí — el servidor refleja cualquier Origin (autenticación bearer,
sin cookies), así que un preflight que funcione no prueba nada sobre el intermediario.
Despliegue en producción
mcp.generect.com ejecuta pm2, no Docker (.github/workflows/deploy-prod.yml
es la ruta Docker sin usar). Instancia única, siempre: el estado OAuth y las sesiones MCP
viven en memoria, así que un segundo worker dividiría el cerebro de la autenticación.
ssh root@chronos # 65.21.69.164
su - mcp_user && source ~/.nvm/nvm.sh # node via nvm
cd ~/generect_mcp
cp -r dist dist.bak.$(date +%H%M%S) # what previous deploys did; keeps a rollback
git pull && npm ci && npm run build
$EDITOR .env # consent vars, redirect policy
pm2 reload generect-mcp && pm2 list # version column should show the new one
Luego verifica desde fuera de la máquina — que pm2 list muestre online no es evidencia
de que el nuevo comportamiento esté activo:
curl -s https://mcp.generect.com/health
curl -s -o /dev/null -w '%{redirect_url}\n' \
"https://mcp.generect.com/oauth/authorize?client_id=<id>&redirect_uri=…&response_type=code&code_challenge=…&code_challenge_method=S256"