关于 mcp-server-skills
这是一份在 Next.js App Router 项目中构建 MCP 服务的开发指南。它让 MCP 路由、Server Actions 和网页测试界面复用工具逻辑与 Zod 架构。
主要功能
- 01共享 Zod 架构与工具逻辑
- 02连接轻量级 MCP 路由
- 03在 Server Actions 中复用逻辑
- 04支持 HTTP 和 SSE 传输
- 05通过网页界面测试
适用场景
- 01在 Next.js 应用中构建 MCP 服务
- 02保持界面与 MCP 的验证规则一致
- 03通过 Server Actions 测试工具行为
MCP 相关
介绍通过 MCP 处理器以 HTTP 或 SSE 传输方式公开工具的模式,也说明如何用 mcp-remote 将 Claude Desktop 客户端连接到路由。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ gocallum/ nextjs16-agent-skills --skill mcp-server-skills安装后在 Claude Code 中输入/mcp-server-skills确认已加载。
详细介绍
链接
- Model Context Protocol:https://modelcontextprotocol.io/
- mcp-handler (HTTP):https://www.npmjs.com/package/mcp-handler
- 参考实现(Roll Dice):https://github.com/gocallum/rolldice-mcpserver
- Claude Desktop + mcp-remote 桥接:https://www.npmjs.com/package/mcp-remote
文件夹结构(Next.js App Router)
app/
api/[transport]/route.ts # One handler for all transports (e.g., /api/mcp)
actions/mcp-actions.ts # Server actions reusing the same logic/schemas
lib/
dice.ts | tools.ts # Zod schemas, tool definitions, pure logic
components/ # UI that calls server actions for web testing
**目标:**保持 route.ts 精简。将逻辑和 Zod 模式放在 lib/* 中,让 MCP 处理程序和服务端操作共享唯一事实来源。
共享 Zod 模式 + 工具定义
// lib/dice.ts
import { z } from "zod";
export const diceSchema = z.number().int().min(2);
export function rollDice(sides: number) {
const validated = diceSchema.parse(sides);
const value = 1 + Math.floor(Math.random() * validated);
return { type: "text" as const, text: `🎲 You rolled a ${value}!` };
}
export const rollDiceTool = {
name: "roll_dice",
description: "Rolls an N-sided die",
schema: { sides: diceSchema },
} as const;
可复用的服务端操作(Web UI + 测试)
// app/actions/mcp-actions.ts
"use server";
import { rollDice as rollDiceCore, rollDiceTool } from "@/lib/dice";
export async function rollDice(sides: number) {
try {
const result = rollDiceCore(sides);
return { success: true, result: { content: [result] } };
} catch {
return {
success: false,
error: { code: -32602, message: "Invalid parameters: sides must be >= 2" },
};
}
}
export async function listTools() {
return {
success: true,
result: {
tools: [
{
name: rollDiceTool.name,
description: rollDiceTool.description,
inputSchema: {
type: "object",
properties: { sides: { type: "number", minimum: 2 } },
required: ["sides"],
},
},
],
},
};
}
服务端操作调用与 MCP 处理程序相同的逻辑,并为 Web UI 提供支持,确保响应一致。
轻量级 MCP 路由
// app/api/[transport]/route.ts
import { createMcpHandler } from "mcp-handler";
import { rollDice, rollDiceTool } from "@/lib/dice";
const handler = createMcpHandler(
(server) => {
server.tool(
rollDiceTool.name,
rollDiceTool.description,
rollDiceTool.schema,
async ({ sides }) => ({ content: [rollDice(sides)] }),
);
},
{}, // server options
{
basePath: "/api", // must match folder path
maxDuration: 60,
verboseLogs: true,
},
);
export { handler as GET, handler as POST };
模式要点
- 路由只负责接入
createMcpHandler;不在其中编写业务逻辑。 server.tool使用共享的工具模式和描述,并调用共享逻辑。basePath应与文件夹路径一致(例如,/api/[transport])。- 支持 SSE/HTTP 传输;如有需要,可另外添加 stdio。
Claude Desktop 配置(mcp-remote)
{
"mcpServers": {
"rolldice": {
"command": "npx",
"args": ["-y", "mcp-remote", "http://localhost:3000/api/mcp"]
}
}
}
最佳实践
- 唯一事实来源——将模式和逻辑放在
lib/*中;MCP 工具和服务端操作都从中导入。 - 先验证——使用 Zod 验证输入,并让 UI 和 MCP 共用相同的模式。
- 保持 route.ts 轻量——只负责接入处理程序、日志记录和传输配置。
- 共享响应——为工具和 UI 统一
{ success, result | error }结构。 - 适配 Vercel——避免使用有状态的全局变量;必要时配置
maxDuration和runtime。 - 多种传输方式——通过
/api/[transport]提供 HTTP/SSE;需要时添加 stdio 入口点。 - 本地测试——通过 Web UI 调用服务端操作,确保 MCP 响应保持同步。
评论
支持 Markdown