MCP 多服务器架构实战:一个 Agent 同时操控地图、浏览器和文件

从零掌握 MCP 多服务器架构:让 AI 同时操控地图、浏览器和文件系统

前言

想象一下:你只需要用自然语言说一句"帮我查北京南站附近的酒店,把结果截图保存到本地",AI 就能自动调用高德地图查酒店、操控浏览器截图、再写入本地文件------全程无需你手动操作任何工具。

这就是 MCP(Model Context Protocol,模型上下文协议) 带来的变革。本文基于一个实际项目,带你从零理解 MCP 的多服务器架构,并手把手实现一个 AI Agent 同时连接 4 个 MCP Server。


一、什么是 MCP?为什么它很重要?

1.1 一句话理解

MCP 就是 AI 的"USB 接口协议"。就像 USB 让电脑能连接键盘、鼠标、U盘等各种外设一样,MCP 让 AI 能连接地图、浏览器、文件系统、数据库等各种工具。

1.2 核心价值:可复用

有了 MCP 协议后,任何人都可以开发基于这个协议的 MCP Server,然后可以直接复用。

这就是 MCP 最大的魅力------一次开发,到处使用。高德官方开发了地图 MCP Server,你不需要自己封装地图 API,直接拿来用就行。

1.3 两种连接方式

连接方式 传输协议 适用场景 示例
远程 HTTP HTTP/SSE 第三方服务、云端API 高德地图 MCP
本地 stdio 标准输入输出 本地工具、浏览器控制 Chrome DevTools、FileSystem

知识点 1:MCP 协议

MCP 是什么:Model Context Protocol,是 Anthropic 开源的一套标准协议,定义了 AI 模型与外部工具之间的通信规范。它让 LLM 能够以统一的方式发现、调用各种外部工具,而不需要为每个工具写定制化的胶水代码。

核心概念

  • Server:提供工具的进程(可以是本地程序,也可以是远程服务)
  • Client:连接 Server 并获取工具列表的客户端
  • Tool:Server 暴露的具体能力(如"查询经纬度"、"打开网页"、"写文件")

为什么重要:在 MCP 出现之前,让 AI 调用外部工具需要为每个工具单独写适配代码。MCP 统一了这个过程------就像 USB 统一了外设连接标准。


二、项目架构总览

scss 复制代码
┌─────────────────────────────────────────────────────┐
│                    AI Agent (DeepSeek)               │
│                 理解自然语言 → 决策调用哪些工具        │
└──────────────────────┬──────────────────────────────┘
                       │ bindTools()
┌──────────────────────▼──────────────────────────────┐
│              MultiServerMCPClient                     │
│            (LangChain MCP Adapter)                   │
│         统一管理多个 MCP Server 的工具                 │
└──┬──────────┬──────────────┬──────────────┬─────────┘
   │ HTTP     │ stdio        │ stdio        │ stdio
┌──▼────┐ ┌───▼──────┐ ┌────▼──────┐ ┌───▼─────────┐
│ 高德地图 │ │ 自定义MCP │ │Chrome      │ │ FileSystem  │
│  MCP   │ │  Server  │ │DevTools MCP│ │    MCP      │
│ (远程)  │ │ (本地)    │ │  (本地)    │ │   (本地)    │
└────────┘ └──────────┘ └────────────┘ └─────────────┘

核心依赖(package.json):

  • @langchain/mcp-adapters:LangChain 的 MCP 适配层,提供 MultiServerMCPClient
  • @langchain/openai:兼容 OpenAI 协议的模型调用(这里连的是 DeepSeek)
  • @modelcontextprotocol/sdk:MCP 官方 SDK,用于自定义 MCP Server

三、创建你自己的 MCP Server

先从最简单的开始------用 MCP SDK 写一个本地 Server。代码见 my-mcp-server.mjs

javascript 复制代码
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import { z } from 'zod';

// 1. 创建 Server 实例
const server = new McpServer({
  name: 'my-mcp-server',
  version: '1.0.0',
});

// 2. 注册工具:加法
server.tool(
  'add',
  '计算两个数字的和',
  {
    a: z.number().describe('第一个数字'),   // ← zod 定义参数 schema
    b: z.number().describe('第二个数字'),
  },
  async ({ a, b }) => ({
    content: [{ type: 'text', text: String(a + b) }],  // ← 返回标准格式
  })
);

// 3. 通过 stdio 启动,等待客户端连接
const transport = new StdioServerTransport();
await server.connect(transport);

知识点 2:MCP Server 的三要素

每个 MCP 工具都包含三个核心部分:

1. 名称(name) :唯一标识,如 'add'。AI 通过名称来区分和选择工具。

2. 参数 Schema(input schema) :用 Zod 定义参数类型和描述。Zod 是 TypeScript/JavaScript 的 schema 校验库。AI 会读取这个 schema 来理解"这个工具需要什么参数"。

javascript 复制代码
{ a: z.number().describe('第一个数字') }

z.number() 表示参数类型是数字,.describe() 是给 AI 看的参数说明。

3. 回调函数(handler) :实际执行业务逻辑的函数,返回 { content: [{ type: 'text', text: '...' }] } 格式。

stdio 传输:客户端通过启动子进程的方式运行 MCP Server,两者通过标准输入/输出(stdin/stdout)交换 JSON 消息。这意味着 MCP Server 可以是任何语言写的命令行程序。


四、AI Agent 客户端:同时连接多个 MCP Server

最精彩的部分在这里------mcp-test.mjs。它用一个 MultiServerMCPClient 统一管理所有 MCP Server:

javascript 复制代码
const mcpClient = new MultiServerMCPClient({
    mcpServers: {
        // 类型1:远程 HTTP MCP
        'amap': {
            "url": "https://mcp.amap.com/mcp?key=YOUR_KEY"
        },
        // 类型2:本地 stdio MCP(运行 JS 文件)
        'my-mcp-server': {
            command: 'node',
            args: ['./src/my-mcp-server.mjs']
        },
        // 类型3:本地 stdio MCP(通过 npx 运行 npm 包)
        'chrome-devtools': {
            command: 'npx',
            args: ['-y', 'chrome-devtools-mcp']
        },
        // 类型4:文件系统 MCP
        'filesystem': {
            command: 'npx',
            args: ['-y', '@modelcontextprotocol/server-filesystem', './output']
        }
    }
});

// 一行代码获取所有 Server 的全部工具!
const tools = await mcpClient.getTools();

四类 Server 的配置对比:

MCP Server 类型 配置方式
高德地图 HTTP 远程 直接填 URL,SDK 自动处理连接
自定义 Server stdio 本地 command: 'node' + 脚本路径
Chrome DevTools stdio 本地 npx -y 拉取 npm 包运行
FileSystem stdio 本地 同上,后面跟允许访问的目录

知识点 3:MultiServerMCPClient 如何工作

MultiServerMCPClient 是 LangChain MCP Adapter 提供的聚合客户端。

工作流程

  1. 读取配置中的每个 MCP Server
  2. 对 HTTP 类型 → 发 HTTP 请求获取工具列表
  3. 对 stdio 类型 → 启动子进程,通过 stdin/stdout 通信
  4. 将所有 Server 的工具合并成一个统一的工具列表
  5. 通过 model.bindTools(tools) 把工具注入给 AI 模型

关键优势:AI 不需要知道每个工具来自哪个 Server------它只看到一个统一的工具列表,直接按需调用即可。这就像操作系统的"设备抽象层"。


五、AI Agent 循环:让模型自主决策

有了工具列表后,怎么让 AI 自主调用它们?核心是 Agent Loop(代理循环)

javascript 复制代码
async function runAgentWithTools(query, maxIterations = 10) {
    const messages = [new HumanMessage(query)];

    for (let i = 0; i < maxIterations; i++) {
        // 第1步:把对话历史发给模型
        const response = await modelWithTools.invoke(messages);
        messages.push(response);

        // 第2步:如果模型直接返回文本 → 任务完成!
        if (!response.tool_calls || response.tool_calls.length === 0) {
            return response.content;
        }

        // 第3步:模型说要调用工具 → 逐个执行
        for (const tool_call of response.tool_calls) {
            const foundTool = tools.find(t => t.name === tool_call.name);
            const result = await foundTool.invoke(tool_call.args);

            // 第4步:把工具执行结果告诉模型,让它决定下一步
            messages.push(new ToolMessage({
                content: result,
                tool_call_id: tool_call.id,
            }));
        }
        // 回到第1步,模型根据结果继续推理...
    }
}

知识点 4:Agent Loop 的执行流程

整个过程就像一个"智能 while 循环":

css 复制代码
用户: "查北京南站附近酒店,写入文件"
   ↓
第1轮: AI 调用 amap.search("北京南站附近酒店")        ← 我需要位置数据
   ↓ (工具返回:酒店列表)
第2轮: AI 调用 amap.get_detail(酒店1_id)              ← 我需要详细信息
   ↓ (工具返回:名称、地址、评分)
第3轮: AI 调用 filesystem.write("hotels.txt", 结果)   ← 数据够了,写文件
   ↓ (工具返回:写入成功)
第4轮: AI 返回 "已完成!酒店信息已写入 hotels.txt"     ← 任务完成,停止循环

关键设计

  • ToolMessage:工具执行结果被包装成 ToolMessage 追加到消息历史,这样模型能看到"上次调用工具的结果"
  • maxIterations:防止无限循环的安全阀(比如工具一直失败)
  • 模型自主决策:每一步调用哪个工具、传什么参数,全部由模型判断

六、实战演示

场景1:地图 + 文件联动

javascript 复制代码
await runAgentWithTools(`
    帮我查询北京南站附近的酒店,找最近的 3 个。
    对每个酒店,把名称、地址、评分等信息,
    写入 hotels_near_beijing_south_station.txt 文件中。
`);

AI 会自动:调用高德地图 MCP 搜索 → 获取详情 → 调用 FileSystem MCP 写入文件。

场景2:浏览器操控

javascript 复制代码
await runAgentWithTools('打开百度首页,告诉我页面标题是什么');

AI 自动调用 Chrome DevTools MCP 的 navigate_pagetake_snapshot 工具。


知识点 5:Chrome DevTools MCP 的作用

chrome-devtools-mcp 是一个 npm 包,提供了 29 个浏览器操控工具

分类 工具
页面导航 navigate_page, new_page, close_page, select_page
元素交互 click, fill, hover, drag, type_text, press_key
数据获取 take_screenshot, take_snapshot, evaluate_script
调试分析 list_console_messages, list_network_requests, performance_start_trace

它让你用自然语言就能操控浏览器------"打开淘宝搜 iPhone"、"截图并保存"、"查看控制台报错",AI 都能帮你完成。

注意:需要本机装有 Chrome 或 Edge 浏览器(Chromium 内核即可)。


知识点 6:环境变量管理

项目使用 dotenv 管理敏感配置(.env):

ini 复制代码
DEEPSEEK_API_KEY=sk-xxx
DEEPSEEK_API_BASE_URL=https://api.deepseek.com/v1
DEEPSEEK_MODEL=deepseek-v4-flash

代码中通过 import 'dotenv/config' 自动加载,然后用 process.env.XXX 读取。永远不要把 API Key 硬编码在代码里


七、总结

核心要点回顾

  1. MCP 是 AI 的工具协议:统一了 AI 与外部工具的通信方式,让工具可以复用
  2. 两种传输方式:HTTP(远程服务)和 stdio(本地进程)
  3. MultiServerMCPClient:一个客户端同时管理多个 MCP Server,AI 无需关心工具来源
  4. Agent Loop:AI 在循环中"思考→调工具→看结果→再思考",直到完成任务
  5. 自定义 MCP Server 只需三步:创建 Server → 注册 tool(name + zod schema + handler)→ 连接 transport

文件索引

文件 作用
readme.md 项目笔记,记录应用场景和设计思路
my-mcp-server.mjs 自定义 MCP Server 示例(add/get_current_time/reverse_string)
mcp-test.mjs AI Agent 客户端,连接多个 MCP Server + Agent Loop
package.json 项目依赖
.env 环境变量(API Key)

一句话记住 MCP:它让 AI 从"只会聊天"变成了"什么都能干"------而你要做的,只是把 MCP Server 的配置填进去。

欢迎评论区交流!如果你也写了有趣的 MCP Server,欢迎分享 🚀

相关推荐
儒雅的名4 小时前
GoF设计模式——策略模式
设计模式·bash·策略模式
折哥的程序人生 · 物流技术专研13 小时前
第4篇:Lambda 简化策略模式(Java 8+)
java·设计模式·策略模式·函数式编程·lambda·代码简化·扩充系列
jsonbro20 小时前
手把手带你实现发布订阅模式
前端·vue.js·设计模式
workflower21 小时前
室内外配送机器人-应用路径
人工智能·机器学习·设计模式·矩阵·自动化
ttod_qzstudio1 天前
【软考设计模式】原型模式:“克隆“对象与深拷贝、浅拷贝精讲
设计模式·原型模式
geovindu1 天前
java: Builder Pattern
java·开发语言·后端·设计模式·建造者模式·生成器模式
折哥的程序人生 · 物流技术专研1 天前
第5篇:框架里的模板方法:HttpServlet、JdbcTemplate、AbstractList
设计模式·源码分析·jdbctemplate·httpservlet·模版方法模式·扩充系列
researcher-Jiang2 天前
Design Patterns——Template Method入门到情景实战
python·设计模式·模板方法模式
饼干哥哥2 天前
用Claude Code跑通跨境电商的5大场景,顶10个人的团队
人工智能·设计模式·正则表达式