MCP
MCP 快速开始
先做一个最小能力,再慢慢理解它为什么这样设计。
1. 先选一个小能力
第一版只做一个输入清楚、输出清楚的能力。不要一上来就做“大而全”的服务。
适合的新手能力查文档、取一条记录、校验文件、创建工单、总结已知数据集。
不适合的新手能力完整数据库管理、随意执行命令、模糊的“项目管理”工具、宽泛的账号控制。
2. 定义契约
写代码前,先定好工具名、描述、输入 schema、输出结构和错误行为。客户端和模型都是靠这个契约决定如何调用的。
tool: search_docs
description: 搜索文档索引并返回最相关的页面。
input:
query: string
limit: number
output:
results:
- title: string
url: string
snippet: string3. 实现服务端
服务端负责真实集成。它验证输入、调用后端系统、处理权限,并返回结构化输出。
- 每个工具只做一件事。
- 先校验,再碰外部系统。
- 错误要可读,不要直接抛原始堆栈。
- 记录调用日志,方便以后审计。
// server.js
const docs = [
{ title: "MCP 概览", url: "/mcp", text: "MCP 让 AI 客户端连接工具和数据。" },
{ title: "Skill 概览", url: "/skill", text: "Skill 把可复用的任务经验打包起来。" },
{ title: "MCP 与 Skill", url: "/compare/mcp-vs-skill", text: "MCP 是接入,Skill 是步骤。" }
]
export function searchDocs({ query, limit = 3 }) {
if (!query || typeof query !== "string") {
return {
error: {
code: "INVALID_QUERY",
message: "query 必须是非空字符串",
retryable: false
}
}
}
const q = query.toLowerCase()
return {
results: docs
.filter((doc) => `${doc.title} ${doc.text}`.toLowerCase().includes(q))
.slice(0, limit)
.map(({ title, url, text }) => ({ title, url, snippet: text }))
}
}4. 连接客户端
客户端负责发现服务端、把能力展示给模型,并判断什么时候该调用工具。
新手规则 如果你说不清楚模型为什么要调用这个能力,通常说明这个能力描述还不够具体。
5. 验证流程
要测试发现、调用、结果处理和失败场景。光有一个成功路径是不够的。
A
发现
客户端能看到工具名、描述和输入 schema。
B
调用
客户端发送合法输入,服务端能安全处理非法输入。
C
结果
返回的数据足够清楚,模型不用瞎猜就能继续用。
6. 手动练习
复制下面这个极小的调用壳,不借助框架先把契约搞懂,再加真实 MCP SDK。
// practice.js
import { searchDocs } from "./server.js"
console.log(searchDocs({ query: "MCP", limit: 2 }))
console.log(searchDocs({ query: "", limit: 2 })){
"results": [
{
"title": "MCP 概览",
"url": "/mcp",
"snippet": "MCP 让 AI 客户端连接工具和数据。"
},
{
"title": "MCP 与 Skill",
"url": "/compare/mcp-vs-skill",
"snippet": "MCP 是接入,Skill 是步骤。"
}
]
}