Tutu MCP
Enables searching for buses and trains, and when direct routes are unavailable, it provides the underlying data needed to assemble multi-leg itineraries with transfers.
README
Туда, куда не ищется
Собираем поездку через пересадку, когда прямого билета нет.
Поиск любого сервиса отвечает на вопрос «есть ли билет из А в Б». Если прямого сообщения нет, выдача пустая — и человек уходит. Хотя доехать можно, и оба нужных билета продаются там же.
Живой пример. Запрос «Москва → Углич» на 20 августа 2026 в MCP Туту:
search_multitransport → 0 вариантов
search_bus → 0 вариантов
search_rail → 0 вариантов
Наш ответ на тот же запрос:
Москва → Ярославль автобус 09:00 → 13:00 863 ₽
пересадка в Ярославле — 40 минут
Ярославль → Углич автобус 13:40 → 16:25 616 ₽
итого 1 479 ₽, на месте в 16:25
Оба билета продаёт Туту. Их поиск этого маршрута не покажет никогда.
Как это работает
запрос «Москва → Плёс»
↓
MCP Туту: прямой поиск → 0 вариантов, регион «Ивановская область»
↓
узлы-кандидаты: справочник «регион → центр» + предложения агента
↓
для каждого узла: сначала плечо «узел → цель», затем «откуда → узел»
↓
код сводит стыковки: отбрасывает рейсы, на которые не успеть, считает запас и сумму
↓
карточки маршрутов
Поиском управляет агент: он сам решает, какие города и даты проверять, и человек видит ход его работы лентой на экране. Но стыковки, цены и ранжирование считает код — модель к арифметике не допущена, именно там агенты ошибаются. Тяжёлые ответы Туту через модель не проходят: она получает идентификаторы найденных плеч и короткие сводки, а полные данные уходят прямо в интерфейс.
Если уехать в выбранный день нельзя, бэкенд досылает агента за гостиницами: ищется ближайший день отъезда и подбирается ночлег ровно на столько ночей, сколько ждать.
Если агент недоступен или упёрся в лимит, интерфейс молча переключается на детерминированный поиск — экран показывает результат в любом случае.
Запуск
npm install
cp .env.example .env # вписать OPENROUTER_API_KEY (необязательно)
npm run db:up # Postgres в Docker
npm run migrate # схема базы
npm run warm # прогрев кэша реальными ответами Туту
npm run dev # http://localhost:3100
OPENROUTER_API_KEY опционален: без него подсказка городов отключается,
поиск работает на справочнике регионов.
Команды
| Команда | Что делает |
|---|---|
npm run dev |
приложение на http://localhost:3100 |
npm run route -- Москва Углич 2026-08-20 |
сборка маршрута в консоли |
npm run warm |
прогрев кэша из src/modules/tutu/fixtures/ |
npm run cache |
что сейчас в кэше |
npm run smoke |
проверка живой связки с MCP Туту |
npm run db:up / db:down |
Postgres в Docker |
npm run migrate |
миграции Prisma |
npm run lint |
ESLint |
Структура
Весь код в src/, в корне только конфигурация. Интерфейс собран одной папкой,
логика разложена по модулям — по смыслу, а не по типу файла:
src/
app/ роутинг Next: страница и три API — тонкие, только вызовы модулей
api/agent/ агентный поиск потоком
api/route/ детерминированный поиск (страховка)
api/stay/ гостиницы
frontend/ всё, что видно в браузере
components/route/ форма, календарь, подсказки, лента, карточки, гостиницы
hooks/ чтение потока агента, определение города
design.ts палитра и подписи из макета
format.ts, geo.ts форматирование и расстояния
config.ts константы интерфейса
modules/ логика, зависимости однонаправленные: agent → routing → tutu
tutu/ клиент MCP, кэш, типы, прокси, снятые ответы (fixtures)
routing/ сборка маршрутов, справочники регионов и городов
agent/ цикл, инструменты, промпт, ошибки, ретраи, состояние
lib/ клиент Prisma
Почему внутри модулей нет слоёв domain/, infra/, api/. Такая нарезка
оправдана на десятках тысяч строк и полутора десятках доменов. Здесь один
сценарий: слои дали бы папки по одному файлу и пустой contract/. Когда модуль
перерастёт тысячу строк, они появятся вокруг существующих файлов.
Работа с MCP Туту
Подключение: https://mcp.tutu.ru/mcp, streamable HTTP, авторизация не нужна.
Два инженерных решения, без которых это не работает:
Ответы весят ~26 КБ. Инструменты обёрнуты так, что полный JSON уходит в
интерфейс и рисуется карточками, а в языковую модель — сжатая выжимка через
toModelOutput. Замер на реальном поиске: 26 305 → 1 971 символ, экономия 93 %.
У сервера жёсткий rate limit. Около полусотни запросов подряд закрыли нам
доступ ко всему домену на уровне TCP на несколько часов. Поэтому: view: 'compact',
кэш ответов в Postgres, не больше двух узлов на поиск, а перед демо — прогрев
кэша из fixtures/ командой npm run warm. Если сервер недоступен, экран
показывает то, что есть в кэше, и не падает.
Стек
Next.js 16 (App Router) · TypeScript · @ai-sdk/mcp · Prisma 7 + Postgres 18 ·
Tailwind 4 + shadcn/ui · OpenRouter (опционально)
Документы
SPECIFICATION.md— продукт целиком: проблема, доказательства, техника, регламентSCREEN-SPEC.md— спецификация экрана для вёрсткиUSER-GUIDE.md— руководство пользователяfixtures/README.md— что за сохранённые ответы и зачем
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.
Neon Database
MCP server for interacting with Neon Management API and databases
E2B
Using MCP to run code via e2b.
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.