Article·  

Как мы сделали MCP-сервер для Nuxt

Как устроен Nuxt MCP server: доступ AI-ассистентов к документации через структурированные данные и композаблы.
Hugo Richard

Hugo Richard

@hugorcd

Sébastien Chopin

Sébastien Chopin

@Atinux

ИИ-ассистенты становятся важной частью опыта разработчика. Чтобы они могли давать точную и актуальную информацию о Nuxt, мы сделали MCP-сервер, который отдаёт документацию, посты блога и гайды по деплою в структурированном виде. Ниже — как мы это сделали с Nuxt MCP Toolkit и как вы можете собрать свой сервер.

Хотите попробовать MCP-сервер Nuxt? Перейдите в документацию Nuxt MCP Server.

Что такое MCP и зачем мы его сделали

Model Context Protocol (MCP) — открытый стандарт, который даёт ИИ-ассистентам безопасный доступ к данным и инструментам. По сути это API для ИИ: вместо HTML или «сырого» JSON он отдаёт структурированные семантические данные, удобные для LLM.

В MCP есть три основные сущности:

  • Resources — данные, которые сервер отдаёт как контекст для моделей: файлы, схемы БД, специфичная для приложения информация. Каждый ресурс идентифицируется URI.
  • Tools — возможность для моделей вызывать внешние системы и выполнять операции (поиск, вызовы API и т.д.).
  • Prompts — переиспользуемые шаблоны промптов с аргументами, которые может вызывать пользователь.

Почему MCP, а не RAG?

По нашим наблюдениям, ассистенты с MCP-серверами дают заметно лучшие ответы, чем классический RAG (Retrieval-Augmented Generation):

  • Структура на входе и выходе — у инструментов явные параметры и типизированные ответы, меньше галлюцинаций.
  • Композиция инструментов — ассистент может вызывать цепочки (например, поиск по теме, затем загрузка полного контента).
  • Быстрее и точнее — не нужно обрабатывать и чанкить большие документы в момент запроса.
  • Всегда актуально — прямой доступ к контенту без переиндексации.
  • Контекстная навигация — ИИ может осмысленно переходить по связям между материалами.

И Nuxt, и Nuxt UI теперь имеют MCP-серверы с похожей архитектурой — ассистентам проще помогать разработчикам с этими фреймворками.

Техническая архитектура

MCP-сервер встроен в nuxt.com и собран на модуле Nuxt MCP Toolkit. Модуль автоматически обнаруживает инструменты, ресурсы и промпты в server-директории:

nuxt.com/
├── server/
│   └── mcp/
│       ├── tools/
│       │   ├── list-documentation-pages.ts
│       │   ├── get-documentation-page.ts
│       │   └── ...
│       ├── resources/
│       │   ├── nuxt-documentation-pages.ts
│       │   └── ...
│       └── prompts/
│           ├── find-documentation-for-topic.ts
│           └── ...
└── nuxt.config.ts

Архитектура простая: инструменты, ресурсы и промпты задаются отдельными файлами, модуль сам их регистрирует и поднимает HTTP endpoint для MCP-клиентов. Ручная настройка сервера и транспорта не нужна — достаточно создать файлы в нужных директориях.

Разбор реализации

Подключение модуля

Достаточно добавить модуль в конфиг Nuxt:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/mcp-toolkit'],
  mcp: {
    name: 'Nuxt',
  }
})

Модуль сам сканирует server/mcp/ и регистрирует всё найденное.

Tools: операции для моделей

Инструменты позволяют языковым моделям вызывать внешние системы: принимают параметры и выполняют операции. Так реализован наш инструмент list_documentation_pages:

server/mcp/tools/list-documentation-pages.ts
import { z } from 'zod'
import { queryCollection } from '@nuxt/content/server'

export default defineMcpTool({
  description: `Lists all available Nuxt documentation pages with their categories and basic information.

WHEN TO USE: Use this tool when you need to EXPLORE or SEARCH for documentation about a topic but don't know the exact page path.

WHEN NOT TO USE: If you already know the specific page path, use get_documentation_page directly instead.`,
  inputSchema: {
    version: z.enum(['3.x', '4.x', 'all']).optional().default('4.x').describe('Documentation version to fetch')
  },
  cache: '1h',
  async handler({ version }) {
    const event = useEvent()

    const allDocs = await queryCollection(event, 'docsv4')
      .select('title', 'path', 'description')
      .all()

    return jsonResult(allDocs.map(doc => ({
      title: doc.title,
      path: doc.path,
      description: doc.description,
      url: `https://nuxt.com${doc.path}`
    })))
  }
})

Важные детали:

  • defineMcpTool подхватывается автоимпортом
  • inputSchema — Zod для валидации параметров
  • cache: '1h' включает кэширование ответов
  • jsonResult() — хелпер для форматирования ответа

Имя инструмента берётся из имени файла (list-documentation-pages.tslist_documentation_pages).

Resources: контекст для моделей

Ресурсы дают серверам возможность отдавать данные в качестве контекста (файлы, схемы БД, данные приложения). Каждый ресурс идентифицируется URI.

Самый простой способ отдать файл — свойство file: URI, MIME-тип и чтение файла обрабатываются автоматически:

server/mcp/resources/readme.ts
export default defineMcpResource({
  name: 'readme',
  description: 'Файл README проекта',
  file: 'README.md' // Относительно корня проекта
})

Для динамических ресурсов можно задать свой handler:

server/mcp/resources/nuxt-documentation-pages.ts
import { queryCollection } from '@nuxt/content/server'

export default defineMcpResource({
  uri: 'resource://nuxt-com/documentation-pages',
  description: 'Полный список страниц документации Nuxt (по умолчанию v4.x)',
  cache: '1h',
  async handler(uri: URL) {
    const event = useEvent()

    const allDocs = await queryCollection(event, 'docsv4')
      .select('title', 'path', 'description')
      .all()

    const result = allDocs.map(doc => ({
      title: doc.title,
      path: doc.path,
      description: doc.description,
      version: '4.x',
      url: `https://nuxt.com${doc.path}`
    }))

    return {
      contents: [{
        uri: uri.href,
        mimeType: 'application/json',
        text: JSON.stringify(result, null, 2)
      }]
    }
  }
})

В отличие от инструментов, которыми управляет модель, ресурсами управляет приложение: оно решает, как их подключать (через UI, автоматический контекст и т.д.).

Prompts: переиспользуемые шаблоны

Промпты — шаблоны с аргументами, которые может вызывать пользователь. Они возвращают формат диалога и направляют ИИ по нужному сценарию:

server/mcp/prompts/find-documentation-for-topic.ts
import { z } from 'zod'
import { queryCollection } from '@nuxt/content/server'

export default defineMcpPrompt({
  description: 'Подобрать подходящую страницу документации Nuxt по теме или возможностям',
  inputSchema: {
    topic: z.string().describe('О чём хотите узнать'),
    version: z.enum(['3.x', '4.x']).optional().describe('Версия документации для поиска')
  },
  async handler({ topic, version = '4.x' }) {
    const event = useEvent()
    const docsVersion = version === '4.x' ? 'docsv4' : 'docsv3'

    const allDocs = await queryCollection(event, docsVersion)
      .select('title', 'path', 'description')
      .all()

    const allPages = allDocs?.map(doc => ({
      title: doc.title,
      path: doc.path,
      description: doc.description,
      url: `https://nuxt.com${doc.path}`
    })) || []

    return {
      messages: [{
        role: 'user' as const,
        content: {
          type: 'text' as const,
          text: `Помоги найти подходящую страницу документации Nuxt по теме: «${topic}». Доступные страницы: ${JSON.stringify(allPages, null, 2)}`
        }
      }]
    }
  }
})

Промпты вызываются пользователем и возвращают сообщения диалога; инструменты вызываются моделью и возвращают структурированные данные.

Встроенные хелперы

Модуль даёт автоимпортируемые хелперы:

  • defineMcpTool, defineMcpResource, defineMcpPrompt — объявление примитивов MCP
  • jsonResult(data) — форматирование JSON-ответа для инструментов
  • errorResult(message) — ответ с ошибкой из инструмента

Nuxt server utilities в обработчиках

Чтобы использовать в обработчиках утилиты вроде useEvent(), включите asyncContext в конфиге Nuxt:

nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    asyncContext: true
  }
})

После этого доступны H3 event и серверные композаблы Nuxt, например queryCollection из Nuxt Content.

Свой MCP-сервер

Хотите поднять MCP-сервер для своего приложения? С Nuxt MCP Toolkit это делается за несколько минут.

1. Установка модуля

Terminal
npx nuxi module add mcp-toolkit

2. Настройка модуля

Добавьте базовую конфигурацию в конфиг Nuxt:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/mcp-toolkit'],
  mcp: {
    name: 'my-app'
  }
})

3. Первый инструмент

Создайте файл в server/mcp/tools/:

server/mcp/tools/search.ts
import { z } from 'zod'

export default defineMcpTool({
  description: 'Поиск по моему контенту',
  inputSchema: {
    query: z.string().describe('Поисковый запрос')
  },
  async handler({ query }) {
    // Ваша логика поиска
    const results = await searchContent(query)
    return jsonResult(results)
  }
})

Готово. MCP-сервер доступен по адресу https://your-domain.com/mcp.

4. Ресурсы и промпты (по желанию)

Ресурсы и промпты добавляются по той же схеме:

server/mcp/resources/readme.ts
export default defineMcpResource({
  name: 'readme',
  description: 'Файл README проекта',
  file: 'README.md'
})

Расширенные опции конфигурации — в документации Nuxt MCP Toolkit.

Подключение к MCP-серверу Nuxt

MCP-сервер Nuxt уже доступен: в нём документация, посты блога и гайды по деплою.

Быстрая установка в Cursor

Проще всего подключить через установку в один клик в Cursor:

Установить Nuxt MCP Server в Cursor

Другие ИИ-ассистенты

MCP-сервер Nuxt работает с Claude Desktop, Windsurf, Visual Studio Code, ChatGPT и другими MCP-совместимыми ассистентами. Инструкции по настройке для всех платформ — в документации MCP.

Собирайте MCP-серверы для своих приложений: документация, API, доменные знания — MCP помогает ассистентам давать точную и полезную информацию пользователям.

Исходный код нашего MCP-сервера — в GitHub, директория server/mcp/. Можете использовать его как основу для своей реализации.

← Вернуться в блог
Nuxt on LinkedInNuxt on BlueskyNuxt on X