Skills: 自定义工具开发
最后更新:2026-08-31
内置工具不够用?自己造——MCP 协议让 Skill 的能力没有边界。
1. MCP 协议基础
(1) 什么是 MCP
Model Context Protocol 是 AI 工具的标准协议:
TEXT
📖 仅展示
MCP 架构
┌──────────┐ MCP 协议 ┌──────────────┐
│ AI 客户端 │ ←──────────→ │ MCP 服务器 │
│ (Claude) │ │ (自定义工具) │
└──────────┘ └──────────────┘
↕
┌──────────────┐
│ 外部服务 │
│ (DB/API/文件) │
└──────────────┘
(2) 工具类型
| 类型 | 说明 | 示例 |
|---|---|---|
| 资源工具 | 提供数据读取 | 数据库查询、文件系统 |
| 动作工具 | 执行操作 | 发送邮件、创建工单 |
| 提示工具 | 提供模板 | 报告模板、审查清单 |
2. 开发自定义工具
(1) 需求分析
TEXT
📖 仅展示
自定义工具开发流程
1. 识别内置工具无法满足的需求
2. 确定工具的输入/输出
3. 选择实现方式(Node.js / Python)
4. 实现工具逻辑
5. 配置 MCP 服务器
6. 在 Skill 中绑定使用
(2) 最小实现
TYPESCRIPT
// mcp-server-example/index.ts
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
const server = new McpServer({ name: "db-query", version: "1.0.0" });
server.tool("query_database", { sql: { type: "string" } }, async ({ sql }) => {
const result = await executeQuery(sql);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
});
const transport = new StdioServerTransport();
await server.connect(transport);
(3) 配置接入
JSON
{
"mcpServers": {
"db-query": {
"command": "node",
"args": ["./mcp-servers/db-query/index.js"],
"env": {
"DATABASE_URL": "postgresql://localhost/mydb"
}
}
}
}
3. 工具设计原则
(1) 单一职责
每个工具只做一件事:
| ✅ 好设计 | ❌ 坏设计 |
|---|---|
query_database |
do_database_stuff |
send_email |
communicate |
search_logs |
find_stuff |
(2) 输入验证
TYPESCRIPT
server.tool("query_database", {
sql: {
type: "string",
description: "SQL 查询语句(仅允许 SELECT)",
validate: (sql: string) => {
if (/^\s*(DROP|DELETE|UPDATE|INSERT|ALTER)/i.test(sql)) {
throw new Error("Only SELECT queries are allowed");
}
}
}
}, handler);
(3) 错误处理
TYPESCRIPT
async ({ sql }) => {
try {
const result = await executeQuery(sql);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
} catch (error) {
return {
content: [{ type: "text", text: `Query failed: ${error.message}` }],
isError: true
};
}
};
4. 工具调试与发布
(1) 本地调试
BASH
# 直接运行 MCP 服务器测试
node ./mcp-servers/db-query/index.js
# 发送测试请求
echo '{"method":"tools/list"}' | node ./mcp-servers/db-query/index.js
(2) 日志记录
TYPESCRIPT
// 添加日志中间件
server.tool("query_database", { sql: { type: "string" } }, async ({ sql }) => {
console.error(`[DB-QUERY] SQL: ${sql}`);
const start = Date.now();
const result = await executeQuery(sql);
console.error(`[DB-QUERY] Duration: ${Date.now() - start}ms`);
return { content: [{ type: "text", text: JSON.stringify(result) }] };
});
(3) 发布与分发
TEXT
📖 仅展示
发布方式
├── npm 包:npm publish @your-org/mcp-server-xxx
├── Docker:docker build + docker push
├── Git 仓库:直接 clone 使用
└── 配置模板:提供 JSON 配置模板
5. 自定义工具实战
▶ 示例:日志搜索工具
Alice 开发了一个日志搜索 MCP 工具:
YAML
---
name: log-analyzer
description: "日志分析:搜索、过滤、统计"
tools:
- Read
- search_logs # 自定义 MCP 工具
---
Bob 说:"自定义工具的价值在于连接 AI 和你的专属系统——通用工具够不到的地方,定制工具来补。"
❓ 常见问题
Q 必须用 TypeScript 开发 MCP 工具吗?
A 不是。MCP 协议是 JSON-RPC,任何语言都能实现。官方 SDK 提供 TypeScript 和 Python 版本。
Q 自定义工具有安全风险吗?
A 有。务必在工具内部做输入验证和权限控制,不要把安全责任完全交给 Skill 提示词。
Q 一个 MCP 服务器可以提供多个工具吗?
A 可以。但建议每个服务器不超过 5 个工具,保持职责聚焦。
📖 小节
- MCP 协议:AI 客户端与自定义工具的标准通信协议
- 开发流程:需求分析 → 实现 → 配置 → 调试 → 发布
- 设计原则:单一职责、输入验证、错误处理
- 核心价值:连接 AI 与专属系统,扩展 Skill 能力边界
📝 作业
- 基础题(难度⭐):使用 MCP SDK 创建一个最简单的 Hello World 工具并接入 Skill。
- 进阶题(难度⭐⭐):开发一个数据库查询 MCP 工具,包含输入验证和错误处理。
- 挑战题(难度⭐⭐⭐):开发一个完整的日志分析 MCP 工具,支持搜索、过滤和统计,并编写调试和发布文档。