2025年1月20日
10 分钟阅读
MCP 调用入门:用最简单的方式理解和使用模型上下文协议
MCP 调用入门:用最简单的方式理解和使用模型上下文协议
你是不是听说过 MCP,但觉得听起来很高深?别担心,这篇文章会用最简单的方式告诉你 MCP 是什么,以及怎么用它来让你的 AI 应用变得更强大。
什么是 MCP?简单来说就是"给 AI 扩展能力"
最通俗的理解
想象一下,ChatGPT 就像是一个很聪明的人,但他只能靠自己的知识回答问题。而 MCP(Model Context Protocol,模型上下文协议)就像给他装了一个"工具箱",让他可以:
- 查数据库
- 调用各种 API
- 访问文件系统
- 执行代码
- 做更多的事情
关键点:
- MCP 不是 AI 模型本身,而是一个"协议"(你可以理解为规则)
- 它让 AI 可以调用外部工具和服务
- 有点像给 AI 装插件,扩展它的能力
MCP 能解决什么问题?
问题:AI 模型只能回答训练时学过的内容,不知道实时的、外部的信息。
解决方案:通过 MCP,AI 可以:
- 实时查询数据库
- 调用外部 API 获取最新信息
- 访问文件系统读取文档
- 执行代码进行计算
MCP 的基本概念
三个核心角色
- 客户端(Client):你的应用,想要调用 AI 功能
- MCP 服务器(MCP Server):提供工具和资源,比如数据库服务器、文件服务器
- AI 模型:实际执行任务的模型
客户端 → MCP 服务器 → AI 模型 → 返回结果
MCP 的工作原理
简单来说就是:
- 你发起请求:问 AI 一个问题
- AI 判断需要什么:可能需要查数据库、调用 API 等
- 通过 MCP 调用工具:MCP 服务器提供这些工具
- 获取结果:把结果返回给 AI
- AI 整合答案:基于获取的信息给你回答
如何开始使用 MCP?
第一步:安装 MCP SDK
首先需要安装 MCP 的开发工具包:
# 安装 Node.js 版本的 MCP SDK
npm install @modelcontextprotocol/sdk或者如果你用 Python:
pip install mcp第二步:连接 MCP 服务器
创建一个简单的客户端连接:
// 最简单的 MCP 客户端示例
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
// 连接到 MCP 服务器
const transport = new StdioClientTransport({
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/directory"],
});
const client = new Client(
{
name: "my-app",
version: "1.0.0",
},
{
capabilities: {},
}
);
await client.connect(transport);第三步:列出可用工具
看看 MCP 服务器提供了哪些工具:
// 获取可用工具列表
const tools = await client.listTools();
console.log("可用工具:", tools);
// 输出示例:
// [
// { name: "read_file", description: "读取文件内容" },
// { name: "write_file", description: "写入文件" },
// { name: "list_directory", description: "列出目录" }
// ]实际调用示例
示例 1:读取文件
最常见的用法是让 AI 读取文件内容:
// 调用读取文件工具
const result = await client.callTool({
name: "read_file",
arguments: {
path: "/path/to/document.txt",
},
});
console.log("文件内容:", result.content);实际场景:
- AI 需要读取文档才能回答问题
- 通过 MCP 让 AI 访问文件系统
- AI 读取文件后给你答案
示例 2:查询数据库
让 AI 可以查询数据库:
// 假设有一个数据库 MCP 服务器
const dbResult = await client.callTool({
name: "query_database",
arguments: {
sql: "SELECT * FROM users WHERE age > 18",
},
});
console.log("查询结果:", dbResult.data);实际场景:
- 你问:"公司有多少员工?"
- AI 通过 MCP 查询数据库
- 返回实时的、准确的数据
示例 3:调用外部 API
让 AI 可以获取实时信息:
// 调用天气 API
const weatherResult = await client.callTool({
name: "get_weather",
arguments: {
city: "北京",
date: "2025-01-20",
},
});
console.log("天气信息:", weatherResult);实际场景:
- 你问:"今天北京天气怎么样?"
- AI 不能凭空知道,需要通过 API 获取
- MCP 让它可以调用天气服务
完整示例:构建一个简单的 MCP 客户端
创建客户端
// mcp-client.js
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
async function createMCPClient() {
// 创建传输层(这里用标准输入输出)
const transport = new StdioClientTransport({
command: "npx",
args: ["-y", "@modelcontextprotocol/server-filesystem", process.cwd()],
});
// 创建客户端
const client = new Client(
{
name: "my-mcp-client",
version: "1.0.0",
},
{
capabilities: {
tools: {},
},
}
);
// 连接服务器
await client.connect(transport);
return client;
}使用客户端
async function main() {
// 创建客户端
const client = await createMCPClient();
try {
// 1. 列出可用工具
const tools = await client.listTools();
console.log(
"可用工具:",
tools.tools.map((t) => t.name)
);
// 2. 调用工具读取文件
const fileContent = await client.callTool({
name: "read_file",
arguments: {
path: "./README.md",
},
});
console.log("文件内容:", fileContent.content);
// 3. 列出目录
const directory = await client.callTool({
name: "list_directory",
arguments: {
path: "./",
},
});
console.log("目录内容:", directory.entries);
} finally {
// 断开连接
await client.close();
}
}
main().catch(console.error);与 AI 模型集成
让 AI 自动调用 MCP
关键是要让 AI 知道有哪些工具可用,并在需要时自动调用:
// 简化的 AI + MCP 集成示例
async function askAIWithMCP(question) {
const client = await createMCPClient();
try {
// 1. 获取可用工具
const tools = await client.listTools();
// 2. 把工具信息告诉 AI(这里简化处理)
const toolDescriptions = tools.tools.map((tool) => ({
name: tool.name,
description: tool.description,
}));
// 3. AI 根据问题判断需要调用什么工具
// 比如用户问:"README.md 里写了什么?"
// AI 识别需要调用 read_file 工具
// 4. 调用工具
const result = await client.callTool({
name: "read_file",
arguments: { path: "./README.md" },
});
// 5. 把结果给 AI,让它生成回答
const answer = `文件内容:\n${result.content}\n\n根据文件内容,${question} 的答案是...`;
return answer;
} finally {
await client.close();
}
}
// 使用
askAIWithMCP("README.md 里写了什么?").then(console.log);常见使用场景
场景 1:文档问答系统
需求:让 AI 回答关于公司文档的问题。
// 1. 连接到文件系统 MCP 服务器
const fsClient = await createFileSystemMCPClient();
// 2. 用户问问题
const question = "公司的请假流程是什么?";
// 3. AI 识别需要读取文档
const doc = await fsClient.callTool({
name: "read_file",
arguments: { path: "./documents/leave-policy.md" },
});
// 4. AI 基于文档内容回答
const answer = generateAnswer(question, doc.content);场景 2:实时数据查询
需求:让 AI 回答关于实时数据的问题。
// 1. 连接到数据库 MCP 服务器
const dbClient = await createDatabaseMCPClient();
// 2. 用户问:"这个月销售额多少?"
const question = "这个月销售额多少?";
// 3. AI 识别需要查询数据库
const result = await dbClient.callTool({
name: "query",
arguments: {
sql: "SELECT SUM(amount) FROM sales WHERE month = '2025-01'",
},
});
// 4. AI 基于查询结果回答
const answer = `本月销售额是 ${result.data[0].sum} 元`;场景 3:代码执行
需求:让 AI 可以执行代码并看到结果。
// 1. 连接到代码执行 MCP 服务器
const codeClient = await createCodeExecutionMCPClient();
// 2. 用户问:"计算斐波那契数列第 10 项是多少?"
const question = "计算斐波那契数列第 10 项是多少?";
// 3. AI 生成代码并执行
const result = await codeClient.callTool({
name: "execute_code",
arguments: {
code: `
function fibonacci(n) {
if (n <= 1) return n;
return fibonacci(n-1) + fibonacci(n-2);
}
console.log(fibonacci(10));
`,
language: "javascript",
},
});
// 4. AI 基于执行结果回答
const answer = `斐波那契数列第 10 项是 ${result.output}`;错误处理
处理调用失败
async function safeCallTool(client, toolName, arguments) {
try {
const result = await client.callTool({
name: toolName,
arguments,
});
return { success: true, data: result };
} catch (error) {
console.error(`调用工具 ${toolName} 失败:`, error.message);
return {
success: false,
error: error.message,
};
}
}
// 使用
const result = await safeCallTool(client, "read_file", {
path: "./file.txt",
});
if (result.success) {
console.log("成功:", result.data);
} else {
console.log("失败:", result.error);
}验证工具是否存在
async function callToolIfExists(client, toolName, arguments) {
// 先检查工具是否存在
const tools = await client.listTools();
const toolExists = tools.tools.some((t) => t.name === toolName);
if (!toolExists) {
throw new Error(`工具 ${toolName} 不存在`);
}
// 调用工具
return await client.callTool({
name: toolName,
arguments,
});
}最佳实践
1. 合理选择 MCP 服务器
根据需求选择合适的服务器:
- 文件操作:使用文件系统服务器
- 数据查询:使用数据库服务器
- API 调用:使用 HTTP 服务器
2. 错误处理要完善
try {
const result = await client.callTool({...});
} catch (error) {
// 记录错误
console.error("MCP 调用失败:", error);
// 给用户友好的提示
return "抱歉,无法获取数据,请稍后重试";
}3. 缓存结果
如果数据不经常变化,可以考虑缓存:
const cache = new Map();
async function getCachedResult(key, fetchFunction) {
if (cache.has(key)) {
return cache.get(key);
}
const result = await fetchFunction();
cache.set(key, result);
return result;
}4. 限制调用频率
避免过于频繁的调用:
let lastCallTime = 0;
const MIN_INTERVAL = 1000; // 最小间隔 1 秒
async function rateLimitedCall(client, toolName, arguments) {
const now = Date.now();
const timeSinceLastCall = now - lastCallTime;
if (timeSinceLastCall < MIN_INTERVAL) {
await new Promise((resolve) =>
setTimeout(resolve, MIN_INTERVAL - timeSinceLastCall)
);
}
lastCallTime = Date.now();
return await client.callTool({ name: toolName, arguments });
}总结
MCP 其实就是给 AI 装插件,让它能做更多事情。关键是:
- 理解概念:MCP 是协议,让 AI 可以调用外部工具
- 安装 SDK:选择合适的语言版本
- 连接服务器:找到或搭建 MCP 服务器
- 调用工具:通过 client.callTool() 调用
- 处理结果:拿到结果后给 AI 处理
记住:MCP 的核心是扩展 AI 的能力。通过 MCP,AI 不再只是一个"回答问题的工具",而是一个可以"行动的系统"。
现在就开始试试吧!找一个 MCP 服务器,写几行代码,看看 AI 是怎么调用外部工具的。