LangChain集成MCP协议:构建模块化AI应用的新范式
1. 项目概述当LangChain遇见MCP构建下一代AI应用的新范式如果你最近在捣鼓LangChain想给AI应用加点“料”比如让它能实时查询数据库、调用外部API甚至控制智能家居那你大概率会遇到一个核心痛点如何安全、高效、标准化地让大语言模型LLM与外部工具和数据进行交互传统的做法要么是写一堆硬编码的函数调用要么是依赖特定供应商的闭源SDK项目一复杂代码就成了一团乱麻维护和扩展都让人头疼。这正是“guinacio/langchain-mcp-client”这个项目要解决的。简单来说它是一个LangChain的集成组件让你能够无缝地使用模型上下文协议Model Context Protocol 简称MCP定义的服务器。MCP可以理解为一套“通用插座”标准它定义了AI模型如GPT-4、Claude如何与外部数据源文件、数据库、API和工具计算器、代码执行器进行通信的规范。而langchain-mcp-client就是这个“通用插座”在LangChain生态里的“适配器”。想象一下你之前需要为每个外部功能比如查天气、读数据库、发邮件都手动编写一个LangChain Tool并处理复杂的认证和错误。现在你只需要启动一个符合MCP标准的服务器比如一个能查询公司内部知识库的服务器然后通过langchain-mcp-client连接上它LangChain Agent就能立刻、安全地调用这个服务器提供的所有能力。这极大地降低了集成复杂度将开发者的重心从“如何连接”转移到了“提供什么服务”上。这个项目适合所有正在或计划使用LangChain构建复杂AI应用的开发者、研究者和技术负责人。无论你是想构建一个能分析公司财报的智能助手还是一个能自动化操作多个软件的工作流机器人通过MCP和这个客户端你都能获得一种更模块化、更可维护的架构方案。接下来我们就深入拆解它的设计思路、核心用法以及那些在官方文档里可能不会明说的实操细节。2. 核心架构与设计哲学为什么是MCP在深入代码之前我们必须先理解MCP协议本身的价值以及langchain-mcp-client在这个生态中的定位。这决定了你是否应该采用它以及如何用好它。2.1 MCP协议AI世界的“USB-C”接口MCP的核心思想是标准化和解耦。在MCP出现之前AI应用与外部资源的交互是“百花齐放”但也是“各自为政”的。OpenAI有Function Calling Anthropic有Tool Use LangChain自己定义了Tool的基类。如果你想让一个Agent同时使用来自不同提供商或自研的工具就需要写大量的胶水代码进行适配。MCP定义了一套与模型无关的协议包括资源Resources代表模型可以读取的数据比如一个文本文件、数据库查询结果的一个片段。服务器可以“列出”可用的资源模型可以“读取”资源的内容。工具Tools代表模型可以执行的操作每个工具都有明确的输入参数JSON Schema定义。模型“调用”工具服务器执行并返回结果。提示Prompts预定义的文本模板服务器可以提供给模型用于引导模型完成特定任务。这套协议通过JSON-RPC over STDIO标准输入输出或SSE服务器发送事件进行通信。这意味着任何实现了MCP服务器标准的程序无论用什么语言编写Python、Go、Rust、Node.js都能被任何支持MCP的客户端包括langchain-mcp-client所使用。这带来的直接好处是工具和数据的提供者服务器开发者与消费者AI应用开发者被分离开了。你可以从社区直接获取一个现成的“PostgreSQL MCP服务器”或“GitHub MCP服务器”像插拔U盘一样插入你的LangChain应用立即获得相关能力而无需关心其内部实现。2.2langchain-mcp-client的桥梁角色langchain-mcp-client项目本质上是一个LangChain生态的“协议转换器”。它的职责非常清晰发现Discovery连接到指定的MCP服务器通过进程启动或网络连接获取该服务器提供的所有工具Tools和资源Resources列表。封装Wrapping将获取到的每个MCP工具动态地封装成一个LangChain框架能识别的BaseTool子类对象。这样LangChain的Agent、Chain就可以像使用原生Tool一样去使用它们。路由与调用Routing Invocation当LangChain Agent决定调用某个工具时客户端负责将调用请求按照MCP协议的格式转发给对应的服务器并接收、解析服务器的响应最后以LangChain期望的格式返回结果。生命周期管理Lifecycle Management管理服务器的连接、会话状态并在适当的时候关闭连接。这种设计使得你的核心AI应用逻辑保持干净。你不再需要为每一个外部依赖编写具体的工具类只需要配置好MCP客户端告诉它“去连接那个服务器”剩下的工具发现和调用都由客户端自动完成。2.3 与其他方案的对比为了更直观地理解其优势我们可以做一个简单对比方案集成复杂度可维护性工具复用性安全性硬编码函数高。每个功能都需手动实现并嵌入Agent。低。业务逻辑、工具代码、AI逻辑耦合深。极低。几乎无法跨项目复用。取决于实现。需自行管控权限。LangChain 原生Tool中。需为每个功能定义Tool类。中。工具与AI逻辑解耦但工具实现仍与项目绑定。中。可通过Python包共享但依赖特定框架。中。在Tool实现中控制。MCP langchain-mcp-client低。只需配置客户端连接。工具自动发现。高。AI应用、工具服务器完全解耦独立演进。高。任何MCP服务器可被任何客户端使用跨语言、跨框架。高。权限控制在服务器端客户端仅代理调用。注意MCP并非银弹。对于极其简单、单一的工具比如一个固定的字符串处理函数直接硬编码或写一个简单的LangChain Tool可能更直接。MCP的优势在管理大量、复杂、可能动态变化的外部工具和数据源时才会淋漓尽致地体现出来。3. 从零开始环境准备与基础集成理论讲得再多不如动手跑一遍。我们假设一个最常见的场景你想让LangChain Agent能够进行简单的数学计算。我们将使用一个现成的、简单的MCP服务器示例并通过langchain-mcp-client将其集成到LangChain中。3.1 基础环境搭建首先确保你的Python环境建议3.10以上并安装核心依赖。我们使用uv作为包管理器它比pip更快、更现代当然用pip也可以。# 使用 uv (推荐) uv init mcp-langchain-demo cd mcp-langchain-demo uv add langchain langchain-openai langchain-community uv add langchain-mcp-client # 或者使用 pip pip install langchain langchain-openai langchain-community langchain-mcp-client这里我们安装了langchain: LangChain核心框架。langchain-openai: 用于接入OpenAI的LLM。langchain-community: 包含一些社区贡献的组件langchain-mcp-client目前位于其中。langchain-mcp-client: 我们今天的主角。接下来你需要一个MCP服务器来连接。为了演示我们可以使用MCP官方提供的一个非常简单的“快速计算器”服务器。它通常是一个独立的可执行文件或Python脚本。这里我们用一个概念性的Python服务器示例实际使用时你可能需要从社区寻找或自己编写。假设我们有一个最简单的calculator_server.py#!/usr/bin/env python3 import json import sys import asyncio from mcp import Server, StdioServerTransport from mcp.types import Tool, TextContent # 1. 创建MCP服务器实例 server Server(quick-calculator) # 2. 定义一个工具加法 server.list_tools() async def handle_list_tools(): return [ Tool( nameadd, descriptionAdd two numbers together., inputSchema{ type: object, properties: { a: {type: number, description: The first number}, b: {type: number, description: The second number}, }, required: [a, b], }, ) ] # 3. 处理工具调用 server.call_tool() async def handle_call_tool(name: str, arguments: dict): if name add: result arguments[a] arguments[b] return [TextContent(typetext, textstr(result))] else: raise ValueError(fUnknown tool: {name}) # 4. 启动服务器使用Stdio传输 async def main(): async with StdioServerTransport() as transport: await server.run(transport) if __name__ __main__: asyncio.run(main())这个服务器通过标准输入输出stdio通信提供了一个名为add的工具。你需要先运行这个服务器python calculator_server.py它会在后台等待客户端连接。3.2 在LangChain中集成MCP客户端现在我们在另一个Python脚本中使用langchain-mcp-client来连接这个服务器并将它的工具提供给LangChain Agent。import asyncio from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_openai import ChatOpenAI from langchain_core.prompts import ChatPromptTemplate from langchain_community.agent_toolkits.mcp import create_mcp_toolkit async def main(): # 1. 创建MCP工具包连接到我们的计算器服务器 # 注意这里假设服务器进程已经启动并通过stdio通信。 # ‘command’参数是启动服务器的命令对于已运行的进程通常需要通过子进程管理。 # 更常见的生产用法是连接到网络套接字。 # 为了演示我们使用一个简化配置。实际中你可能使用 McpServer 类进行更精细的控制。 # 首先演示通过子进程启动并管理服务器 from langchain_community.tools.mcp import McpServer import subprocess # 启动服务器进程 server_process subprocess.Popen( [python, path/to/your/calculator_server.py], stdinsubprocess.PIPE, stdoutsubprocess.PIPE, textTrue ) # 创建MCP服务器配置使用stdio传输并指定进程的stdin/stdout # 注意langchain-mcp-client 的内部API可能仍在演进以下为概念性代码 # 实际请参考最新文档或源码中的 create_mcp_toolkit 函数用法 toolkit await create_mcp_toolkit( # 这里需要传入服务器配置。一种常见模式是使用 McpServer 列表。 # 假设我们有一个辅助函数来从进程创建连接 servers[...] # 具体配置需查阅最新文档 ) # 获取工具列表 tools toolkit.get_tools() print(f从MCP服务器获取到 {len(tools)} 个工具) for tool in tools: print(f - {tool.name}: {tool.description}) # 2. 初始化LLM (这里使用OpenAI GPT-4你需要设置OPENAI_API_KEY环境变量) llm ChatOpenAI(modelgpt-4-turbo-preview, temperature0) # 3. 创建Agent提示词 prompt ChatPromptTemplate.from_messages([ (system, 你是一个乐于助人的助手可以使用工具来回答问题。), (human, {input}), (placeholder, {agent_scratchpad}), ]) # 4. 创建Tool Calling Agent agent create_tool_calling_agent(llmllm, toolstools, promptprompt) # 5. 创建Agent执行器 agent_executor AgentExecutor(agentagent, toolstools, verboseTrue) # 6. 运行一个查询 result await agent_executor.ainvoke({input: 请计算123和456的和是多少}) print(f\n最终答案: {result[output]}) # 7. 清理关闭服务器进程 server_process.terminate() server_process.wait() if __name__ __main__: asyncio.run(main())实操心得在实际开发中直接管理子进程的stdio流比较复杂且容易出错。更稳健的做法是让MCP服务器以网络服务如HTTP/SSE模式运行然后客户端通过ws://或http://地址连接。许多社区维护的MCP服务器如mcp-server-postgres,mcp-server-filesystem都提供了这种模式。langchain-mcp-client通常也支持这两种连接方式。4. 深入核心工具动态加载与高级配置上面的例子展示了最基本的集成。但在真实项目中你会面临更复杂的情况多个服务器、工具过滤、权限控制、会话管理等。langchain-mcp-client提供了相应的配置项来应对。4.1 连接多个MCP服务器一个AI应用可能需要连接数据库、搜索引擎、内部API等多个服务。你可以轻松地集成多个MCP服务器。from langchain_community.agent_toolkits.mcp import create_mcp_toolkit from langchain_community.tools.mcp import McpServer import asyncio async def setup_advanced_toolkit(): # 定义多个MCP服务器配置 servers [ McpServer( namecompany-db, # 假设这是一个连接到公司PostgreSQL的MCP服务器运行在本地5001端口 urlhttp://localhost:5001/sse, # 可选的认证信息如果需要 # headers{Authorization: Bearer your-token} ), McpServer( nameweb-search, # 假设这是一个提供网络搜索功能的MCP服务器 command[node, /path/to/mcp-server-web-search/index.js], # 通过命令行参数传递配置如API密钥 env{SERPAPI_KEY: your_serpapi_key_here} ), McpServer( namelocal-files, # 一个提供本地文件系统访问的服务器需谨慎控制权限 urlhttp://localhost:5002/sse, ) ] # 创建集成所有服务器工具的工具包 toolkit await create_mcp_toolkit(serversservers) all_tools toolkit.get_tools() print(f总共从 {len(servers)} 个服务器加载了 {len(all_tools)} 个工具。) # 工具名称通常会以服务器名为前缀如 company-db.query_table return toolkit通过这种方式你的Agent就同时具备了查询数据库、搜索网络和读取特定目录文件的能力。所有工具的发现、封装和调用都由客户端自动处理。4.2 工具过滤与权限管理你不可能把所有服务器的所有工具都无差别地暴露给Agent。比如文件服务器可能提供read_file和write_file工具但你只希望Agent拥有读取权限。在MCP服务器端进行权限控制是最佳实践。你可以在启动服务器时通过配置或认证来限定其暴露的工具范围。例如为Agent创建一个只读权限的令牌服务器根据令牌决定提供哪些工具。在客户端你也可以进行一层过滤。虽然langchain-mcp-client的顶层API可能不直接提供工具过滤但你可以在获取工具列表后手动筛选async def get_filtered_tools(): toolkit await create_mcp_toolkit(servers[...]) all_tools toolkit.get_tools() # 定义允许使用的工具名称模式白名单 allowed_tool_patterns [ company-db.query_*, # 允许所有查询工具 web-search.search, local-files.read_*, # 只允许读取文件不允许写入或删除 ] import fnmatch filtered_tools [] for tool in all_tools: if any(fnmatch.fnmatch(tool.name, pattern) for pattern in allowed_tool_patterns): filtered_tools.append(tool) else: print(f已过滤工具: {tool.name}) return filtered_tools重要安全提示将文件系统、数据库甚至系统命令暴露给LLM是极其危险的。务必遵循最小权限原则服务器端沙箱MCP服务器自身应在严格的沙箱或受限环境中运行。例如文件服务器只允许访问/tmp/agent_workspace这样的特定目录。输入验证与净化服务器端必须对所有输入参数进行严格的验证和净化防止路径遍历../../../etc/passwd、SQL注入等攻击。审计与日志记录所有工具调用包括参数和调用者便于事后审计和问题排查。网络隔离确保MCP服务器监听在安全的网络边界内如本地回环地址127.0.0.1避免暴露到公网。4.3 处理复杂工具与资源MCP工具的参数由JSON Schema定义支持复杂的嵌套结构。langchain-mcp-client能很好地处理这些复杂定义并将其转换为LangChain Tool可用的格式。例如一个“发送邮件”的工具可能有复杂的参数{ type: object, properties: { to: {type: array, items: {type: string}, description: 收件人列表}, subject: {type: string}, body: {type: string}, attachments: { type: array, items: { type: object, properties: { filename: {type: string}, resource: {type: string} // 引用一个MCP资源如file:///path/to/doc.pdf } } } } }当Agent调用这个工具时langchain-mcp-client会确保参数符合schema并将资源引用正确地传递给服务器。对于LLM来说它只需要“知道”有这么一个发邮件的工具以及工具需要哪些参数而不需要理解附件资源是如何被读取和附加的。这种抽象极大地简化了Agent的提示工程。5. 实战案例构建一个企业知识库问答助手让我们结合一个更贴近生产的例子看看如何利用langchain-mcp-client、一个向量数据库MCP服务器和一个通用SQL MCP服务器快速构建一个能回答公司内部问题的智能助手。场景公司内部文档存储在Confluence或任何Wiki业务数据在PostgreSQL中。我们想做一个助手能回答“上一季度华东区的销售额是多少请附上相关的产品更新文档。”架构文档检索使用mcp-server-chroma或mcp-server-pinecone假设存在。这个服务器将文档向量化并存储提供“语义搜索文档”的工具。数据查询使用mcp-server-postgres。这个服务器连接公司数据库提供“执行SQL查询”的工具应限制为只读和特定表。AI大脑LangChain Agent使用GPT-4等模型并集成上述两个MCP服务器提供的工具。编排层langchain-mcp-client负责与两个MCP服务器通信。实现步骤概览部署MCP服务器启动mcp-server-postgres配置好数据库连接串和允许查询的schema。启动mcp-server-chroma并提前将Confluence文档导入Chroma向量库。编写LangChain应用import asyncio from langchain_openai import ChatOpenAI from langchain.agents import AgentExecutor, create_tool_calling_agent from langchain_core.prompts import ChatPromptTemplate from langchain_community.agent_toolkits.mcp import create_mcp_toolkit from langchain_community.tools.mcp import McpServer async def create_enterprise_assistant(): # 1. 配置MCP服务器连接 servers [ McpServer( namepostgres-db, urlhttp://localhost:8080/sse, # postgres mcp server ), McpServer( namedoc-chroma, urlhttp://localhost:8081/sse, # chroma mcp server ) ] # 2. 创建工具包 toolkit await create_mcp_toolkit(serversservers) tools toolkit.get_tools() # 3. 为Agent设计提示词明确工具职责 prompt ChatPromptTemplate.from_messages([ (system, 你是一个公司内部助手可以查询数据库和文档库来回答问题。 你有以下工具 - postgres-db.execute_sql: 用于查询业务数据。用户问题涉及数字、销售额、订单、客户等时使用。 - doc-chroma.semantic_search: 用于搜索相关的内部文档、产品说明、会议纪要等。 请遵循以下规则 1. 如果问题需要具体数据优先使用SQL工具查询。 2. 如果问题涉及产品功能、政策、流程或需要背景资料使用文档搜索工具。 3. 如果问题同时需要数据和文档可以按顺序使用两个工具。 4. 对查询结果进行总结用自然语言回答。 ), (human, {input}), (placeholder, {agent_scratchpad}), ]) # 4. 创建Agent和执行器 llm ChatOpenAI(modelgpt-4-turbo, temperature0) agent create_tool_calling_agent(llmllm, toolstools, promptprompt) agent_executor AgentExecutor(agentagent, toolstools, verboseTrue, handle_parsing_errorsTrue) return agent_executor async def main(): assistant await create_enterprise_assistant() questions [ 上一季度华东区的销售额是多少, 我们的产品A最近有哪些更新找一下相关的发布文档。, 对比一下产品A和产品B在过去半年的客户支持请求数量。 ] for q in questions: print(f\n 问题: {q} ) try: result await assistant.ainvoke({input: q}) print(f回答: {result[output][:500]}...) # 截断长输出 except Exception as e: print(f执行出错: {e}) if __name__ __main__: asyncio.run(main())这个案例展示了langchain-mcp-client如何作为“胶水”将异构的后端服务数据库、向量库统一成Agent可用的工具集快速构建出功能强大的复合型AI应用。6. 常见问题、排查技巧与性能优化在实际集成和使用过程中你肯定会遇到各种问题。下面是一些常见坑点及其解决方案。6.1 连接与通信问题问题1连接MCP服务器失败报ConnectionRefusedError或超时。排查确认服务器是否运行ps aux | grep mcp-server或检查对应端口是否监听 (netstat -tulpn | grep :8080)。检查连接配置确认McpServer配置的url如http://localhost:8080/sse或command路径是否正确。检查传输协议服务器可能使用stdio传输但客户端配置成了sse或者反之。确保两端协议匹配。检查防火墙/网络策略如果是远程服务器确保端口可访问。问题2工具调用成功但Agent得不到预期结果或者响应格式错误。排查查看MCP服务器日志MCP服务器通常会有详细日志记录收到的请求和发出的响应。这是第一手调试信息。检查工具输出格式MCP协议要求工具返回一个Content列表如TextContent或ImageContent。确保你的服务器返回了正确的结构。langchain-mcp-client默认期望TextContent的text字段作为主要输出。在LangChain外单独测试工具可以写一个简单的脚本直接用langchain-mcp-client的低级API调用工具看原始返回是什么排除Agent提示词或LLM理解的问题。6.2 工具发现与加载问题问题3create_mcp_toolkit执行成功但get_tools()返回空列表。原因MCP服务器可能没有正确声明任何工具或者客户端没有权限访问工具列表。解决使用mcp命令行工具如果有安装直接测试服务器mcp list-tools server-address看是否能列出工具。检查服务器初始化代码确保server.list_tools()装饰的函数正确返回了工具列表。如果服务器需要认证检查是否在McpServer配置中正确提供了headers或env变量。6.3 性能优化建议当工具数量多或调用频繁时性能可能成为瓶颈。连接池与长连接对于网络SSE/HTTP模式的服务器确保客户端使用了连接池并保持长连接避免为每次工具调用都建立新的HTTP连接。检查langchain-mcp-client或底层库如mcp-client是否支持配置连接复用。工具过滤如前所述只加载必要的工具。过多的工具会增大Agent的提示词降低LLM推理速度并增加其选择错误工具的概率。服务器性能MCP服务器本身可能是瓶颈。对于计算密集型或IO密集型的工具如全文检索、复杂查询确保服务器端有足够的资源和优化如数据库索引、向量索引缓存。异步调用确保你的整个LangChain调用链是异步的使用ainvoke以在等待工具响应时不会阻塞事件循环这对于需要调用多个慢速工具的场景尤为重要。6.4 调试与日志开启详细日志是排查问题的利器。import logging # 设置MCP客户端和底层库的日志级别为DEBUG logging.basicConfig(levellogging.DEBUG) logging.getLogger(langchain_community.tools.mcp).setLevel(logging.DEBUG) # 你可能还需要找到底层mcp_client库的logger logging.getLogger(mcp_client).setLevel(logging.DEBUG)运行你的应用你会看到详细的握手、工具列表获取、调用请求和响应的日志这对于理解通信过程非常有帮助。7. 生态展望与进阶玩法langchain-mcp-client的价值随着MCP生态的繁荣而增长。目前MCP生态正在快速发展中。丰富的服务器生态除了前面提到的数据库、向量库、文件系统社区已经出现了用于Slack、GitHub、JIRA、Notion、甚至Docker和Kubernetes的MCP服务器。这意味着你的LangChain Agent可以轻松获得与几乎所有现代软件和服务交互的能力。客户端多样性除了LangChainMCP也有用于Claude Desktop、Cursor IDE、Continue.dev等客户端的实现。这体现了MCP“一次编写到处运行”的潜力你编写的MCP服务器可以同时为多个AI平台提供能力。自定义服务器开发当你需要连接内部私有系统时开发自己的MCP服务器是必经之路。使用官方mcpSDKPython/TypeScript你可以快速将内部API包装成标准的MCP工具。这比直接为每个AI框架写适配器要高效和可持续得多。与LangGraph结合对于需要复杂工作流和状态管理的AI应用你可以将langchain-mcp-client加载的工具与LangGraph的图计算能力结合起来。用LangGraph编排多个MCP工具的调用顺序和条件分支构建出极其强大和可靠的AI智能体。一个进阶想法你可以开发一个“工具路由”MCP服务器。这个服务器本身不提供具体功能但它根据请求的内容动态地将调用代理到其他内部微服务或API并统一管理认证、限流和审计。然后你的LangChain应用只需要连接这一个“路由”服务器就能获得整个中台的能力。这进一步简化了AI应用与后端架构的集成。回过头看guinacio/langchain-mcp-client这个项目虽然代码量可能不大但它所代表的思路——通过标准化协议实现AI与外部环境的解耦集成——正是构建复杂、可维护、安全的企业级AI应用的关键。它可能不是每个简单Demo的必需品但当你开始认真考虑将AI能力嵌入到现有业务流程中时这类工具将成为你技术栈里不可或缺的一环。