MCP ETO Travel

MCP ETO Travel

Enables searching tours on eto.travel using browser automation via Playwright. Supports finding a single tour or a categorized selection (budget, optimal, premium) based on filters like destination, departure city, nights, and month.

Category
访问服务器

README

MCP ETO Travel

MCP-сервер для поиска туров на eto.travel через браузерную автоматизацию Playwright.

Проект подготовлен для двух сценариев использования:

  • Local / stdio — пользователь запускает MCP локально на своей машине.
  • Remote / self-hosted HTTP — пользователь поднимает MCP у себя на сервере и подключается к нему по URL.

В репозитории нет привязки к вашему серверу, IP или временному домену. Всё оформлено как универсальный self-hosted проект, который любой человек сможет развернуть у себя.

Что умеет сервер

  • ищет туры через реальный UI сайта https://eto.travel/search/
  • принимает структурированные фильтры вместо одного свободного текста
  • возвращает один тур или небольшую подборку туров
  • сообщает клиенту, что долгий поиск начался и может занять около минуты
  • просит уточнить критичные данные, если не указаны направление, город вылета или число взрослых
  • ослабляет только не-критичные фильтры (month, departureCity, nights), если строгий поиск не дал результата
  • отбрасывает нерелевантные карточки для точечных направлений вроде Сочи

Инструменты

  • find_any_tour — поиск одного подходящего тура
  • find_tour_options — поиск подборки туров с категориями:
    • budget — самый бюджетный вариант
    • optimal — самый сбалансированный вариант
    • premium — самый дорогой или комфортный вариант из найденных

Общие входные аргументы:

  • destination — обязательное направление или курорт, например Турция или Сочи
  • departureCity — город вылета, например Москва
  • adults — количество взрослых
  • nights — количество ночей или null
  • month — месяц в нормализованном виде (январь ... декабрь) или null
  • rawQuery — исходная пользовательская формулировка или null

Быстрый старт для обычного пользователя

Если человек просто хочет поставить проект у себя, у него есть два простых варианта.

Вариант 1. Локально без сервера

git clone https://github.com/nyxandro/mcp-eto-travel.git
cd mcp-eto-travel
npm install
npx playwright install chromium
npm run build

Дальше MCP можно подключать как локальный процесс.

Вариант 2. На своём сервере по URL

git clone https://github.com/nyxandro/mcp-eto-travel.git
cd mcp-eto-travel
cp .env.example .env

После этого нужно открыть .env и заменить хотя бы:

  • ALLOWED_HOSTS
  • PUBLIC_DOMAIN

Потом запуск:

docker-compose up -d --build

Health check:

curl http://127.0.0.1:3000/health

Если нужен публичный домен без порта, ставится reverse proxy вроде Nginx.

Установка для разработки

Требования:

  • Node.js 20+
  • npm 10+
  • Chromium для Playwright

Если Chromium ещё не установлен:

npx playwright install chromium

Установка:

npm install
npx playwright install chromium
npm run build

Локальный MCP для OpenCode

Запуск вручную:

node dist/index.js

Или в dev-режиме:

npm run dev

Пример OpenCode-конфига:

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "eto-travel-local": {
      "type": "local",
      "command": ["node", "./dist/index.js"],
      "enabled": true,
      "timeout": 180000
    }
  }
}

Готовый пример лежит в examples/opencode.local.json.

Классический MCP-конфиг для клиентов с mcpServers:

{
  "mcpServers": {
    "eto-travel": {
      "command": "node",
      "args": ["/absolute/path/to/mcp-eto-travel/dist/index.js"]
    }
  }
}

Или:

{
  "mcpServers": {
    "eto-travel": {
      "command": ["node", "/absolute/path/to/mcp-eto-travel/dist/index.js"]
    }
  }
}

Self-hosted remote MCP по URL

1. Настройка .env

Скопируйте пример:

cp .env.example .env

Пример .env:

TRANSPORT_MODE=http
HOST=0.0.0.0
PORT=3000
MCP_PATH=/mcp
ALLOWED_HOSTS=mcp.example.com,localhost,127.0.0.1
PUBLIC_DOMAIN=mcp.example.com

Что важно заменить:

  • ALLOWED_HOSTS — сюда обязательно впишите свой домен
  • PUBLIC_DOMAIN — тоже замените на свой реальный домен

2. Запуск через Docker Compose

docker-compose up -d --build

Это поднимет:

  • MCP HTTP endpoint внутри контейнера
  • health endpoint на /health
  • основной MCP path на /mcp

3. Проверка

Локально на сервере:

curl http://127.0.0.1:3000/health

Ожидаемый ответ:

{"status":"ok"}

4. Публичный URL через Nginx

В репозитории лежит шаблон nginx.mcp-eto-travel.conf.

Он показывает, как проксировать запросы на контейнер.

Типовой итоговый endpoint будет таким:

https://mcp.example.com/mcp

Важно:

  • в server_name нужно указать свой домен
  • в .env тот же домен должен быть в ALLOWED_HOSTS

Пример OpenCode-конфига для remote режима

{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "eto-travel-remote": {
      "type": "remote",
      "url": "https://mcp.example.com/mcp",
      "enabled": true,
      "timeout": 180000
    }
  }
}

Готовый пример лежит в examples/opencode.remote.json.

Классический MCP-конфиг для обычных клиентов:

{
  "mcpServers": {
    "eto-travel": {
      "url": "https://mcp.example.com/mcp"
    }
  }
}

Если клиент требует явный transport:

{
  "mcpServers": {
    "eto-travel": {
      "url": "https://mcp.example.com/mcp",
      "transport": "streamable-http"
    }
  }
}

Что лежит в репозитории для удобного деплоя

  • Dockerfile — готовый образ для запуска
  • docker-compose.yml — запуск через Compose
  • .env.example — пример env-настроек
  • nginx.mcp-eto-travel.conf — шаблон reverse proxy
  • examples/opencode.local.json — локальный OpenCode-конфиг
  • examples/opencode.remote.json — remote OpenCode-конфиг

Архитектура

  • src/index.ts — entrypoint, переключает режим запуска между stdio и http
  • src/runtime/config.ts — нормализация runtime env-конфига
  • src/runtime/http-server.ts — HTTP transport для remote MCP
  • src/mcp/server.ts — регистрация MCP tools
  • src/mcp/find-any-tour.ts — single-result MCP handler
  • src/mcp/find-tour-options.ts — multi-result MCP handler
  • src/eto-travel/search-service.ts — orchestration сценария поиска
  • src/eto-travel/search-results-reader.ts — чтение нескольких карточек из выдачи
  • src/eto-travel/tour-collection.ts — категоризация budget / optimal / premium
  • src/eto-travel/search-plan.ts — fallback-план ослабления фильтров
  • src/eto-travel/tour-normalizer.ts — нормализация карточки и проверка релевантности направления
  • src/shared/query-parser.ts — нормализация направлений, месяцев и городов вылета

Примеры вызова инструментов

Один тур:

{
  "tool": "find_any_tour",
  "arguments": {
    "destination": "Турция",
    "departureCity": "Москва",
    "adults": 2,
    "nights": 7,
    "month": "июнь",
    "rawQuery": "Найди тур в Турцию из Москвы на июнь на 7 ночей для 2 взрослых"
  }
}

Подборка:

{
  "tool": "find_tour_options",
  "arguments": {
    "destination": "Турция",
    "departureCity": "Москва",
    "adults": 2,
    "nights": 7,
    "month": "июнь",
    "rawQuery": "Подбери несколько туров в Турцию из Москвы на июнь на 7 ночей для 2 взрослых"
  }
}

Пример ответа для подборки:

{
  "tours": [
    {
      "category": "budget",
      "title": "Budget Hotel",
      "price": "90 000 RUB",
      "url": "https://example.com/budget"
    },
    {
      "category": "optimal",
      "title": "Comfort Hotel",
      "price": "115 000 RUB",
      "url": "https://example.com/optimal"
    },
    {
      "category": "premium",
      "title": "Luxury Resort",
      "price": "180 000 RUB",
      "url": "https://example.com/premium"
    }
  ]
}

Проверка и разработка

npm test
npm run lint
npm run typecheck
npm run build

Проверка через Inspector для локального режима:

npx @modelcontextprotocol/inspector node ./dist/index.js

Что стоит проверить:

  • видны оба tools: find_any_tour и find_tour_options
  • single-tool возвращает одну карточку
  • multi-tool возвращает подборку из нескольких карточек, если сайт их отдал
  • при нехватке критичных данных сервер просит уточнение
  • при нерелевантной карточке сервер не подменяет курорт другим регионом

Важные нюансы

  • сайт eto.travel/search/ использует внешний виджет tourvisor.ru
  • стабильность зависит от DOM-структуры виджета и доступности стороннего контента
  • итоговая ссылка на карточку может вести не на eto.travel, а на tourcart.ru — это штатное поведение виджета
  • для долгих поисков у MCP-клиента лучше ставить timeout не меньше 180000 мс

Что публиковать на GitHub

Для публичной раздачи проекта достаточно оставить в репозитории:

  • исходный код
  • Dockerfile
  • docker-compose.yml
  • .env.example
  • nginx.mcp-eto-travel.conf
  • examples/opencode.local.json
  • examples/opencode.remote.json

И не публиковать:

  • временные IP
  • приватные dev-домены
  • локальные override-файлы под конкретный сервер

В таком виде любой пользователь сможет либо подключить локальный MCP, либо поднять remote MCP у себя почти без ручной доработки.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选
mcp-server-qdrant

mcp-server-qdrant

这个仓库展示了如何为向量搜索引擎 Qdrant 创建一个 MCP (Managed Control Plane) 服务器的示例。

官方
精选
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选