diff --git a/mcp-server.md b/mcp-server.md new file mode 100644 index 0000000..59a57c7 --- /dev/null +++ b/mcp-server.md @@ -0,0 +1,175 @@ +# MCP-сервер «Rubber Duck» — план реализации + +## Контекст + +Проект **rubber-duck** — интерактивная уточка для дебага. MCP-сервер расширяет концепцию: LLM-модель (Claude, Cursor) может «обращаться к уточке» за кряком и мудростью. Сервер — **отдельный репозиторий**, деплой на **Vercel**, стек: **Express + TypeScript + Streamable HTTP**. + +--- + +## Философия сервера + +Сервер не решает задачи за модель. Он — **Explicit Reasoning Buffer** (буфер явных рассуждений). Когда модель застревает в логическом цикле или склонна к галлюцинациям, вызов `quack()` заставляет её: + +1. **Сформулировать аргументы** — чтобы вызвать инструмент, модель должна выгрузить промежуточные мысли из весов в текст. Неявные рассуждения становятся явными данными. +2. **Прервать генерацию** — вместо того чтобы «проскочить» сложный момент, модель делает паузу и структурирует задачу. +3. **Создать внешнюю память** — записывая статус в «уточку», модель формирует краткое резюме пройденных этапов. + +Описывается через **Resource** `about://rubber-duck` — текстовый документ, который сервер отдаёт при запросе. Модель читает его и понимает контекст. + +--- + +## Архитектура + +```txt +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`. На каждый запрос: + +1. Новый `McpServer` (с tools + resources) +2. `StreamableHTTPServerTransport` — **stateless** (`sessionIdGenerator: undefined`) +3. Подключение + обработка запроса + +Локально: `index.ts` с `app.listen(3000)`. + +--- + +## Деплой на Vercel + +`vercel.json`: маппинг `/mcp` → `api/mcp.ts` через `@vercel/node`. + +1. Push в GitHub +2. Vercel → Add New Project → выбрать репозиторий +3. Deploy +4. URL: `https://.vercel.app/mcp` + +Ограничения: таймаут 10 сек (Hobby), 60 сек (Pro). Stateless — каждый вызов независим. + +--- + +## Тестирование + +**Локально**: `npm run dev` → MCP Inspector или curl POST на `/mcp`. + +**Удалённо**: `curl -i https://.vercel.app/mcp` → MCP Inspector с удалённым URL. + +--- + +## Подключение к клиентам + +- **Cursor**: Settings → Features → MCP → Streamable HTTP → URL `/mcp` +- **Claude Desktop**: `claude_desktop_config.json` → `url: "https://.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) — полный цикл + +1. Инициализация проекта: `package.json`, `tsconfig.json`, зависимости +2. `src/tools/quack.ts` — Tool #1 (quack) +3. `src/server.ts` — McpServer + регистрация quack tool (без resource) +4. `src/index.ts` — Express dev-сервер +5. `api/mcp.ts` + `vercel.json` — Vercel конфигурация +6. `npm run typecheck` → исправить ошибки +7. `npm run build` → убедиться что компилируется +8. **Тест MCP Inspector локально** — вызвать quack, проверить ответ +9. **Тест curl локально** — POST запрос, проверить JSON-RPC ответ +10. `git init` + `git push` → деплой на Vercel +11. **Тест MCP Inspector удалённо** — проверить что работает через Vercel URL +12. **Тест curl удалённо** — POST запрос к Vercel endpoint +13. **Подключение к Cursor** — проверить что LLM видит и вызывает quack +14. **Подключение к Claude Desktop** — проверить что LLM видит и вызывает quack + +### ФАЗА 2: Tool #2 + Philosophy (после проверки ФАЗЫ 1) + +1. `src/data/wisdoms.ts` — наполнить базу мудростей +2. `src/tools/quack-wisdom.ts` — Tool #2 (quack_wisdom) +3. Добавить регистрацию quack_wisdom в `src/server.ts` +4. Зарегистрировать Resource `about://rubber-duck` в `src/server.ts` +5. `npm run typecheck` → исправить ошибки +6. `npm run build` → проверить +7. **Тест MCP Inspector локально** — проверить что видит оба tool + resource +8. **Тест curl локально** — вызвать quack_wisdom +9. `git push` → автодеплой на Vercel +10. **Тест MCP Inspector удалённо** — проверить что оба tool работают +11. **Подключение к Cursor/Claude** — проверить что LLM использует quack_wisdom