详情

首页手游攻略 目前最火AI协议 - MCP 协议实战:从原理到落地:让 AI 拥有“超能力”

目前最火AI协议 - MCP 协议实战:从原理到落地:让 AI 拥有“超能力”

佚名 2026-07-14 08:27:58

前言

2026 年最火的 AI 协议是什么?

目前最火AI协议-> MCP 协议实战:从原理到落地,让 AI 拥有"超能力"

MCP(Model Context Protocol)——模型上下文协议。

几乎所有 AI 产品都在接入:Cursor、Claude、豆包、Trae...

今天我们从原理出发,实战接入高德地图 MCP文件系统 MCP浏览器控制 MCP,彻底搞懂 MCP 的本质。


一、MCP 是什么?

1.1 从"聊天"到"干活"

 复制代码豆包手机 AI Agent 的全新体验:
- 不再只是 chat
- 帮我们把活干了

传统 AI 的局限:

能力传统 AIMCP 加持后
聊天 可以 可以
查地图 不能 调用高德地图
读写文件 不能 操作本地文件
控制浏览器 不能 打开 Chrome
查数据库 不能 查询 MySQL

MCP 的本质:

 复制代码MCP = AI 的"USB 接口"

就像 USB 让各种设备可以连接电脑一样,MCP 让 AI 可以连接各种外部服务。

1.2 MCP 的定义

 复制代码Model Context Protocol(模型上下文协议)25 年最火的协议,定义了模型和外界服务之间的通信标准。

核心思想:

  • 标准化:统一的协议格式,一次开发,到处使用
  • 可扩展:任何人都可以开发 MCP Server
  • 安全:权限控制,用户授权

MCP 的架构:

 复制代码┌─────────────┐
│   AI 模型    │  ← 大脑(LLM)
└──────┬──────┘
       │
       ▼
┌─────────────┐
│  MCP Client │  ← 客户端(Cursor/Trae/你的代码)
└──────┬──────┘
       │
       ├──────────────┬──────────────┐
       ▼              ▼              ▼
┌──────────┐   ┌──────────┐   ┌──────────┐
│ 高德地图  │   │ 文件系统  │   │ 浏览器   │
│   MCP    │   │   MCP    │   │   MCP    │
└──────────┘   └──────────┘   └──────────┘

三个角色:

角色职责例子
AI 模型思考和决策GPT-4、Claude、Qwen
MCP Client协议适配、工具调用Cursor、你的代码
MCP Server提供具体能力高德地图、文件系统

二、MCP 的两种接入方式

2.1 Stdio 方式(本地进程)

 复制代码{
  command: "npx",
  args: ["-y", "@modelcontextprotocol/server-filesystem", "/path/to/dir"]
}

特点:

  • 启动一个本地进程
  • 通过标准输入/输出(stdin/stdout)通信
  • 适合本地工具(文件系统、数据库等)

2.2 HTTP 方式(远程服务)

 复制代码{
  url: "https://mcp.amap.com/mcp?key=YOUR_API_KEY"
}

特点:

  • 连接远程服务
  • 通过 HTTP 请求通信
  • 适合云服务(地图、天气、API 等)

对比:

方式通信方式适用场景性能
Stdio本地进程本地工具
HTTP网络请求云服务受网络影响

三、实战:接入三个 MCP Server

3.1 项目结构

 复制代码mcp-test/
├── main.mjs              # 主程序
├── package.json
├── .env                  # 环境变量(API Key)
└── beijing_south_station_hotels.md  # AI 生成的文档

3.2 完整代码

 复制代码// main.mjs
import "dotenv/config";
import { MultiServerMCPClient } from "@langchain/mcp-adapters";
import { ChatOpenAI } from "@langchain/openai";
import chalk from "chalk";
import {
  HumanMessage,
  SystemMessage,
  ToolMessage,
} from "@langchain/core/messages";// 1. 初始化 AI 模型
const model = new ChatOpenAI({
  modelName: process.env.MODEL_NAME,
  apiKey: process.env.OPENAI_API_KEY,
  configuration: {
    baseURL: process.env.OPENAI_BASE_URL,
  },
});// 2. 配置多个 MCP Server
const mcpClient = new MultiServerMCPClient({
  mcpServers: {
    // 高德地图 MCP(HTTP 方式)
    "amap-maps-streamableHTTP": {
      url: `${process.env.AMAP_MAPS_API_KEY}`,
    },
    // 文件系统 MCP(Stdio 方式)
    filesystem: {
      command: "npx",
      args: [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "D:workspacelesson_zpaiagentmcp_in_actionmcp-test",
      ],
    },
    // 浏览器控制 MCP(Stdio 方式)
    "chrome-devtools": {
      command: "npx",
      args: ["-y", "chrome-devtools-mcp@latest"],
    },
  },
});// 3. 获取所有工具
const tools = await mcpClient.getTools();
const modelWithTools = model.bindTools(tools);// 4. Agent 循环
async function runAgentWithTools(query, maxIterations = 30) {
  const messages = [new HumanMessage(query)];
  
  for (let i = 0; i < maxIterations; i++) {
    console.log(chalk.bgGreen("⏳正在等待AI思考..."));
    const response = await modelWithTools.invoke(messages);
    messages.push(response);    // 5. 如果没有工具调用,返回最终结果
    if (!response.tool_calls || response.tool_calls.length === 0) {
      console.log(`n AI 最终回复:n ${response.content}n`);
      return response.content;
    }    // 6. 处理工具调用
    console.log(
      chalk.bgBlue(` 检测到 ${response.tool_calls.length} 个工具调用`)
    );
    console.log(
      chalk.bgBlue(
        ` 工具调用: ${response.tool_calls.map((t) => t.name).join(", ")}`
      )
    );    // 7. 执行每个工具
    for (const toolCall of response.tool_calls) {
      const foundTool = tools.find((t) => t.name === toolCall.name);
      if (foundTool) {
        const toolResult = await foundTool.invoke(toolCall.args);
        let contentStr;
        if (typeof toolResult === "string") {
          contentStr = toolResult;
        } else if (toolResult && toolResult.text) {
          contentStr = toolResult.text;
        }
        messages.push(
          new ToolMessage({
            content: contentStr,
            tool_call_id: toolCall.id,
          })
        );
      }
    }
  }
  return messages[messages.length - 1].content;
}// 8. 执行任务
await runAgentWithTools(`
北京南站附近的3个酒店,拿到酒店照片,展开浏览器,展示每个酒店的图片
每个tab一个url展示,并且把那个页面标题改为酒店名
`);await mcpClient.close();

四、逐行解析

4.1 初始化 AI 模型

 复制代码const model = new ChatOpenAI({
  modelName: process.env.MODEL_NAME,
  apiKey: process.env.OPENAI_API_KEY,
  configuration: {
    baseURL: process.env.OPENAI_BASE_URL,
  },
});

逐行解析:

 复制代码modelName: process.env.MODEL_NAME,
  • 从环境变量读取模型名称
  • 可以是 gpt-4qwen-maxdeepseek-chat
 复制代码apiKey: process.env.OPENAI_API_KEY,
  • API 密钥,用于身份验证
  • 不要硬编码在代码中,使用 .env 文件
 复制代码configuration: {
  baseURL: process.env.OPENAI_BASE_URL,
}
  • API 基础 URL
  • 如果使用国内模型(如 Qwen),需要修改为对应的 baseURL

为什么用环境变量?

  • 安全性:API Key 不会泄露到代码仓库
  • 灵活性:不同环境使用不同配置
  • 标准化:12-Factor App 最佳实践

4.2 配置 MCP Server

 复制代码const mcpClient = new MultiServerMCPClient({
  mcpServers: {
    "amap-maps-streamableHTTP": {
      url: `${process.env.AMAP_MAPS_API_KEY}`,
    },
    filesystem: {
      command: "npx",
      args: [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "D:workspacelesson_zpaiagentmcp_in_actionmcp-test",
      ],
    },
    "chrome-devtools": {
      command: "npx",
      args: ["-y", "chrome-devtools-mcp@latest"],
    },
  },
});

逐行解析:

 复制代码"amap-maps-streamableHTTP": {
  url: `${process.env.AMAP_MAPS_API_KEY}`,
}
  • 高德地图 MCP,使用 HTTP 方式
  • url:MCP Server 的地址
  • key:高德地图 API Key,需要在高德开放平台申请
 复制代码filesystem: {
  command: "npx",
  args: [
    "-y",
    "@modelcontextprotocol/server-filesystem",
    "D:workspacelesson_zpaiagentmcp_in_actionmcp-test",
  ],
}
  • 文件系统 MCP,使用 Stdio 方式
  • command: "npx":使用 npx 运行
  • args
    • -y:自动确认安装
    • @modelcontextprotocol/server-filesystem:官方文件系统 MCP 包
    • 最后一个参数:允许访问的目录路径
 复制代码"chrome-devtools": {
  command: "npx",
  args: ["-y", "chrome-devtools-mcp@latest"],
}
  • 浏览器控制 MCP
  • chrome-devtools-mcp@latest:使用最新版本
  • 可以控制 Chrome 浏览器(打开页面、点击、输入等)

三个 MCP Server 对比:

Server方式功能用途
高德地图HTTP查地点、路线、POI地理信息查询
文件系统Stdio读写文件生成文档、保存结果
浏览器控制Stdio控制 Chrome展示内容、自动化操作

4.3 获取工具并绑定

 复制代码const tools = await mcpClient.getTools();
const modelWithTools = model.bindTools(tools);

逐行解析:

 复制代码const tools = await mcpClient.getTools();
  • 从所有 MCP Server 获取工具列表
  • 每个工具包含:名称、描述、参数 schema
  • 例如:maps_geo(地理编码)、maps_direction(路线规划)等
 复制代码const modelWithTools = model.bindTools(tools);
  • 将工具绑定到 AI 模型
  • AI 可以根据用户请求,自动选择调用哪个工具
  • 这就是 Function Calling(函数调用)机制

Function Calling 流程:

 复制代码用户:北京南站附近的酒店
  ↓
AI 思考:需要调用地图工具
  ↓
AI 输出:调用 maps_search_around 工具
  ↓
MCP Client:执行工具,返回结果
  ↓
AI 思考:根据结果生成回复
  ↓
最终回复:推荐 3 个酒店...

4.4 Agent 循环

 复制代码async function runAgentWithTools(query, maxIterations = 30) {
  const messages = [new HumanMessage(query)];
  
  for (let i = 0; i < maxIterations; i++) {
    console.log(chalk.bgGreen("⏳正在等待AI思考..."));
    const response = await modelWithTools.invoke(messages);
    messages.push(response);

逐行解析:

 复制代码const messages = [new HumanMessage(query)];
  • 创建消息数组,初始包含用户的问题
  • HumanMessage:用户消息
  • 后续会不断追加 AI 回复和工具结果
 复制代码for (let i = 0; i < maxIterations; i++) {
  • Agent 循环,最多执行 30 次
  • 防止无限循环(AI 一直调用工具)
 复制代码const response = await modelWithTools.invoke(messages);
messages.push(response);
  • 调用 AI 模型,传入所有历史消息
  • AI 会返回:
    • 纯文本回复(结束)
    • 工具调用(继续循环)

4.5 判断是否结束

 复制代码if (!response.tool_calls || response.tool_calls.length === 0) {
  console.log(`n AI 最终回复:n ${response.content}n`);
  return response.content;
}

逐行解析:

 复制代码if (!response.tool_calls || response.tool_calls.length === 0) {
  • 检查 AI 是否调用了工具
  • 如果没有工具调用,说明 AI 已经给出最终答案
 复制代码console.log(`n AI 最终回复:n ${response.content}n`);
return response.content;
  • 输出最终回复
  • 返回结果,结束函数

4.6 处理工具调用

 复制代码console.log(
  chalk.bgBlue(` 检测到 ${response.tool_calls.length} 个工具调用`)
);
console.log(
  chalk.bgBlue(
    ` 工具调用: ${response.tool_calls.map((t) => t.name).join(", ")}`
  )
);

解析:

  • 输出检测到的工具调用数量
  • 输出工具名称列表
  • 使用 chalk 库给日志上色,便于调试

4.7 执行工具

 复制代码for (const toolCall of response.tool_calls) {
  const foundTool = tools.find((t) => t.name === toolCall.name);
  if (foundTool) {
    const toolResult = await foundTool.invoke(toolCall.args);
    let contentStr;
    if (typeof toolResult === "string") {
      contentStr = toolResult;
    } else if (toolResult && toolResult.text) {
      contentStr = toolResult.text;
    }
    messages.push(
      new ToolMessage({
        content: contentStr,
        tool_call_id: toolCall.id,
      })
    );
  }
}

逐行解析:

 复制代码for (const toolCall of response.tool_calls) {
  • 遍历所有工具调用
  • AI 可能一次调用多个工具
 复制代码const foundTool = tools.find((t) => t.name === toolCall.name);
  • 根据工具名称找到对应的工具实例
 复制代码const toolResult = await foundTool.invoke(toolCall.args);
  • 执行工具,传入参数
  • 返回工具执行结果
 复制代码let contentStr;
if (typeof toolResult === "string") {
  contentStr = toolResult;
} else if (toolResult && toolResult.text) {
  contentStr = toolResult.text;
}
  • 处理工具返回结果
  • 可能是字符串,也可能是对象(包含 text 属性)
 复制代码messages.push(
  new ToolMessage({
    content: contentStr,
    tool_call_id: toolCall.id,
  })
);
  • 创建 ToolMessage,包含工具结果
  • tool_call_id:关联到对应的工具调用
  • 追加到消息历史,供 AI 继续思考

消息类型:

类型用途例子
HumanMessage用户输入"北京南站附近的酒店"
AIMessageAI 回复"我来帮你查询..."
ToolMessage工具结果"找到 3 个酒店..."
SystemMessage系统提示"你是一个助手..."

4.8 执行任务

 复制代码await runAgentWithTools(`
北京南站附近的3个酒店,拿到酒店照片,展开浏览器,展示每个酒店的图片
每个tab一个url展示,并且把那个页面标题改为酒店名
`);await mcpClient.close();

逐行解析:

 复制代码await runAgentWithTools(`...`);
  • 执行 Agent,传入复杂任务
  • 任务包含多个步骤:
    1. 查询北京南站附近的酒店
    2. 获取酒店照片
    3. 打开浏览器展示
    4. 修改页面标题
 复制代码await mcpClient.close();
  • 关闭 MCP Client
  • 释放资源,断开连接

五、执行流程

5.1 完整流程图

 复制代码用户输入:北京南站附近的3个酒店...
  ↓
AI 思考:需要调用地图工具
  ↓
调用 maps_search_around(高德地图 MCP)
  ↓
返回:3 个酒店信息
  ↓
AI 思考:需要获取酒店照片
  ↓
调用 maps_photo(高德地图 MCP)
  ↓
返回:照片 URL
  ↓
AI 思考:需要打开浏览器展示
  ↓
调用 chrome_navigate(浏览器 MCP)
  ↓
打开 3 个 Tab,展示照片
  ↓
调用 chrome_set_document_title(浏览器 MCP)
  ↓
修改页面标题
  ↓
AI 思考:任务完成
  ↓
最终回复:已完成,展示了 3 个酒店...

5.2 实际输出示例

 复制代码⏳正在等待AI思考...
 检测到 1 个工具调用
 工具调用: maps_search_around⏳正在等待AI思考...
 检测到 3 个工具调用
 工具调用: maps_photo, maps_photo, maps_photo⏳正在等待AI思考...
 检测到 3 个工具调用
 工具调用: chrome_navigate, chrome_navigate, chrome_navigate⏳正在等待AI思考...
 检测到 3 个工具调用
 工具调用: chrome_set_document_title, chrome_set_document_title, chrome_set_document_title⏳正在等待AI思考...AI 最终回复:
已完成,展示了 3 个酒店的图片:
1. 米家青年酒店(北京南站店)
2. 汉庭酒店(北京南站护城河店)
3. 如家酒店(北京南站店)

六、生成的文档

AI 还会自动生成一个 Markdown 文档:

 复制代码# 北京南站附近酒店及交通指南## 北京南站位置信息- **名称**: 北京南站
- **地址**: 北京市丰台区
- **坐标**: 116.378059, 39.867679## 推荐酒店### 1. 米家青年酒店(北京南站店)- **地址**: 右外东庄21号楼
- **坐标**: 116.377765, 39.868995
- **评分**: 3.6分
- **距离北京南站**: 约304米步行
- **步行时间**: 约4分钟### 2. 汉庭酒店(北京南站护城河店)- **地址**: 开阳路6号院1号楼
- **评分**: 4.6分
- **距离北京南站**: 约851米步行
- **步行时间**: 约11分钟

这个文档是怎么生成的?

  1. AI 调用高德地图 MCP,获取酒店信息
  2. AI 调用文件系统 MCP,创建 Markdown 文件
  3. AI 将信息整理成结构化文档

七、扩展:MCP 的未来

7.1 MCP 生态

 复制代码MCP Server 生态(部分):官方提供:
- filesystem(文件系统)
- postgres(数据库)
- sqlite(数据库)
- puppeteer(浏览器自动化)第三方提供:
- 高德地图(地理信息)
- 百度搜索(搜索引擎)
- GitHub(代码仓库)
- Slack(即时通讯)
- Notion(笔记)
- ...

7.2 MCP vs 传统 API

特性传统 APIMCP
标准化每个 API 不同统一协议
开发成本需要适配每个 API一次开发,到处使用
AI 集成需要手动编写调用逻辑AI 自动选择工具
生态分散统一生态

7.3 MCP 的应用场景

 复制代码1. AI 编程助手(Cursor/Trae)
   - 读写文件
   - 执行命令
   - 搜索代码2. AI 办公助手
   - 查地图、订酒店
   - 发邮件、发消息
   - 操作 Excel、PPT3. AI 数据分析
   - 查询数据库
   - 生成报表
   - 可视化图表4. AI 自动化
   - 控制浏览器
   - 操作手机 App
   - 定时任务

八、总结

核心要点

  1. MCP = AI 的"USB 接口",让 AI 可以连接各种外部服务
  2. 两种接入方式:Stdio(本地)和 HTTP(远程)
  3. 三个角色:AI 模型、MCP Client、MCP Server
  4. Function Calling:AI 自动选择并调用工具
  5. Agent 循环:思考 → 调用工具 → 获取结果 → 继续思考

实战收获

通过这个项目,我们实现了:

  • 接入高德地图 MCP(HTTP 方式)
  • 接入文件系统 MCP(Stdio 方式)
  • 接入浏览器控制 MCP(Stdio 方式)
  • 实现 Agent 循环,自动调用多个工具
  • 完成复杂任务:查酒店 → 获取照片 → 打开浏览器 → 修改标题

MCP 的价值

 复制代码传统 AI:只能聊天
MCP 加持:可以干活从"Chat AI"到"Agent AI"的跨越

点击查看更多
推荐专题
热门阅读