manage-mcp
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseManage MCP
管理MCP
Complete skill for managing Model Context Protocol (MCP) servers in Nuxt applications. Setup, create, customize with middleware and handlers, review, and troubleshoot.
这是一份在Nuxt应用中管理Model Context Protocol(MCP)服务器的完整指南,涵盖搭建、创建、使用中间件与处理器自定义、审核及故障排查等内容。
When to Use
适用场景
- Setup: "Setup an MCP server in my Nuxt app"
- Create: "Create a tool to calculate BMI" / "Add a resource to read the README"
- Customize: "Add authentication to my MCP server" / "Create middleware for rate limiting"
- Review: "Review my MCP implementation" / "Check for best practices"
- Troubleshoot: "My auto-imports aren't working" / "Cannot connect to endpoint"
- Test: "Create tests for my MCP tools"
- 搭建:"在我的Nuxt应用中搭建MCP服务器"
- 创建:"创建一个计算BMI的工具" / "添加一个读取README的资源"
- 自定义:"为我的MCP服务器添加认证" / "创建限流中间件"
- 审核:"审核我的MCP实现" / "检查最佳实践"
- 故障排查:"我的自动导入功能无法工作" / "无法连接到端点"
- 测试:"为我的MCP工具创建测试"
Setup MCP Server
搭建MCP服务器
Installation
安装
Automatic (recommended):
bash
npx nuxt module add mcp-toolkitManual:
bash
pnpm add -D @nuxtjs/mcp-toolkit zodAdd to :
nuxt.config.tstypescript
export default defineNuxtConfig({
modules: ['@nuxtjs/mcp-toolkit'],
mcp: {
name: 'My MCP Server',
},
})自动安装(推荐):
bash
npx nuxt module add mcp-toolkit手动安装:
bash
pnpm add -D @nuxtjs/mcp-toolkit zod添加至:
nuxt.config.tstypescript
export default defineNuxtConfig({
modules: ['@nuxtjs/mcp-toolkit'],
mcp: {
name: 'My MCP Server',
},
})Directory Structure
目录结构
server/mcp/
├── tools/ # Actions AI can perform
├── resources/ # Data AI can read
└── prompts/ # Message templatesserver/mcp/
├── tools/ # AI可执行的操作
├── resources/ # AI可读取的数据
└── prompts/ # 消息模板Verification
验证
- Start:
pnpm dev - Check: (should redirect)
http://localhost:3000/mcp - Open DevTools (Shift+Alt+D) → MCP tab
- 启动服务:
pnpm dev - 检查:访问(应自动跳转)
http://localhost:3000/mcp - 打开开发者工具(Shift+Alt+D)→ MCP标签页
Create Tools
创建工具
Tools are functions AI assistants can call.
工具是AI助手可以调用的函数。
Basic Structure
基础结构
typescript
import { z } from 'zod'
export default defineMcpTool({
description: 'What the tool does',
inputSchema: {
param: z.string().describe('Parameter description'),
},
handler: async ({ param }) => {
return {
content: [{
type: 'text',
text: 'Result',
}],
}
},
})typescript
import { z } from 'zod'
export default defineMcpTool({
description: 'What the tool does',
inputSchema: {
param: z.string().describe('Parameter description'),
},
handler: async ({ param }) => {
return {
content: [{
type: 'text',
text: 'Result',
}],
}
},
})Input Patterns
输入模式
typescript
// Required
name: z.string().describe('User name')
// Optional with default
limit: z.number().default(10).describe('Max results')
// Enum
format: z.enum(['json', 'xml']).describe('Format')
// Array
tags: z.array(z.string()).describe('Tags')typescript
// 必填项
name: z.string().describe('User name')
// 带默认值的可选项
limit: z.number().default(10).describe('Max results')
// 枚举类型
format: z.enum(['json', 'xml']).describe('Format')
// 数组类型
tags: z.array(z.string()).describe('Tags')Error Handling
错误处理
typescript
if (!param) {
return {
content: [{ type: 'text', text: 'Error: param required' }],
isError: true,
}
}typescript
if (!param) {
return {
content: [{ type: 'text', text: 'Error: param required' }],
isError: true,
}
}Caching
缓存设置
typescript
export default defineMcpTool({
cache: '5m', // 5 minutes
// ...
})See detailed examples →
typescript
export default defineMcpTool({
cache: '5m', // 5分钟
// ...
})查看详细示例 →
Create Resources
创建资源
Resources expose read-only data.
资源用于暴露只读数据。
File Resource
文件资源
typescript
import { readFile } from 'node:fs/promises'
export default defineMcpResource({
description: 'Read a file',
uri: 'file:///README.md',
mimeType: 'text/markdown',
handler: async (uri: URL) => {
const content = await readFile('README.md', 'utf-8')
return {
contents: [{
uri: uri.toString(),
text: content,
mimeType: 'text/markdown',
}],
}
},
})typescript
import { readFile } from 'node:fs/promises'
export default defineMcpResource({
description: 'Read a file',
uri: 'file:///README.md',
mimeType: 'text/markdown',
handler: async (uri: URL) => {
const content = await readFile('README.md', 'utf-8')
return {
contents: [{
uri: uri.toString(),
text: content,
mimeType: 'text/markdown',
}],
}
},
})API Resource
API资源
typescript
export default defineMcpResource({
description: 'Fetch API data',
uri: 'api:///users',
mimeType: 'application/json',
cache: '5m',
handler: async (uri: URL) => {
const data = await $fetch('https://api.example.com/users')
return {
contents: [{
uri: uri.toString(),
text: JSON.stringify(data, null, 2),
mimeType: 'application/json',
}],
}
},
})typescript
export default defineMcpResource({
description: 'Fetch API data',
uri: 'api:///users',
mimeType: 'application/json',
cache: '5m',
handler: async (uri: URL) => {
const data = await $fetch('https://api.example.com/users')
return {
contents: [{
uri: uri.toString(),
text: JSON.stringify(data, null, 2),
mimeType: 'application/json',
}],
}
},
})Dynamic Resource
动态资源
typescript
import { z } from 'zod'
export default defineMcpResource({
description: 'Fetch by ID',
uriTemplate: {
uriTemplate: 'user:///{id}',
arguments: {
id: z.string().describe('User ID'),
},
},
handler: async (uri: URL, args) => {
const user = await fetchUser(args.id)
return {
contents: [{
uri: uri.toString(),
text: JSON.stringify(user),
mimeType: 'application/json',
}],
}
},
})See detailed examples →
typescript
import { z } from 'zod'
export default defineMcpResource({
description: 'Fetch by ID',
uriTemplate: {
uriTemplate: 'user:///{id}',
arguments: {
id: z.string().describe('User ID'),
},
},
handler: async (uri: URL, args) => {
const user = await fetchUser(args.id)
return {
contents: [{
uri: uri.toString(),
text: JSON.stringify(user),
mimeType: 'application/json',
}],
}
},
})查看详细示例 →
Create Prompts
创建提示词
Prompts are reusable message templates.
提示词是可复用的消息模板。
Static Prompt
静态提示词
typescript
export default defineMcpPrompt({
description: 'Code review',
handler: async () => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: 'Review this code for best practices.',
},
}],
}
},
})typescript
export default defineMcpPrompt({
description: 'Code review',
handler: async () => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: 'Review this code for best practices.',
},
}],
}
},
})Dynamic Prompt
动态提示词
typescript
import { z } from 'zod'
export default defineMcpPrompt({
description: 'Custom review',
inputSchema: {
language: z.string().describe('Language'),
focus: z.array(z.string()).describe('Focus areas'),
},
handler: async ({ language, focus }) => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `Review my ${language} code: ${focus.join(', ')}`,
},
}],
}
},
})See detailed examples →
typescript
import { z } from 'zod'
export default defineMcpPrompt({
description: 'Custom review',
inputSchema: {
language: z.string().describe('Language'),
focus: z.array(z.string()).describe('Focus areas'),
},
handler: async ({ language, focus }) => {
return {
messages: [{
role: 'user',
content: {
type: 'text',
text: `Review my ${language} code: ${focus.join(', ')}`,
},
}],
}
},
})查看详细示例 →
Middleware & Handlers
中间件与处理器
Customize MCP behavior with middleware and handlers for authentication, logging, rate limiting, and more.
使用中间件和处理器自定义MCP行为,支持认证、日志、限流等功能。
Basic Middleware
基础中间件
typescript
// server/mcp/middleware.ts
export default defineMcpMiddleware({
handler: async (event, next) => {
console.log('MCP Request:', event.path)
// Check auth
const token = event.headers.get('authorization')
if (!token) {
return createError({ statusCode: 401, message: 'Unauthorized' })
}
return next()
},
})typescript
// server/mcp/middleware.ts
export default defineMcpMiddleware({
handler: async (event, next) => {
console.log('MCP Request:', event.path)
// 检查认证
const token = event.headers.get('authorization')
if (!token) {
return createError({ statusCode: 401, message: 'Unauthorized' })
}
return next()
},
})Custom Handler
自定义处理器
typescript
// server/mcp/handlers/custom.ts
export default defineMcpHandler({
name: 'custom-mcp',
route: '/mcp/custom',
handler: async (event) => {
return {
tools: await loadCustomTools(),
resources: [],
prompts: [],
}
},
})typescript
// server/mcp/handlers/custom.ts
export default defineMcpHandler({
name: 'custom-mcp',
route: '/mcp/custom',
handler: async (event) => {
return {
tools: await loadCustomTools(),
resources: [],
prompts: [],
}
},
})Common Use Cases
常见使用场景
- Authentication: API keys, JWT tokens
- Rate limiting: Per IP or per user
- Logging: Request/response tracking
- CORS: Cross-origin configuration
- Multiple endpoints: Public/admin separation
See detailed middleware guide →
- 认证:API密钥、JWT令牌
- 限流:基于IP或用户
- 日志:请求/响应追踪
- CORS:跨域配置
- 多端点:公共/管理员端点分离
查看详细中间件指南 →
Review & Best Practices
审核与最佳实践
Tool Checklist
工具检查清单
✅ Use kebab-case filenames
✅ Add to all Zod fields
✅ Return for errors
✅ Add caching for expensive ops
✅ Clear, actionable descriptions
✅ Validate all inputs
.describe()isError: true❌ Generic descriptions
❌ Skip error handling
❌ Expose sensitive data
❌ No input validation
✅ 使用短横线命名法(kebab-case)的文件名
✅ 为所有Zod字段添加
✅ 错误返回时设置
✅ 为耗时操作添加缓存
✅ 清晰、可执行的描述
✅ 验证所有输入
.describe()isError: true❌ 通用模糊的描述
❌ 跳过错误处理
❌ 暴露敏感数据
❌ 不做输入验证
Resource Checklist
资源检查清单
✅ Descriptive URIs ()
✅ Set appropriate MIME types
✅ Enable caching when needed
✅ Handle errors gracefully
✅ Use URI templates for collections
config:///app❌ Unclear URI schemes
❌ Skip MIME types
❌ Expose sensitive data
❌ Return huge datasets without pagination
✅ 描述性URI(如)
✅ 设置合适的MIME类型
✅ 必要时启用缓存
✅ 优雅处理错误
✅ 为集合使用URI模板
config:///app❌ 不清晰的URI协议
❌ 跳过MIME类型设置
❌ 暴露敏感数据
❌ 返回无分页的超大数据集
Prompt Checklist
提示词检查清单
✅ Clear descriptions
✅ Meaningful parameters
✅ Default values where appropriate
✅ Single, focused purpose
✅ Reusable design
❌ Overly complex
❌ Skip descriptions
❌ Mix multiple concerns
✅ 清晰的描述
✅ 有意义的参数
✅ 合适的默认值
✅ 单一、明确的用途
✅ 可复用的设计
❌ 过于复杂
❌ 跳过描述
❌ 混合多个关注点
Troubleshooting
故障排查
Auto-imports Not Working
自动导入功能失效
Fix:
- Check in config
modules: ['@nuxtjs/mcp-toolkit'] - Restart dev server
- Files in directory?
server/mcp/ - Run
pnpm nuxt prepare
解决方法:
- 检查配置中是否包含
modules: ['@nuxtjs/mcp-toolkit'] - 重启开发服务器
- 文件是否在目录下?
server/mcp/ - 运行
pnpm nuxt prepare
Endpoint Not Accessible
端点无法访问
Fix:
- Dev server running?
- Test:
curl http://localhost:3000/mcp - Check in config
enabled: true - Review server logs
解决方法:
- 开发服务器是否在运行?
- 测试:
curl http://localhost:3000/mcp - 检查配置中是否设置
enabled: true - 查看服务器日志
Validation Errors
验证错误
Fix:
- Required fields provided?
- Types match schema?
- Use for optional fields
.optional() - Enum values exact match?
解决方法:
- 是否提供了必填字段?
- 类型是否与 schema 匹配?
- 为可选项使用
.optional() - 枚举值是否完全匹配?
Tool Not Discovered
工具未被发现
Fix:
- File extension or
.ts?.js - Using ?
export default - File in correct directory?
- Restart dev server
See detailed troubleshooting →
解决方法:
- 文件扩展名是否为或
.ts?.js - 是否使用导出?
export default - 文件是否在正确的目录下?
- 重启开发服务器
查看详细故障排查指南 →
Testing with Evals
使用Evals测试
Setup
搭建测试环境
bash
pnpm add -D evalite vitest @ai-sdk/mcp aiAdd to :
package.jsonjson
{
"scripts": {
"eval": "evalite",
"eval:ui": "evalite watch"
}
}bash
pnpm add -D evalite vitest @ai-sdk/mcp ai添加至:
package.jsonjson
{
"scripts": {
"eval": "evalite",
"eval:ui": "evalite watch"
}
}Basic Test
基础测试
Create :
test/mcp.eval.tstypescript
import { experimental_createMCPClient as createMCPClient } from '@ai-sdk/mcp'
import { generateText } from 'ai'
import { evalite } from 'evalite'
import { toolCallAccuracy } from 'evalite/scorers'
evalite('MCP Tool Selection', {
data: async () => [
{
input: 'Calculate BMI for 70kg 1.75m',
expected: [{
toolName: 'bmi-calculator',
input: { weight: 70, height: 1.75 },
}],
},
],
task: async (input) => {
const mcp = await createMCPClient({
transport: { type: 'http', url: 'http://localhost:3000/mcp' },
})
try {
const result = await generateText({
model: 'openai/gpt-4o',
prompt: input,
tools: await mcp.tools(),
})
return result.toolCalls ?? []
}
finally {
await mcp.close()
}
},
scorers: [
({ output, expected }) => toolCallAccuracy({
actualCalls: output,
expectedCalls: expected,
}),
],
})创建:
test/mcp.eval.tstypescript
import { experimental_createMCPClient as createMCPClient } from '@ai-sdk/mcp'
import { generateText } from 'ai'
import { evalite } from 'evalite'
import { toolCallAccuracy } from 'evalite/scorers'
evalite('MCP Tool Selection', {
data: async () => [
{
input: 'Calculate BMI for 70kg 1.75m',
expected: [{
toolName: 'bmi-calculator',
input: { weight: 70, height: 1.75 },
}],
},
],
task: async (input) => {
const mcp = await createMCPClient({
transport: { type: 'http', url: 'http://localhost:3000/mcp' },
})
try {
const result = await generateText({
model: 'openai/gpt-4o',
prompt: input,
tools: await mcp.tools(),
})
return result.toolCalls ?? []
}
finally {
await mcp.close()
}
},
scorers: [
({ output, expected }) => toolCallAccuracy({
actualCalls: output,
expectedCalls: expected,
}),
],
})Running
运行测试
bash
undefinedbash
undefinedStart server
启动服务器
pnpm dev
pnpm dev
Run tests (in another terminal)
运行测试(在另一个终端)
pnpm eval
pnpm eval
Or with UI
或使用UI界面
pnpm eval:ui # http://localhost:3006
See [detailed testing guide →](./references/testing.md)
---pnpm eval:ui # http://localhost:3006
查看[详细测试指南 →](./references/testing.md)
---Quick Reference
快速参考
Common Commands
常用命令
bash
undefinedbash
undefinedSetup
搭建
npx nuxt module add mcp-toolkit
npx nuxt module add mcp-toolkit
Dev
开发
pnpm dev
pnpm dev
Test endpoint
测试端点
Regenerate types
重新生成类型
pnpm nuxt prepare
pnpm nuxt prepare
Run evals
运行测试
pnpm eval
undefinedpnpm eval
undefinedConfiguration
配置示例
typescript
// nuxt.config.ts
export default defineNuxtConfig({
mcp: {
name: 'My Server',
route: '/mcp',
enabled: true,
dir: 'mcp',
},
})typescript
// nuxt.config.ts
export default defineNuxtConfig({
mcp: {
name: 'My Server',
route: '/mcp',
enabled: true,
dir: 'mcp',
},
})Debug Tools
调试工具
- DevTools: Shift+Alt+D → MCP tab
- Logs: Check terminal
- curl: Test endpoint
- 开发者工具:Shift+Alt+D → MCP标签页
- 日志:查看终端输出
- curl:测试端点