Agentic Travel Recommendations Service
Servicio agéntico de recomendaciones de viajes
Este proyecto es una prueba de concepto en TypeScript y Node.js para un servicio de recomendaciones de viajes multiinquilino. Expone capacidades compartidas de recomendación a través de una API REST, un endpoint MCP de Streamable HTTP y una interfaz de línea de comandos.
Características principales
API REST para salud, perfiles de miembros y recomendaciones
Endpoint MCP de Streamable HTTP
Herramienta MCP:
get_member_profileHerramienta MCP:
get_recommendationsResolución autoritativa del inquilino derivada del miembro
Límites de recomendaciones específicos del socio
Exclusiones de categorías específicas del socio
Generación determinista de recomendaciones
Comportamiento de configuración del socio con cierre ante fallos
IDs de solicitud y registros JSON estructurados
Demostración mínima de CLI
Construcción Docker de varias etapas
Pruebas automatizadas
Arquitectura de un vistazo
REST / MCP / CLI
|
v
RecommendationService
|
v
MemberDataService
|
| member.partnerId
v
PartnerConfigurationService
|
v
CandidateGenerator
|
v
RecommendationPolicy
|
| exclusions then cap
v
Final RecommendationsLos llamadores proporcionan solo memberId; no seleccionan el partnerId autoritativo. El perfil del miembro determina la configuración del socio, y REST, MCP y CLI reutilizan la misma capa de negocio.
Inicio rápido
npm ci
npm run devEl servicio está disponible por defecto en http://localhost:3000.
Comprobación de tipos
npm run typecheck
npm run typecheck:test
npm run typecheck:allPruebas
npm testLa base verificada actual es de 46 pruebas superadas en 6 archivos.
Compilación de producción
npm run build
npm startAPI REST
GET /health
GET /api/members/:memberId
GET /api/recommendations/:memberIdEjemplos de solicitudes:
curl http://localhost:3000/api/members/MEMBER-001
curl http://localhost:3000/api/recommendations/MEMBER-001MCP
El servidor MCP se expone a través de:
POST /mcpProporciona estas herramientas:
get_member_profileget_recommendations
Ambas herramientas aceptan solo el identificador del miembro:
{
"memberId": "MEMBER-001"
}La implementación utiliza el transporte Streamable HTTP del SDK oficial @modelcontextprotocol/sdk. El llamador no proporciona partnerId; este se resuelve a partir del perfil autoritativo del miembro.
CLI
npm run cli -- MEMBER-001Miembros de demostración:
MEMBER-001→BANK_AMEMBER-002→BANK_BMEMBER-003→CREDIT_UNION_C
Docker
docker build -t agentic-travel-recommendations .
docker run --rm -p 3000:3000 agentic-travel-recommendationsLa imagen utiliza una compilación de varias etapas, un runtime de Node 24 y un usuario de runtime no root. El servidor HTTP gestiona las señales de apagado ordenado.
Sección A — Arquitectura y compensaciones
Resumen de la arquitectura
El servicio es una aplicación TypeScript y Node.js sin estado que expone el mismo flujo de trabajo de recomendaciones a través de REST, MCP de Streamable HTTP y una CLI. Cada transporte valida su entrada y delega en el RecommendationService compartido; los manejadores de transporte no implementan la política del socio por sí mismos.
El flujo autoritativo del inquilino es:
memberId
→ MemberDataService
→ MemberProfile.partnerId
→ PartnerConfigurationService
→ CandidateGenerator
→ RecommendationPolicy
→ final recommendationsLos llamadores proporcionan memberId y nunca seleccionan el partnerId autoritativo. El perfil del miembro devuelto por MemberDataService determina qué configuración del socio se recupera. Ambos servicios ascendentes también correlacionan la identidad incrustada en una respuesta con la identidad solicitada, y RecommendationService realiza una comprobación adicional de identidad del socio antes de la generación.
La generación de candidatos es intencionadamente independiente de la política del socio. El generador determinista produce primero candidatos brutos a partir del perfil del miembro; la capa de política genérica elimina después los candidatos en excludedCategories y aplica recommendationCap, en ese orden. Solo se devuelven las recomendaciones resultantes. El Servicio de Datos del Miembro y el Servicio de Configuración del Socio están simulados (mocked) para esta prueba de concepto, y el acceso a la configuración del socio es de solo lectura.
Compensaciones de diseño
Corrección frente a disponibilidad. Si la configuración autoritativa del socio falta, no está disponible, no es válida según el esquema o no coincide la identidad, la solicitud falla de forma segura (fail closed). El servicio no sustituye permisos por defecto ni devuelve recomendaciones sin restricciones. Esto puede reducir la disponibilidad durante un fallo ascendente, pero evita que las recomendaciones escapen a la política correcta del inquilino.
Configuración actual frente a caché. La primera versión recupera la configuración del socio para cada solicitud de recomendación en lugar de añadir infraestructura de caché. Esto mantiene el comportamiento simple y asegura que cada solicitud exitosa use la política actual. Acepta latencia y carga ascendentes adicionales; una caché de corta duración es apropiada más adelante solo si el rendimiento medido justifica la compensación de consistencia.
Generación determinista frente a un LLM externo. La generación de candidatos es reproducible, comprobable, sin coste y operativamente predecible. Esto limita la sofisticación de la personalización, pero hace que el comportamiento de la política y los resultados de evaluación sean fáciles de verificar. Un futuro LLM o componente de clasificación podría reemplazar la generación de candidatos sin cambiar la aplicación determinista de la política.
Gestión de cambios en la configuración del socio
El Servicio de Configuración del Socio es una dependencia de solo lectura. Si un socio cambia su límite de recomendaciones de ilimitado a 3, o añade cruise a excludedCategories, el servicio de recomendaciones no necesita ningún cambio de código ni ninguna rama específica por inquilino. La siguiente solicitud exitosa lee la configuración actual y la lógica de política genérica aplica los nuevos valores de exclusión y límite.
Mientras la configuración siga siendo compatible con el esquema existente, la aplicación no requiere una nueva implementación. Si se introduce caché de configuración más adelante, debe tener un TTL intencionadamente corto o una estrategia de invalidación fiable, porque una configuración obsoleta podría violar temporalmente la política actual del socio.
Sección B — Preparación para producción y respuesta ante incidentes
Entrada del runbook de incidentes
Escenario: Un miembro informa de que el AI Concierge mostró una recomendación de crucero aunque su socio excluye los cruceros.
Identificar y correlacionar. Obtenga el ID de solicitud o correlación del informe cuando esté disponible y localice los registros estructurados correspondientes. Registre la
operation, elmemberId, elpartnerIdautoritativo una vez resuelto, elresultCodey el estado HTTP cuando corresponda. El historial de viajes y las cargas de recomendaciones no se registran intencionadamente, por lo que debe usar identificadores y metadatos de resultado para la correlación.Verificar el inquilino autoritativo. Recupere el miembro afectado a través de
MemberDataServicey confirme que elmemberIdsolicitado es igual almember.memberIddevuelto. Derive el inquilino solo a partir demember.partnerId. No confíe en un ID de socio proporcionado por un frontend, un llamador MCP, un parámetro de consulta o un informe de soporte.Verificar la configuración del socio. Recupere la configuración usando
member.partnerIdy confirme queconfiguration.partnerId === member.partnerId. InspeccioneexcludedCategoriesyrecommendationCap, y determine sicruiseestá excluido en la configuración autoritativa actual. La configuración faltante, no disponible, malformada o con identidad no coincidente debe hacer que el servicio falle de forma segura (fail closed) en lugar de usar valores por defecto permisivos.Reproducir el pipeline. Ejecute el miembro a través del mismo flujo de trabajo de recomendaciones. Un crucero en la salida bruta de
CandidateGeneratorno es en sí mismo un defecto porque la generación ignora deliberadamente la política del socio. Verifique queRecommendationPolicyprocesacandidatos brutos → eliminar categorías excluidas → aplicar límite de recomendaciones → recomendaciones finales, y confirme que los cruceros están ausentes del resultado final.Aislar la ubicación del fallo. Si los cruceros aparecen en los candidatos brutos pero no en las recomendaciones finales, la política está operando correctamente. Investigue una respuesta de cliente obsoleta, una respuesta asociada al miembro equivocado, otro consumidor o endpoint que omita el flujo de trabajo esperado, o una diferencia entre el momento del informe y la configuración actual. Si un crucero sobrevive a
RecommendationPolicy, inspeccione la comparación o normalización de categorías, el contenido e identidad de la configuración autoritativa, y los cambios o regresiones recientes de la política.Contener. Si no se puede establecer o reproducir de forma segura la política correcta del socio, falle de forma segura (fail closed) en lugar de devolver recomendaciones potencialmente no conformes. No intente modificar el Servicio de Configuración del Socio de solo lectura desde esta aplicación.
Corregir y verificar. Corrija el defecto en la capa responsable y añada una prueba de regresión que reproduzca el fallo exacto. Ejecute:
npm run typecheck:all npm test npm run buildVerifique el socio afectado, al menos un inquilino no afectado, el comportamiento REST y el comportamiento MCP cuando corresponda.
Seguimiento. Registre la causa raíz, el alcance del socio y miembro afectados, la ventana de impacto, la remediación, la cobertura de regresión y la acción preventiva.
Parte B2 — Pregunta de razonamiento requerida
Un asistente de codificación con IA podría plausiblemente producir una implementación que valide con Zod los registros ascendentes de miembros y socios pero que nunca correlacione las identidades devueltas con las identidades solicitadas. El código sería seguro en cuanto a tipos, las pruebas de validación de esquema y de camino feliz pasarían, y una revisión superficial vería una validación defensiva razonable. La falta de la invariante entre inquilinos seguiría creando un grave riesgo de política.
Por ejemplo, MEMBER-001 pertenece a BANK_A. RecommendationService solicita la configuración de BANK_A, pero un servicio ascendente con errores o mal enrutado devuelve una configuración de BANK_B completamente válida según el esquema, con un límite ilimitado y sin exclusiones de categorías. Zod acepta correctamente su forma, pero aplicar esa política a MEMBER-001 podría eludir las restricciones de BANK_A.
Detectaría esto con una prueba de regresión adversarial: solicitar BANK_A mientras un doble
Mantuve el RecommendationService compartido, el CandidateGenerator determinista, la RecommendationPolicy separada, la resolución de tenant derivada del miembro, el contrato de configuración de solo lectura y la lógica de negocio REST/MCP/CLI compartida. Esta estructura hace que la política de tenant sea comprobable de forma independiente y evita implementaciones de reglas específicas del transporte. También conservé intencionadamente la generación determinista en lugar de añadir una dependencia externa de LLM. La evaluación se centra en el diseño del servicio y la aplicación de políticas, y la salida reproducible es más fácil de probar, depurar y demostrar. Cada incremento se aceptó solo después de que su comportamiento coincidiera con los invariantes arquitectónicos y las comprobaciones se superaran.
Interacción 3 — Auditoría de producción y seguridad
Lo que pregunté
Una vez que la aplicación funcionó, le pedí a la IA que dejara de añadir funciones y auditará el repositorio desde las perspectivas de un ingeniero senior, un revisor de seguridad multi-tenant, un responsable de producción de guardia y un revisor de API REST/MCP.
Lo que proporcionó la IA
La auditoría reveló que las respuestas ascendentes válidas según el esquema no se correlacionaban originalmente con la identidad del miembro o socio solicitada. También descubrió que un JSON malformado podía fallar antes de que el middleware de ID de solicitud estableciera el contexto de la solicitud. Se sugirieron mejoras adicionales de menor prioridad.
Lo que mantuve, cambié o rechacé
Acepté ambos hallazgos de alto valor porque afectaban a la corrección del tenant y a las operaciones seguras. Para la correlación de identidad, la implementación ahora verifica que un memberId devuelto coincida con el miembro solicitado, que configuration.partnerId coincida con el member.partnerId autoritativo, y que RecommendationService repita la comprobación de identidad de configuración de forma defensiva. Las discrepancias fallan en modo cerrado, y las pruebas de regresión adversariales verifican que la generación de candidatos nunca comienza cuando no se puede establecer la configuración autoritativa.
Para el JSON malformado, el contexto de la solicitud y el ID de solicitud ahora se establecen antes del análisis. Los cuerpos no válidos reciben una respuesta estructurada 400 segura sin detalles del analizador, trazas de pila, rutas del sistema de archivos ni contenido bruto de la solicitud.
Diferí las ideas de menor prioridad, como las sesiones MCP persistentes, la infraestructura distribuida adicional y una observabilidad más avanzada, porque no eran necesarias para la prueba de concepto de cuatro semanas y aumentarían el alcance operativo. Evalué cada recomendación en función de los requisitos del encargo, la corrección del tenant, la capacidad de prueba, el riesgo operativo y el alcance de la entrega. El asistente ofreció opciones y ayuda con la implementación, pero yo revisé el razonamiento, seleccioné los cambios y los verifiqué mediante pruebas específicas y comprobaciones de extremo a extremo.
Primer paso de cuatro semanas
Lo que se publica primero
El objetivo de cuatro semanas es una primera prueba de concepto interna publicable. Demuestra el flujo de trabajo requerido con una aplicación segura de la política de tenant y los fundamentos operativos; no es una afirmación de que todas las capacidades necesarias para un despliegue amplio en producción estén completas.
Semana 1 — Fundamentos del servicio
Establecer la base del servicio TypeScript y Node.js.
Definir modelos de dominio, validación estricta de límites con Zod y errores tipados.
Añadir el contrato
MemberDataServicey la implementación mock.Añadir el contrato de solo lectura
PartnerConfigurationServicey la implementación mock.Establecer la resolución de tenant autoritativa derivada del miembro y la base inicial de pruebas unitarias.
Objetivo: Establecer límites seguros del servicio y la autoridad del tenant antes de implementar la lógica de recomendación.
Semana 2 — Flujo de trabajo de recomendación
Implementar el
CandidateGeneratordeterminista independientemente de las reglas del socio.Implementar
RecommendationPolicy, incluidas las exclusiones de categorías y los límites de recomendaciones.Aplicar el orden requerido: primero las exclusiones, luego el límite.
Añadir la orquestación de
RecommendationServicey el comportamiento de configuración con fallo cerrado.Cubrir la política y la orquestación con pruebas unitarias específicas.
Objetivo: Demostrar que las reglas contractuales del socio son deterministas e independientes de la generación de candidatos.
Semana 3 — Interfaces y flujo de extremo a extremo
Exponer los endpoints REST y el endpoint MCP Streamable HTTP.
Proporcionar las herramientas MCP
get_member_profileyget_recommendations.Añadir la demostración CLI.
Enrutar REST, MCP y CLI a través de la capa de negocio compartida.
Añadir pruebas de integración REST/MCP y pruebas de anulación de tenant.
Objetivo: Demostrar el flujo de trabajo completo de recomendación a través de las interfaces requeridas por el encargo.
Semana 4 — Preparación para producción y entrega
Añadir ID de solicitud, campos de correlación, registro estructurado en JSON y manejo seguro de errores.
Gestionar el JSON malformado de forma segura e implementar el apagado elegante.
Añadir la compilación Docker de varias etapas y el tiempo de ejecución sin root.
Realizar el typecheck del código fuente de producción y de las pruebas por separado.
Realizar la auditoría de producción/seguridad y añadir pruebas adversariales de correlación de identidad.
Completar la verificación final de extremo a extremo y del contenedor.
Preparar el README, el runbook de incidentes y el vídeo de demostración.
Objetivo: Hacer que la prueba de concepto sea mantenible por el equipo que la posee en guardia.
Lo que viene después
El siguiente trabajo se pospone deliberadamente hasta después de la primera entrega de cuatro semanas:
Integraciones reales con sistemas ascendentes. Sustituir las implementaciones mock de
MemberDataServiceyPartnerConfigurationServicepor clientes REST reales de arrivia, preservando los contratos de servicio existentes y los invariantes de correlación de identidad.Integración con la autenticación y autorización existentes. Integrar con los mecanismos de identidad y pasarela existentes de arrivia en lugar de introducir una nueva plataforma de identidad. La autorización debe preservar la autoridad de tenant derivada del miembro.
Resiliencia de red. Para las dependencias HTTP ascendentes reales, validar y configurar tiempos de espera de solicitud y conexión, reintentos limitados cuando las operaciones sean seguras de reintentar, y un comportamiento de error explícito. La incertidumbre en la configuración debe seguir fallando en modo cerrado.
Validación del rendimiento. Ejecutar pruebas de carga y rendimiento realistas antes de optimizar. Considerar el almacenamiento en caché de corta duración de la configuración del socio solo si las mediciones lo justifican. Una política obsoleta es un riesgo de corrección, por lo que cualquier caché requiere una estrategia clara de frescura e invalidación.
Inteligencia de recomendación. Potencialmente reemplazar o ampliar el
CandidateGeneratordeterminista con un LLM, un modelo de clasificación o una personalización más rica.RecommendationPolicydebe seguir siendo determinista y estar fuera del modelo para que la salida generada no pueda anular las reglas del socio.Observabilidad en producción. Conectar los eventos estructurados existentes y los ID de correlación con las métricas, el rastreo, las alertas y las herramientas operativas aprobadas por arrivia.
Evolución de MCP. Considerar el comportamiento de MCP con estado o reanudable solo cuando un requisito de producto concreto necesite estado entre solicitudes. La implementación actual de Streamable HTTP sin estado es intencional para este servicio.
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 Connectors
Hotel booking MCP server. Search, book, and manage reservations across 250K+ properties worldwide.
AI marketplace — flights, tours, activities, transport & more via MCP. No auth required.
MCP server exposing the Backtest360 engine API as tools for AI agents.
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/Varma904/agentic-travel-recommendations'
If you have feedback or need assistance with the MCP directory API, please join our Discord server