MCP 通讯方式与实现指南
一、三种 MCP 通讯方式对比MCPModel Context Protocol目前支持三种通讯方式各有特点1. stdio标准输入输出工作原理通过本地进程的 stdin/stdout 进行通信客户端以子进程方式启动 MCP 服务器双方通过管道交换 JSON-RPC 格式消息换行符分割适用场景本地进程间通信如命令行工具、文件系统操作简单的批处理任务或工具调用优点限制实现简单低延迟仅限本地不支持分布式部署无需网络配置服务端不能输出控制台日志会污染协议流适合本地开发——————————————————2. SSEServer-Sent Events⚠️ 已弃用工作原理基于 HTTP 长连接实现单向消息推送客户端通过GET /sse建立连接服务器通过 SSE 流发送 JSON-RPC 消息客户端通过POST /message发送请求适用场景远程服务调用如云服务、多客户端监控需要实时数据推送的场景如流式对话优点限制支持实时单向推送2025年3月后已被 Streamable HTTP 取代适合流式交互连接中断后无法恢复————————需维持长连接资源消耗较高3. Streamable HTTP流式 HTTP✅ 官方推荐工作原理2025年3月引入通过统一的/message端点实现双向通信客户端通过 HTTP POST 发送请求服务器可将响应升级为 SSE 流式传输按需支持无状态模式无需维持长连接核心优势✅ 支持连接恢复无需重新开始✅ 无需维持长连接降低资源消耗✅ 统一端点设计/message简化接口✅ 兼容现有基础设施负载均衡、中间件等适用场景高并发远程服务调用需要灵活流式响应的场景如 AI 助手动态输出二、stdio 模式实现架构流程图创建 Server → 启动服务 → Client 连接 → 加载 Tools → Agent 调用Step 1创建 MCP Serverfrom mcp.server.fastmcp import FastMCP mcp FastMCP(Math Tools) mcp.tool() def add(a: int, b: int) - int: return a b mcp.tool() def multiply(a: int, b: int) - int: return a * b if __name__ __main__: mcp.run(transportstdio) # ← 关键stdio 模式说明使用mcp.tool()注册工具方法run(transportstdio)启动服务。Step 2启动 MCP Serverpython server.py 服务启动后会持续监听 stdin/stdout 的读写事件。Step 3开发 MCP Client含 Agent3.1 定义 Server 参数server_params StdioServerParameters( commandpython, args[path/to/mcp_stdio_server.py] )3.2 加载 MCP Toolsasync with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await load_mcp_tools(session) print(f成功加载 {len(tools)} 个工具)3.3 创建 Agent 并调用agent initialize_agent( toolstools, llmllm, agentAgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verboseTrue, ) resp await agent.ainvoke(1417*5?)完整示例代码import os import asyncio from dotenv import load_dotenv from mcp import StdioServerParameters, ClientSession from mcp.client.stdio import stdio_client from langchain_mcp_adapters.tools import load_mcp_tools from langchain.agents import initialize_agent, AgentType from langchain_openai import ChatOpenAI load_dotenv() llm ChatOpenAI( modelqwen-plus, api_keyos.getenv(DASHSCOPE_API_KEY), base_urlhttps://ws-kcaoxz5olbi6r3qa.cn-beijing.maas.aliyuncs.com/compatible-mode/v1, streamingTrue, temperature0.7, ) async def create_mcp_stdio_client(): server_params StdioServerParameters( commandpython, args[D:/sd14/ai-agent/app/mcp_/stdio/mcp_stdio_server.py] ) try: async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await load_mcp_tools(session) print(f成功加载 {len(tools)} 个工具) agent initialize_agent( toolstools, llmllm, agentAgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verboseTrue, ) resp await agent.ainvoke(1417*5?) print(f\n回答: {resp}) return resp except Exception as e: print(f连接失败: {e}) traceback.print_exc() if __name__ __main__: asyncio.run(create_mcp_stdio_client())三、SSE 模式实现已弃用仅供参考⚠️官方已废弃建议直接使用 Streamable HTTPServer 端差异if __name__ __main__: mcp.run(transportsse) # ← 仅 transport 参数不同Client 端差异from langchain_mcp_adapters.client import MultiServerMCPClient client MultiServerMCPClient({ math: { url: http://127.0.0.1:8000/sse, transport: sse, # ← 指定传输方式 } }) tools await client.get_tools()SSE 模式完整代码SSE Server 端 (mcp_sse_server.py)from mcp.server.fastmcp import FastMCP # 创建 MCP 服务器实例 mcp FastMCP(Math Tools - SSE) # 注册工具方法 mcp.tool() def add(a: int, b: int) - int: 计算两个整数的和 return a b mcp.tool() def multiply(a: int, b: int) - int: 计算两个整数的乘积 return a * b mcp.tool() def subtract(a: int, b: int) - int: 计算两个整数的差 (a - b) return a - b mcp.tool() def divide(a: int, b: int) - float: 计算两个整数的商 (a / b) if b 0: raise ValueError(除数不能为0) return a / b mcp.tool() def power(base: int, exponent: int) - int: 计算幂运算 (base ^ exponent) return base ** exponent # 启动服务 if __name__ __main__: mcp.run(transportsse)SSE Client 端 (mcp_sse_client.py)import os import asyncio from dotenv import load_dotenv from langchain_mcp_adapters.client import MultiServerMCPClient from langchain.agents import initialize_agent, AgentType from langchain_openai import ChatOpenAI # 加载环境变量 load_dotenv() # 初始化 LLM llm ChatOpenAI( modelqwen-plus, api_keyos.getenv(DASHSCOPE_API_KEY), base_urlhttps://ws-kcaoxz5olbi6r3qa.cn-beijing.maas.aliyuncs.com/compatible-mode/v1, streamingTrue, temperature0.7, ) # 创建 SSE 客户端 async def create_mcp_sse_client(): try: # 创建多服务器客户端 client MultiServerMCPClient( { math: { url: http://127.0.0.1:8000/sse, # SSE 端点 transport: sse, # 指定传输方式 } } ) # 获取所有工具 tools await client.get_tools() print(f✅ 成功加载 {len(tools)} 个工具:) for tool in tools: print(f - {tool.name}: {tool.description}) # 创建 Agent agent initialize_agent( toolstools, llmllm, agentAgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verboseTrue, handle_parsing_errorsTrue, ) # 测试调用 print(\n *50) print( 测试 1: 基础运算) print(*50) resp1 await agent.ainvoke(请计算 14 17 * 5 ?) print(f\n 回答: {resp1[output]}\n) print(*50) print( 测试 2: 复杂表达式) print(*50) resp2 await agent.ainvoke(计算 (100 - 25) * 4 / 3 ?) print(f\n 回答: {resp2[output]}\n) print(*50) print( 测试 3: 幂运算) print(*50) resp3 await agent.ainvoke(计算 2 的 10 次方等于多少) print(f\n 回答: {resp3[output]}\n) return resp1 except Exception as e: print(f❌ 连接失败: {e}) import traceback traceback.print_exc() return None # 入口 if __name__ __main__: print( 启动 SSE MCP 客户端...) print( 请确保 SSE 服务器已启动: python mcp_sse_server.py) print() asyncio.run(create_mcp_sse_client())SSE 模式启动步骤# 终端1: 启动 SSE Server python mcp_sse_server.py # 终端2: 启动 SSE Client python mcp_sse_client.py四、Streamable HTTP 模式实现 ✅ 推荐Server 端if __name__ __main__: mcp.run(transportstreamable-http)Client 端client MultiServerMCPClient({ math: { url: http://127.0.0.1:8000/mcp, transport: streamable_http, # ← 注意下划线 } }) tools await client.get_tools()Streamable HTTP 完整代码Streamable HTTP Server 端 (mcp_streamable_server.py)from mcp.server.fastmcp import FastMCP # 创建 MCP 服务器实例 mcp FastMCP(Math Tools - Streamable HTTP) # 注册工具方法 mcp.tool() def add(a: int, b: int) - int: 计算两个整数的和 return a b mcp.tool() def multiply(a: int, b: int) - int: 计算两个整数的乘积 return a * b mcp.tool() def subtract(a: int, b: int) - int: 计算两个整数的差 (a - b) return a - b mcp.tool() def divide(a: int, b: int) - float: 计算两个整数的商 (a / b) if b 0: raise ValueError(除数不能为0) return a / b mcp.tool() def power(base: int, exponent: int) - int: 计算幂运算 (base ^ exponent) return base ** exponent mcp.tool() def factorial(n: int) - int: 计算阶乘 (n!) if n 0: raise ValueError(阶乘只支持非负整数) if n 0 or n 1: return 1 result 1 for i in range(2, n 1): result * i return result mcp.tool() def fibonacci(n: int) - list: 生成前 n 个斐波那契数列 if n 0: return [] if n 1: return [0] fib [0, 1] for i in range(2, n): fib.append(fib[i-1] fib[i-2]) return fib # 启动服务 if __name__ __main__: mcp.run(transportstreamable-http)Streamable HTTP Client 端 (mcp_streamable_client.py)import os import asyncio from dotenv import load_dotenv from langchain_mcp_adapters.client import MultiServerMCPClient from langchain.agents import initialize_agent, AgentType from langchain_openai import ChatOpenAI from langchain.callbacks import StreamingStdOutCallbackHandler # 加载环境变量 load_dotenv() # 初始化 LLM llm ChatOpenAI( modelqwen-plus, api_keyos.getenv(DASHSCOPE_API_KEY), base_urlhttps://ws-kcaoxz5olbi6r3qa.cn-beijing.maas.aliyuncs.com/compatible-mode/v1, streamingTrue, temperature0.7, callbacks[StreamingStdOutCallbackHandler()], ) # 创建 Streamable HTTP 客户端 async def create_mcp_streamable_client(): try: # 创建多服务器客户端 client MultiServerMCPClient( { math: { url: http://127.0.0.1:8000/mcp, # Streamable HTTP 端点 transport: streamable_http, # 注意下划线 } } ) # 获取所有工具 tools await client.get_tools() print(f\n✅ 成功加载 {len(tools)} 个工具:) for tool in tools: print(f - {tool.name}: {tool.description}) # 创建 Agent agent initialize_agent( toolstools, llmllm, agentAgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verboseTrue, handle_parsing_errorsTrue, max_iterations5, ) # 测试调用 test_cases [ 请计算 14 17 * 5 ?, 计算 (100 - 25) * 4 / 3 ?, 2 的 10 次方等于多少, 计算 5!5的阶乘等于多少, 生成前 10 个斐波那契数列, ] for i, query in enumerate(test_cases, 1): print(\n * 60) print(f 测试 {i}: {query}) print( * 60) try: resp await agent.ainvoke(query) print(f\n 最终回答:\n{resp[output]}\n) except Exception as e: print(f❌ 调用失败: {e}) return True except Exception as e: print(f❌ 连接失败: {e}) import traceback traceback.print_exc() return False # 高级用法上下文管理 async def advanced_usage(): 展示如何优雅地管理客户端生命周期 async with MultiServerMCPClient( { math: { url: http://127.0.0.1:8000/mcp, transport: streamable_http, } } ) as client: tools await client.get_tools() print(f✅ 加载了 {len(tools)} 个工具) # 创建 Agent agent initialize_agent( toolstools, llmllm, agentAgentType.STRUCTURED_CHAT_ZERO_SHOT_REACT_DESCRIPTION, verboseTrue, ) # 多轮对话 queries [ 计算 3 4 * 5, 计算 10!, 生成前 5 个斐波那契数列, ] for query in queries: print(f\n 用户: {query}) resp await agent.ainvoke(query) print(f AI: {resp[output]}) # 入口 if __name__ __main__: print( 启动 Streamable HTTP MCP 客户端...) print( 请确保 Streamable HTTP 服务器已启动: python mcp_streamable_server.py) print( 访问地址: http://127.0.0.1:8000/mcp) print() # 基础用法 asyncio.run(create_mcp_streamable_client()) # 高级用法取消注释使用 # asyncio.run(advanced_usage())Streamable HTTP 模式启动步骤# 终端1: 启动 Streamable HTTP Server python mcp_streamable_server.py # 终端2: 启动 Streamable HTTP Client python mcp_streamable_client.py快速对比总览特性stdioSSE已弃用Streamable HTTP ✅适用场景本地开发远程调用生产环境/云服务网络需求无需网络需要 HTTP需要 HTTP连接状态进程级需维持长连接支持无状态连接恢复N/A❌ 不支持✅ 支持资源消耗低高低官方推荐本地开发❌ 已淘汰✅强烈推荐五、补充如何选择合适的传输方式┌─────────────────────────────────────────────────────┐ │ 你的需求是什么 │ ├─────────────────────────────────────────────────────┤ │ • 本地开发/测试 → 使用 stdio │ │ • 远程服务/生产部署 → 使用 Streamable HTTP│ │ • 需要流式响应 → 使用 Streamable HTTP│ │ • 高并发场景 → 使用 Streamable HTTP│ │ • 旧项目维护不推荐新项目→ SSE但建议迁移 │ └─────────────────────────────────────────────────────┘六、踩坑提醒 问题解决方案stdio 模式服务端不能print()使用logging输出到文件SSE 连接中断迁移到 Streamable HTTPStreamable HTTP端口被占用更换端口或检查服务是否已启动工具加载失败检查 server 端的 transport 参数是否匹配环境变量未生效确保.env文件在项目根目录使用load_dotenv()

相关新闻

Codex界面汉化实战:从原理到配置的完整指南

Codex界面汉化实战:从原理到配置的完整指南

在实际开发工作中,我们常常会遇到一些功能强大但界面语言为英文的开发工具或插件,这给非英语母语的开发者带来了一定的学习门槛和使用不便。Codex 作为一款备受关注的智能代码辅助工具,其核心能力在于理解代码上下文并提供精准的代码补全或生…

2026/10/10 19:33:31 阅读更多 →
业务数据报表工具哪家强?2026主流报表工具横向实测对比

业务数据报表工具哪家强?2026主流报表工具横向实测对比

一、行业开篇:报表工具选型核心痛点在日常办公、业务运营、学术研究、投研分析等场景中,绝大多数用户都会面临报表制作难题:手动整理数据耗时费力、公式函数操作门槛高、图表制作不规范、报告素材匮乏、多份数据难以整合。传统办公工具仅能满…

2026/10/12 0:25:00 阅读更多 →
让AI系统10分钟学会你的企业知识

让AI系统10分钟学会你的企业知识

今年,每个企业都在尝试用AI提升效率。但一个尴尬的事实始终存在: AI工具越来越多,却没有一个真正"懂"你的业务。它不知道你的品牌调性,不理解你的客户画像,更无法沉淀你的行业经验。每次对话都要从零开始解释…

2026/10/10 5:36:51 阅读更多 →

最新新闻

稳定细胞系构建与高表达克隆筛选:从瞬时转染到稳定株的完整指南

稳定细胞系构建与高表达克隆筛选:从瞬时转染到稳定株的完整指南

上个月接了一个蛋白药物早期研发的需求。对方上来就问:稳定细胞系构建怎么收费,能不能顺便帮筛几个高表达克隆。多聊了几句我才搞清楚,他们刚用瞬时转染跑完一轮预实验,分泌量看着不错,团队内部已经把预算和排期都排到…

2026/10/14 10:11:49 阅读更多 →
PTA C++编程题解题攻略:常见题型与踩坑经验总结

PTA C++编程题解题攻略:常见题型与踩坑经验总结

1. 拿到PTA编程题,先别急着敲代码这些年我在某高校带过好几轮C上机课,也帮着学弟学妹们辅导过不少PTA的作业题,发现大多数人卡住的原因其实不是代码能力不够,而是打心底里没把“编程题”当成一道需要审题、拆解的工程题来做。大一…

2026/10/14 10:11:49 阅读更多 →
自托管PS5游戏库与硬件维护:一个极简Web面板的设计实践

自托管PS5游戏库与硬件维护:一个极简Web面板的设计实践

任何一台PS5,玩久了都会攒出一堆散乱的数字资产:买过的游戏、还没补的DLC、借给朋友的光盘、上次清灰的时间、某个账号里卡在80%的奖杯列表。身边不少人用Excel或者手机备忘录在记,但一旦跨设备、跨主机、跨朋友借还,很快就乱成一…

2026/10/14 10:11:49 阅读更多 →
LiteLLM实战:统一大模型API接入与代理网关部署指南

LiteLLM实战:统一大模型API接入与代理网关部署指南

如果你手上同时要接好几家大模型的 API,估计你早就被“每家一套请求格式、鉴权方式、限流策略”磨到没脾气。litellm就是干这个的:一个 Python 库,也是一个可以独立部署的代理网关,把各家大模型接口统一成一套调用方式&#xff0c…

2026/10/14 10:11:49 阅读更多 →
Excel SUMIFS函数详解:多条件求和高阶技巧

Excel SUMIFS函数详解:多条件求和高阶技巧

1. 为什么需要SUMIFS函数? 刚接触Excel那会儿,我经常被各种销售报表折磨得焦头烂额。记得有次老板让我统计"华东地区手机品类在Q2的销售额",我硬是用了三个辅助列才勉强算出来。直到后来发现了SUMIFS这个神器,才发现原来…

2026/10/14 10:11:49 阅读更多 →
Django+Flask智能营销系统:银行数字化转型实战

Django+Flask智能营销系统:银行数字化转型实战

1. 项目背景与核心价值在金融数字化转型浪潮中,银行业务营销正从传统人工经验驱动转向数据智能驱动。这个基于DjangoFlask的智能营销系统,正是利用爬虫技术获取多维金融数据,通过大数据分析生成客户画像,最终以可视化大屏呈现营销…

2026/10/14 10:10:46 阅读更多 →

日新闻

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 阅读更多 →