docs: update docs

This commit is contained in:
2026-09-03 16:50:16 +05:00
parent c64d84d160
commit c1dda4d257
2 changed files with 158 additions and 362 deletions
+79 -120
View File
@@ -2,19 +2,30 @@
## Контекст
Проект **rubber-duck** — интерактивная уточка для дебага. MCP-сервер расширяет концепцию: LLM-модель (Claude, Cursor) может «обращаться к уточке» за кряком и мудростью. Сервер — **отдельный репозиторий**, деплой на **Vercel**, стек: **Express + TypeScript + Streamable HTTP**.
Проект **rubber-duck** — интерактивная уточка для дебага. MCP-сервер расширяет концепцию: LLM (Claude, Cursor) может «обращаться к уточке» за кряком и мудростью. Сервер — отдельный репозиторий, деплой на Vercel (Hobby, бесплатно).
---
## Стек
| Что | Пакет | Зачем |
| ----------- | ------------------------------------- | ------------------------------------------------- |
| Фреймворк | **Next.js 15+** (App Router) | Route Handlers на Vercel, autodeploy из коробки |
| MCP-адаптер | **`mcp-handler` ^2.1.1** | HTTP-адаптер от Vercel, stateless Streamable HTTP |
| MCP SDK | **`@modelcontextprotocol/server` ^2** | McpServer, registerTool, registerResource |
| Валидация | **`zod` ^4** | Schema для input тулзов |
`@vercel/mcp-adapter` и `@modelcontextprotocol/sdk` v1 — **устарели**. Используем `mcp-handler` v2 + `@modelcontextprotocol/server` v2.
---
## Философия сервера
Сервер не решает задачи за модель. Он**Explicit Reasoning Buffer** (буфер явных рассуждений). Когда модель застревает в логическом цикле или склонна к галлюцинациям, вызов `quack()` заставляет её:
Сервер — **Explicit Reasoning Buffer** (буфер явных рассуждений). Не решает задачи за модель. Когда LLM застревает в логическом цикле, вызов `quack()` заставляет:
1. **Сформулировать аргументы**чтобы вызвать инструмент, модель должна выгрузить промежуточные мысли из весов в текст. Неявные рассуждения становятся явными данными.
2. **Прервать генерацию**вместо того чтобы «проскочить» сложный момент, модель делает паузу и структурирует задачу.
3. **Создать внешнюю память** — записывая статус в «уточку», модель формирует краткое резюме пройденных этапов.
Описывается через **Resource** `about://rubber-duck` — текстовый документ, который сервер отдаёт при запросе. Модель читает его и понимает контекст.
1. **Сформулировать аргументы**выгрузить мысли из весов в текст.
2. **Прервать генерацию**сделать паузу и структурировать задачу.
3. **Создать внешнюю память** — задокументировать пройденный этап.
---
@@ -22,154 +33,102 @@
```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
├── app/
│ ├── layout.tsx — корневой layout
│ ├── page.tsx заглушка
── api/mcp/route.ts — MCP-хендлер (GET + POST)
├── lib/
│ └── mcp.ts — McpServer + инструменты
├── package.json
── tsconfig.json
── tsconfig.json
└── next.config.ts
```
---
## Зависимости
## Инструменты
- **@modelcontextprotocol/sdk** — McpServer + StreamableHTTPServerTransport
- **express** — HTTP-сервер
- **@types/express, typescript** — типизация
- **tsx** — dev-запуск TypeScript без сборки
### Tool #1: `quack` (ФАЗА 1)
---
Заставляет модель остановиться. Аргумент `mood` (опциональный): `"happy" | "confused" | "excited" | "sleepy"`. Без аргумента — случайный кряк из общей пуллы. Возвращает `TextContent` с текстом кряка.
## Инструменты (Tools)
### Tool #2: `quack_wisdom` (ФАЗА 2)
### Tool #1: `quack` (ФАЗА 1 — полная реализация)
Кряк + случайная мудрость программиста. Аргумент `topic` (опциональный): `"debugging" | "life" | "code" | "random"`. База мудростей — массив `{ text, author?, topic? }` в `src/data/wisdoms.ts`.
- **Назначение**: Заставляет модель остановиться и сформулировать мысль
- **Аргументы**: `mood` (опциональный) — `"happy" | "confused" | "excited" | "sleepy"`
- **Логика**: Без аргументов — случайный кряк. С `mood` — кряк подбирается по настроению
- **Возвращает**: `TextContent` с текстом кряка
### Resource: `about://rubber-duck` (ФАЗА 2)
### 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)`.
Текстовый документ (~10-15 строк) с описанием философии сервера. Модель читает его и понимает контекст.
---
## Деплой на Vercel
`vercel.json`: маппинг `/mcp``api/mcp.ts` через `@vercel/node`.
### Вариант A: Vercel CLI (без GitHub)
```bash
npm i -g vercel
vercel login # авторизация через браузер
vercel --prod # деплой
```
При первом запуске `vercel` задаст вопросы — отвечаем: Yes, наш аккаунт, No (новый проект), текущая директория. URL будет `https://rubber-duck-mcp.vercel.app`.
### Вариант B: GitHub (автодеплой)
1. Push в GitHub
2. Vercel → Add New Project → выбрать репозиторий
3. Deploy
4. URL: `https://<project>.vercel.app/mcp`
3. Framework: Next.js (автоопределение) → Deploy
Ограничения: таймаут 10 сек (Hobby), 60 сек (Pro). Stateless — каждый вызов независим.
### Лимиты Hobby (бесплатно)
---
## Тестирование
**Локально**: `npm run dev` → MCP Inspector или curl POST на `/mcp`.
**Удалённо**: `curl -i https://<project>.vercel.app/mcp` → MCP Inspector с удалённым URL.
Таймаут функции 300с, деплои 100/день, проектов 200. Для quack ответ за ~1мс — лимиты не актуальны. `vercel.json` не нужен.
---
## Подключение к клиентам
- **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`
**Cursor:** Settings → Features → MCP → Streamable HTTP → URL `/api/mcp`
**Claude Desktop:** в `claude_desktop_config.json` прописать `"url": "https://<project>.vercel.app/api/mcp"`. Если клиент не поддерживает Streamable HTTP — через `mcp-remote` как бридж.
---
## Чеклист
| Проверка | Результат |
| ------------------------ | --------------------------------- |
| `npm run typecheck` | 0 ошибок |
| `npm run build` | Сборка OK |
| MCP Inspector (локально) | Видит tools + resource |
| curl `tools/call` | Возвращает кряк / кряк + мудрость |
| Vercel deploy | 200 OK |
| MCP Inspector (удалённо) | Работает |
| Cursor/Claude | LLM вызывает инструменты |
| Проверка | Результат |
| ------------------------ | ------------------ |
| `npm run typecheck` | 0 ошибок |
| `npm run build` | Сборка OK |
| MCP Inspector (локально) | Видит tools |
| curl `tools/call` | Возвращает кряк |
| `vercel --prod` | Деплой OK |
| MCP Inspector (удалённо) | Работает |
| Cursor / Claude | LLM вызывает quack |
---
## Порядок реализации
### ФАЗА 1: Tool #1 (quack) — полный цикл
### ФАЗА 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`
1. `npx create-next-app@latest rubber-duck-mcp --typescript --app`
2. Установить `mcp-handler`, `@modelcontextprotocol/server`, `zod`
3. Создать `lib/mcp.ts` — функция `createMcpServer()` с tool `quack`
4. Создать `app/api/mcp/route.ts` — хендлер через `createMcpHandler`
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
6. `npm run build`убедиться
7. Тест локально: MCP Inspector + curl
8. Деплой: `vercel --prod` (или через GitHub)
9. Тест удалённо: MCP Inspector + curl к Vercel URL
10. Подключение к Cursor и Claude Desktop — проверить что LLM вызывает quack
### ФАЗА 2: quack_wisdom + Philosophy
1. Создать `src/data/wisdoms.ts` — база мудростей
2. Добавить tool `quack_wisdom` в `lib/mcp.ts`
3. Зарегистрировать resource `about://rubber-duck`
4. `npm run typecheck` + `npm run build`
5. Тест локально: MCP Inspector видит оба tool + resource
6. `vercel --prod` → тест удалённо
7. Подключение к Cursor/Cude — проверить quack_wisdom