MCP协议 进阶 MCP 开发规范 工具开发 最佳实践

MCP工具开发规范:从设计到发布的完整指南

AIEng Hub
阅读约 16 分钟

引言

随着MCP生态的繁荣,遵循统一的开发规范至关重要。一个好的规范不仅能提升工具质量,还能降低用户的使用门槛。

命名规范

工具命名

✅ 正确示例
─────────────
search_codebase          # 动词_名词,清晰表达功能
get_file_content         # get/set/create 开头
calculate_price          # 具体描述操作
validate_email_format    # 明确输入内容

❌ 错误示例
─────────────
process                  # 太通用,不清楚做什么
do_stuff                 # 无意义
utils                    # 分类名而非工具名
my_tool                  # 对用户无信息量

命名规则

规则示例说明
snake_casesearch_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

功能: 工具描述

参数:

参数类型必填默认值说明
param1string-参数说明
param2number10参数说明

示例:

{
  "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。