Tutu MCP

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.

Category
Visit Server

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

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.

Official
Featured
TypeScript
Magic Component Platform (MCP)

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.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

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.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

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.

Official
Featured
TypeScript
Kagi MCP Server

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.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Exa Search

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.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured