diff --git a/mcp-server.md b/mcp-server.md index 59a57c7..59b4fc2 100644 --- a/mcp-server.md +++ b/mcp-server.md @@ -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://.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://.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://.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://.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 diff --git a/mcp.md b/mcp.md index 6632a67..09495be 100644 --- a/mcp.md +++ b/mcp.md @@ -22,7 +22,7 @@ - **Польза**: Записывая статус в «уточку», модель создает для самой себя краткое резюме (summary) пройденных этапов. -## Как это описать в описании MCP-сервера: +## Как это описать в описании MCP-сервера Вы можете описать это как «Explicit Reasoning Buffer» (Буфер явных рассуждений). @@ -31,7 +31,7 @@ --- -Чтобы сделать свой Model Context Protocol (MCP) сервер, вам нужно реализовать приложение, которое общается с клиентом (например, Claude Desktop, Cursor или ИИ-агентом) через JSON-RPC 2.0. Протокол стандартизирован компанией Anthropic и работает поверх стандартных потоков ввода-вывода (Stdio) или WebSockets. [1, 2] +Чтобы сделать свой Model Context Protocol (MCP) сервер, вам нужно реализовать приложение, которое общается с клиентом (например, Claude Desktop, Cursor или ИИ-агентом) через JSON-RPC 2.0. Протокол стандартизирован компанией Anthropic и работает поверх стандартных потоков ввода-вывода (Stdio) или Streamable HTTP. [1, 2] --- @@ -160,299 +160,136 @@ if __name__ == "__main__": --- -Развертывание MCP-сервера на Vercel накладывает важное техническое ограничение: [Vercel](https://vercel.com/) работает на Serverless-функциях, поэтому стандартный локальный протокол связи (через терминал Stdio) здесь использовать нельзя. +## Деплой MCP-сервера на Vercel -Вместо этого удаленные серверы общаются через SSE (Server-Sent Events) и POST-запросы. Vercel предоставляет официальный пакет `@vercel/mcp-adapter`, который делает за вас всю грязную работу по управлению сессиями в Serverless-среде. [1, 2, 3] +Vercel работает на Serverless-функциях, поэтому стандартный локальный протокол Stdio здесь использовать нельзя. Современное решение — **Streamable HTTP** (спека MCP 2026-07-28). Пакет `mcp-handler` от Vercel принимает HTTP POST-запросы и отвечает JSON-RPC. Stateless, без Redis, без долгоживущих SSE-соединений — идеально для serverless. -Ниже пошаговый план, как создать такой сервер на SvelteKit и развернуть на Vercel. [3, 4] +> **Актуальные пакеты** (сентябрь 2026): `mcp-handler` v2.1.1 + `@modelcontextprotocol/server` v2 + `zod` v4. Пакеты `@vercel/mcp-adapter` и `@modelcontextprotocol/sdk` v1 — **устарели**. ---- - -## Шаг 1. Инициализация SvelteKit-проекта - -Если у вас еще нет проекта, создайте его: +### Шаг 1. Инициализация Next.js-проекта ```bash -npm create svelte@latest my-mcp-server +npx create-next-app@latest my-mcp-server --typescript --app cd my-mcp-server -npm install ``` -Установите необходимые зависимости для работы MCP-сервера в среде Vercel: [4] +Установите зависимости для MCP-сервера: ```bash -npm install @modelcontextprotocol/sdk @vercel/mcp-adapter -npm install -D @sveltejs/adapter-vercel +npm install mcp-handler@^2 @modelcontextprotocol/server@^2 zod@^4 ``` -Убедитесь, что в файле `svelte.config.js` подключен верный адаптер: [5] +### Шаг 2. Создание API эндпоинта (route.ts) -```js -import adapter from "@sveltejs/adapter-vercel"; -import { vitePreprocess } from "@sveltejs/vite-plugin-svelte"; - -/** @type {import('@sveltejs/kit').Config} */ -const config = { - preprocess: vitePreprocess(), - kit: { - adapter: adapter(), // Адаптер для Vercel - }, -}; - -export default config; -``` - ---- - -## Шаг 2. Создание API эндпоинта (+server.ts) - -По спецификации MCP на базе SSE, серверу требуются два роута: один открывает бесконечный поток для чтения событий (SSE), а второй принимает входящие POST-команды от клиента. Пакет `@vercel/mcp-adapter` объединяет их в один обработчик. [2, 6] - -Создайте файл `src/routes/api/mcp/+server.ts` и добавьте следующий код: +Создайте файл `app/api/mcp/route.ts`: ```typescript -import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { createMcpHandler } from "mcp-handler"; import { z } from "zod"; -import { createActionHandler } from "@vercel/mcp-adapter"; -import type { RequestHandler } from "./$types"; -// 1. Инициализируем стандартный MCP-сервер из SDK Anthropic -const server = new McpServer({ - name: "SvelteKit MCP Server", - version: "1.0.0", +const handler = createMcpHandler((server) => { + server.registerTool( + "getWeather", + { + title: "Weather", + description: "Возвращает текущую погоду для указанного города", + inputSchema: z.object({ + city: z.string().describe("Название города на английском или русском"), + }), + }, + async ({ city }) => { + return { + content: [ + { + type: "text" as const, + text: `В городе ${city} сейчас отличная погода, +22°C, солнечно.`, + }, + ], + }; + }, + ); }); -// 2. Регистрируем ваш инструмент (Tool) -server.tool( - "getWeather", - "Возвращает текущую погоду для указанного города", - { - city: z.string().describe("Название города на английском или русском"), - }, - async ({ city }) => { - // Здесь может быть ваш реальный fetch к какому-нибудь Weather API - return { - content: [ - { - type: "text", - text: `В городе ${city} сейчас отличная погода, +22°C, солнечно.`, - }, - ], - }; - }, -); - -// 3. Создаем обработчик для Vercel с помощью адаптера. -// Адаптер автоматически поддерживает Streamable HTTP и SSE. -const mcpHandler = createActionHandler(server); - -// Экспортируем методы для SvelteKit -export const GET: RequestHandler = async ({ request }) => { - return mcpHandler(request); -}; - -export const POST: RequestHandler = async ({ request }) => { - return mcpHandler(request); -}; +export { handler as GET, handler as POST }; ``` ---- +### Шаг 3. Деплой на Vercel -## Шаг 3. Деплой на Vercel +1. Запуште код в Git-репозиторий (GitHub, GitLab или Bitbucket). +2. Vercel → **Add New > Project** → выбрать репозиторий. +3. Framework: **Next.js** (автоопределение). +4. **Deploy**. -1. Запуште ваш код в Git-репозиторий (GitHub, GitLab или Bitbucket). -2. Зайдите в панель управления Vercel и нажмите **Add New > Project**. -3. Выберите ваш репозиторий. Vercel автоматически определит, что это SvelteKit, и выставит правильные настройки сборки. -4. Нажмите **Deploy**. [7] +URL: `https://my-mcp-server.vercel.app` +MCP-эндпоинт: `https://<ваш-проект>.vercel.app/api/mcp` -После завершения деплоя вы получите URL вашего сайта, например: `https://my-mcp-server.vercel.app`. Ваш MCP эндпоинт будет доступен по адресу `https://<ваш-проект>.vercel.app`. +**Лимиты Vercel Hobby (бесплатно):** -## Шаг 4. Подключение к клиенту (Cursor / Claude Desktop) +| Ресурс | Лимит | Наш сервер | +| --------------- | ----------- | -------------- | +| Таймаут функции | 300с (макс) | ~1мс на вызов | +| Деплои/день | 100 | 1 (autodeploy) | +| Redis | Не нужен | Stateless | -Поскольку сервер теперь находится в сети и работает по протоколу SSE, его настройка в приложениях немного отличается от локальной. [2] +### Шаг 4. Подключение к клиентам -### Для Cursor (и аналогичных IDE): +**Cursor:** -1. Откройте **Settings > Features > MCP**. -2. Нажмите **+ Add New MCP Server**. -3. Заполните поля: - - **Name**: `SvelteKit-MCP` - - **Type**: из выпадающего списка выберите `SSE`. - - **URL**: `https://<ваш-проект>.vercel.app` [8] +1. Settings > Features > MCP → + Add New MCP Server +2. Type: **Streamable HTTP** +3. URL: `https://<ваш-проект>.vercel.app/api/mcp` -### Для Claude Desktop: - -Откройте файл конфигурации `claude_desktop_config.json` и пропишите вызов через команду `curl` или встроенный в Node.js транспорт (утилита автоматически преобразует SSE в понятный для Claude формат): +**Claude Desktop:** ```json { "mcpServers": { - "sveltekit-remote-mcp": { - "command": "npx", - "args": ["-y", "@modelcontextprotocol/inspector", "sse", "https://<ваш-проект>.vercel.app"] + "my-mcp": { + "url": "https://<ваш-проект>.vercel.app/api/mcp" } } } ``` -## Важные нюансы при работе на Vercel: +Если клиент не поддерживает Streamable HTTP, используйте `mcp-remote` как бридж: -- **Таймауты serverless-функций**: На бесплатном тарифе Vercel (Hobby) лимит на выполнение функции составляет 10–15 секунд. Убедитесь, что ваши инструменты (запросы к сторонним API, вычисления) укладываются в это время, иначе соединение оборвется. -- **Базы данных и переменные окружения**: Если вашему инструменту понадобятся API-ключи, обязательно добавьте их в панель Vercel в разделе **Project Settings > Environment Variables**. [9, 10] - ---- - -Поскольку данные статичны, мы можем сделать код максимально чистым, используя TypeScript и встроенную валидацию через Zod. - -Вот готовый пример реализации файла `src/routes/api/mcp/+server.ts`, где данные (например, документация по вашему проекту или готовая база знаний) хранятся прямо внутри: - -```typescript -import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; -import { z } from "zod"; -import { createActionHandler } from "@vercel/mcp-adapter"; -import type { RequestHandler } from "./$types"; - -// 1. Статические данные (база знаний сервера) -const KNOWLEDGE_BASE: Record = { - api: "Наш API использует методы GET для чтения и POST для отправки команд.", - deploy: "Деплой автоматизирован через Vercel Git Integration при каждом пуше в main.", - contacts: "Техническая поддержка доступна по адресу support@mycompany.com.", - rules: "Все новые фичи должны быть покрыты тестами перед слиянием (ветка staging).", -}; - -// 2. Инициализируем MCP-сервер -const server = new McpServer({ - name: "SvelteKit Static MCP", - version: "1.0.0", -}); - -// 3. Регистрируем инструмент для поиска по готовым данным -server.tool( - "getStaticData", - "Возвращает готовую справочную информацию по ключевому слову (api, deploy, contacts, rules).", - { - topic: z.enum(["api", "deploy", "contacts", "rules"]).describe("Ключевое слово темы для поиска"), - }, - async ({ topic }) => { - // Извлекаем уже готовые данные - const info = KNOWLEDGE_BASE[topic]; - - return { - content: [ - { - type: "text", - text: info || `Информация по теме "${topic}" не найдена.`, - }, - ], - }; - }, -); - -// 4. Настройка адаптера для работы с Vercel Serverless -const mcpHandler = createActionHandler(server); - -export const GET: RequestHandler = async ({ request }) => mcpHandler(request); -export const POST: RequestHandler = async ({ request }) => mcpHandler(request); +```json +{ + "mcpServers": { + "my-mcp": { + "command": "npx", + "args": ["-y", "mcp-remote", "https://<ваш-проект>.vercel.app/api/mcp"] + } + } +} ``` -## Как это будет работать для ИИ: +### Проверка сервера -Когда вы подключите этот сервер к Cursor или Claude Desktop, модель поймет, какие темы доступны (благодаря `z.enum`). Если вы спросите ИИ: «Как связаться с поддержкой?» или «Каковы правила деплоя?», модель автоматически вызовет инструмент `getStaticData` с нужным параметром и мгновенно получит зашитый в код ответ. - -## Что делать дальше? - -1. Замените ключи и тексты в объекте `KNOWLEDGE_BASE` на ваши реальные данные. -2. Обновите список доступных тем в `z.enum([...])`. -3. Сделайте `git commit` и `git push` — Vercel сам пересоберет проект за пару секунд. - ---- - -## Вот 3 лучших способа проверить валидность вашего сервера от самого простого к продвинутому. - -### Способ 1. Самый быстрый (в браузере за 5 секунд) - -Так как ваш сервер развернут на Vercel и принимает GET-запросы, вы можете проверить его прямо в браузере или через curl. - -1. Откройте браузер и перейдите по адресу вашего эндпоинта (например, `https://<ваш-проект>.vercel.app`). -2. Что вы должны увидеть: Браузер должен начать бесконечную загрузку страницы или отобразить текстовый поток (SSE Stream), начинающийся со строки: - - ``` - event: endpoint - data: /api/mcp?session_id=... - ``` - - Если вы увидели эту строку и статус ответа `200 OK` — транспортный уровень SSE работает корректно. - ---- - -### Способ 2. Официальный веб-интерфейс (MCP Inspector) - -Команда Anthropic создала специальную интерактивную панель для тестирования локальных и удаленных серверов. - -Запустите в терминале команду (утилита скачается и запустится автоматически через npx): +**curl (быстрая проверка JSON-RPC):** ```bash -npx @modelcontextprotocol/inspector sse https://<ваш-проект>.vercel.app -``` - -(Замените URL на ваш адрес на Vercel) - -Что произойдет дальше: - -1. В терминале появится ссылка (обычно `http://localhost:5173`). Откройте ее в браузере. -2. Вы увидите графическую панель управления вашим MCP-сервером. -3. Нажмите кнопку **List Tools** — в интерфейсе должен появиться ваш инструмент `getStaticData` со всей схемой параметров. -4. Вы можете заполнить поля формы (например, выбрать тему `api`) и нажать **Call Tool**. Вы мгновенно увидите сырой JSON-ответ от Vercel. - -> Это эталонный метод проверки: если Inspector работает без ошибок, значит, любой ИИ (Cursor, Claude) гарантированно поймет ваш сервер. - -### Способ 3. Проверка через Postman / Insomnia / cURL - -Если вы хотите убедиться, что JSON-RPC команды обрабатываются правильно, можно сымитировать запрос от ИИ вручную. Для этого нужно сделать POST-запрос, но с одной важной деталью: протокол SSE требует ID сессии, который сервер выдает при GET-запросе. - -Проще всего сделать это через curl в два шага: - -**Шаг 1: Инициализация сессии (GET)** - -```bash -curl -i https://<ваш-проект>.vercel.app -``` - -В ответе найдите строку `data: /api/mcp?session_id=ХХХХХХ`. Скопируйте этот хвост с ID сессии. - -**Шаг 2: Вызов инструмента (POST)** - -Отправьте JSON-RPC запрос на полученный адрес сессии: - -```bash -curl -X POST "https://<ваш-проект>.vercel.app/api/mcp?session_id=ХХХХХХ" \ +curl -X POST "https://<ваш-проект>.vercel.app/api/mcp" \ -H "Content-Type: application/json" \ -d '{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { - "name": "getStaticData", - "arguments": { - "topic": "api" - } + "name": "getWeather", + "arguments": { "city": "Moscow" } } }' ``` -Правильный ответ сервера должен выглядеть так: +**MCP Inspector (локально):** -```json -{ - "jsonrpc": "2.0", - "id": 1, - "result": { - "content": [ - { - "type": "text", - "text": "Наш API использует методы GET для чтения и POST для отправки команд." - } - ] - } -} +```bash +npx @modelcontextprotocol/inspector npx mcp-remote http://localhost:3000/api/mcp +``` + +**MCP Inspector (удалённо):** + +```bash +npx @modelcontextprotocol/inspector npx mcp-remote https://<ваш-проект>.vercel.app/api/mcp ```