引言
随着MCP生态的繁荣,遵循统一的开发规范至关重要。一个好的规范不仅能提升工具质量,还能降低用户的使用门槛。
命名规范
工具命名
✅ 正确示例
─────────────
search_codebase # 动词_名词,清晰表达功能
get_file_content # get/set/create 开头
calculate_price # 具体描述操作
validate_email_format # 明确输入内容
❌ 错误示例
─────────────
process # 太通用,不清楚做什么
do_stuff # 无意义
utils # 分类名而非工具名
my_tool # 对用户无信息量
命名规则
| 规则 | 示例 | 说明 |
|---|---|---|
| snake_case | search_codebase | 全小写+下划线 |
| 动词开头 | create_user, get_config | 表示操作 |
| 简洁明确 | 3-4个词最佳 | 避免过长或过短 |
| 避免缩写 | get_document 而非 get_doc | 除非是行业通用缩写 |
参数命名
{
"name": "search_codebase",
"inputSchema": {
"type": "object",
"properties": {
"search_pattern": { "type": "string" }, // ✅ 明确含义
"file_type_filter": { "type": "string" }, // ✅ 带类型后缀
// ❌ 不推荐的命名
"s": { "type": "string" }, // 单字母,不清楚
"stuff": { "type": "object" }, // 无意义
"args": { "type": "object" } // 太宽泛
}
}
}
Schema设计规范
完整的inputSchema
{
"name": "send_email",
"description": "发送电子邮件。支持纯文本和HTML格式,可添加多个收件人和附件。",
"inputSchema": {
"type": "object",
"properties": {
"to": {
"type": "array",
"items": { "type": "string", "format": "email" },
"description": "收件人邮箱地址列表",
"minItems": 1,
"maxItems": 50
},
"subject": {
"type": "string",
"description": "邮件主题",
"minLength": 1,
"maxLength": 200
},
"body": {
"type": "string",
"description": "邮件正文内容",
"maxLength": 100000
},
"format": {
"type": "string",
"enum": ["plain", "html"],
"description": "邮件格式,默认为纯文本",
"default": "plain"
},
"priority": {
"type": "string",
"enum": ["low", "normal", "high"],
"description": "邮件优先级",
"default": "normal"
}
},
"required": ["to", "subject", "body"]
}
}
Schema设计要求
| 要素 | 要求 | 原因 |
|---|---|---|
| type | 每个属性必须声明 | JSON Schema基础要求 |
| description | 每个属性必须写 | 帮助LLM理解参数含义 |
| default | 可选参数尽量提供 | 减少LLM需要决策的参数 |
| enum | 固定取值使用枚举 | 避免LLM生成无效值 |
| min/max | 字符串和数字加限制 | 防止边界值问题 |
| 格式校验 | email、uri等使用format | 增强输入验证 |
错误处理标准
统一错误格式
// 标准错误响应
{
"content": [
{
"type": "text",
"text": "错误类型: 参数验证失败\n" +
"详细信息: 参数 'email' 格式无效\n" +
"建议操作: 请提供有效的邮箱地址,如 user@example.com"
}
],
"isError": true
}
错误信息模板
function formatError(
type: string,
detail: string,
suggestion: string
): ToolResult {
return {
content: [{
type: "text",
text: [
`错误类型: ${type}`,
`详细信息: ${detail}`,
`建议操作: ${suggestion}`,
].join("\n"),
}],
isError: true,
};
}
// 使用示例
return formatError(
"权限不足",
"当前配置不允许删除文件 'config.json'",
"请使用只读操作或联系管理员获取写入权限"
);
常见错误模板
| 错误类型 | 错误信息 | 建议操作 |
|---|---|---|
| 参数验证失败 | 参数 ‘X’ 类型错误/格式错误 | 请提供正确的参数值 |
| 资源未找到 | 资源 ‘X’ 不存在 | 请检查资源路径或ID |
| 权限不足 | 无权访问 ‘X’ | 请使用只读操作 |
| 执行超时 | 操作执行超过 X 秒 | 请简化查询条件 |
| 外部服务错误 | 上游服务返回 X 错误 | 请稍后重试 |
安全要求
安全检查清单
☐ 输入验证
☐ 所有参数使用Schema校验
☐ 路径参数过滤 `..` 穿越
☐ 字符串长度限制
☐ 凭证安全
☐ API Key使用环境变量
☐ 不在响应中返回凭证
☐ 响应内容脱敏处理
☐ 资源限制
☐ 设置合理的超时时间
☐ 限制返回结果数量
☐ 限制可访问的文件路径
☐ 错误信息
☐ 不暴露内部实现细节
☐ 不包含堆栈信息
☐ 不包含环境变量值
路径安全模板
// 路径安全检查模板
function validatePath(
requestedPath: string,
allowedBases: string[]
): string {
// 1. 规范化路径
const resolved = path.resolve(requestedPath);
// 2. 检查路径穿越
if (resolved.includes("..")) {
throw new Error("路径不能包含 '..'");
}
// 3. 检查白名单
const isAllowed = allowedBases.some(base =>
resolved.startsWith(path.resolve(base))
);
if (!isAllowed) {
throw new Error(`路径不在允许范围内`);
}
// 4. 解析符号链接(防止绕过)
const realPath = fs.realpathSync(resolved);
const isRealAllowed = allowedBases.some(base =>
realPath.startsWith(path.resolve(base))
);
if (!isRealAllowed) {
throw new Error("路径解析后超出允许范围");
}
return resolved;
}
文档标准
README模板
# My MCP Server
一句话描述Server的功能。
## 功能
- 功能1: 简短描述
- 功能2: 简短描述
- 功能3: 简短描述
## 安装
```bash
npm install my-mcp-server
# 或
pip install my-mcp-server
配置
{
"mcpServers": {
"my-server": {
"command": "npx",
"args": ["my-mcp-server"],
"env": {
"API_KEY": "your-api-key"
}
}
}
}
工具
tool_name
功能: 工具描述
参数:
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
param1 | string | 是 | - | 参数说明 |
param2 | number | 否 | 10 | 参数说明 |
示例:
{
"name": "tool_name",
"arguments": {
"param1": "value",
"param2": 5
}
}
环境变量
| 变量 | 必填 | 说明 |
|---|---|---|
API_KEY | 是 | 服务API密钥 |
安全说明
- 哪些资源可访问
- 哪些操作有风险
- 推荐的权限配置
### 工具文档要求
| 文档项 | 要求 | 说明 |
|------------|------|--------------------|
| **README** | 必须 | 完整的安装和使用说明 |
| **示例** | 必须 | 至少3个工具调用示例 |
| **安全说明** | 必须 | 明确告知用户安全风险 |
| **变更日志** | 推荐 | 版本更新记录 |
| **API文档** | 推荐 | 生成API参考文档 |
## 发布流程
### 发布清单
```markdown
## 发布前检查清单
### 功能
☐ 所有工具功能完整
☐ 参数验证正常工作
☐ 错误返回格式正确
☐ 边界情况已处理
### 安全
☐ 无硬编码凭证
☐ 路径穿越防护
☐ 响应脱敏
☐ 超时设置合理
### 文档
☐ README完整
☐ 配置示例正确
☐ 所有工具均有文档
☐ 安全注意事项写明
### 测试
☐ 工具功能测试
☐ 错误处理测试
☐ 安全性测试
☐ 版本兼容性测试
### 打包
☐ package.json/Pyproject.toml 完整
☐ LICENSE文件
☐ .npmignore/.gitignore 配置
版本号规范
遵循语义化版本(SemVer):
| 版本变化 | 示例 | 说明 |
|---|---|---|
| 主版本 | 2.0.0 | 不兼容的API变更 |
| 次版本 | 1.3.0 | 向后兼容的新功能 |
| 修订版 | 1.2.1 | 向后兼容的Bug修复 |
测试规范
测试覆盖要求
describe("Tool: send_email", () => {
// 1. 正常功能测试
it("should send email with valid parameters", async () => {});
it("should support HTML format", async () => {});
// 2. 参数验证测试
it("should reject empty 'to' list", async () => {});
it("should reject invalid email format", async () => {});
it("should reject body exceeding max length", async () => {});
// 3. 错误处理测试
it("should handle SMTP server error", async () => {});
it("should handle timeout gracefully", async () => {});
// 4. 边界情况测试
it("should handle single recipient", async () => {});
it("should handle maximum recipients", async () => {});
});
总结
MCP工具开发的核心规范:
| 规范维度 | 关键要求 | 验收标准 |
|---|---|---|
| 命名 | snake_case, 动词开头 | 一眼能猜到功能 |
| Schema | 完整类型+描述+默认值 | LLM能正确调用 |
| 错误 | 统一格式+建议操作 | 用户知道怎么修 |
| 安全 | 输入验证+凭证保护 | 无明显安全漏洞 |
| 文档 | README+示例+安全说明 | 用户能独立使用 |
| 测试 | 功能+边界+错误+安全 | 覆盖所有核心路径 |
下一步学习建议:
本文最后更新于 2024-07-24。