返回博客列表
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 的基本概念

三个核心角色

  1. 客户端(Client):你的应用,想要调用 AI 功能
  2. MCP 服务器(MCP Server):提供工具和资源,比如数据库服务器、文件服务器
  3. AI 模型:实际执行任务的模型
客户端 → MCP 服务器 → AI 模型 → 返回结果

MCP 的工作原理

简单来说就是:

  1. 你发起请求:问 AI 一个问题
  2. AI 判断需要什么:可能需要查数据库、调用 API 等
  3. 通过 MCP 调用工具:MCP 服务器提供这些工具
  4. 获取结果:把结果返回给 AI
  5. 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 装插件,让它能做更多事情。关键是:

  1. 理解概念:MCP 是协议,让 AI 可以调用外部工具
  2. 安装 SDK:选择合适的语言版本
  3. 连接服务器:找到或搭建 MCP 服务器
  4. 调用工具:通过 client.callTool() 调用
  5. 处理结果:拿到结果后给 AI 处理

记住:MCP 的核心是扩展 AI 的能力。通过 MCP,AI 不再只是一个"回答问题的工具",而是一个可以"行动的系统"。

现在就开始试试吧!找一个 MCP 服务器,写几行代码,看看 AI 是怎么调用外部工具的。