组合多个远程 MCP Server:让 Agent 同时调用高德地图、Chrome DevTools 和文件系统

0 阅读13分钟

组合多个远程 MCP Server:让 Agent 同时调用高德地图、Chrome DevTools 和文件系统

摘要:一个 Agent 如果能同时调用高德地图查位置、用 Chrome DevTools 打开网页、用 FileSystem 写入文件,它就能完成多么复杂的任务?本文用 LangChain 的 MultiServerMCPClient 连接多个 MCP Server——本地、远程 HTTP、stdio 三种方式全涵盖——构建一个能跨进程调用多种工具的 Agent。

📑 目录

  • MCP 的核心价值:跨进程调用
  • 项目目标:两个任务,展示 MCP 的组合威力
  • 环境准备与依赖包详解
  • MultiServerMCPClient:同时连接多个 Server
  • 配置详解:本地、远程 HTTP、stdio 三种方式
  • Agent 循环:处理不同类型的 Tool 返回值
  • 任务一:搜索酒店 + 浏览器展示图片
  • 任务二:搜索酒店 + 路线规划 + 保存文档
  • 一点总结
  • 互动讨论

MCP 的核心价值:跨进程调用

MCP(Model Context Protocol)的本质还是 Tool,但它给 Tool 包了一层进程,可以通过 stdio 或 HTTP 来跨进程访问

这意味着什么?

text

┌─────────────────────────────────────────────────────────────┐
│  本地 Tool(之前的方式)                                    │
│  ┌─────────────┐                                           │
│  │   Agent     │── 直接调用 ──▶ Tool(同进程)              │
│  └─────────────┘                                           │
│  问题:Tool 只能在本项目中使用,换语言/换项目就要重写       │
└─────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────┐
│  MCP Tool(现在的方式)                                    │
│  ┌─────────────┐    MCP协议     ┌──────────────────────┐   │
│  │   Agent     │── stdio/HTTP ──▶│  MCP Server(独立进程)│   │
│  └─────────────┘                └──────────────────────┘   │
│  优势:Tool 独立部署,跨语言、跨进程、跨项目复用            │
└─────────────────────────────────────────────────────────────┘

[此处插入图片:BC43E74C-94F4-4C46-811C-AC2102221D81.png]

有了 MCP 协议后,任何人都可以开发基于这个协议的 MCP Server,然后直接被复用。高德地图有 MCP Server,Chrome DevTools 有 MCP Server,FileSystem 也有 MCP Server——把它们组合在一起,Agent 的能力边界就被极大地扩展了。

项目目标:两个任务,展示 MCP 的组合威力

在 mcp-test.mjs 中,我配置了四个 MCP Server,让 Agent 同时拥有多种能力:

MCP Server连接方式能力
my-mcp-serverstdio(本地进程)查询用户信息(自定义)
amap-maps-httpHTTP(远程服务)高德地图:位置查询、路线规划、POI 搜索
fileSystemstdio(npx 临时安装)读写本地文件
chrome-devtoolsstdio(npx 临时安装)控制浏览器:打开页面、截图、点击元素

7d7d1ab886fffe88779d84ddfaeeddc5.png

这张图清晰展示了 Agent 通过 MCP Adapter 连接多个 MCP Server 的架构——高德 MCP 走 HTTP,Chrome DevTools 和 FileSystem 走 stdio,所有 Tool 统一汇聚到 Agent。

项目执行了两个任务,分别展示 MCP 的不同组合方式:

任务一:调用高德 MCP + Chrome DevTools MCP

“告诉我宁波老外滩附近的三个酒店,拿到酒店图片,打开我的默认浏览器(Edge),展示每个酒店的图片,每个 tab 一个 url 展示,并且把那个页面标题改为酒店名”

任务二:调用高德 MCP + FileSystem MCP

“北京南站附近的2个酒店,以及去的路线,路线规划生成文档保存到当前目录的一个 md 文件”

两个任务都用到高德 MCP,但第二个任务用 FileSystem 保存文档,第一个任务用 Chrome DevTools 操作浏览器——展示了 MCP 工具的可组合性。

环境准备与依赖包详解

bash

pnpm i @langchain/mcp-adapters @langchain/openai dotenv chalk

各依赖包的作用

包名版本作用
@langchain/mcp-adapters最新LangChain 官方 MCP 适配器,提供 MultiServerMCPClient,让 Agent 连接 MCP Server
@langchain/openai最新LangChain 的 OpenAI 兼容接口,用于调用大模型(DeepSeek 兼容 OpenAI 接口)
dotenv最新读取 .env 文件中的环境变量,如 DEEPSEEK_API_KEY
chalk最新终端输出着色,让 Agent 的迭代过程更直观可读

核心 SDK 说明

@langchain/mcp-adapters 内部依赖了 @modelcontextprotocol/sdk,这是 MCP 协议的标准实现。MultiServerMCPClient 的核心工作:

  1. 根据配置启动子进程(command + args)或建立 HTTP 连接(url
  2. 通过 MCP 协议与 Server 握手,获取所有 Tool 列表
  3. 将 MCP Tool 包装成 LangChain Tool 格式,统一返回

MultiServerMCPClient:同时连接多个 Server

javascript

import { MultiServerMCPClient } from '@langchain/mcp-adapters';

const mcpClient = new MultiServerMCPClient({
    mcpServers: {
        'my-mcp-server': {
            command: 'node',
            args: ['src/my-mcp-server.mjs'],
            cwd: 'D:/workspace/yjs_ai/ai/agent_in_action/mcp-demo',
        },
        'amap-maps-http': {
            url: 'https://mcp.amap.com/mcp?key=15b9da040ee6a3242f4708b7e3a6ea31',
        },
        'fileSystem': {
            command: 'npx',
            args: ['-y', '@modelcontextprotocol/server-filesystem', 'D:/workspace/yjs_ai/ai/agent_in_action/remote-mcp'],
        },
        'chrome-devtools': {
            command: 'npx',
            args: [
                '-y',
                'chrome-devtools-mcp@latest',
                '--executablePath',
                'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
            ]
        },
    }
});

MultiServerMCPClient 接收一个 mcpServers 对象,每个 Server 用 key 标识,值是连接配置。调用 getTools() 后,它会自动连接所有 Server,拉取各自的 Tool 列表,合并成一个统一的 Tool 数组。Agent 完全不知道这些 Tool 来自不同的进程——它只看到一堆可用的 Tool。

配置详解:本地、远程 HTTP、stdio 三种方式

1. 本地 stdio Server(自定义)

javascript

'my-mcp-server': {
    command: 'node',
    args: ['src/my-mcp-server.mjs'],
    cwd: 'D:/workspace/yjs_ai/ai/agent_in_action/mcp-demo',
}
  • command:启动子进程的命令,这里是 node
  • args:传递给命令的参数数组,即运行哪个文件
  • cwd:子进程的工作目录,确保相对路径正确解析

这种方式适合自定义业务逻辑的 Tool,用 Node.js 编写,通过 stdio 通信。

2. 远程 HTTP Server(高德地图)

javascript

'amap-maps-http': {
    url: 'https://mcp.amap.com/mcp?key=15b9da040ee6a3242f4708b7e3a6ea31',
}
  • url:MCP Server 的 HTTP 端点地址
  • key:高德 API 密钥,用于身份认证和计费

4C1A8994-BAAD-4A11-B1E2-AD68422BB862.png

这张图对比了两种跨进程调用方式:通过 stdio 调用本地 Java 进程,通过 HTTP 调用远程 Java 服务。高德 MCP 走的是 HTTP 路线——Agent 发送 HTTP 请求到高德服务器,服务器返回结果。远程 HTTP 方式的优势是 Server 可以独立部署在任何地方,语言无关。

3. stdio Server(npx 临时安装)

javascript

'fileSystem': {
    command: 'npx',
    args: ['-y', '@modelcontextprotocol/server-filesystem', 'D:/workspace/yjs_ai/ai/agent_in_action/remote-mcp'],
},
'chrome-devtools': {
    command: 'npx',
    args: [
        '-y',
        'chrome-devtools-mcp@latest',
        '--executablePath',
        'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
    ]
}

npx -y 会在运行时临时安装指定的 npm 包,-y 参数自动确认所有提示,无需手动交互。执行后自动清理,不用提前安装依赖,非常方便。

chrome-devtools-mcp 是官方 MCP Server,支持任何基于 Chromium 的浏览器。--executablePath 指定了 Edge 浏览器的可执行文件路径,让 MCP Server 控制 Edge 浏览器而不是默认的 Chrome。

7FC56A3C-D6CA-4BF8-9662-265C1E62DD5D.png

这张图展示了 Agent 调用本地 MCP Server(stdio)和远程 MCP Server(HTTP)的完整流程——Agent 通过 tool.invoke() 调用,底层由 MCP Adapter 处理通信细节。

Agent 循环:处理不同类型的 Tool 返回值

MultiServerMCPClient.getTools() 返回的 Tool 数组统一了接口,但不同 MCP Server 的返回值格式可能不同:

javascript

const tools = await mcpClient.getTools();
const modelWithTools = model.bindTools(tools);

for (const toolCall of response.tool_calls) {
    const foundTool = tools.find(t => t.name === toolCall.name);
    if (foundTool) {
        try {
            const toolResult = await foundTool.invoke(toolCall.args);
            let contentStr;
            // 返回值可能是纯字符串
            if (typeof toolResult === 'string') {
                contentStr = toolResult;
            // fileSystem 返回的是对象,包含 text 字段
            } else if (toolResult && toolResult.text) {
                contentStr = toolResult.text;
            // 其他情况序列化为 JSON
            } else {
                contentStr = JSON.stringify(toolResult);
            }
            messages.push(new ToolMessage({
                content: contentStr,
                tool_call_id: toolCall.id
            }));
        } catch (err) {
            // 工具执行失败,返回错误信息给 LLM
            messages.push(new ToolMessage({
                content: `工具执行失败: ${err.message}`,
                tool_call_id: toolCall.id
            }));
        }
    }
}

不同 MCP Server 的返回值差异:

  • 高德 MCP:返回 JSON 对象,包含位置、酒店、路线等信息
  • fileSystem MCP:返回 { text: '文件内容' } 对象
  • chrome-devtools MCP:返回操作结果字符串或对象

try-catch 包裹了工具调用,确保任何单个 Tool 失败不会导致整个 Agent 循环崩溃。错误信息通过 ToolMessage 返回给 LLM,让它可以决定下一步怎么处理(如重试、换参数、告知用户)。

任务一:搜索酒店 + 浏览器展示图片

Agent 执行的第一个任务是:

“告诉我宁波老外滩附近的三个酒店,拿到酒店图片,打开我的默认浏览器(Edge),展示每个酒店的图片,每个 tab 一个 url 展示,并且把那个页面标题改为酒店名”

执行流程

text

用户输入任务
    ↓
LLM 拆解:需要先搜索酒店,再打开浏览器展示图片
    ↓
【高德 MCP】搜索“宁波老外滩附近酒店”
    → 返回三个酒店的名称、地址、图片 URL
    ↓
【Chrome DevTools MCP】打开第一个酒店的图片 URL
    → 创建新 tab,导航到图片地址
    ↓
【Chrome DevTools MCP】将 tab 标题改为酒店名
    ↓
(重复以上两步,处理剩余两个酒店)
    ↓
任务完成

屏幕截图 2026-07-13 181611.png

屏幕截图 2026-07-13 181624.png

屏幕截图 2026-07-13 181618.png

上图展示了最终执行结果:Edge 浏览器中三个 tab 分别显示三家酒店的图片,每个 tab 的标题已经被改为对应的酒店名(如“汉庭酒店”“喆啡酒店”等)。

这个任务展示了高德 MCP + Chrome DevTools MCP 的组合:一个负责获取信息,一个负责可视化展示。Agent 在两个 MCP Server 之间协调调用,完成了完整的“搜索 → 展示”工作流。

任务二:搜索酒店 + 路线规划 + 保存文档

第二个任务是:

“北京南站附近的2个酒店,以及去的路线,路线规划生成文档保存到当前目录的一个 md 文件”

执行流程

text

用户输入任务
    ↓
LLM 拆解:需要搜索酒店、规划路线、保存文档
    ↓
【高德 MCP】搜索“北京南站附近酒店”
    → 返回两个酒店的名称、地址、评分
    ↓
【高德 MCP】规划从天安门到北京南站的路线
    → 返回地铁、公交等多种方案
    ↓
【FileSystem MCP】将结果写入 markdown 文件
    → 保存到当前目录的 md 文件中
    ↓
任务完成

执行后生成了 北京南站周边酒店及路线规划.md 文件,内容包含:

  • 北京南站的位置信息(地址、经纬度)
  • 两个推荐酒店(汉庭酒店、喆啡酒店)的地址、评分、特点
  • 详细的路线规划(步行路线、地铁路线、公交路线)
  • 路线规划总览图(ASCII 地图)
  • 出行小贴士

下面最终生成内容:

🚄 北京南站周边酒店及路线规划

生成时间:2025年
数据来源:高德地图


一、北京南站位置信息

项目内容
地址北京市丰台区
经纬度116.378059, 39.867679
交通枢纽地铁4号线、14号线、多路公交

二、推荐酒店

🏨 酒店一:汉庭酒店(北京南站北广场店)

项目内容
地址北京南站 F1 楼 1 层 1001 室
评分⭐ 4.4 分
类型经济型连锁酒店
特点就在北京南站站内北广场,出站即达,极为便捷

🏨 酒店二:喆啡酒店(北京南站店)

项目内容
地址右外东滨河路东庄甲 6 号
评分⭐ 4.4 分
类型精品酒店(咖啡主题)
特点紧邻北京南站,步行约 7 分钟,环境雅致,有咖啡文化特色

三、路线规划

路线①:北京南站 → 汉庭酒店(北广场店)

🚶 步行约 403 米 · 约 5 分钟

北京南站出站
  ↓ 沿南站幸福路向西步行 98 米
  ↓ 向南步行 79 米
  ↓ 向东南步行 15 米
  ↓ 向东南步行 99 米
  ↓ 向西南步行 112 米
到达:汉庭酒店(北京南站北广场店)

路线②:北京南站 → 喆啡酒店(北京南站店)

🚶 步行约 528 米 · 约 7 分钟

北京南站出站
  ↓ 沿南站幸福路向东步行 88 米
  ↓ 步行 9 米后右转
  ↓ 沿南站幸福路向东步行 66 米
  ↓ 左转进入幸福二巷,向北步行 259 米
  ↓ 沿右安门东滨河路向东步行 86 米
  ↓ 沿东庄一巷向南步行 20 米
到达:喆啡酒店(北京南站店)

路线③:天安门 → 北京南站(公共交通推荐)

🚇 全程约 38 分钟 · 约 6 公里

🅰️ 方案一:地铁(推荐·最快)
步骤路线时间
🚶 从 天安门广场 步行至 前门站(约 10 分钟)约 10 分钟
🚇 地铁 2 号线内环(前门 → 宣武门,1 站)约 6 分钟
🚇 站内换乘 地铁 4 号线(宣武门 → 北京南站,3 站)约 9 分钟
🚶 从 北京南站 A 北出口 出站约 1 分钟
总计约 38 分钟
天安门广场
    ↓ 步行 10 分钟
前门站(地铁2号线内环)
    ↓ 1 站(途经:和平门)
宣武门站(换乘4号线)
    ↓ 3 站(途经:菜市口、陶然亭)
北京南站(A北出口出站)
🅱️ 方案二:公交 106 路
步骤路线
🚶 从天安门步行至 前门站
🚌 乘坐 106 路(前门 → 北京南站,途经:大栅栏→珠市口南→天桥→北纬路→太平街→陶然桥北→南站幸福路)

四、路线规划总览图

                         ┌─────────────────────┐
                         │   天安门 / 市中心     │
                         └──────────┬──────────┘
                                    │
                          🚇 地铁2号线→4号线
                          🚌 公交106路等
                                    │
                         ┌──────────▼──────────┐
                         │    ★ 北京南站 ★      │
                         │  116.378059,39.867679 │
                         └──┬──────────────┬───┘
                            │              │
            🚶 步行403米    │              │  🚶 步行528米
                            │              │
              ┌─────────────▼──┐    ┌──────▼────────────┐
              │ 汉庭酒店(北广场店)│    │ 喆啡酒店(北京南站店) │
              │  评分:⭐4.4    │    │  评分:⭐4.4       │
              │  站内北广场F1层  │    │  右外东滨河路东庄甲6号│
              └────────────────┘    └───────────────────┘

五、出行小贴士

  1. 🚇 地铁优先:北京南站是地铁 4 号线和 14 号线的换乘站,去往北京各区域非常方便
  2. 🏨 汉庭酒店适合赶早班车/晚到站的旅客,出站即达
  3. ☕ 喆啡酒店环境更有特色,步行约 7 分钟,适合想稍作休整的旅客
  4. 💡 北京南站周边餐饮、便利店齐全,出行前可提前购齐所需物品

本路线规划由高德地图数据生成,信息仅供参考,实际出行请以实时路况为准。

这个任务展示了高德 MCP + FileSystem MCP 的组合:一个负责获取位置和路线数据,一个负责持久化保存。Agent 完成了“搜索 → 规划 → 保存”的完整工作流,结果以文档形式保留下来。

一点总结

通过这个项目,我理解了:

  1. MCP 的本质是跨进程 Tool 调用:通过 stdio(本地)或 HTTP(远程)实现。

  2. MultiServerMCPClient:LangChain 提供的适配器,可以同时连接多个 MCP Server,统一管理 Tool。

  3. 三种连接方式

    • command + args + cwd:启动本地 Node.js 进程(stdio)
    • url:连接远程 HTTP 服务
    • npx -y:临时安装并执行 npm 包
  4. 返回值类型处理:不同 MCP Server 返回格式不同,需要做类型判断和转换,配合 try-catch 确保稳定性。

  5. MCP 的组合威力:高德地图 + Chrome DevTools + FileSystem 组合起来,Agent 能完成“搜索 → 获取信息 → 打开浏览器 → 保存文档”的完整工作流。

  6. 任务驱动的 Agent 设计:给 Agent 一个自然语言任务,它会自动拆解、调用合适的 MCP Server、组合结果。

互动讨论

  1. MCP 和普通 Tool 的核心区别是什么?  为什么说 MCP 让 Tool 变得“可复用”?
  2. stdio 和 HTTP 两种通信方式分别适合什么场景?  本地和远程的边界在哪里?
  3. npx -y 临时安装的方式有什么优缺点?  在什么场景下适合使用?
  4. 任务一中 Agent 需要调用两个 MCP Server,它是如何协调顺序的?  如果酒店搜索失败了,浏览器还会打开吗?
  5. 高德 MCP + Chrome DevTools + FileSystem 的组合还能完成什么自动化任务?

📌 一点心得:MCP 最大的价值不是“让 Agent 能调用 Tool”,而是“让任何人开发的 Tool 都能被任何 Agent 调用”。这种解耦让工具生态可以独立发展,Agent 的能力边界也随之无限扩展。