Ventor MCP

Conecta agentes externos a las herramientas de Ventor

MCP permite que Codex, Cursor, Claude y otros clientes usen herramientas de Ventor con permisos controlados por token u OAuth.

STDIO

Alternativa para clientes locales que lanzan un proceso, como Claude Desktop o Cursor.

Streamable HTTP

Camino principal: una URL remota de Ventor y autenticación por Bearer token u OAuth.

OAuth

Requerido para conectores visuales privados como Claude.ai custom connectors.

Seccion 1

Qué es MCP en Ventor

MCP no es una URL REST. Es un servidor de herramientas que habla el protocolo estándar Model Context Protocol.

Ventor expone herramientas como buscar chats, leer mensajes, enviar mensajes, trabajar con plantillas, consultar tablas, ejecutar automatizaciones existentes, crear automatizaciones nuevas con VentorIA y leer métricas. El token define qué herramientas quedan habilitadas.

No hay un permiso genérico separado para MCP: cada tool exige el scope de su dominio. Varias capacidades también tienen endpoint REST, pero el constructor conversacional de VentorIA es deliberadamente MCP-only y usa automations:write sin publicar el JSON interno de una automatización.

Dónde va la llave

En Codex Streamable HTTP, el token se envía como header Bearer. En Claude, no pegues tokens: pega la URL remota y deja que OAuth abra Ventor para autorizar. En clientes STDIO, el token va en una variable de entorno:VENTOR_API_TOKEN. No va en el campo Name ni en Arguments.
Seccion 2

Streamable HTTP

Usa esta opción cuando el cliente MCP permite conectar por URL remota. Claude usa OAuth; Codex puede usar header Bearer.

CampoValorNotas
NameVentorNombre visible del servidor MCP.
Remote MCP URLhttps://api.ventorchat.com/api/mcpURL del servidor MCP remoto de Ventor.
Claude OAuth fieldsVacíosClaude descubre OAuth y abre Ventor para autorizar.
Codex Header keyAuthorizationSolo para clientes que permiten headers manuales.
Codex Header valueBearer vtr_live_...Token creado en Ventor > Avanzado > Integraciones.
Claude custom connector
Name: Ventor
Remote MCP server URL: https://api.ventorchat.com/api/mcp
OAuth Client ID: dejar vacío
OAuth Client Secret: dejar vacío
Codex Streamable HTTP
Name: Ventor
Transport: Streamable HTTP
Remote MCP server URL: https://api.ventorchat.com/api/mcp
Header:
Authorization = Bearer vtr_live_TU_TOKEN
Codex Streamable HTTP por config.toml
[mcp_servers.ventor]
url = "https://api.ventorchat.com/api/mcp"
bearer_token_env_var = "VENTOR_API_TOKEN"

Si el formulario no muestra autenticación

Si una plataforma solo pide URL y no permite Bearer token ni OAuth, no debe usarse para datos privados de Ventor. En ese caso, la ruta correcta es OAuth.
Seccion 3

STDIO

Usa esta opción cuando el cliente MCP lanza un comando local.

CampoValorNotas
NameVentorNombre visible del servidor MCP.
CommandnpxComando que lanza el adaptador MCP STDIO.
Arguments-y @ventor.ai/mcpInstala/ejecuta el paquete MCP de Ventor.
VENTOR_API_TOKENvtr_live_...Token creado en Ventor > Avanzado > Integraciones.
Valores para el formulario STDIO
Name: Ventor
Transport: STDIO
Command: npx
Arguments: -y @ventor.ai/mcp

Environment variables:
VENTOR_API_TOKEN=vtr_live_TU_TOKEN
~/.codex/config.toml para STDIO
[mcp_servers.ventor]
command = "npx"
args = ["-y", "@ventor.ai/mcp"]

[mcp_servers.ventor.env]
VENTOR_API_TOKEN = "vtr_live_TU_TOKEN"

Desarrollo local

Para trabajar sobre el adaptador sin instalar la versión publicada, apunta directamente al archivo del repositorio.

Config local de desarrollo
[mcp_servers.ventor]
command = "node"
args = ["/absolute/path/to/ai-bot-back/ventor-mcp/bin/ventor-mcp.js"]

[mcp_servers.ventor.env]
VENTOR_API_TOKEN = "vtr_live_TU_TOKEN"
VENTOR_API_BASE_URL = "https://api.ventorchat.com"

Claude.ai custom connector

En Claude usa https://api.ventorchat.com/api/mcp como Remote MCP server URL y deja vacíos OAuth Client ID y OAuth Client Secret. Claude descubrirá los endpoints OAuth de Ventor y abrirá la pantalla de autorización.
Seccion 4

Herramientas disponibles

Las herramientas se habilitan según los permisos del token.

ToolUso
ventor_get_capabilitiesDescubre reglas, recursos y los channelId asociados a cada número conectado.
ventor_search_chatsBusca o lista conversaciones, incluido el estado activo o pausado del asistente.
ventor_get_chat_filter_optionsDescubre canales, etiquetas, asignaciones y filtros publicitarios disponibles para buscar chats.
ventor_list_ad_referralsAgrupa los primeros contactos atribuidos a anuncios y muestra su conversión por etiquetas.
ventor_list_funnelsLista los embudos y etapas actuales para obtener un funnelUuid válido.
ventor_get_crm_funnel_reportDevuelve conteos por etiquetas o etapas actuales, con cohortes precisas por primer contacto, último mensaje o actividad durante un rango.
ventor_get_funnel_stage_historyCuenta entradas, salidas y movimientos reales por etapa, con cobertura histórica explícita desde el watermark.
ventor_resume_assistant_in_chatsReactiva el asistente en chats pausados sin enviar mensajes. Requiere chats:write.
ventor_read_chat_messagesLee mensajes de una conversación.
ventor_send_messageEnvía un mensaje visible al cliente en un chat existente.
ventor_add_assistant_contextAgrega datos temporales al contexto interno sin enviar un mensaje ni disparar una respuesta. Requiere assistant:write.
ventor_get_product_schemaDevuelve las columnas y estructura del catálogo Productos.
ventor_search_productsBusca productos del catálogo.
ventor_upsert_productsCrea o actualiza hasta 100 productos. Requiere products:write.
ventor_inspect_product_sales_configurationReúne configuración, auditoría del catálogo y automatizaciones sin modificar nada.
ventor_audit_product_search_catalogAudita cobertura, consistencia y oportunidades de enriquecimiento del catálogo sin modificar productos.
ventor_preview_product_catalog_enrichmentPrevisualiza adiciones seguras a etiquetas y campos existentes.
ventor_apply_product_catalog_enrichmentAplica el mismo preview después de aprobación explícita y rechaza propuestas obsoletas.
ventor_list_templatesLista plantillas visibles.
ventor_create_templateCrea o actualiza una plantilla.
ventor_send_templateEnvía una plantilla aprobada por chatUuid o phoneNumber.
ventor_create_campaignCrea y ejecuta un envío masivo.
ventor_get_campaign_statusConsulta el estado de una campaña.
ventor_list_tablesLista tablas disponibles.
ventor_create_tableCrea una tabla de negocio con columnas tipadas y asociación opcional por chat.
ventor_update_tableActualiza la estructura y configuración de una tabla existente.
ventor_query_tableConsulta filas de una tabla.
ventor_upsert_table_rowsCrea o actualiza filas.
ventor_build_automationDiseña una automatización nueva con VentorIA en lenguaje natural. Requiere automations:write.
ventor_edit_automationDiagnostica y prepara cambios parciales con el runner interno de VentorIA. Requiere automations:read y automations:write.
ventor_confirm_automationGuarda la última creación o edición después de la aprobación explícita del usuario.
ventor_list_automationsLista automatizaciones ejecutables.
ventor_get_automation_required_paramsDevuelve los parámetros obligatorios antes de ejecutar una automatización por API.
ventor_run_automationEjecuta una automatización existente.
ventor_get_automation_runConsulta historial o detalle de ejecución.
ventor_get_metricsLee métricas de chats.
ventor_get_assistant_configLee la configuración vigente del asistente y su configVersion.
ventor_test_assistant_conversationPrueba una conversación en modo seguro sin enviar mensajes reales ni escribir en aplicaciones externas.
ventor_preview_assistant_config_updatePrevisualiza cambios de configuración y los ajustes que aplicaría la plataforma.
ventor_update_assistant_configGuarda una configuración completa con control de concurrencia mediante expectedConfigVersion.

Reportes de embudos y etiquetas por fecha

Para un reporte agregado usa primero ventor_get_crm_funnel_report. Si necesitas un embudo concreto, obtén su funnelUuid con ventor_list_funnels; si lo omites, el reporte incluye las etiquetas independientes y todos los embudos.

Elige dateBasis según la pregunta: first_contact para cuándo ingresó el lead, last_message para el último mensaje del chat o message_activity para cualquier mensaje dentro del periodo. Usa fromDay/toDay para días calendario inclusivos y una zona IANA; usa from/to para instantes ISO, donde el final es exclusivo. No mezcles ambos estilos.

Los conteos representan la etapa actual de los chats que forman la cohorte; no demuestran que hayan cambiado de etapa durante esas fechas. Los detalles de clientes se omiten por defecto. Al usar includeClients: true, el límite es 200 por página global y los conteos siguen siendo completos. Para continuar, envía clientPage.nextCursor como clientCursor con los mismos filtros hasta recibir null; las listas por etapa son el subconjunto de esa página.

Si la pregunta es cuántos entraron, salieron o se movieron entre etapas durante el periodo, usa ventor_get_funnel_stage_history. Esta herramienta consulta eventos reales y devuelve historyAvailableFrom, coverage.complete y coverage.reason, además de asOf y coverage.ongoing. El historial se captura hacia adelante: ningún asistente debe presentar como completo un rango anterior al watermark ni un día que todavía no terminó. Los movimientos ambiguos se cuentan sin inventar una transición.

Cohortes del CRM con fechas precisas
// Leads que ingresaron del 1 al 7 de agosto y su etapa actual
ventor_get_crm_funnel_report({
  "funnelUuid": "embudo_ventas_uuid",
  "dateBasis": "first_contact",
  "fromDay": "2026-08-01",
  "toDay": "2026-08-07",
  "timezone": "America/Lima",
  "includeClients": false
})

// Actividad en instantes exactos: el final es exclusivo [from,to)
ventor_get_crm_funnel_report({
  "dateBasis": "message_activity",
  "from": "2026-08-01T00:00:00-05:00",
  "to": "2026-08-08T00:00:00-05:00",
  "canal": "whatsapp",
  "includeClients": true,
  "clientLimit": 100
})

// Movimientos reales del 1 al 7 de agosto (toDay es inclusivo)
ventor_get_funnel_stage_history({
  "funnelUuid": "00000000-0000-4000-8000-000000000001",
  "fromDay": "2026-08-01",
  "toDay": "2026-08-07",
  "timezone": "America/Lima"
})

Crear o actualizar productos por MCP

Usa ventor_get_product_schema para descubrir las columnas del catálogo y luego ventor_upsert_products. El agente puede cargar 50 inmuebles en una sola llamada sin pedir acceso de escritura al resto de tablas.

Carga de productos
// 1. Descubre las columnas reales del catálogo
ventor_get_product_schema({})

// 2. Crea o actualiza hasta 100 productos en una llamada
ventor_upsert_products({
  "products": [
    {
      "fields": [
        { "columnName": "nombre", "value": "Departamento en Miraflores" },
        { "columnName": "descripcion", "value": "2 dormitorios, 85 m² y cochera" },
        { "columnName": "currency", "value": "USD" },
        { "columnName": "precio", "value": 185000 }
      ]
    },
    {
      "fields": [
        { "columnName": "nombre", "value": "Casa en La Molina" },
        { "columnName": "currency", "value": "USD" },
        { "columnName": "precio", "value": 420000 }
      ]
    }
  ]
})

Configurar recomendaciones y cross-selling

Antes de cambiar instrucciones, criterios de recomendación o datos de productos, usa ventor_inspect_product_sales_configuration. La inspección combina las fuentes de verdad del asistente, la auditoría del catálogo, el flujo de compra derivado y el inventario de automatizaciones para detectar contradicciones, relaciones sin evidencia y productos sin página de compra.

El negocio describe en lenguaje natural cómo quiere vender. El MCP conserva esa regla en las instrucciones y, si cambia dónde termina la compra, compila internamente solo ese canal en la misma actualización. No le pide al usuario estados, modos ni banderas técnicas; el backend deriva el registro de interés, la reserva de stock, los datos de checkout y la protección del enlace.

El enriquecimiento masivo nunca reemplaza nombre, identidad, precio, stock, disponibilidad, imágenes, URLs ni variantes. Primero llama ventor_preview_product_catalog_enrichment, muestra el resultado y espera una aprobación explícita. Después llama ventor_apply_product_catalog_enrichment con los mismos cambios y el previewToken. Si el catálogo cambió, el backend exige una nueva previsualización.

Por defecto, pulsar Lo quiero confirma interés en el producto principal, pero no acepta ver relacionados. Si el negocio quiere preguntar primero, conserva esa oferta y la espera de un sí explícito en instructions, sin configurar productRecommendationPolicy.onProductSelected.

Solo si el negocio indica expresamente que debe mostrarlos de inmediato sin volver a preguntar, configura el disparador ejecutable en productRecommendationPolicy.onProductSelected. El backend fuerza una sola búsqueda relacionada y conserva las validaciones de relación, estado, stock y límite.

Diagnóstico y enriquecimiento con confirmación
// 1. Reúne configuración, catálogo y automatizaciones sin modificar nada
ventor_inspect_product_sales_configuration({
  "desiredTags": [
    { "tag": "impresora", "aliases": ["equipo de impresión"] },
    { "tag": "consumible", "aliases": ["tinta", "tóner"] }
  ]
})

// 2. Previsualiza únicamente adiciones sustentadas
ventor_preview_product_catalog_enrichment({
  "changes": [
    {
      "rowId": 2107,
      "confidence": "high",
      "evidence": ["Tipo de producto: Impresora"],
      "addTags": ["impresora"],
      "fields": [
        {
          "name": "tipo_producto",
          "mode": "fill_if_empty",
          "value": "impresora"
        }
      ]
    }
  ]
})

// 3. Muestra el preview y espera aprobación explícita.
// Luego usa exactamente los mismos changes y el previewToken recibido:
ventor_apply_product_catalog_enrichment({
  "changes": [/* mismos cambios previsualizados */],
  "previewToken": "preview_token_de_64_caracteres",
  "confirmed": true
})

Crear y editar automatizaciones con VentorIA

Usa ventor_build_automation para describir el objetivo en lenguaje natural mediante el parámetro message, no description. VentorIA puede responder con needs_input y una pregunta de negocio, o con needs_confirmation y un resumen. Conserva siempre el sessionId entre turnos.

Si el resumen incluye setupRequirements, muestra cada prerrequisito antes de confirmar. Por ejemplo, una automatización que usa plantillas o formularios de WhatsApp devolverá Conecta WhatsApp cuando el workspace no tenga un canal activo. La propuesta no crea conexiones ni realiza envíos.

Cuando el borrador esté listo, muestra su resumen al usuario. Solo después de recibir una aprobación explícita llama ventor_confirm_automation. Los turnos administrados de creación y edición consumen créditos de VentorIA; la confirmación únicamente guarda la propuesta preparada y no vuelve a llamar al modelo. Revisa también summary.supportingResources: esas tablas o plantillas auxiliares se crearán junto con la automatización.

Para una automatización existente usa ventor_edit_automation. El runner interno carga su definición y, si reportaste un fallo, consulta las ejecuciones necesarias para preparar una corrección puntual. El cliente MCP recibe únicamente el diagnóstico funcional o un resumen confirmable: no recibe JSON, operaciones internas, prompts, credenciales ni logs crudos.

Si Claude u otro cliente ya estaba conectado antes de habilitar este permiso, vuelve a conectarlo para que el consentimiento OAuth incluya automations:write y, para editar, automations:read. Los tokens existentes conservan únicamente los permisos aprobados originalmente.

Creación conversacional con confirmación
// 1. Describe el objetivo en lenguaje natural
ventor_build_automation({
  "message": "Cuando ingrese un lead de Lima, avisa al equipo comercial",
  "idempotencyKey": "crear-aviso-leads-lima-01"
})

// Si status = "needs_input", pregunta al usuario y continúa la misma sesión
ventor_build_automation({
  "sessionId": "session_uuid",
  "message": "El aviso debe llegar al equipo comercial",
  "idempotencyKey": "crear-aviso-leads-lima-02"
})

// Si status = "needs_confirmation", muestra summary y espera un sí explícito
ventor_confirm_automation({
  "sessionId": "session_uuid",
  "confirmationId": "confirmation_uuid"
})

// Si devuelve needs_setup, solo con autorización del usuario puedes guardarla
// inactiva para completar luego sus conexiones desde Ventor:
ventor_confirm_automation({
  "sessionId": "session_uuid",
  "confirmationId": "confirmation_uuid",
  "saveAsDraft": true
})
Diagnóstico y edición parcial con confirmación
// Diagnostica y prepara un cambio puntual sin recibir el JSON ni los logs
ventor_edit_automation({
  "automationUuid": "automation_uuid",
  "message": "Revisa las ejecuciones fallidas y corrige solo el paso responsable",
  "idempotencyKey": "corregir-automatizacion-01"
})

// Si status = "needs_input", responde en la misma sesión y automatización
ventor_edit_automation({
  "automationUuid": "automation_uuid",
  "sessionId": "session_uuid",
  "message": "Debe reintentar una vez y luego avisar al equipo",
  "idempotencyKey": "corregir-automatizacion-02"
})

// Si status = "needs_confirmation", muestra summary y espera aprobación
ventor_confirm_automation({
  "sessionId": "session_uuid",
  "confirmationId": "confirmation_uuid"
})

El JSON interno no es parte del contrato

El MCP devuelve preguntas de negocio, diagnósticos funcionales, resúmenes y referencias opacas. No devuelve prompts, schemas, pasos internos, logs crudos ni credenciales. Para ejecutar una automatización existente usa ventor_run_automation; editarla y ejecutarla son operaciones separadas.

Datos relacionados y contexto temporal

Para pagos, pedidos, citas u otros datos por cliente que deban mantenerse actualizados, usa una tabla con chatAssociationEnabled: true y vincula cada fila con chatUuid. ventor_get_capabilities y ventor_list_tables indican assistantReadable: true cuando el asistente del negocio puede consultarla. La lectura siempre queda limitada al chat actual.

Para un resultado puntual ya obtenido por una API, usa ventor_add_assistant_context. No envía nada al cliente y tampoco dispara una respuesta por sí solo: deja el dato disponible para la próxima ejecución del asistente. ventor_send_message siempre es visible.

Dentro de una automatización que atiende el turno actual, el patrón equivalente es consultar la API y pasar su resultado a send_message con mode: assistant y destino {{ChatId}}. Si el dato debe conservarse, actualiza también la tabla relacionada.

Datos duraderos y contexto temporal
// Datos duraderos: vincula cada registro al chat
ventor_upsert_table_rows({
  "tableUuid": "tabla_pagos_uuid",
  "rows": [
    {
      "chatUuid": "chat_uuid",
      "cells": [
        { "columnName": "pago_id", "value": "P-1042" },
        { "columnName": "estado", "value": "confirmado" },
        { "columnName": "monto", "value": 149.9 }
      ]
    }
  ]
})

// Dato temporal: contexto invisible para la próxima ejecución del asistente
ventor_add_assistant_context({
  "chatUuid": "chat_uuid",
  "source": "API de disponibilidad",
  "context": "La sede Centro tiene 2 cupos disponibles hoy a las 17:00."
})

Reactivar el asistente en chats pausados

Busca primero con assistantStatus: "paused" y luego usa ventor_resume_assistant_in_chats. No uses ventor_send_message, no edites las instrucciones y no envíes resume_bot: esa cadena no es un comando.

Flujo seguro de reactivación
// 1. Verifica primero los chats pausados
ventor_search_chats({
  "assistantStatus": "paused",
  "limit": 50
})

// 2. Reactiva por estado interno, sin enviar mensajes
ventor_resume_assistant_in_chats({
  "scope": "all_paused",
  "allMatching": true,
  "maxChats": 1000
})

Enviar plantilla por MCP

ventor_send_template acepta chatUuid para conversaciones existentes o phoneNumber para iniciar el envío directo por WhatsApp. Con chatUuid, Ventor usa siempre el número asociado al chat. Con phoneNumber, consulta primero ventor_get_capabilities para relacionar cada channelId con su número y ventor_list_templates para confirmar que la plantilla esté aprobada en ese canal.

No adivinar el número de origen

Si después de filtrar por canales activos y aprobación queda una sola opción, el agente puede usarla automáticamente. Si quedan dos o más y el usuario no indicó cuál usar, debe preguntar antes de enviar. Para campañas se aplica la misma regla.
Argumentos de ventor_send_template
// 1. Antes de un envío a teléfono nuevo, descubre los WhatsApp conectados
ventor_get_capabilities({})
// resources.channels:
// [{ channelId: 45, type: "whatsapp", displayName: "Ventas", phoneNumber: "51911111111", canSendOfficialWhatsapp: true }]

// 2. Verifica que la plantilla esté aprobada para ese channelId
ventor_list_templates({})
// approvedChannelIds: [45]

// Chat existente: no envíes channelId; Ventor usa el WhatsApp del chat
ventor_send_template({
  "templateId": 123,
  "chatUuid": "chat_uuid",
  "variables": [
    { "name": "nombre", "value": "María" },
    { "name": "pedido", "value": "A-1042" }
  ]
})

// Número nuevo: indica el channelId elegido y aprobado
ventor_send_template({
  "templateId": 123,
  "phoneNumber": "51999999999",
  "channelId": 45,
  "variables": [
    { "name": "nombre", "value": "María" },
    { "name": "pedido", "value": "A-1042" }
  ]
})
Seccion 5

Estado de compatibilidad

Streamable HTTP y OAuth ya están implementados; quedan las validaciones de cliente y la distribución STDIO.

1

Streamable HTTP — operativo

/api/mcp expone el servidor remoto mediante una URL fija de Ventor.
2

OAuth remoto — implementado

Incluye discovery, Dynamic Client Registration, PKCE, consentimiento, token exchange y refresh.
3

Claude.ai y Claude Code — validación E2E pendiente

Falta registrar una conexión real y verificar consentimiento, tools/list y una ejecución completa en cada cliente.
4

@ventor.ai/mcp — publicado

La versión pública se instala desde npm en clientes que solo soportan STDIO local.