MCP 协议开发实战:从零搭建 AI Agent 工具链
系列前文 GitHub Actions 深度实践零运维搭建 CI/CD 流水线本文定位在「流水线能自动构建/发布」之后解决下一层问题——AI Agent 如何标准化连接外部工具。技术栈Python 3.10 · 官方mcpSDKFastMCP·langchain-mcp-adapters·可选GitHub Actions 做门禁MCPModel Context Protocol正在成为 AI Agent 连接外部工具的事实标准。它解决了传统 AI 集成的m×n 困境m 个大模型 × n 个工具往往要做 m×n 次适配MCP 将其降维为mn——模型侧实现一次 Client工具侧实现一次 Server即可全互联。本文将通过可运行的实战代码从零构建一套完整的 MCP 工具链并说明每个关键技术的应用价值。一、理解 MCP 的核心架构MCP 采用 Host / Client / Server 三层┌─────────────────────────────────────────────┐ │ Host宿主 │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ Client A │ │ Client B │ │ Client C │ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ └────────┼─────────────┼─────────────┼────────┘ │ │ │ ┌─────▼─────┐ ┌─────▼─────┐ ┌─────▼─────┐ │ MCP Server│ │ MCP Server│ │ MCP Server│ │ 数据库 │ │ 文件系统│ │ 天气 API│ └───────────┘ └───────────┘ └───────────┘角色职责类比Host运行 AI 的应用Claude Desktop、自研 Agent操作系统ClientHost 内组件维持与某个 Server 的独立会话驱动Server暴露 Tools / Resources / Prompts外设与服务底层通信基于JSON-RPC 2.0。本地开发常用stdio进程管道远程/多客户端场景常用Streamable HTTP / SSE便于 Server → Client 推送。应用价值工具开发与 Agent 开发彻底解耦。业务方只维护一个 MCP ServerCursor、Claude Desktop、LangChain Agent 都能按同一协议接入不必为每个宿主重写插件。二、环境准备2.1 Python 环境# 创建虚拟环境 python -m venv mcp-agent-env # Windows mcp-agent-env\Scripts\activate # macOS / Linux # source mcp-agent-env/bin/activate pip install mcp[cli] httpx pydantic langchain-openai langchain-mcp-adapters langgraphWindows 下命令一般是python不是python3。下文示例统一写python按本机解释器调整即可。2.2 项目结构mcp-toolchain/ ├── mcp_server.py # MCP Server暴露工具 ├── agent_host.py # 最小 Host发现/调用工具 ├── langchain_integration.py # LangChain Agent 集成 ├── .github/workflows/ci.yml # 可选用 Actions 做门禁 └── requirements.txt与系列前文的对应关系前文Actions本文MCPWorkflow 发布过程代码化Server 工具能力代码化Secrets 管密钥Token / 权限在 Server 层校验失败可观测 ArtifactTool 调用审计日志 限流三、构建 MCP Server暴露工具能力用官方FastMCP实现天气查询、知识库检索、网页摘要三个工具。# mcp_server.py import json import httpx from mcp.server.fastmcp import FastMCP mcp FastMCP(ResearchAssistantTools) # Tool 1: 天气查询 mcp.tool() async def get_weather(city: str) - str: 查询指定城市的实时天气信息。 Args: city: 城市名称例如 Beijing、Shanghai async with httpx.AsyncClient() as client: response await client.get( fhttps://wttr.in/{city}, params{format: j1}, timeout10.0, ) response.raise_for_status() data response.json() current data[current_condition][0] return json.dumps( { city: city, temperature_c: current[temp_C], feels_like_c: current[FeelsLikeC], humidity: current[humidity], description: current[weatherDesc][0][value], }, ensure_asciiFalse, ) # Tool 2: 知识库检索 KNOWLEDGE_BASE { MCP协议: ( MCPModel Context Protocol是开放标准协议 用于让 AI 应用以统一方式连接外部工具与数据源。 ), AI Agent: ( AI Agent智能体能感知环境、决策并调用工具完成任务 工具调用通常通过 Function Calling 或 MCP 完成。 ), } mcp.tool() async def search_knowledge(query: str) - str: 从本地知识库中检索相关信息。 results [] q query.lower() for key, value in KNOWLEDGE_BASE.items(): if q in key.lower() or q in value.lower(): results.append({topic: key, content: value}) if not results: return json.dumps( {status: no_result, message: f未找到与{query}相关的知识}, ensure_asciiFalse, ) return json.dumps({status: success, results: results}, ensure_asciiFalse) # Tool 3: 网页摘要预览 mcp.tool() async def summarize_url(url: str) - str: 获取指定 URL 的网页内容预览生产环境应再接摘要模型。 async with httpx.AsyncClient() as client: response await client.get(url, timeout15.0, follow_redirectsTrue) content response.text[:3000] return json.dumps( { url: url, status_code: response.status_code, content_preview: content[:1500], char_count: len(response.text), }, ensure_asciiFalse, ) if __name__ __main__: # stdio适合本地 Host 拉起子进程远程场景可改为 streamable-http / sse mcp.run(transportstdio)关键技术与价值技术点作用应用价值mcp.tool()把函数注册为可发现工具docstring / 类型注解自动变成 Agent 可理解的 schemaasynchttpx非阻塞外呼多工具并发时不堵死事件循环transportstdio标准输入输出通信零端口、零 CORS本地调试最快返回 JSON 字符串统一结果载体Host / 多模型侧解析成本低对比「每个平台写一套 Plugin」同等三个工具传统适配往往要几百行胶水FastMCP 声明式注册后维护点收敛到一个 Server 进程。本地自检可选# 若已安装 mcp CLI mcp dev mcp_server.py四、构建 MCP Host连接 Server 并驱动调用Host 是「能力消费者」通过 MCP Client 发现工具、发起tools/call。# agent_host.py import asyncio import logging from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client logging.basicConfig( levellogging.INFO, format%(asctime)s - HOST - %(levelname)s - %(message)s, ) async def main(): server_params StdioServerParameters( commandpython, args[mcp_server.py], ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() logging.info(Host 已连接到 MCP Server) # 1. 发现工具 listed await session.list_tools() print(可用工具:, [t.name for t in listed.tools]) # 2. 调用天气 weather await session.call_tool(get_weather, {city: Beijing}) print(天气:, weather.content) # 3. 调用知识库 knowledge await session.call_tool( search_knowledge, {query: MCP协议} ) print(知识:, knowledge.content) if __name__ __main__: asyncio.run(main())运行python agent_host.py关键技术与价值技术点作用应用价值StdioServerParameters声明如何拉起 Server 子进程Host 不关心工具内部实现只关心命令与参数list_tools运行时能力发现新增mcp.tool后 Host 无需改协议代码call_toolJSON-RPCtools/call封装调用面统一便于做审计、重试、熔断双层async with正确关闭管道与会话避免僵尸子进程占满文件句柄这一层还不接大模型——先保证「发现 → 调用 → 拿结果」稳定再接到 Agent排障成本低一个数量级。五、LangChain 集成可治理的 Agent原则LangChain / LangGraph 是「大脑」MCP 是「手脚」。所有外呼走 MCP Tool权限与限流放在 Server 侧避免模型「直接摸」任意 HTTP。使用官方适配库langchain-mcp-adapters不要再用虚构的langchain.tools.mcpAPI。# langchain_integration.py import asyncio import logging import time from langchain.agents import create_agent from langchain_mcp_adapters.client import MultiServerMCPClient from langchain_mcp_adapters.tools import load_mcp_tools logging.basicConfig(levellogging.INFO) logger logging.getLogger(audit) async def main(): client MultiServerMCPClient( { research: { command: python, args: [mcp_server.py], transport: stdio, } } ) # 有状态会话同一 Server 连接上复用适合多步工具编排 async with client.session(research) as session: tools await load_mcp_tools(session) logger.info(已加载工具: %s, [t.name for t in tools]) agent create_agent( modelopenai:gpt-4o, toolstools, system_prompt( 你是智能研究助手只能通过已提供的工具查询天气、 检索知识库、获取网页预览。不要编造工具结果。 ), ) result await agent.ainvoke( { messages: [ { role: user, content: 北京今天天气怎么样另外简要解释 MCP 协议是什么。, } ] } ) print(最终回答:, result[messages][-1].content) if __name__ __main__: asyncio.run(main())需要 OpenAI 兼容密钥时# Windows PowerShell $env:OPENAI_API_KEYsk-... python langchain_integration.py5.1 审计回调可观测若你使用带 callback 的 Executor / 自定义图节点建议输出结构化步骤日志class AuditCallbackHandler: 示意记录工具名与入参便于审计与排障。 def on_tool_start(self, tool_name: str, tool_input: dict): logging.info( agent_step, extra{ tool: tool_name, input: tool_input, timestamp: time.time(), }, )关键技术与价值技术点作用应用价值MultiServerMCPClient同时挂多个 MCP Server天气、知识库、内部 API 可分进程拆分互不影响load_mcp_toolsMCP Tool → LangChain ToolAgent 框架与工具协议解耦换大脑不必重写手脚create_agent工具调用 Agent多步任务由模型编排人只写工具与策略审计日志记录每步 tool / input满足内控「谁在何时调了什么」线上事故可回放六、进阶JSON-RPC 与 SSE / Streamable HTTP6.1 JSON-RPC 2.0 请求{ jsonrpc: 2.0, id: 1, method: tools/call, params: { name: get_weather, arguments: { city: Beijing } } }响应{ jsonrpc: 2.0, id: 1, result: { content: [{ type: text, text: ... }] } }应用价值抓包/日志按id对齐请求与响应自研 Host 时不必发明私有 RPC。6.2 SSE / Streamable HTTP远程场景远程部署时Server 可改为 HTTP 传输具体路径以当前 SDK 版本文档为准典型事件流形态Content-Type: text/event-stream Cache-Control: no-cache Connection: keep-alive event: message data: {jsonrpc:2.0,id:1,result:{tools:[...]}}应用价值多 Host 共享同一工具集群与 K8s Service / 网关鉴权更好接。本地仍推荐stdio降低复杂度。把 Server 改成 HTTP 传输后Client 配置示例client MultiServerMCPClient( { research: { url: http://127.0.0.1:8000/mcp, transport: http, # 或文档推荐的 streamable-http / sse } } )七、与 GitHub Actions 衔接给 MCP 工具链加门禁前文解决「代码怎么自动验证与发布」MCP Server 同样需要 CI否则 Agent 一上线就踩坏工具。# .github/workflows/mcp-ci.yml name: MCP Toolchain CI on: push: branches: [main] pull_request: jobs: smoke: runs-on: ubuntu-latest timeout-minutes: 10 steps: - uses: actions/checkoutv4 - uses: actions/setup-pythonv5 with: python-version: 3.12 cache: pip - name: Install run: | python -m pip install -U pip pip install mcp[cli] httpx pytest pytest-asyncio - name: Import list tools smoke run: | python - PY import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def smoke(): params StdioServerParameters(commandpython, args[mcp_server.py]) async with stdio_client(params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await session.list_tools() names {t.name for t in tools.tools} assert {get_weather, search_knowledge, summarize_url} names print(smoke ok:, sorted(names)) asyncio.run(smoke()) PY应用价值PR 合入前证明「工具可发现、进程可拉起」避免只测 Python import、不测 MCP 握手的假绿。八、生产级最佳实践8.1 权限与安全在 Server 层def validate_token(token: str | None) - str: if not token or token ! demo-token: raise PermissionError(无效令牌) return user-demo def has_permission(user_id: str, action: str) - bool: return action in {weather, knowledge} mcp.tool() async def get_weather(city: str, token: str | None None) - str: 带权限校验的天气查询示意。 user_id validate_token(token) if not has_permission(user_id, weather): raise PermissionError(无权访问天气服务) # ... 原业务逻辑 return json.dumps({city: city, ok: True}, ensure_asciiFalse)更稳妥的做法是把身份放在HTTP Header / 网关而不是让模型自由填写token参数——上面仅作「Server 必须有权控」的示意。8.2 异常兜底手段做法价值超时httpxtimeout10外部 API 挂了不拖死 Agent步数上限Agent / Graph 限制迭代次数防止工具互调死循环烧 Token敏感操作返回pending_approval高风险动作人工确认后再执行幂等写操作带request_id重试不产生重复工单/重复扣费8.3 可观测性每次tools/call打结构化日志tool/latency_ms/ok/error_type与前文 Actions 的失败通知打通Server 健康检查失败 → Webhook 告警对外部依赖做熔断连续失败则短时拒绝避免雪崩九、总结对比对比维度传统方式MCP 方式适配成本m×nmn代码维护点各平台各一套 Plugin一个 Server多 Host 复用扩展性新工具要重写适配新mcp.tool即插即用可治理性依赖各宿主特性统一在 Server 做权限 / 审计 / 限流与 CI/CD难统一回归stdio 冒烟可直接挂进 Actions落地顺序建议1. FastMCP 暴露 13 个只读工具stdio 2. agent_host 验证 list_tools / call_tool 3. langchain-mcp-adapters 接到 Agent 4. 加权限、超时、审计 5. CI 冒烟 可选HTTP 远程部署MCP 的核心价值是零适配工具开发与 Agent 开发解耦「一次编写到处调用」。叠加上文的零运维流水线整条链路变成代码推送 → Actions 自动验证/发布 → MCP Server 对外暴露工具 → Agent 按协议发现并调用这才是「深度实践」想拼完整的一环而不是又一个只能 Demo 的脚本。系列续篇工具接上之后必须打开多步推理黑盒——见 可观测性深度实践零盲盒追踪 Agent 多步推理。参考Model Context Protocol 规范MCP Python SDK / FastMCPLangChain MCP 文档langchain-mcp-adapters系列前文GitHub Actions 深度实践零运维搭建 CI/CD 流水线

相关新闻

网页版Minecraft开发实战:从Three.js到性能优化

网页版Minecraft开发实战:从Three.js到性能优化

这类项目最值得先看的不是功能有多全,而是能不能在普通浏览器环境里稳定跑起来。网页版 Minecraft 听起来很酷,但真正落地时,最该盯住的是渲染性能、输入响应和资源加载这三块。如果你只是想快速验证一个基础版本,我更建议把第一次…

2026/10/3 5:35:15 阅读更多 →
Express框架核心原理与Node.js实战指南

Express框架核心原理与Node.js实战指南

1. Express框架核心定位解析Express作为Node.js生态中最流行的Web应用框架,其核心设计哲学体现在"轻量级"和"非侵入式"这两个关键词上。我在实际项目中使用Express已有五年多时间,最深刻的体会是:它既提供了Web开发必需的…

2026/10/9 2:50:01 阅读更多 →
05_3a概论

05_3a概论

2026/10/14 11:40:32 阅读更多 →

最新新闻

ECharts玫瑰图如何同时展示两个维度百分比?三种实现方案详解

ECharts玫瑰图如何同时展示两个维度百分比?三种实现方案详解

看到这个标题,你应该也在做类似的需求:一张玫瑰图里,要展示两个维度的数据,而且两个维度都要体现各自所占的百分比。这个场景在实际业务里太常见了——比如某公司报表里既要看“各产品线销售额占总销售额的比例”,又要…

2026/10/14 15:15:04 阅读更多 →
精灵标注助手导入XML数据全攻略:从预处理到批量导入的工程化实践

精灵标注助手导入XML数据全攻略:从预处理到批量导入的工程化实践

1. 从一份“打不开”的XML说起:精灵标注助手导入功能的真实使用场景第一次接触精灵标注助手的人,多半是被它“轻量、离线、支持多格式”这几个特点吸引过来的。尤其是做目标检测、图像分类或者文本实体识别的朋友,手里往往已经积累了一批标注…

2026/10/14 15:15:04 阅读更多 →
580集PS教程深度拆解:从软件操作到设计决策的系统学习路径

580集PS教程深度拆解:从软件操作到设计决策的系统学习路径

1. 这套580集PS教程到底值不值得啃第一次看到“580集”这个数字,我的反应跟大多数人一样:要么是标题党,要么就是把一个十分钟的小技巧拆成三集来凑数。但真正把这套内容翻了一遍之后,我发现它跟市面上那种“三天学会PS”“七天接单…

2026/10/14 15:15:04 阅读更多 →
游戏目标检测实战:3000张6类MOBA数据集从标注转换到YOLO训练全流程

游戏目标检测实战:3000张6类MOBA数据集从标注转换到YOLO训练全流程

简介:本资源为LOL英雄联盟角色检测数据集,面向计算机视觉方向的目标检测学习者与算法工程师,可用于训练和验证游戏场景下的多目标识别模型。数据集共3000张jpg图片,每张均配有对应的VOC格式xml标注与YOLO格式txt标注,标…

2026/10/14 15:15:04 阅读更多 →
Java开发实战:从基础到框架的常见问题解析

Java开发实战:从基础到框架的常见问题解析

1. Java学习中的常见困惑与解决思路最近在技术社区看到不少Java初学者提出的共性问题,让我回想起自己当年踩过的坑。从环境配置到框架选择,从语法理解到性能优化,每个阶段都会遇到不同的"拦路虎"。今天就把这些典型问题做个系统梳理…

2026/10/14 15:15:04 阅读更多 →
单片机毕设项目:基于51单片机的老人跌倒报警定时定位上报系统设计 基于单片机的老人安全定位监护与跌倒报警系统设计(032602)

单片机毕设项目:基于51单片机的老人跌倒报警定时定位上报系统设计 基于单片机的老人安全定位监护与跌倒报警系统设计(032602)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于嵌入式单片机,Java、小程序技术领域和毕业项目实战 ✌️…

2026/10/14 15:14:02 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/13 16:22:04 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →