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.
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— количество ночей илиnullmonth— месяц в нормализованном виде (январь...декабрь) илиnullrawQuery— исходная пользовательская формулировка или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_HOSTSPUBLIC_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 proxyexamples/opencode.local.json— локальный OpenCode-конфигexamples/opencode.remote.json— remote OpenCode-конфиг
Архитектура
src/index.ts— entrypoint, переключает режим запуска междуstdioиhttpsrc/runtime/config.ts— нормализация runtime env-конфигаsrc/runtime/http-server.ts— HTTP transport для remote MCPsrc/mcp/server.ts— регистрация MCP toolssrc/mcp/find-any-tour.ts— single-result MCP handlersrc/mcp/find-tour-options.ts— multi-result MCP handlersrc/eto-travel/search-service.ts— orchestration сценария поискаsrc/eto-travel/search-results-reader.ts— чтение нескольких карточек из выдачиsrc/eto-travel/tour-collection.ts— категоризацияbudget / optimal / premiumsrc/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
Для публичной раздачи проекта достаточно оставить в репозитории:
- исходный код
Dockerfiledocker-compose.yml.env.examplenginx.mcp-eto-travel.confexamples/opencode.local.jsonexamples/opencode.remote.json
И не публиковать:
- временные IP
- приватные dev-домены
- локальные override-файлы под конкретный сервер
В таком виде любой пользователь сможет либо подключить локальный MCP, либо поднять remote MCP у себя почти без ручной доработки.
Recommended Servers
playwright-mcp
A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.
Magic Component Platform (MCP)
An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.
Audiense Insights MCP Server
Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.
VeyraX MCP
Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.
graphlit-mcp-server
The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.
Kagi MCP Server
An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.
E2B
Using MCP to run code via e2b.
Neon Database
MCP server for interacting with Neon Management API and databases
Exa Search
A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.
Qdrant Server
This repository is an example of how to create a MCP server for Qdrant, a vector search engine.