深入学 LangChain 官方文档十四MCP 模型上下文协议首讲本篇对应的官方文档Model Context Protocol (MCP)支撑MultiServerMCPClient、transport、session、Tools、Resources、Prompts、返回内容与 Interceptor 的讲解。本篇讲解范围本篇讲清 MCP 在 LangChain Agent 中的接入位置并用客服 Agent 串起多服务连接、工具适配、会话生命周期、返回内容和权限治理。MCP OAuth 的完整实现、Registry、远程部署、协议版本协商和 Server 开发细节留给后续专题。一个客服 Agent 需要查商品资料、读取订单、创建售后单。三个能力可能分别来自本地脚本、公司内网服务和第三方平台。如果每接一个系统都手写一套 SDK 包装、参数转换和返回值解析工具数量越多Agent 代码越像一块集成补丁板。MCP 想解决的就是这层重复接入服务端用共同协议公开能力客户端按共同协议发现和调用。LangChain 再把发现到的 MCP tool 转换为 Agent 已经认识的 LangChain tool。Agent loop 并没有被替换变化的是外部能力从哪里来、怎样被描述和怎样建立连接。左侧每个外部系统都有独立 SDK、参数映射和错误处理右侧由 MCP Server 按统一协议公开能力LangChain 客户端负责发现并适配。协议减少的是接入差异不会替业务系统决定权限和事务。先把 MCP 协议边界和 Agent 执行边界分开再看连接配置后面的对象关系会清楚很多。一、MCP 统一能力入口不接管 Agent 决策第 06 篇已经讲过 Tool Calling模型根据 tool schema 生成调用请求执行层真正运行工具再用ToolMessage把结果交回模型。MCP 没有改变这条循环。它新增的是一层标准化来源。过去开发者在 Python 进程里直接定义get_order()接入 MCP 后订单服务可以作为独立 Server 暴露同名能力MCP Client 读取它的名称、描述和输入 schema再转换成 LangChain tool。模型仍然只看到“有哪些工具、参数是什么”。是否调用、调用哪一个仍由 Agent loop 决定调用能否执行、当前用户有无权限仍由应用和服务端决定。把 MCP 接上并不等于自动获得可信工具市场更不等于所有工具都可以无条件开放给模型。二、四个角色必须分清在 LangChain 场景里可以先固定四层对象。用户应用承载 Agent、会话状态与业务流程LangChain Agent 负责模型推理和工具循环MCP Client 管理连接、发现能力并做对象适配MCP Server 连接真实文件、数据库或 API并执行自己公开的能力。用户请求先进入 LangChain Agent需要外部能力时Agent 调用已经适配好的 toolMCP Client 通过对应连接访问 ServerServer 再操作业务系统。返回结果沿原路进入ToolMessage而不是由 Server 直接控制模型。这四层一旦混在一起常见误区就会出现把 Agent 的对话 State 当成 MCP Session把 Server 的进程存活当成用户登录状态或者认为 Client 加了认证 header 就已经完成业务授权。一个更稳妥的判断是Agent 保存“任务进行到哪里”MCP Session 保存“客户端和某个 Server 的协议会话”业务系统保存“订单和用户权限等权威事实”。三类状态可以关联但不能互相替代。三、MCP Server 不只公开 ToolsMCP 的三类核心能力是 Tools、Resources 和 Prompts。它们都来自 Server却不承担同一种职责。Tools 是可执行动作例如查询订单、创建售后单。LangChain 可以把它们转换成 Agent tools由模型在运行中选择调用。Resources 是可读取数据例如一份政策文件或一条数据库记录。client.get_resources()返回 Blob应用可以读取文本或二进制内容再决定是否放进上下文、索引或缓存。Resource 不会仅因来自 MCP 就自动变成模型可执行的工具。Prompts 是 Server 提供的可复用消息模板。client.get_prompt()返回 messages应用仍要决定何时取用、是否附加变量以及它是否适合当前 Agent 的 system prompt 或某个工作流节点。Tools 进入执行面Resources 进入数据读取面Prompts 进入消息模板面。三者共享协议连接但消费方式不同全部塞进 tools 会把“读数据”和“执行动作”的权限边界抹平。因此接入一个 MCP Server 前先问它公开了什么能力。客服 Agent 可能把lookup_order作为 tool把售后政策作为 resource把工单摘要模板作为 prompt。只有第一个需要进入模型的工具选择集合。四、stdio与 HTTP 决定连接位置LangChain 当前文档展示了stdio和 HTTP 两种主要连接方式。stdio由客户端启动本地子进程通过标准输入输出通信适合本机脚本、开发工具和受控环境。连接配置需要command和args路径和可执行文件都属于部署合同。Server 进程拥有当前操作系统用户能够访问的资源因此本地不等于天然安全。HTTP 面向独立运行的远程或内网 Server配置由url指向 MCP endpoint。认证信息可以通过headers传递也可以实现httpx.Auth。这里的 token 应来自运行时安全配置不能硬编码进博客示例、仓库或模型上下文。stdio在应用机器上启动子进程部署简单但继承本机权限HTTP 连接独立服务适合跨进程和跨机器调用同时必须处理网络认证、超时与服务可用性。选择 transport 先看部署边界不看名字是否更“高级”。项目可以同时连接多个 Server。MultiServerMCPClient用配置中的名称区分连接后续get_tools()汇总它们公开的工具。五、从 MCP tools 到 LangChain Agent下面的客户端连接一个本地商品 Server 和一个远程订单 Server。示例只说明对象关系product_server.py、URL 和 token 都需要由真实环境提供。importasyncioimportosfromlangchain.agentsimportcreate_agentfromlangchain_mcp_adapters.clientimportMultiServerMCPClientfromlangchain_openaiimportChatOpenAI# 作用连接两个 MCP Server加载工具并执行一次客服查询。asyncdefrun_customer_service_agent()-None:clientMultiServerMCPClient({product:{transport:stdio,command:python,args:[C:/absolute/path/product_server.py],},order:{transport:http,url:https://mcp.example.com/order,headers:{Authorization:fBearer{os.environ[ORDER_MCP_TOKEN]}},},})toolsawaitclient.get_tools()modelChatOpenAI(modelqwen3.7-plus,api_keyos.environ[MODEL_API_KEY],base_urlos.environ[MODEL_BASE_URL],)agentcreate_agent(modelmodel,toolstools)resultawaitagent.ainvoke({messages:[{role:user,content:查询订单 A-2048并判断耳机是否满足售后条件,}]})print(result[messages][-1].content)if__name____main__:asyncio.run(run_customer_service_agent())client.get_tools()是适配边界。它向 Server 获取工具定义再生成 LangChain 能识别的工具对象。create_agent接收到的仍是普通tools集合因此后面的模型选择、messages、middleware 和 streaming 能继续沿用前文机制。MCP Server 公开名称、描述与 input schemaget_tools()将其适配为 LangChain toolcreate_agent再把工具集合交给模型。适配层连接两套对象合同但不改写 Agent loop。模型生成 tool call 后LangChain 会调用适配好的工具请求再由 MCP Client 交给对应 Server。执行结果沿这条链路返回转换成 ToolMessage 后进入 Agent StateServer 不会越过 Client 直接把答案写进聊天记录。一次 MCP tool call 仍处在 Agent 的“模型请求工具—执行工具—结果配对—模型继续推理”循环中。tool_call_id负责把请求与ToolMessage对齐协议连接只负责把执行跨到 Server。这里应复用第 06 篇的安全判断模型生成了合法参数不代表操作已经获得授权。创建售后单、退款或改库存等副作用工具仍需 schema 校验、身份检查、幂等键和必要审批。六、默认无状态不等于不能保留会话MultiServerMCPClient默认按无状态方式使用每次工具调用创建新的ClientSession完成执行后清理。对只依赖显式参数的查询工具这种方式简单也减少了隐式会话残留。如果 Server 需要在多个调用之间保留上下文应显式打开持久 Session并在这个上下文里加载工具。fromlangchain.agentsimportcreate_agentfromlangchain_mcp_adapters.toolsimportload_mcp_tools# 作用在同一个 MCP ClientSession 中加载并连续使用工具。asyncdefrun_with_persistent_session(client,model)-None:asyncwithclient.session(order)assession:toolsawaitload_mcp_tools(session)agentcreate_agent(modelmodel,toolstools)awaitagent.ainvoke({messages:[{role:user,content:继续处理订单 A-2048}]})这段代码把 Session 的打开、工具加载、多次调用和关闭放进同一个生命周期。与默认路径并排看差异不在create_agent而在 MCP Client 是否显式保留同一个协议会话。默认路径为每次 tool call 建立并清理 Session显式client.session()才在代码块生命周期内复用会话。stdio子进程持续运行也不能证明每次调用共享同一协议 Session。持久 Session 是协议状态不是业务数据库。即使 Server 记住了上一次游标订单状态仍应从权威系统读取即使 Agent 有同一个thread_id也不代表 MCP Server 自动识别当前用户。需要关联时应由应用明确传递稳定标识并定义超时、重连和失效策略。七、返回值可能不只是文本MCP tool 可以同时返回面向阅读的文本和机器可处理的 structured content。LangChain adapter 会把 structured content 放进MCPToolArtifact调用方通过ToolMessage.artifact读取。这样订单查询既能给模型一段摘要也能给应用一份结构化订单对象。多模态返回则会转换成标准content_blocks。截图工具可能返回文本说明和图片消费者应按 block 类型读取 URL 或 base64而不是把整个结果强制拼成字符串。普通文本进入消息内容structured content 保存在ToolMessage.artifact多模态部分转换为标准content_blocks。展示层、模型上下文和业务逻辑可以消费不同视图避免重复解析自然语言。工具失败也要分层处理。当前 LangChain 文档说明MCP tool 返回CallToolResult(isErrorTrue)时默认会作为statuserror的工具消息交给模型让 Agent 有机会修正参数或选择替代路径若设置handle_tool_errorsFalse则改为抛出异常。但 transport、session 和内容转换失败始终属于客户端或基础设施异常。网络断开不能伪装成“订单不存在”内容解析失败也不能让模型随意猜测结构。应用需要分别记录工具业务错误与连接错误才能给出正确的重试和降级策略。八、Interceptor 是运行时治理边界MCP Server 运行在独立进程中默认看不到 LangGraph runtime 的 context、state 或 store。Tool Interceptor 在调用进入 Server 前提供了一道应用侧控制面。它可以从request.runtime.context读取当前用户标识向工具参数注入租户信息可以根据 State 判断用户是否完成认证也可以做限流、重试、日志或短路返回。需要修改请求时应使用request.override()生成新请求而不是原地改变共享对象。Agent 产生调用后Interceptor 先读取 runtime context 与 State完成身份注入、权限判断、限流或短路再决定是否访问 MCP Server。Server 仍需执行自己的授权校验客户端拦截不能成为唯一防线。最重要的边界是不要把凭据交给模型。API token 应由连接配置、认证对象或 Interceptor 从安全存储读取模型只需要决定业务参数不需要看到完整认证 header。Server 端还要用当前身份重新校验资源范围不能盲目信任模型传来的user_id。Interceptor 也不是 Middleware 的替代品。Middleware 管理 Agent loop 的模型、工具和状态生命周期MCP tool interceptor 聚焦 MCP 工具执行边界。两者可以协作但应该清楚哪条策略在哪一层生效避免同一操作重复重试或重复审计。九、生产接入先检查四个问题第一个问题是能力类型。需要模型选择并执行的是 Tool需要应用读取的是 Resource需要复用消息模板的是 Prompt。分类错误会直接扩大模型权限。第二个问题是部署与连接。本地能力是否适合stdio远程服务是否使用 HTTP认证从哪里注入连接超时和失败如何处理。不要把“连接成功”当成“业务可用”。第三个问题是生命周期。工具是否只依赖本次参数还是需要持久 SessionAgent thread、MCP Session 与业务登录态如何关联重连后哪些状态可以恢复哪些必须重新读取。第四个问题是风险。谁负责授权、参数校验、幂等、审批、审计和敏感数据脱敏。MCP Server 公开的每个 tool 都应拥有最小权限尤其不能把文件删除、支付或配置修改能力作为无条件工具暴露。接入顺序从能力分类开始再选择 transport 和认证方式随后确定 Session 生命周期最后补齐授权、幂等、审批与观测。任一层没有明确责任人都不应因为“工具已经被发现”就直接交给生产 Agent。完成这些判断后MCP 才真正降低集成成本Agent 代码不再了解每个服务的 SDK 细节Server 可以独立演进应用仍保留明确的控制面和失败边界。十、MCP 应该用在什么地方当多个 Agent 或应用需要复用同一组外部能力服务需要独立部署和演进或者团队希望用共同协议管理工具发现MCP 很合适。它把连接与能力描述从单个 Agent 项目中抽出来也让 LangChain tools 可以来自不同 Server。如果只有一个稳定的本地函数没有跨进程复用、动态发现或独立部署需求直接定义 LangChain tool 往往更简单。为了“用了 MCP”而增加 Server、transport 和 session只会把一个函数调用变成分布式问题。选择时可以用一句话收束MCP 统一外部能力的接入合同LangChain 负责 Agent 运行合同业务系统负责权限与事实合同。三份合同边界清晰协议才会减少耦合边界混在一起统一入口反而会放大风险。总结标准化接入不等于自动可信LangChain 通过langchain-mcp-adapters连接一个或多个 MCP Server。MultiServerMCPClient管理stdio与 HTTP connectionget_tools()把 MCP tools 转换为 LangChain tools再交给create_agent进入已有的 Tool Calling 循环。Tools、Resources、Prompts 分别承担动作、数据和模板职责默认无状态调用与显式持久 Session 解决不同生命周期问题文本、structured content 和多模态内容也有不同落点。Interceptor 能把 runtime context、权限、限流和日志带到工具执行边界却不能替代 Server 端授权。真正可用的 MCP 接入要同时回答能力是什么、连接在哪里、状态保留多久、风险由谁控制。协议把接口变得一致工程系统仍要对每一次真实动作负责。下一篇将进入《Human-in-the-loop 与 Guardrails高风险动作如何审批和拦截》。MCP 让外部能力可以被统一接入但“能调用”并不等于“应当自动执行”接下来会把审批、拦截、暂停与恢复串起来看清支付、删除、配置修改等高风险动作怎样在真正执行前经过人工和策略闸门。
深入学 LangChain 官方文档(十四)MCP 模型上下文协议首讲
深入学 LangChain 官方文档十四MCP 模型上下文协议首讲本篇对应的官方文档Model Context Protocol (MCP)支撑MultiServerMCPClient、transport、session、Tools、Resources、Prompts、返回内容与 Interceptor 的讲解。本篇讲解范围本篇讲清 MCP 在 LangChain Agent 中的接入位置并用客服 Agent 串起多服务连接、工具适配、会话生命周期、返回内容和权限治理。MCP OAuth 的完整实现、Registry、远程部署、协议版本协商和 Server 开发细节留给后续专题。一个客服 Agent 需要查商品资料、读取订单、创建售后单。三个能力可能分别来自本地脚本、公司内网服务和第三方平台。如果每接一个系统都手写一套 SDK 包装、参数转换和返回值解析工具数量越多Agent 代码越像一块集成补丁板。MCP 想解决的就是这层重复接入服务端用共同协议公开能力客户端按共同协议发现和调用。LangChain 再把发现到的 MCP tool 转换为 Agent 已经认识的 LangChain tool。Agent loop 并没有被替换变化的是外部能力从哪里来、怎样被描述和怎样建立连接。左侧每个外部系统都有独立 SDK、参数映射和错误处理右侧由 MCP Server 按统一协议公开能力LangChain 客户端负责发现并适配。协议减少的是接入差异不会替业务系统决定权限和事务。先把 MCP 协议边界和 Agent 执行边界分开再看连接配置后面的对象关系会清楚很多。一、MCP 统一能力入口不接管 Agent 决策第 06 篇已经讲过 Tool Calling模型根据 tool schema 生成调用请求执行层真正运行工具再用ToolMessage把结果交回模型。MCP 没有改变这条循环。它新增的是一层标准化来源。过去开发者在 Python 进程里直接定义get_order()接入 MCP 后订单服务可以作为独立 Server 暴露同名能力MCP Client 读取它的名称、描述和输入 schema再转换成 LangChain tool。模型仍然只看到“有哪些工具、参数是什么”。是否调用、调用哪一个仍由 Agent loop 决定调用能否执行、当前用户有无权限仍由应用和服务端决定。把 MCP 接上并不等于自动获得可信工具市场更不等于所有工具都可以无条件开放给模型。二、四个角色必须分清在 LangChain 场景里可以先固定四层对象。用户应用承载 Agent、会话状态与业务流程LangChain Agent 负责模型推理和工具循环MCP Client 管理连接、发现能力并做对象适配MCP Server 连接真实文件、数据库或 API并执行自己公开的能力。用户请求先进入 LangChain Agent需要外部能力时Agent 调用已经适配好的 toolMCP Client 通过对应连接访问 ServerServer 再操作业务系统。返回结果沿原路进入ToolMessage而不是由 Server 直接控制模型。这四层一旦混在一起常见误区就会出现把 Agent 的对话 State 当成 MCP Session把 Server 的进程存活当成用户登录状态或者认为 Client 加了认证 header 就已经完成业务授权。一个更稳妥的判断是Agent 保存“任务进行到哪里”MCP Session 保存“客户端和某个 Server 的协议会话”业务系统保存“订单和用户权限等权威事实”。三类状态可以关联但不能互相替代。三、MCP Server 不只公开 ToolsMCP 的三类核心能力是 Tools、Resources 和 Prompts。它们都来自 Server却不承担同一种职责。Tools 是可执行动作例如查询订单、创建售后单。LangChain 可以把它们转换成 Agent tools由模型在运行中选择调用。Resources 是可读取数据例如一份政策文件或一条数据库记录。client.get_resources()返回 Blob应用可以读取文本或二进制内容再决定是否放进上下文、索引或缓存。Resource 不会仅因来自 MCP 就自动变成模型可执行的工具。Prompts 是 Server 提供的可复用消息模板。client.get_prompt()返回 messages应用仍要决定何时取用、是否附加变量以及它是否适合当前 Agent 的 system prompt 或某个工作流节点。Tools 进入执行面Resources 进入数据读取面Prompts 进入消息模板面。三者共享协议连接但消费方式不同全部塞进 tools 会把“读数据”和“执行动作”的权限边界抹平。因此接入一个 MCP Server 前先问它公开了什么能力。客服 Agent 可能把lookup_order作为 tool把售后政策作为 resource把工单摘要模板作为 prompt。只有第一个需要进入模型的工具选择集合。四、stdio与 HTTP 决定连接位置LangChain 当前文档展示了stdio和 HTTP 两种主要连接方式。stdio由客户端启动本地子进程通过标准输入输出通信适合本机脚本、开发工具和受控环境。连接配置需要command和args路径和可执行文件都属于部署合同。Server 进程拥有当前操作系统用户能够访问的资源因此本地不等于天然安全。HTTP 面向独立运行的远程或内网 Server配置由url指向 MCP endpoint。认证信息可以通过headers传递也可以实现httpx.Auth。这里的 token 应来自运行时安全配置不能硬编码进博客示例、仓库或模型上下文。stdio在应用机器上启动子进程部署简单但继承本机权限HTTP 连接独立服务适合跨进程和跨机器调用同时必须处理网络认证、超时与服务可用性。选择 transport 先看部署边界不看名字是否更“高级”。项目可以同时连接多个 Server。MultiServerMCPClient用配置中的名称区分连接后续get_tools()汇总它们公开的工具。五、从 MCP tools 到 LangChain Agent下面的客户端连接一个本地商品 Server 和一个远程订单 Server。示例只说明对象关系product_server.py、URL 和 token 都需要由真实环境提供。importasyncioimportosfromlangchain.agentsimportcreate_agentfromlangchain_mcp_adapters.clientimportMultiServerMCPClientfromlangchain_openaiimportChatOpenAI# 作用连接两个 MCP Server加载工具并执行一次客服查询。asyncdefrun_customer_service_agent()-None:clientMultiServerMCPClient({product:{transport:stdio,command:python,args:[C:/absolute/path/product_server.py],},order:{transport:http,url:https://mcp.example.com/order,headers:{Authorization:fBearer{os.environ[ORDER_MCP_TOKEN]}},},})toolsawaitclient.get_tools()modelChatOpenAI(modelqwen3.7-plus,api_keyos.environ[MODEL_API_KEY],base_urlos.environ[MODEL_BASE_URL],)agentcreate_agent(modelmodel,toolstools)resultawaitagent.ainvoke({messages:[{role:user,content:查询订单 A-2048并判断耳机是否满足售后条件,}]})print(result[messages][-1].content)if__name____main__:asyncio.run(run_customer_service_agent())client.get_tools()是适配边界。它向 Server 获取工具定义再生成 LangChain 能识别的工具对象。create_agent接收到的仍是普通tools集合因此后面的模型选择、messages、middleware 和 streaming 能继续沿用前文机制。MCP Server 公开名称、描述与 input schemaget_tools()将其适配为 LangChain toolcreate_agent再把工具集合交给模型。适配层连接两套对象合同但不改写 Agent loop。模型生成 tool call 后LangChain 会调用适配好的工具请求再由 MCP Client 交给对应 Server。执行结果沿这条链路返回转换成 ToolMessage 后进入 Agent StateServer 不会越过 Client 直接把答案写进聊天记录。一次 MCP tool call 仍处在 Agent 的“模型请求工具—执行工具—结果配对—模型继续推理”循环中。tool_call_id负责把请求与ToolMessage对齐协议连接只负责把执行跨到 Server。这里应复用第 06 篇的安全判断模型生成了合法参数不代表操作已经获得授权。创建售后单、退款或改库存等副作用工具仍需 schema 校验、身份检查、幂等键和必要审批。六、默认无状态不等于不能保留会话MultiServerMCPClient默认按无状态方式使用每次工具调用创建新的ClientSession完成执行后清理。对只依赖显式参数的查询工具这种方式简单也减少了隐式会话残留。如果 Server 需要在多个调用之间保留上下文应显式打开持久 Session并在这个上下文里加载工具。fromlangchain.agentsimportcreate_agentfromlangchain_mcp_adapters.toolsimportload_mcp_tools# 作用在同一个 MCP ClientSession 中加载并连续使用工具。asyncdefrun_with_persistent_session(client,model)-None:asyncwithclient.session(order)assession:toolsawaitload_mcp_tools(session)agentcreate_agent(modelmodel,toolstools)awaitagent.ainvoke({messages:[{role:user,content:继续处理订单 A-2048}]})这段代码把 Session 的打开、工具加载、多次调用和关闭放进同一个生命周期。与默认路径并排看差异不在create_agent而在 MCP Client 是否显式保留同一个协议会话。默认路径为每次 tool call 建立并清理 Session显式client.session()才在代码块生命周期内复用会话。stdio子进程持续运行也不能证明每次调用共享同一协议 Session。持久 Session 是协议状态不是业务数据库。即使 Server 记住了上一次游标订单状态仍应从权威系统读取即使 Agent 有同一个thread_id也不代表 MCP Server 自动识别当前用户。需要关联时应由应用明确传递稳定标识并定义超时、重连和失效策略。七、返回值可能不只是文本MCP tool 可以同时返回面向阅读的文本和机器可处理的 structured content。LangChain adapter 会把 structured content 放进MCPToolArtifact调用方通过ToolMessage.artifact读取。这样订单查询既能给模型一段摘要也能给应用一份结构化订单对象。多模态返回则会转换成标准content_blocks。截图工具可能返回文本说明和图片消费者应按 block 类型读取 URL 或 base64而不是把整个结果强制拼成字符串。普通文本进入消息内容structured content 保存在ToolMessage.artifact多模态部分转换为标准content_blocks。展示层、模型上下文和业务逻辑可以消费不同视图避免重复解析自然语言。工具失败也要分层处理。当前 LangChain 文档说明MCP tool 返回CallToolResult(isErrorTrue)时默认会作为statuserror的工具消息交给模型让 Agent 有机会修正参数或选择替代路径若设置handle_tool_errorsFalse则改为抛出异常。但 transport、session 和内容转换失败始终属于客户端或基础设施异常。网络断开不能伪装成“订单不存在”内容解析失败也不能让模型随意猜测结构。应用需要分别记录工具业务错误与连接错误才能给出正确的重试和降级策略。八、Interceptor 是运行时治理边界MCP Server 运行在独立进程中默认看不到 LangGraph runtime 的 context、state 或 store。Tool Interceptor 在调用进入 Server 前提供了一道应用侧控制面。它可以从request.runtime.context读取当前用户标识向工具参数注入租户信息可以根据 State 判断用户是否完成认证也可以做限流、重试、日志或短路返回。需要修改请求时应使用request.override()生成新请求而不是原地改变共享对象。Agent 产生调用后Interceptor 先读取 runtime context 与 State完成身份注入、权限判断、限流或短路再决定是否访问 MCP Server。Server 仍需执行自己的授权校验客户端拦截不能成为唯一防线。最重要的边界是不要把凭据交给模型。API token 应由连接配置、认证对象或 Interceptor 从安全存储读取模型只需要决定业务参数不需要看到完整认证 header。Server 端还要用当前身份重新校验资源范围不能盲目信任模型传来的user_id。Interceptor 也不是 Middleware 的替代品。Middleware 管理 Agent loop 的模型、工具和状态生命周期MCP tool interceptor 聚焦 MCP 工具执行边界。两者可以协作但应该清楚哪条策略在哪一层生效避免同一操作重复重试或重复审计。九、生产接入先检查四个问题第一个问题是能力类型。需要模型选择并执行的是 Tool需要应用读取的是 Resource需要复用消息模板的是 Prompt。分类错误会直接扩大模型权限。第二个问题是部署与连接。本地能力是否适合stdio远程服务是否使用 HTTP认证从哪里注入连接超时和失败如何处理。不要把“连接成功”当成“业务可用”。第三个问题是生命周期。工具是否只依赖本次参数还是需要持久 SessionAgent thread、MCP Session 与业务登录态如何关联重连后哪些状态可以恢复哪些必须重新读取。第四个问题是风险。谁负责授权、参数校验、幂等、审批、审计和敏感数据脱敏。MCP Server 公开的每个 tool 都应拥有最小权限尤其不能把文件删除、支付或配置修改能力作为无条件工具暴露。接入顺序从能力分类开始再选择 transport 和认证方式随后确定 Session 生命周期最后补齐授权、幂等、审批与观测。任一层没有明确责任人都不应因为“工具已经被发现”就直接交给生产 Agent。完成这些判断后MCP 才真正降低集成成本Agent 代码不再了解每个服务的 SDK 细节Server 可以独立演进应用仍保留明确的控制面和失败边界。十、MCP 应该用在什么地方当多个 Agent 或应用需要复用同一组外部能力服务需要独立部署和演进或者团队希望用共同协议管理工具发现MCP 很合适。它把连接与能力描述从单个 Agent 项目中抽出来也让 LangChain tools 可以来自不同 Server。如果只有一个稳定的本地函数没有跨进程复用、动态发现或独立部署需求直接定义 LangChain tool 往往更简单。为了“用了 MCP”而增加 Server、transport 和 session只会把一个函数调用变成分布式问题。选择时可以用一句话收束MCP 统一外部能力的接入合同LangChain 负责 Agent 运行合同业务系统负责权限与事实合同。三份合同边界清晰协议才会减少耦合边界混在一起统一入口反而会放大风险。总结标准化接入不等于自动可信LangChain 通过langchain-mcp-adapters连接一个或多个 MCP Server。MultiServerMCPClient管理stdio与 HTTP connectionget_tools()把 MCP tools 转换为 LangChain tools再交给create_agent进入已有的 Tool Calling 循环。Tools、Resources、Prompts 分别承担动作、数据和模板职责默认无状态调用与显式持久 Session 解决不同生命周期问题文本、structured content 和多模态内容也有不同落点。Interceptor 能把 runtime context、权限、限流和日志带到工具执行边界却不能替代 Server 端授权。真正可用的 MCP 接入要同时回答能力是什么、连接在哪里、状态保留多久、风险由谁控制。协议把接口变得一致工程系统仍要对每一次真实动作负责。下一篇将进入《Human-in-the-loop 与 Guardrails高风险动作如何审批和拦截》。MCP 让外部能力可以被统一接入但“能调用”并不等于“应当自动执行”接下来会把审批、拦截、暂停与恢复串起来看清支付、删除、配置修改等高风险动作怎样在真正执行前经过人工和策略闸门。