关于 mcp-development
面向 MCP 开发者的实践指南,介绍如何构建带工具、资源和提示词模板的服务器,并设置传输、输入验证及错误处理。还包含客户端配置与开发检查项。
主要功能
- 01创建带工具的 MCP 服务
- 02定义资源与提示词模板
- 03配置 Stdio 与 SSE 传输
- 04使用 Zod 验证输入
- 05处理错误与优雅关闭
- 06编写客户端配置
适用场景
- 01实现可供客户端调用的服务器工具
- 02向客户端提供只读资源
- 03为常见任务设计提示词模板
- 04检查 MCP 服务实现与配置
MCP 相关
内容聚焦 MCP 服务端开发,也涵盖客户端配置。说明服务如何通过 Stdio 或 SSE 传输向 MCP 客户端提供工具、资源和提示词。
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ rohitg00/ awesome-claude-code-toolkit --skill mcp-development安装后在 Claude Code 中输入/mcp-development确认已加载。
详细介绍
MCP 开发
带工具的 MCP 服务
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
import { z } from "zod";
const server = new McpServer({
name: "project-tools",
version: "1.0.0",
});
server.tool(
"search_files",
"Search for files matching a glob pattern in the project directory",
{
pattern: z.string().describe("Glob pattern (e.g., '**/*.ts')"),
directory: z.string().optional().describe("Base directory to search from"),
},
async ({ pattern, directory }) => {
const files = await glob(pattern, { cwd: directory ?? process.cwd() });
return {
content: [
{
type: "text",
text: files.length > 0
? files.join("\n")
: `No files found matching ${pattern}`,
},
],
};
}
);
server.tool(
"run_query",
"Execute a read-only SQL query against the application database",
{
query: z.string().describe("SQL SELECT query to execute"),
limit: z.number().default(100).describe("Maximum rows to return"),
},
async ({ query, limit }) => {
if (!query.trim().toUpperCase().startsWith("SELECT")) {
return {
content: [{ type: "text", text: "Only SELECT queries are allowed" }],
isError: true,
};
}
const rows = await db.query(`${query} LIMIT ${limit}`);
return {
content: [{ type: "text", text: JSON.stringify(rows, null, 2) }],
};
}
);
资源
server.resource(
"schema",
"db://schema",
"Current database schema with all tables, columns, and relationships",
async () => {
const schema = await db.query(`
SELECT table_name, column_name, data_type, is_nullable
FROM information_schema.columns
WHERE table_schema = 'public'
ORDER BY table_name, ordinal_position
`);
return {
contents: [
{
uri: "db://schema",
mimeType: "application/json",
text: JSON.stringify(schema, null, 2),
},
],
};
}
);
server.resource(
"config",
"config://app",
"Application configuration (secrets redacted)",
async () => {
const config = await loadConfig();
const safe = redactSecrets(config);
return {
contents: [
{
uri: "config://app",
mimeType: "application/json",
text: JSON.stringify(safe, null, 2),
},
],
};
}
);
提示词模板
server.prompt(
"review-code",
"Review code changes for bugs, security issues, and style",
{
diff: z.string().describe("Git diff or code to review"),
focus: z.enum(["security", "performance", "style", "all"]).default("all"),
},
async ({ diff, focus }) => ({
messages: [
{
role: "user",
content: {
type: "text",
text: `Review this code diff. Focus: ${focus}\n\n${diff}`,
},
},
],
})
);
客户端配置
{
"mcpServers": {
"project-tools": {
"command": "node",
"args": ["./mcp-server/dist/index.js"],
"env": {
"DATABASE_URL": "postgres://localhost:5432/app"
}
},
"remote-server": {
"url": "https://mcp.example.com/sse",
"headers": {
"Authorization": "Bearer ${MCP_TOKEN}"
}
}
}
}
传输设置
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const transport = new StdioServerTransport();
await server.connect(transport);
对于基于 HTTP 的服务,请使用 SSE 传输向客户端流式传输响应。
反模式
- 创建描述含糊、未说明适用场景的工具
- 处理前未使用 Zod schema 验证输入
- 向客户端返回原始错误堆栈跟踪
- 错误响应中缺少
isError: true标记 - 创建过多粒度过细的工具,而不是可组合的工具
- 未在资源响应中对机密信息进行脱敏
检查清单
- 每个工具都有清晰的描述,说明何时以及为何使用
- 使用 Zod schema 验证输入参数,并提供描述性消息
- 错误响应包含
isError: true和便于用户理解的消息 - 资源公开只读数据,并对机密信息进行脱敏
- 提示词模板为常见任务提供结构化的起点
- 服务能够在 SIGINT/SIGTERM 时平稳关闭
- 工具可组合(各司其职),而非功能庞杂
- 记录客户端配置及所需的环境变量
评论
支持 Markdown