9.0 KiB
MCP-сервер «Rubber Duck» — план реализации
Контекст
Проект rubber-duck — интерактивная уточка для дебага. MCP-сервер расширяет концепцию: LLM-модель (Claude, Cursor) может «обращаться к уточке» за кряком и мудростью. Сервер — отдельный репозиторий, деплой на Vercel, стек: Express + TypeScript + Streamable HTTP.
Философия сервера
Сервер не решает задачи за модель. Он — Explicit Reasoning Buffer (буфер явных рассуждений). Когда модель застревает в логическом цикле или склонна к галлюцинациям, вызов quack() заставляет её:
- Сформулировать аргументы — чтобы вызвать инструмент, модель должна выгрузить промежуточные мысли из весов в текст. Неявные рассуждения становятся явными данными.
- Прервать генерацию — вместо того чтобы «проскочить» сложный момент, модель делает паузу и структурирует задачу.
- Создать внешнюю память — записывая статус в «уточку», модель формирует краткое резюме пройденных этапов.
Описывается через Resource about://rubber-duck — текстовый документ, который сервер отдаёт при запросе. Модель читает его и понимает контекст.
Архитектура
rubber-duck-mcp/
├── api/mcp.ts — Express handler для Vercel Serverless
├── src/
│ ├── server.ts — McpServer: регистрация tools + resources
│ ├── tools/
│ │ ├── quack.ts — Tool: случайный кряк
│ │ └── quack-wisdom.ts — Tool: кряк + мудрость программиста (ФАЗА 2)
│ ├── data/
│ │ └── wisdoms.ts — Массив цитат/мудростей (ФАЗА 2)
│ └── index.ts — Express dev-сервер (localhost)
├── vercel.json
├── package.json
└── tsconfig.json
Зависимости
- @modelcontextprotocol/sdk — McpServer + StreamableHTTPServerTransport
- express — HTTP-сервер
- @types/express, typescript — типизация
- tsx — dev-запуск TypeScript без сборки
Инструменты (Tools)
Tool #1: quack (ФАЗА 1 — полная реализация)
- Назначение: Заставляет модель остановиться и сформулировать мысль
- Аргументы:
mood(опциональный) —"happy" | "confused" | "excited" | "sleepy" - Логика: Без аргументов — случайный кряк. С
mood— кряк подбирается по настроению - Возвращает:
TextContentс текстом кряка
Tool #2: quack_wisdom (ФАЗА 2 — после проверки Tool #1)
- Назначение: Кряк + случайная мудрость для программиста
- Аргументы:
topic(опциональный) —"debugging" | "life" | "code" | "random" - Логика: Генерирует кряк, выбирает мудрость из базы (фильтр по topic), форматирует
- Возвращает:
TextContent— кряк + мудрость + автор
База мудростей (data/wisdoms.ts) — ФАЗА 2
Массив { text, author?, topic? }. Классические цитаты (Kernighan, Knuth, Stallman) + юмористические фразы. Каждая запись с полем topic для фильтрации.
Resource: философия сервера — ФАЗА 2
- URI:
about://rubber-duck - Название: "About Rubber Duck MCP"
- Содержимое: Текстовый документ (~10-15 строк):
- Что это (Explicit Reasoning Buffer)
- Зачем (замедление, фиксация контекста, внешняя память)
- Как использовать (вызывай quack() когда застрял)
Промпты
Не используются. Промпты — шаблоны для пользователя в UI. Для простого сервера из двух тулзов избыточны: модель свободно вызывает инструменты сама.
Express-хендлер
Один эндпоинт POST /mcp. На каждый запрос:
- Новый
McpServer(с tools + resources) StreamableHTTPServerTransport— stateless (sessionIdGenerator: undefined)- Подключение + обработка запроса
Локально: index.ts с app.listen(3000).
Деплой на Vercel
vercel.json: маппинг /mcp → api/mcp.ts через @vercel/node.
- Push в GitHub
- Vercel → Add New Project → выбрать репозиторий
- Deploy
- URL:
https://<project>.vercel.app/mcp
Ограничения: таймаут 10 сек (Hobby), 60 сек (Pro). Stateless — каждый вызов независим.
Тестирование
Локально: npm run dev → MCP Inspector или curl POST на /mcp.
Удалённо: curl -i https://<project>.vercel.app/mcp → MCP Inspector с удалённым URL.
Подключение к клиентам
- Cursor: Settings → Features → MCP → Streamable HTTP → URL
/mcp - Claude Desktop:
claude_desktop_config.json→url: "https://<project>.vercel.app/mcp" - VS Code:
.vscode/mcp.json→type: "http", url/mcp
Чеклист
| Проверка | Результат |
|---|---|
npm run typecheck |
0 ошибок |
npm run build |
Сборка OK |
| MCP Inspector (локально) | Видит tools + resource |
curl tools/call |
Возвращает кряк / кряк + мудрость |
| Vercel deploy | 200 OK |
| MCP Inspector (удалённо) | Работает |
| Cursor/Claude | LLM вызывает инструменты |
Порядок реализации
ФАЗА 1: Tool #1 (quack) — полный цикл
- Инициализация проекта:
package.json,tsconfig.json, зависимости src/tools/quack.ts— Tool #1 (quack)src/server.ts— McpServer + регистрация quack tool (без resource)src/index.ts— Express dev-серверapi/mcp.ts+vercel.json— Vercel конфигурацияnpm run typecheck→ исправить ошибкиnpm run build→ убедиться что компилируется- Тест MCP Inspector локально — вызвать quack, проверить ответ
- Тест curl локально — POST запрос, проверить JSON-RPC ответ
git init+git push→ деплой на Vercel- Тест MCP Inspector удалённо — проверить что работает через Vercel URL
- Тест curl удалённо — POST запрос к Vercel endpoint
- Подключение к Cursor — проверить что LLM видит и вызывает quack
- Подключение к Claude Desktop — проверить что LLM видит и вызывает quack
ФАЗА 2: Tool #2 + Philosophy (после проверки ФАЗЫ 1)
src/data/wisdoms.ts— наполнить базу мудростейsrc/tools/quack-wisdom.ts— Tool #2 (quack_wisdom)- Добавить регистрацию quack_wisdom в
src/server.ts - Зарегистрировать Resource
about://rubber-duckвsrc/server.ts npm run typecheck→ исправить ошибкиnpm run build→ проверить- Тест MCP Inspector локально — проверить что видит оба tool + resource
- Тест curl локально — вызвать quack_wisdom
git push→ автодеплой на Vercel- Тест MCP Inspector удалённо — проверить что оба tool работают
- Подключение к Cursor/Claude — проверить что LLM использует quack_wisdom