Skip to main content
Glama

Заезд

Un motor de viajes que empieza por el motivo. La persona no sabe adónde ir, sabe para qué: quiere ir a una conferencia sobre su tema. Заезд encuentra el evento presencial más cercano, calcula el trayecto de ida y vuelta, el hotel cerca de la sede y el precio total de participación, y muestra hasta tres paquetes explicables en una sola pantalla.

La primera vertical son las conferencias de TI. El catálogo de eventos lo proporciona el MCP de confcal, el transporte y el alojamiento los proporciona el MCP de Tutu, y todo lo ensambla un compositor determinista, no un modelo.

Qué hay dónde

Qué

Dónde

Pantalla del viaje

/ en la dirección donde hayas iniciado Заезд

Viaje por enlace

/t/<trip_id>, el enlace lo devuelve la pantalla y cualquiera de las herramientas

Endpoint MCP

/mcp, HTTP streamable, sin clave

Comprobación de actividad

/healthz, responde con el modo y la fecha de referencia

Guía de usuario

docs/user-guide.md

Grabación de dos minutos

docs/demo.mp4, servidor, pantalla y agente

Related MCP server: Travel Planner MCP Server

Escenario completo

Abres la raíz. En la pantalla ya hay un viaje ensamblado, no un formulario vacío. Arriba, el evento, la fecha, la ciudad, la sede y el tiempo a pie hasta ella desde el hotel más cercano. Debajo, hasta tres tarjetas: el trayecto de ida con el número de tren o vuelo, el hotel con el precio de toda la estancia y la distancia a la sede, el trayecto de vuelta, el total en una sola cifra y la línea de aritmética debajo, que cuadra. Después, el mapa de la ciudad con la sede y los hoteles, el tiempo para las fechas del viaje, otros eventos sobre el tema y la lista de lo que no se ha incluido y por qué.

Pulsas «Generar enlaces de pago»: aparece una lista de verificación con dos o tres enlaces de Tutu. El pie de cada uno se toma de lo que Tutu devolvió realmente: «Abrir la cesta» donde se abrirá la cesta, y «Abrir la página de selección» donde no habrá cesta.

Lo mismo para el agente: find_event_trips con el tema y la ciudad de salida devuelve el mismo viaje como estructura, get_trip_details despliega el paquete, create_trip_checkout genera la lista de verificación. Un host que sepa dibujar recibe la misma pantalla como MCP App.

Ejecución desde el código fuente

npm install
ZAEZD_MODE=replay npm run dev

Se abrirá http://localhost:8080. En el modo replay el producto funciona con las respuestas grabadas de fixtures/ y no accede a la red: se puede usar sin internet y sin claves, y la fecha de referencia es el día de la grabación. El modo en vivo es ZAEZD_MODE=live.

Verificación completa:

npm run verify

Esto es la sincronización de reglas, la comprobación de los comandos documentados, el tipado, el linter, el ensamblaje del árbol del navegador, los escenarios ejecutables en Gherkin y las pruebas unitarias. Todo offline.

El árbol del navegador se ensambla antes que los escenarios, no por estética. Un escenario solicita al servidor ese mismo boot.js que viaja al host, y en un clon limpio de ese archivo todavía no existe.

Ejecución en contenedor

La imagen se construye desde el repositorio y contiene tanto el código como las fixtures, por lo que en el modo replay el contenedor no necesita ni internet ni secretos.

cp .env.example .env      # и отредактируйте
docker compose up -d --build

La pantalla se levantará en http://127.0.0.1:8080. Sin el archivo .env, compose no arranca: esto es intencionado, para que nadie ejecute el producto con valores ajenos por defecto.

Sin compose, lo mismo con un solo comando:

docker build -t zaezd .
docker run -d --name zaezd -p 127.0.0.1:8080:8080 --env-file .env zaezd

Puntualmente, sin archivo de entorno, solo para echar un vistazo:

docker run --rm -p 127.0.0.1:8080:8080 \
  -e ZAEZD_MODE=replay -e ZAEZD_PUBLIC_URL=http://localhost:8080 zaezd

Variables de entorno

La lista completa con comentarios está en .env.example. En resumen:

Variable

Para qué

Por defecto

ZAEZD_MODE

live accede a las fuentes, replay lee fixtures/

live

PORT

puerto dentro del contenedor

8080

ZAEZD_PUBLIC_URL

dirección por la que el producto se ve desde fuera. De ella se construyen los enlaces al viaje y la CSP del widget

http://localhost:8080

ZAEZD_CONTACT_EMAIL

contacto en User-Agent; Nominatim banea las solicitudes anónimas

zaezd@example.com

ZAEZD_CONFCAL_URL

MCP del catálogo de eventos

confcal público

ZAEZD_TUTU_URL

MCP de Tutu

https://mcp.tutu.ru/mcp

No hay ni una sola clave ni token: ambas fuentes son abiertas. El valor de ZAEZD_PUBLIC_URL es importante definirlo con honestidad: es precisamente esa dirección la que viaja al agente como enlace a la pantalla y entra en la CSP del widget, y si no coincide con la real, el tablero dentro del host quedará vacío.

El contenedor lleva un HEALTHCHECK en /healthz, así que docker ps muestra healthy solo cuando la aplicación realmente responde.

Detrás de un proxy inverso

El propio docker-compose.yaml no sabe nada de proxies, dominios ni redes: son propiedades de la plataforma, no del producto. Todo eso se coloca en docker-compose.override.yaml, que está en el gitignore y vive solo en la máquina que despliega el servicio. Ejemplo para Traefik:

services:
  zaezd:
    ports: !reset []          # наружу светит прокси, а не контейнер
    environment:
      ZAEZD_PUBLIC_URL: https://zaezd.example.com
    labels:
      traefik.enable: 'true'
      traefik.http.routers.zaezd.rule: Host(`zaezd.example.com`)
      traefik.http.routers.zaezd.entrypoints: https
      traefik.http.routers.zaezd.tls: 'true'
      traefik.http.routers.zaezd.tls.certresolver: letsencrypt
      traefik.http.services.zaezd.loadbalancer.server.port: '8080'
    networks: [proxy]

networks:
  proxy:
    external: true

Los nombres del punto de entrada, del resolvedor de certificados y de la red son distintos en cada caso, por eso en el ejemplo son ficticios. Para nginx o Caddy el override será diferente; el producto no cambia por ello: escucha en PORT y sirve /healthz.

Conectar a un agente

El endpoint <dirección>/mcp funciona por HTTP streamable y no requiere clave. Localmente es http://localhost:8080/mcp; en un servicio desplegado, tu dirección de ZAEZD_PUBLIC_URL.

Claude Desktop no acepta servidores remotos directamente en claude_desktop_config.json; allí solo viven comandos stdio, así que o añades Заезд a través de Settings, Connectors, Add custom connector, o configuras un lanzamiento proxy:

{
  "mcpServers": {
    "zaezd": { "command": "npx", "args": ["-y", "mcp-remote", "http://localhost:8080/mcp"] }
  }
}

Claude Code y Codex CLI:

claude mcp add --transport http zaezd http://localhost:8080/mcp
codex mcp add zaezd --url http://localhost:8080/mcp

Qwen Code:

qwen mcp add --transport http zaezd http://localhost:8080/mcp

Un host que sepa dibujar widgets recibirá la misma pantalla a través del recurso ui://zaezd/trip-board. Un host sin widgets recibirá la misma respuesta como texto.

Arquitectura

Las dependencias solo van hacia abajo.

Capa

Dónde

Qué hace

L0

src/composer/{types,dates,selection,feasibility,pricing,hotels,packages,checkout-labels}.ts

reglas puras: fechas, viabilidad, precio, selección de paquetes. Sin E/S y sin reloj

L1

src/sources/

clientes de confcal y Tutu, normalización, caché, modo replay

L2

src/enrich/

geocodificación, calendario laboral, tiempo. Cada uno con timeout y respuesta de respaldo

L3

src/composer/{build-trip,build-checkout,trip-id}.ts

ensamblaje del viaje, presupuestos, enlaces de pago en vivo, consulta en el enlace

L4

src/web/, src/mcp/

pantalla y tres herramientas. Aquí no hay lógica de negocio

El esquema y dos secuencias están en docs/architecture.md; las decisiones con justificaciones, en docs/decisions.md.

Lo clave: las fechas, los precios y la viabilidad los calcula el código, no el modelo. Tres ejecuciones en vivo idénticas a través del modelo dieron tres números distintos de noches y una dispersión de precio de una vez y media. Por eso el algoritmo vive en src/composer/dates.ts y está cubierto por una tabla de escenarios.

Limitaciones

La lista es honesta; léela como parte del producto.

  • Un evento en línea no construye un viaje, y un evento en tu propia ciudad tampoco. En ambos casos Заезд lo dice directamente, en lugar de mostrar una pantalla vacía;

  • el catálogo en vivo de confcal conoce 21 ciudades, y los eventos presenciales en vivo existen aproximadamente en 15 de ellas. Las ciudades vacías no se ocultan; el contador se muestra en la pantalla;

  • en una sola solicitud se calcula un viaje. Hasta cinco eventos más sobre el tema se muestran como lista, pero no se calculan: un abanico de cinco ensamblajes es un spinner, no un producto;

  • la previsión meteorológica solo está disponible para 16 días hacia adelante. Más allá, el bloque del tiempo simplemente desaparece;

  • la dirección de la sede se toma del catálogo y nunca se inventa. Si el catálogo no la proporciona, la pantalla lo dice y no coloca una marca en el mapa, y al agente se le pide en la respuesta que busque la dirección en fuentes abiertas y que diga a la persona que la dirección no proviene del catálogo;

  • el multitransporte de Tutu calcula adultos; no hay tarifas infantiles ni reducidas en el viaje;

  • el enlace al billete de avión en un navegador frío abre la búsqueda, no la cesta: la cesta solo se crea en un navegador con una sesión viva de Tutu. Por eso el pie de ese botón lo dice;

  • no hay esquema de asientos del vagón;

  • el precio de participación en el evento se suma al total solo si el catálogo lo escribió como número. Un precio textual como «gratis para estudiantes» Заезд lo muestra tal cual y no lo incluye en la suma;

  • en el modo replay los enlaces de pago se han generado a partir de la grabación y, muy probablemente, han caducado. La pantalla y la respuesta al agente lo advierten;

  • al catálogo se le solicitan ocho eventos a la vez: con un número mayor deja de entregar el flujo a mitad de la respuesta. La medición y la justificación están en el registro de decisiones.

Medido

Métrica

Valor

Herramientas del MCP de Tutu

16

Manifiesto del MCP de Tutu

102 143 caracteres, unos 25,5 mil tokens

Herramientas de la pasarela de Заезд

3

Manifiesto de la pasarela de Заезд

10 181 caracteres, unos 2,5 mil tokens

Ensamblaje de viaje en vivo, en frío

12,1 s

Ensamblaje de viaje en vivo, repetido

0,2 s

Ensamblaje de viaje desde grabación

36 ms

Fuentes externas

6

Escenarios ejecutables

217

Pruebas unitarias

336

Probado en agentes

Claude Code, Qwen Code

Mapa del repositorio

specs/      спецификация продукта, она же источник правды
features/   исполняемые сценарии на Gherkin и шаги к ним
tests/      юнит-тесты чистого слоя
src/        код продукта по слоям
fixtures/   записанные ответы источников
scripts/    record.ts и вспомогательные утилиты
docs/       руководство пользователя, архитектура, журнал решений

Licencia

MIT, ver LICENSE.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

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

View all related MCP servers

Related MCP Connectors

  • TravelMind: 8 MCP tools for travel (12306 trains, flights, hotels, geocode, planning, policy).

  • whentofly: flexible-date economy/business flight search + price-level context for AI agents

  • Flight search & booking for AI agents. 400+ airlines, $20-50 cheaper than OTAs.

View all MCP Connectors

Latest Blog Posts

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/EvilFreelancer/zaezd'

If you have feedback or need assistance with the MCP directory API, please join our Discord server