LangGraph原理逻辑-LangGraph接入MCP(三)
LangGraph接入MCP一、MCP快速上手二、 详细梳理MCP工作机制三、拆解MCP的两种实现方式:SSE和STDIO四、Agent接入MCP服务五、手写实现一个MCP服务六、章节总结在2024年底claude大模型的开发公司Anthropic提出了一个MCP(ModeIContext Protocol)协议。通过MCP协议可以让应用程序以一种统一的方式向LLM模型提供工具调用。而随着几千个MCP服务突然冒出百度、阿里等厂商也开始大规模接入MCP这个协议也迅速在互联网上引起轩然大波。按照那些流量派见风就是雨的性子 MCP也着实被大吹特吹了一波。随着MCP服务越来越火爆LangGraph的AgeNnt中也提供了MCP的集成。这次我们就分几个部分逐步深度拆解MCP服务。MCP快速上手理解MCP的stdio和sse两种实现模式LangGraph的Agent接入MCP服务补充:自己开发一个MCP服务一、MCP快速上手MCP最神奇的地方就要做下简单的配置就能完成很多复杂的工作。那这次我们就先不来介绍MCP那些花里胡哨的概念直接上手来玩玩MCP。首先我们需要使用一个支持MCP的客户端工具。这类工具现在有很多以后肯定也会越来越多。这次我们使用一个免费的。在VSCode中有一个开发插Cline。通过这个插件可以快速和AI大模型交互。到这里我们就完成了MCP服务的初体验。只需要算单配置一个JSON文件就可以给大模型提供更多扩展的功能。当然除了这里演示到的高德地图的MCP服务外还有很多五花八门的MCP服务。甚至还有很多MCP的信息聚合网站。比如 https://mcp.so 上目前就聚合了好几千个各种各样的MCP服务。通过这些服务我们可以让AI大模型完成聊天以外的各种各样的功能。包括发送邮件、浏览网页等。甚至直接操作本地文件也可以。还有阿里云百炼平台 bailian.console.aliyun.com更是将各种MCP服务聚合成了很多独立的服务。只要开通对应的服务后就可以在阿里云百炼的智能应用中用图形化的方式直接集成这些MCP服务。通过MCP服务可以让大模型不再只是扮演一个大脑的角色而是拥有了四肢直接替代人的工作能力。这样看起来MCP确实给大模型带来一次质的飞跃是事实情况真的是这样吗?作为纯小白或许你只能跟在别人身后听风就是雨。但是作为程序员我们是有能力更全面的去理解MCP的。二、 详细梳理MCP工作机制MCP协议全程Model Context Protocol,中文翻译是模型上下文协议。MCP协议是由Anthropic公司提出的是一个专门用于与AI大语言模型进行交互的是本质上MCP协议只是允许应用程序以一种统一的方式向大语言模型提供Function call函数调用。而Function call是很多大语言模型自身就提供的一种功能。例如通过下面的案例我们就可以很简单的给大模型提供路线规划的能力MCP协议虽然极具大模型的应用特色但是本质上MCP协议本身不包含任何具体的工具实现。他只是用协议的形式规定了应用程序如何向大模型提供函数能力。至于为什么MCP服务使用起来这么简单单其实是Cline这样的工具封装了客户端的实现能力,这是工具的一种简化实现和MCP协议本身是没有太大关系的。这个关系就好像我们以往使用HTTP协议访问各种各样的网站一样的.我们这些普通人可以在完全不用了解HTTP协议是什么东东只要简单的使用浏览访问网站.但是这并不意味着HTTP就是一个简单的协议.在HTTP协议层面要考虑的问题也肯定不能只是简单的保证数据传输还需要对网络传输的安全性等等各个方面做出很多的设计。从这个功能层面上来说MCP协议和HITTP协议本质上是相同的.他基于大模型的Function Call工具实现只不过是是通过协议的方式定义了这些工具要如何样可以极大的提升各种工具的复用能力.但是作为一个协议MCP要考虑的事情同样不应该只是考虑这些工具功能如何实现还需要在各个方面保证不会出乱子。但是事实是怎样的呢?接下来我们再来梳理-一下MCP协议的两种实现方式SSE和STDIO。三、拆解MCP的两种实现方式:SSE和STDIOMCP还没听明白怎么又冒出SSE和STDIO了?不用担心还是老规矩直接上实例。还是以我们之前使用的高德地图的MCP服务为例。在高德地图开放平台的介绍中提供了两种接入高德地图的MCP配置方式一种是我们之前使用过的。配置一个网站地址。这就是典型的SSE实现机制。{mcpServers:{amap-amap-sse:{url:https://mcp.amap.com/sse?key你在高德官网上申请的key}}}另一种没有使用过的STDIO的配置方式是这样的:amap-maps:{command:npxargs:[-yamap/amap-maps-mcp-server],env:{AMAP_MAPS_API_KEY:高德地图key}}这种方式配置方式需要在本地安装Nodejs。很显然是通过在本地执行npx指令执行了一个应用程序从而获得高德地图的数据。至于这个数据是如何获得的? 是调用远端高德地图的服务获得的? 还是读取本地某个神秘文件获取的? 这就只有在高德地图提供的Nodejs源码amap/ammcp-server中才能知道了。从这个案例中我们就能理解出SSE和STDIO到底是怎样的工作机制。SSE:其实是一种基于HTTP协议实现的长连接协议只不过SSE协议是一种从服务端向客户端单向推送数据的长连接协议。也就是高德地图需要提供一个客户端就可以不断的访问高德地图的HTTP服务获得高德地图的服务数据。这时候的工HTTP服务然后客户端可以和这个HTTP服务建立一个长连接这样只是服务端的性能压力会大一点而已。作机制其实和以往我们熟悉的基于HTTP的工作机制本质上是很像的。STDIO:这种工作机制的本质是在客户端本地执行一个应用程序然后通过应用程序获得对应的结果。这时候MCP的核心问题就出来了MCP的服务提供者设计的但是执行却是在客户端的机器执行。也就是说这给服务提供者提供了一种操作客户端机器的机会。这里会有什么问题修改一下你本地的文件或者给你植入一个病毒程序或者。…。大家可以发挥一下自己的想象。四、Agent接入MCP服务LangChain中提供了一个新的功能模块langchain-mcp-adapters 来支持MCP服务#安装对应依赖pip install langchain-mcp-adapters接下来接入MCP服务也相当简单只要增加MCP的配置文件就行。fromlangchain_mcp_adapters.clientimportMultiServerMCPClientfromlanggraph.prebuiltimportcreate_react_agentfromconfig.load_keyimportload_keyfromlangchain_community.chat_modelsimportChatTongyi# 构建阿里云百炼大模型客户端llmChatTongyi(modelqwen-plus api_keyload_key(BAILIAN_API_KEY),#相比Cline客户端配置只要增加transport属性即可。不过测试stremaable_http有问题。不知道是不是版本的原因。clientMultiServerMCPClient({# amap-amap-sse:{# url: https://mcp.amap.com/sse?key451ad40d0e39453600f2a305e31eabe4,# transport:streamable_http#}amap-maps:{comggnd:npx,args:[-y,amap/amap-maps-mcp-server],env:{AMAP_MAPS_API_KEY:451ad40d0e39453600f2a305e31eabe4},transport:stdio}}}toolsawaitclient.get_tools()agentcreate_react_agent(modelllm,toolstools)responseawaitagent.ainvoke({messages:[{role:usercontent:帮我规划一条从长沙梅溪湖到湾镇的自驾路线}]})response五、手写实现一个MCP服务如何实现一个MCP服务?MCP的官网上提供了一系列的SDK来辅助实现MCP的客户端和服务端。官网地址:https://modelcontextprotocol.io/introduction首先需要安装MCP依赖pip install mcp然后就可以参照官网案例快速实现一个MCP服务mcp_server.pyfrommcp.server.fastmcpimportFastMCP mcpFastMCP(roymcpdemo)mcp.tool()defadd(a:int,b:int)-int:Add two numbers together.print(froy mcp demo called :add{a},{b}))returnabmcp.tool()defweather(city:str):获取某个城市的天气 Args: city具体城市 return城市city念天天气不错mcp.resource(greeting://{name})defgreeting(name:str)-str:Greet a person by name.print(froy mcp demo called : greeting{name}))returnfHello,{name}!if__name____main__:#以sse协议暴露服务。mcp.run(transportsse)#以stdio协议暴露服务。#mcp.run(transportstdio)mcp_client.pyfrommcpimportStdioServerParameters,stdio_client,ClientSessionimportmcp.typesastypes server_paramsStdioServerParameters(commandpython,args[/Users/wuyuanshun/PycharmProjects/LongchainDemo1/langGraph/mcp_server.py],envNone)asyncdefhandle_sampling_message(message:types.CreateMessageRequestParams)-types.CreateMessageResult:print(fsampling message:{message})returntypes.CreateMessageResult(roleassistant,contenttypes.TextContent(typetext,textHello,world! from model),modeldeepseek-v4-flash,stopReasonendTurn)asyncdefrun():asyncwithstdio_client(server_params)as(read,write):asyncwithClientSession(read,write,sampling_callbackhandle_sampling_message)assession:awaitsession.initialize()promptsawaitsession.list_prompts()print(fprompts:{prompts})toolsawaitsession.list_tools()print(ftools:{tools})resourcesawaitsession.list_resources()print(fresources:{resources})resultawaitsession.call_tool(weather,{city:北京})print(fresult:{result})if__name____main__:importasyncio asyncio.run(run())接下来也可以用同样的方式尝试在LangGraph中接入服务。当然由于需要依赖服务端的代码实现所以不能简单的配置一个python指令执行。需要打包成nodejs依赖启动。后续就不再做介绍了。六、章节总结通过深度演示MCP服务的客户端和服务端的交互过程让大家对MCP服务有了初步的了解。在深度使用更多的MCP服务的同时合理的看待MCP的安全问题。虽然MCP最大的意义在于简化客户端的调用过程让我们以极小的代价快速接更多的外部服务但是并不代表MCP服务就是安全的。