Article·  

为 Nuxt 构建 MCP 服务器

我们如何构建 Nuxt MCP 服务器,使 AI 助手能够通过结构化数据和可组合工具访问我们的文档。
Hugo Richard

Hugo Richard

@hugorcd__

Sébastien Chopin

Sébastien Chopin

@Atinux

AI 助手正变得越来越重要,提升开发者体验。为了帮助它们提供有关 Nuxt 准确且最新的信息,我们构建了一个 MCP 服务器,以结构化方式暴露我们的文档、博客文章和部署指南。以下是我们的做法,以及你如何构建自己的 MCP 服务器。

想要试用 Nuxt MCP 服务器?跳转到 Nuxt MCP 服务器文档

什么是 MCP,为什么我们要构建它?

模型上下文协议(MCP) 是一个开放标准,使 AI 助手能够安全访问数据和工具。可以将其视为专门为 AI 助手设计的 API:它不返回 HTML 或通用 JSON,而是提供结构化的语义数据,LLM(大型语言模型)可以轻松理解和使用。

MCP 定义了三种主要原语:

  • 资源(Resources):为语言模型提供上下文的数据,通过 URI 唯一标识(如文档页面或博客文章)
  • 工具(Tools):使 AI 模型可以与外部系统交互并执行操作(如搜索或调用 API)
  • 提示(Prompts):可复用的提示模板,带有参数,由用户调用

为什么选择 MCP 而非 RAG?

我们观察到,使用 MCP 服务器的 AI 助手比传统 RAG(检索增强生成)方法提供了明显更优的响应

  • 结构化数据输入,结构化数据输出:工具接受明确的参数并返回类型化数据,有效避免幻觉
  • 可组合的工具:AI 助手可链接多个工具,使用一个工具的输出作为另一个工具的输入(例如:先搜索主题,再获取完整内容)
  • 更快且更精确:无需在查询时处理和拆分大量文档
  • 内容始终最新:直接访问你的内容层,无需重新索引
  • 上下文感知导航:AI 能智能导航内容之间的关系

NuxtNuxt UI 均已提供结构类似的 MCP 服务器,方便 AI 助手帮助开发者使用这些框架。

技术架构

我们的 MCP 服务器直接集成在 nuxt.com,作为服务器路由,利用 Nuxt 的全栈能力:

nuxt.com/
├── server/
│   ├── routes/
│   │   └── mcp.ts  # 主 MCP 服务器
│   └── api/
│       └── mcp/
│           ├── list-documentation-pages.get.ts
│           ├── get-documentation-page.get.ts
│           ├── search-content.get.ts
│           └── ...(其他端点)
└── content/
    ├── blog/
    ├── deploy/
    └── ...(Nuxt Content 文件)

架构简单明了。MCP 服务器路由server/routes/mcp.ts)处理 MCP 协议,API 端点server/api/mcp/*.ts)查询 Nuxt Content,HTTP 传输支持与 AI 助手的实时通信。

实现深度解析

服务器设置

基础是 @modelcontextprotocol/sdk 包。我们创建 MCP 服务器实例并进行配置:

server/routes/mcp.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'

function createServer() {
  const server = new McpServer({
    name: 'nuxt-com',
    version: '1.0.0'
  })

  // 在这里注册资源、工具和提示...
  
  return server
}

资源:为语言模型提供上下文

资源提供语言模型可用的数据和上下文。每个资源由 URI 标识。以下是我们如何暴露所有文档页面:

server/routes/mcp.ts
server.registerResource(
  'nuxt-documentation-pages',
  'resource://nuxt-com/documentation-pages',
  {
    title: 'Nuxt 文档页面',
    description: '所有可用的 Nuxt 文档页面完整列表'
  },
  async (uri) => {
    const result = await $fetch('/api/mcp/list-documentation-pages', {
      query: { version: '4.x' }
    })
    return {
      contents: [{
        uri: uri.href,
        mimeType: 'application/json',
        text: JSON.stringify(result, null, 2)
      }]
    }
  }
)

API 端点使用 Nuxt Content 的 queryCollection 来获取文档页面:

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

const querySchema = z.object({
  version: z.enum(['3.x', '4.x', 'all']).optional().default('4.x')
})

export default defineCachedEventHandler(async (event) => {
  const { version } = await getValidatedQuery(event, querySchema.parse)

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

  return allDocs.map(doc => ({
    title: doc.title,
    path: doc.path,
    description: doc.description,
    version: doc.path.includes('/docs/4.x') ? '4.x' : '3.x',
    url: `https://nuxt.com${doc.path}`
  }))
}, {
  maxAge: 60 * 60, // 缓存 1 小时
  getKey: (event) => `mcp-documentation-pages-${getQuery(event).version || '4.x'}`
})

请注意缓存策略,确保响应快速且内容保持新鲜。更多关于 defineCachedEventHandler 可以参阅 Nitro 文档。

工具:为 AI 模型提供操作能力

工具使语言模型能够通过参数化操作与外部系统交互。我们的 search_content 工具示范了如何用 Zod 进行参数校验:

server/routes/mcp.ts
server.tool(
  'search_content',
  '在所有 Nuxt 内容中搜索,包括文档、博客和部署指南',
  {
    query: z.string().describe('搜索查询'),
    type: z.enum(['docs', 'blog', 'deploy', 'all']).optional(),
    version: z.enum(['3.x', '4.x', 'all']).optional()
  },
  async (params) => {
    const result = await $fetch('/api/mcp/search-content', { query: params })
    return { content: [{ type: 'text', text: JSON.stringify(result, null, 2) }] }
  }
)

搜索实现利用 Nuxt Content 的查询能力:

server/api/mcp/search-content.get.ts
export default defineEventHandler(async (event) => {
  const { query: searchQuery, type, version } = await getValidatedQuery(event, querySchema.parse)

  const results = []

  if (type === 'docs' || type === 'all') {
    const docs = await queryCollection(event, 'docsv4')
      .where('title', 'LIKE', `%${searchQuery}%`)
      .select('title', 'path', 'description')
      .limit(20)
      .all()

    results.push(...docs.map(doc => ({
      type: 'documentation',
      title: doc.title,
      path: doc.path,
      description: doc.description,
      url: `https://nuxt.com${doc.path}`
    })))
  }

  // 对 blog 和 deploy 内容做类似处理...

  return results
})

提示:可复用模板

提示是带参数的可复用模板,用户调用它们。它们返回对话格式,引导 AI 按特定流程工作:

server/routes/mcp.ts
server.registerPrompt(
  'find_documentation_for_topic',
  {
    title: '查找主题相关文档',
    description: '为特定主题查找最佳 Nuxt 文档',
    argsSchema: {
      topic: z.string().describe('你想了解的主题')
    }
  },
  async ({ topic }) => {
    const searchResults = await $fetch('/api/mcp/search-content', {
      query: { query: topic, type: 'docs' }
    })
    
    return {
      messages: [{
        role: 'user',
        content: {
          type: 'text',
          text: `帮我查找关于 "${topic}" 的文档。结果: ${JSON.stringify(searchResults, null, 2)}`
        }
      }]
    }
  }
)

提示和工具不同:提示由用户调用,返回对话消息;工具由模型控制,返回结构化数据。

HTTP 传输层

最后处理 HTTP 通信,使用 Streamable HTTP 传输:

server/routes/mcp.ts
export default defineEventHandler(async (event) => {
  // 浏览器请求重定向到文档
  if (getHeader(event, 'accept')?.includes('text/html')) {
    return sendRedirect(event, '/docs/guide/ai/mcp')
  }

  const server = createServer()

  const transport = new StreamableHTTPServerTransport({
    sessionIdGenerator: undefined
  })

  // 连接关闭时清理
  event.node.res.on('close', () => {
    transport.close()
    server.close()
  })

  await server.connect(transport)

  const body = await readBody(event)
  await transport.handleRequest(event.node.req, event.node.res, body)
})

此处理器完成三个关键操作:

  1. 将浏览器流量重定向到文档
  2. 管理服务器及传输生命周期
  3. 使用 HTTP POST/GET 处理 MCP 协议请求

StreamableHTTPServerTransport 可选使用服务器发送事件(SSE)实现流式响应,适合需要向客户端发送多条消息的场景,同时也支持简单的 JSON 请求-响应模式。

构建你自己的 MCP 服务器

准备为你的应用构建 MCP 服务器?这里有一个简化指南:

1. 安装依赖

Terminal
npm install @modelcontextprotocol/sdk zod

2. 创建服务器路由

在你的 Nuxt 项目中创建 server/routes/mcp.ts

server/routes/mcp.ts
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js'

function createServer() {
  const server = new McpServer({
    name: 'my-app',
    version: '1.0.0'
  })

  // 添加你的资源、工具和提示

  return server
}

export default defineEventHandler(async (event) => {
  const server = createServer()
  const transport = new StreamableHTTPServerTransport()
  
  await server.connect(transport)
  const body = await readBody(event)
  await transport.handleRequest(event.node.req, event.node.res, body)
})

3. 注册你的第一个资源

server/routes/mcp.ts
server.registerResource(
  'my-content',
  'resource://my-app/content',
  {
    title: '我的内容',
    description: '我的全部应用内容'
  },
  async (uri) => {
    const data = await $fetch('/api/my-content')
    return {
      contents: [{
        uri: uri.href,
        mimeType: 'application/json',
        text: JSON.stringify(data, null, 2)
      }]
    }
  }
)

4. 添加搜索工具

server/routes/mcp.ts
server.tool(
  'search',
  '搜索我的内容',
  {
    query: z.string().describe('搜索查询')
  },
  async ({ query }) => {
    const results = await $fetch('/api/search', { query: { q: query } })
    return { content: [{ type: 'text', text: JSON.stringify(results) }] }
  }
)

5. 创建支持的 API 端点

使用 Nuxt Content、数据库或任何数据源支持你的 API 端点:

server/api/my-content.get.ts
import { queryCollection } from '@nuxt/content/server'

export default defineEventHandler(async (event) => {
  const content = await queryCollection(event, 'my-collection').all()
  return content
})

就这样!你的 MCP 服务器现在已可通过 https://your-domain.com/mcp 访问。

我们正在开发一个 Nuxt MCP 模块,帮助你通过目录结构轻松创建 MCP 服务器,敬请期待!

立即开始使用 Nuxt MCP 服务器

准备好体验 Nuxt MCP 的强大功能了吗?我们的服务器已上线,提供对所有 Nuxt 文档、博客文章和部署指南的访问。

Cursor 快速安装

最简单的方式是通过 Cursor 一键安装:

在 Cursor 中安装 Nuxt MCP 服务器

其他 AI 助手

Nuxt MCP 服务器支持 Claude Desktop、Windsurf、Visual Studio Code、ChatGPT 及诸多其他兼容 MCP 的 AI 助手。有关所有平台的完整设置说明,请查阅我们的 MCP 文档

我们鼓励你为自己的应用构建 MCP 服务器。无论是文档、API 参考还是领域知识,MCP 都让 AI 助手轻松为用户提供准确、有用的信息。

我们的 MCP 服务器完整源码托管在 GitHub 项目的 server/routes/mcp.ts 文件和 server/api/mcp/ 目录。欢迎参考借鉴,打造你自己的实现方案!