Skip to main content
Glama

Заезд

여정 엔진, 이유에서 시작합니다. 사람은 어디로 갈지 모르고, 왜 가는지는 압니다: 자기 주제의 컨퍼런스에 가고 싶습니다. Заезд는 가장 가까운 오프라인 이벤트를 찾고, 왕복 교통편을 계산하며, 행사장 근처 호텔과 참가 총비용을 산출해, 한 화면에 설명 가능한 패키지 최대 3개를 보여줍니다.

첫 번째 수직 영역은 IT 컨퍼런스입니다. 이벤트 카탈로그는 confcal MCP가 제공하고, 교통과 숙소는 Tutu MCP가 제공하며, 모든 것을 모으는 것은 모델이 아닌 결정적 컴포저입니다.

구성

항목

위치

여정 화면

Заезд를 실행한 주소의 /

링크로 여정 열기

/t/<trip_id>, 링크는 화면과 모든 도구가 제공

MCP 엔드포인트

/mcp, streamable HTTP, 키 없음

상태 확인

/healthz, 모드와 기준 날짜로 응답

사용자 가이드

docs/user-guide.md

2분 데모

docs/demo.mp4, 서버, 화면, 에이전트

Related MCP server: Travel Planner MCP Server

종단 간 시나리오

루트를 엽니다. 화면에는 빈 폼이 아니라 이미 조립된 여정이 있습니다. 상단에 이벤트, 날짜, 도시, 행사장, 그리고 가장 가까운 호텔에서 행사장까지 도보 시간이 있습니다. 아래에 최대 3개의 카드: 열차 번호 또는 항공편 번호가 있는 가는 길, 전체 숙박 가격과 행사장까지 거리가 있는 호텔, 오는 길, 한 숫자로 된 합계와 그 아래에 맞아떨어지는 계산식이 있습니다. 그 다음 도시 지도에 행사장과 호텔, 여행 날짜의 날씨, 주제 관련 다른 이벤트, 그리고 포함되지 않은 항목과 그 이유 목록이 있습니다.

"결제 링크 만들기"를 누르면 Tutu 링크 2~3개로 된 체크리스트가 나타납니다. 각 링크의 라벨은 Tutu가 실제로 반환한 내용에서 가져옵니다: 장바구니가 열리는 곳에는 "장바구니 열기", 장바구니가 없는 곳에는 "선택 페이지 열기".

에이전트에게도 동일합니다: find_event_trips는 주제와 출발 도시로 동일한 여정을 구조로 반환하고, get_trip_details는 패키지를 펼치며, create_trip_checkout는 체크리스트를 만듭니다. 위젯을 그릴 수 있는 호스트는 MCP App으로 동일한 화면을 받습니다.

소스에서 실행

npm install
ZAEZD_MODE=replay npm run dev

http://localhost:8080이 열립니다. replay 모드에서 제품은 fixtures/의 기록된 응답으로 동작하며 네트워크에 접속하지 않습니다: 인터넷도 키도 없이 사용할 수 있고, 기준 날짜는 기록 당일입니다. 라이브 모드는 ZAEZD_MODE=live입니다.

전체 검증:

npm run verify

이는 규칙 동기화, 문서화된 명령 검증, 타입 검사, 린터, 브라우저 번들 빌드, Gherkin 실행 시나리오, 유닛 테스트입니다. 모두 오프라인입니다.

브라우저 번들은 시나리오 전에 빌드되는데, 장식이 아닙니다. 한 시나리오가 서버에 호스트로 전달되는 바로 그 boot.js를 요청하며, 이 파일의 깨끗한 클론에는 아직 그것이 없습니다.

컨테이너에서 실행

이미지는 저장소에서 빌드되며 내부에 코드와 픽스처를 모두 포함하므로, replay 모드에서 컨테이너는 인터넷도 시크릿도 필요 없습니다.

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

화면은 http://127.0.0.1:8080에서 뜹니다. .env 파일 없이는 compose가 시작되지 않습니다: 이는 의도적인 것으로, 누구도 기본값으로 타인의 값을 사용해 제품을 실행하지 않도록 하기 위함입니다.

compose 없이 같은 작업을 한 명령으로:

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

일회성으로, 환경 파일 없이, 그냥 보기만 하려면:

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

환경 변수

전체 목록과 주석은 .env.example에 있습니다. 요약:

변수

용도

기본값

ZAEZD_MODE

live는 소스에 접속, replayfixtures/ 읽음

live

PORT

컨테이너 내부 포트

8080

ZAEZD_PUBLIC_URL

제품이 외부에서 보이는 주소. 여정 링크와 위젯 CSP가 여기서 생성됨

http://localhost:8080

ZAEZD_CONTACT_EMAIL

User-Agent의 연락처; Nominatim은 익명 요청을 차단함

zaezd@example.com

ZAEZD_CONFCAL_URL

이벤트 카탈로그 MCP

공개 confcal

ZAEZD_TUTU_URL

Tutu MCP

https://mcp.tutu.ru/mcp

키나 토큰은 하나도 없습니다: 두 소스 모두 공개입니다. ZAEZD_PUBLIC_URL 값은 정직하게 설정하는 것이 중요합니다 - 바로 이 주소가 화면 링크로 에이전트에게 전달되고 위젯 CSP에 들어가며, 실제 주소와 일치하지 않으면 호스트 내부의 보드는 빈 상태로 남습니다.

컨테이너는 /healthzHEALTHCHECK를 포함하므로, docker ps는 애플리케이션이 실제로 응답할 때만 healthy를 표시합니다.

리버스 프록시 뒤에서

docker-compose.yaml 자체는 프록시, 도메인, 네트워크에 대해 아무것도 모릅니다 - 이는 플랫폼의 속성이지 제품의 속성이 아닙니다. 이 모든 것은 docker-compose.override.yaml에 넣으며, 이 파일은 gitignore에 있고 서비스를 배포하는 그 머신에만 존재합니다. 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

엔트리포인트 이름, 인증서 리졸버, 네트워크는 모두 다르므로 예시에서는 가상의 값입니다. nginx나 Caddy의 경우 override는 다르며, 제품은 변하지 않습니다: PORT를 듣고 /healthz를 응답합니다.

에이전트에 연결

엔드포인트 <주소>/mcp는 streamable HTTP로 동작하며 키가 필요 없습니다. 로컬에서는 http://localhost:8080/mcp, 배포된 서비스에서는 ZAEZD_PUBLIC_URL의 주소입니다.

Claude Desktop은 claude_desktop_config.json에 원격 서버를 직접 받지 않으며, 거기에는 stdio 명령만 있습니다. 따라서 Settings, Connectors, Add custom connector로 Заезд를 추가하거나 프록시 실행을 설정하세요:

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

Claude Code 및 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

위젯을 그릴 수 있는 호스트는 ui://zaezd/trip-board 리소스를 통해 동일한 화면을 받습니다. 위젯이 없는 호스트는 동일한 응답을 텍스트로 받습니다.

아키텍처

의존성은 아래로만 흐릅니다.

계층

위치

역할

L0

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

순수 규칙: 날짜, 실행 가능성, 가격, 패키지 선별. 입출력도 시계도 없음

L1

src/sources/

confcal 및 Tutu 클라이언트, 정규화, 캐시, replay 모드

L2

src/enrich/

지오코딩, 생산 달력, 날씨. 각각 타임아웃과 대체 응답 포함

L3

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

여정 조립, 예산, 실시간 결제 링크, 링크의 요청

L4

src/web/, src/mcp/

화면과 세 가지 도구. 여기에는 비즈니스 로직이 없음

다이어그램과 두 시퀀스는 docs/architecture.md, 근거가 있는 결정 사항은 docs/decisions.md에 있습니다.

핵심: 날짜, 가격, 실행 가능성은 모델이 아닌 코드가 계산합니다. 모델을 통한 세 번의 동일한 라이브 실행은 세 가지 다른 숙박 일수와 1.5배의 가격 편차를 보였습니다. 따라서 알고리즘은 src/composer/dates.ts에 있으며 시나리오 표로 검증됩니다.

제한 사항

목록은 정직하며, 제품의 일부로 읽어 주세요.

  • 온라인 이벤트는 여정을 만들지 않으며, 같은 도시의 이벤트도 마찬가지입니다. 두 경우 모두 Заезд는 빈 화면을 보여주는 대신 직접적으로 말합니다;

  • 라이브 confcal 카탈로그는 21개 도시를 알고 있으며, 라이브 오프라인 이벤트는 그중 약 15개에 있습니다. 빈 도시는 숨겨지지 않고, 카운터가 화면에 표시됩니다;

  • 한 요청에 하나의 여정이 계산됩니다. 주제의 이벤트 최대 5개가 목록으로 표시되지만 계산되지는 않습니다: 5개 조립의 부채꼴은 제품이 아니라 스피너입니다;

  • 날씨 예보는 16일 앞까지만 제공됩니다. 그 이후에는 날씨 블록이 그냥 사라집니다;

  • 행사장 주소는 카탈로그에서 가져오며 절대 추측하지 않습니다. 카탈로그가 주소를 주지 않으면 화면은 이를 말하고 지도에 마커를 놓지 않으며, 에이전트 응답은 공개 소스에서 주소를 찾아 사람에게 주소가 카탈로그 출처가 아님을 알리도록 요청합니다;

  • Tutu 멀티모달 교통편은 성인을 계산하며, 여정에는 아동·할인 요금이 없습니다;

  • 콜드 브라우저의 항공권 링크는 장바구니가 아닌 검색을 엽니다: 장바구니는 라이브 Tutu 세션이 있는 브라우저에서만 생성됩니다. 따라서 해당 버튼의 라벨이 이를 말합니다;

  • 객차 좌석 배치도는 없습니다;

  • 이벤트 참가비는 카탈로그가 숫자로 기록한 경우에만 합계에 포함됩니다. "학생 무료"와 같은 텍스트 가격은 Заезд가 그대로 표시하고 합계에 넣지 않습니다;

  • replay 모드에서 결제 링크는 기록에서 조립되며 만료되었을 가능성이 높습니다. 화면과 에이전트 응답이 이를 경고합니다;

  • 카탈로그에서 한 번에 8개 이벤트가 요청됩니다: 그 이상에서는 응답 중간에 스트림을 중단합니다. 측정과 근거는 결정 로그에 있습니다.

측정 결과

지표

Tutu MCP 도구 수

16

Tutu MCP 매니페스트

102,143자, 약 25.5천 토큰

Заезд 게이트웨이 도구 수

3

Заезд 게이트웨이 매니페스트

10,181자, 약 2.5천 토큰

라이브 여정 조립, 콜드

12.1초

라이브 여정 조립, 반복

0.2초

기록에서 여정 조립

36ms

외부 소스

6

실행 시나리오

217

유닛 테스트

336

에이전트에서 검증

Claude Code, Qwen Code

저장소 맵

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

라이선스

MIT, 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