Nuxt MCP服务器模板

用于构建生产就绪MCP服务器的Nuxt 4模板,提供MCP模式查询、项目生成和调试功能。

  • by onmax
  • TypeScript
  • 本地部署
  • 更新于
在 GitHub 查看 onmax/mcp-starter

使用说明

Nuxt MCP启动器

Nuxt 4模板,用于构建生产就绪的MCP服务器。通过查询此服务器本身来学习MCP模式。

这是什么

Nuxt MCP服务器,教您如何使用Nuxt构建MCP服务器。查询到:

  • 获取MCP模式的工作代码示例
  • 生成完整的Nuxt MCP项目
  • 调试常见的MCP设置问题
  • 通过指导工作流程学习最佳实践

快速开始

先决条件

  • Node.js 18+(fnm use 24)
  • pnpm
  • OpenAI API密钥(用于评估)

安装

pnpm install
cp .env.example .env  # Add OPENAI_API_KEY
pnpm dev

MCP服务器运行在: http://localhost:3000/mcp

测试

npx @modelcontextprotocol/inspector http://localhost:3000/mcp  # MCP Inspector
pnpm eval        # Run evaluations
pnpm eval:ui     # View results

建筑

清洁分离:协议→ 处理器→ Data

server/
  routes/mcp.ts           # MCP protocol (tools, resources, prompts)
  api/mcp/
    get-pattern.get.ts    # Pattern examples handler
    create-nuxt-project.get.ts  # Project generator
    debug-setup.get.ts    # Debug helper
  utils/
    schemas.ts            # Zod schemas (autoimported)
tests/mcp/
  mcp.eval.ts            # Evaluations

MCP图元

遵循MCP规范:

  1. 资源 -静态数据索引(模式、示例)
  2. 工具 -参数化操作(get_pattern、create_nuxt_project、debug_setup)
  3. 提示词 -引导式工作流(scaffold_for_api、add_tool)

MCP能力

资源(2)

浏览可用数据:

  • resource://nuxt-mcp-starter/patterns -6种MCP模式的索引(列表搜索、缓存、验证、错误处理、分页、身份验证)
  • resource://nuxt-mcp-starter/examples -示例项目(配方API、数据库、文件搜索)

工具(3)

核心功能:

get_pattern -使用工作代码获取MCP实现模式

  • 参数: pattern (列表搜索|缓存|验证|错误处理|分页|认证), format (代码|解释|两者都有)
  • 返回:Nuxt MCP模式的代码示例+解释

create_nuxt_project -生成完整的Nuxt MCP项目

  • 参数: data_source (api |数据库|文件|自定义), use_case (描述), auth_required (布尔值)
  • 返回:完整的项目代码,包括处理程序、模式、MCP注册、评估

debug_setup -解决MCP设置问题

  • 参数: issue (工具未显示|cors错误|模式验证|传输设置|常规), error_message (可选)
  • 返回:诊断、解决方案、故障排除步骤

提示(2)

引导式工作流程:

scaffold_for_api -使用MCP包装API的分步指南

  • 参数: api_description (例如,“GitHub REST API”)
  • 回报:从生成到部署的7步指南

add_tool -向现有MCP服务器添加工具的指南

  • 参数: tool_purpose (工具应该做什么)
  • 回报:分步实施指南

用法示例

创建新的MCP项目

User: I want to create a Nuxt MCP that queries a recipe API
MCP: [Uses create_nuxt_project with data_source: 'api', use_case: 'recipe API']
      [Returns complete project code with:
       - Zod schemas for validation
       - API handler with caching
       - MCP tool registration
       - Evaluation test cases]

学习模式

User: Show me how to implement caching in my MCP
MCP: [Uses get_pattern with pattern: 'caching']
     [Returns code example + explanation of caching strategy]

调试

User: My tools aren't showing up in Claude Desktop
MCP: [Uses debug_setup with issue: 'tools-not-showing']
     [Returns 6 troubleshooting steps with specific fixes]

MCP最佳实践

跟随 MCP SDK指南:

1.为工作流构建,而不是为API终结点构建

将相关操作整合到单个工具中:

// ❌ BAD: 3 separate tools
list_items()
get_item(id)
search_items(query)

// ✅ GOOD: 1 consolidated tool
get_items({ id?, query? })
  // No params → list all
  // id param → get specific
  // query param → search

2.针对有限环境进行优化

  • 简洁的工具描述(20-30字)
  • 高信号响应,而非数据转储
  • 人类可读标识符(名称超过ID)
  • 大型数据集的分页

3.设计可操作的错误消息

// ❌ BAD
throw createError({ statusCode: 404, message: 'Not found' })

// ✅ GOOD
const available = items.map(i => i.id).join(', ')
throw createError({
  statusCode: 404,
  message: `Item '${id}' not found. Available: ${available}`
})

4.工具注释

始终包含注释:

server.registerTool('tool_name', {
  // ...
  annotations: {
    readOnlyHint: true,        // Read-only operation
    destructiveHint: false,    // Non-destructive
    idempotentHint: true,      // Repeatable with same result
    openWorldHint: false,      // Internal data (true for external APIs)
  }
})

5.使用Zod进行输入验证

在中定义架构 server/utils/schemas.ts:

export const ToolSchema = z.object({
  query: z.string().describe('Search query'),
  limit: z.number().min(1).max(100).optional().default(10),
  category: z.enum(['all', 'active', 'archived']).optional(),
})

在处理程序和工具注册中使用:

// Handler
const args = await getValidatedQuery(event, ToolSchema.parse)

// MCP registration
server.registerTool('tool', { inputSchema: ToolSchema, ... })

6.响应缓存

缓存昂贵的操作:

defineCachedEventHandler(async (event) => {
  // Handler logic
}, {
  maxAge: 60 * 60,  // 1 hour for stable content
  getKey: (event) => {
    const { query } = getQuery(event)
    return `tool-${query || 'default'}`
  }
})

何时缓存:

  • 静含量:24小时
  • 参考数据:1h
  • 用户特定:5分钟
  • 实时:不缓存
  • 已验证: maxAge: 0

实施指南

1.定义架构

server/utils/schemas.ts:

import { z } from 'zod'

export const SearchSchema = z.object({
  query: z.string().describe('Search term'),
  limit: z.number().min(1).max(100).optional().default(10),
})

2.创建处理程序

server/api/mcp/search.get.ts:

export default defineCachedEventHandler(async (event) => {
  const { query, limit } = await getValidatedQuery(event, SearchSchema.parse)

  const results = await yourDataSource.search(query)

  return {
    query,
    results: results.slice(0, limit),
    total: results.length
  }
}, {
  maxAge: 60 * 5,
  getKey: (event) => {
    const { query } = getQuery(event)
    return `search-${query}`
  }
})

3.注册工具

server/routes/mcp.ts:

server.registerTool('search', {
  title: 'Search Items',
  description: 'Search items by query term with pagination',
  inputSchema: SearchSchema,
  annotations: {
    readOnlyHint: true,
    destructiveHint: false,
    idempotentHint: true,
    openWorldHint: false,
  },
}, async (args: any) => {
  const data = await $fetch('/api/mcp/search', { query: args })
  return {
    content: [{
      type: 'text',
      text: JSON.stringify(data, null, 2)
    }]
  }
})

4.撰写评价

tests/mcp/mcp.eval.ts:

evalite('Search Tool', {
  data: async () => [{
    input: 'Search for recipes containing chocolate',
    expected: [{ toolName: 'search', args: { query: 'chocolate' } }],
  }],
  task: async (input) => {
    const mcpClient = await createMCPClient({
      transport: { type: 'http', url: 'http://localhost:3000/mcp' }
    })
    const result = await generateText({
      model,
      prompt: input,
      tools: await mcpClient.tools()
    })
    return result.toolCalls
  },
  scorers: [toolCallAccuracy]
})

模式参考

使用 get_pattern 工具查看完整实现。

列表搜索模式

使用可选参数将列表/获取/搜索合并到一个工具中。

缓存模式

基于数据波动性,使用自定义密钥和TTL缓存响应。

验证模式

用于运行时验证和TypeScript推理的Zod模式。

错误处理模式

带有建议和可用选项的可操作错误。

分页模式

处理具有限制/偏移的大型数据集,并具有更多元数据。

身份验证模式

API密钥验证,带有env-var回退和清除错误消息。

部署

采用MCP路由的标准Nuxt部署 /mcp:

# Vercel
vercel deploy

# NuxtHub
npx nuxthub deploy

# Netlify
pnpm build

配置Claude桌面 (~/.config/claude/claude_desktop_config.json):

{
  "mcpServers": {
    "nuxt-mcp-starter": {
      "url": "https://your-domain.com/mcp"
    }
  }
}

CI/CD

自动月度评估

此存储库通过GitHub Actions自动运行每月评估,以确保MCP服务器随时间推移的质量。

先决条件:

  1. 部署到Vercel (或您偏好的平台):

    vercel deploy --prod
    

    部署后,记下您的生产URL(例如。, https://your-app.vercel.app)

  2. 配置GitHub机密 (设置→ 秘密和变量→ 行动):

    • OPENAI_API_KEY:您的OpenAI API密钥
    • MCP_URL:您部署的MCP端点(例如。, https://your-app.vercel.app/mcp)
  3. 工作流程在每月1日UTC凌晨2点自动运行

手动触发器:

# Via GitHub UI
Actions → Monthly Evals → Run workflow

# Via GitHub CLI
gh workflow run evals.yml

它的作用:

  • 对部署的MCP服务器运行评估
  • 测试所有19个评估案例
  • 强制执行85%的分数阈值(如果低于此阈值,则失败)
  • 在GitHub操作摘要中显示结果
  • 将结果作为工件上传(保留90天)
  • 如果评估失败,则会产生问题

地方发展:

# Run evals against local server (default: http://localhost:3000/mcp)
pnpm eval

# Run evals against deployed server
MCP_URL=https://your-app.vercel.app/mcp pnpm eval

查看结果:

  • 操作选项卡→ 月度评估→ 最新跑步记录→ 人工制品
  • 下载 eval-results-* 查看详细分数

当前得分: 约94%(17次测试,分数因LLM非确定性而异)

文件结构

server/
  routes/mcp.ts                    # MCP server + tool/resource/prompt registration
  api/mcp/
    get-pattern.get.ts             # Pattern examples with code
    create-nuxt-project.get.ts     # Project generator
    debug-setup.get.ts             # Debug helper
  utils/
    schemas.ts                     # Zod schemas (autoimported globally)
tests/mcp/
  mcp.eval.ts                      # Evaluation test suites

故障排除

使用 debug_setup 解决常见问题的工具:

Claude Desktop中未显示的工具:

  1. 验证服务器是否正在运行 http://localhost:3000/mcp
  2. 检查 claude_desktop_config.json 具有正确的URL
  3. 完全重新启动克劳德桌面
  4. 使用MCP检查员进行测试

架构验证错误:

  1. 确保处理程序和注册之间的架构匹配
  2. 使用 inputSchema (不是 argsSchema)in registerTool
  3. 单独测试模式: Schema.safeParse({ ... })

运输/连接问题:

  1. 使用 StreamableHTTPServerTransport 对于HTTP
  2. 添加清理: event.node.res.on('close', () => { transport.close(); server.close() })
  3. 阅读正文: await readBody(event)

资源

许可证

麻省理工学院