
如果你所在的团队最近在尝试接入 AI Agent大概率会遇到这样一个场景智能体已经能流畅聊天能写文案、写代码但当你想让它“查一下上个月的客户订单”“把某个审批流程跳转一下”时它却什么都做不了。原因很简单——它没有连接你的业务系统。MCPModel Context Protocol模型上下文协议解决的核心问题正是“AI 如何按标准方式调用外部工具”。它的价值不在于多一个接口标准而在于把工具调用、资源访问、提示词这三类能力统一成一个能被模型自动发现的契约。对于百数这类低代码平台来说接入 MCP 意味着 CRM 表单、业务数据表、流程引擎都能变成智能体可调用的工具而且不需要从零搭建 Agent 基础设施。这篇文章会完整走一遍“百数 MCP 开发”的流程从 MCP 的基础原理、百数平台的接入路径到用 Python 编写私有工具函数、基于 FastMCP 暴露成 MCP Server再到在智能体客户端完成挂载、联调、验证与排错。先说明一句百数平台的开放接口地址、请求头、认证方式和参数结构请以官方开放 API 文档为准。本文示例采用通用封装模式核心目标是帮你掌握“API 能力到 MCP 工具”的转化方法论而不是死记某个具体接口。读完这篇文章你能得到一个最小可用的、连接百数数据的 MCP 服务并且知道它每一步为什么要这么设计。1. 这篇文章真正要解决的问题1.1 会聊天的 Agent 离“能干活”还差一层现在市面上大多数 Agent 产品本质上还是“对话模型 知识检索”。它能回答“订单超时怎么处理”这种制度问题却无法回答“我们公司现在有多少笔超时订单”因为它看不到数据它也不能替你把超时订单的负责人改掉因为它没有操作系统的能力。要让 Agent 产生业务价值必须打通“模型”和“系统”这两层。模型负责理解意图、拆解任务、生成自然语言系统负责提供真实数据和可执行的操作。MCP 就是这两层之间的标准化管道。你可以把它理解为给 Agent 装上一套“USB 接口”让外部工具即插即用。1.2 MCP 不是又一个接口标准而是工具契约化直接调 REST API 不是不行但有一个关键问题模型不知道你的 API 长什么样。就算你把接口文档塞进 PromptURL、鉴权、参数格式稍有变化模型就会调用失败。MCP 的思路是让 Server 主动向模型暴露“工具目录”它有哪些工具、每个工具叫什么、参数是什么、返回什么格式。模型在对话过程中发现工具、生成参数、发起调用整个过程有一套标准的 JSON-RPC 2.0 消息格式来约束。所以MCP 真正改变的是把“人阅读文档后编码调用”变成“模型按契约自动发现并调用”。这对企业级集成来说意义很大一次接入 MCP Server所有支持 MCP 的客户端都能用不用每个客户端各写一套适配器。1.3 百数在 MCP 链路里的定位百数这类低代码平台核心能力是表单、数据表、流程引擎和权限管理。它解决的是“企业应用如何快速搭建”的问题但过去这些能力只对浏览器里的业务用户开放。MCP 的角色是把百数的能力“翻译”给 AI Agent。在整条链路里你会看到四个角色AI 智能体客户端 - MCP Server工具服务 - 百数开放 API - 业务数据表 | ↓ 私有 Python 工具函数业务逻辑这里特别值得强调的是“私有 Python 工具”这一层。它通常用来做四件事参数校验、数据清洗、字段裁剪、跨接口编排。比如平台接口返回一个嵌套很深的 JSON模型看了容易迷糊你就可以在 Python 函数里把它整理成一行简洁的文本再返回。这就是为什么要“编写私有工具”而不是直接把官方 API 暴露给模型。1.4 本文适合哪三类读者第一类低代码平台的二次开发工程师。你想在表单数据之上加一个 AI 入口让用户通过对话完成查询和录入。第二类企业 AI 应用集成工程师。你需要在百数、智能体、内部系统之间搭桥本文的方法论可以直接复用。第三类技术负责人。你想判断 MCP 在企业落地的真实工作量读完大概就知道一个查询工具需要写多少代码、要配什么权限、怎么调试。2. MCP 基础概念与核心原理2.1 MCP 是什么一条链路理解MCP 是 Anthropic 在 2024 年底开源并推动的开放协议随后被多家主流 Agent 客户端跟进支持。它定义了一组标准化的消息格式和通信流程让 AI 应用能与外部工具、数据源、工作流进行能力对接。你可以把它通俗地理解成“USB-C 协议”。USB-C 统一了物理接口MCP 统一了 AI 调用工具的逻辑接口。没有 MCP 之前接入 A 平台是一套代码接入 B 平台是另一套代码有了 MCP只要你的工具服务实现了协议任何支持协议的客户端都能调用。2.2 四个核心角色Host、Client、Server、ToolHost承载 AI 应用的宿主程序比如 Claude Desktop、Cursor、Cherry Studio或者你自己用 Python 写的 Agent 程序。Client在 Host 内部运行负责与 MCP Server 建立会话、发送工具发现请求、转发调用请求。Server提供工具集的服务端进程。它可以是一个独立 Python 进程也可以是一个 HTTP 服务。ToolServer 暴露给模型的最小可调用单元有名称、描述、参数 Schema 和实际执行函数。一次典型的调用流程是这样客户端启动后与 Server 完成 initialize 握手随后客户端请求 tools/list拿到工具目录模型在对话中判断需要调用某个工具生成 JSON 参数客户端发起 tools/call 请求Server 执行对应的 Python 函数把结果返回模型把结果组织成自然语言回复。整个过程中模型并不直接执行代码它只是“决定调用哪个工具”真正干活的是你的 Python 函数。2.3 MCP 的传输方式与三类能力MCP 支持两种主流传输方式。stdioServer 作为客户端的一个子进程通过标准输入输出通信。配置简单适合本地桌面客户端也适合开发调试。本文示例主要用这种方式。Streamable HTTPServer 拥有一个 HTTP 端点客户端通过 HTTP 请求访问。适合服务端部署、多客户端共享、远程调用也是生产环境更推荐的方式。除了 Tools工具MCP 还提供 Resources资源和 Prompts提示模板。Resources 适合给模型提供只读的数据上下文Prompts 适合复用复杂指令模板。但对接百数这类业务系统时最常用到的还是 Tools。2.4 MCP 与 REST API 的对比维度传统 REST APIMCP 工具发现方式需要阅读接口文档人工编码客户端启动时自动获取 tools/list调用协议自定义 URL 和 HTTP 方法标准 JSON-RPC 2.0 方法参数描述写在接口文档或注释里通过 JSON Schema 暴露给模型适配成本每个客户端编写单独适配层一次接入多个客户端复用适用场景后端程序之间的确定性调用Agent 模型自主决策与工具调用一句话总结如果你的消费者是“另一个程序员写的后端服务”REST API 足够如果你的消费者是“会自己决定怎么调用的 AI 模型”MCP 更合适。3. 百数 MCP 接入的三条路径与选型建议3.1 路径A直接用官方 API 封装成 MCP 工具如果百数平台已有开放 API并且你的工具只是“查一条数据、提交一个表单”可以直接在 MCP Server 里调用官方接口。优势是开发最快代码量最小代价是业务校验逻辑只能跟着官方 API 能力走。如果平台接口返回格式较复杂模型可能难以稳定解析。3.2 路径B在 Python 工具函数中封装业务逻辑本文重点这是更推荐的路径。仍然调用百数 API但中间多了一层私有 Python 工具函数。这层函数的价值有三个第一可以把平台的嵌套 JSON 裁剪成模型友好的摘要文本减少 Token 消耗第二可以做参数校验、数据脱敏、业务状态判断第三可以把多个接口调用组合成一个业务工具比如“查询客户完整画像”背后可能要调三个数据表但在 Agent 看来只是一个工具。这层逻辑放在 MCP Server 进程里意味着你可以在原有低代码平台权限模型之上再加一层面向 AI 访问的业务规则。3.3 路径C直接连数据库有人觉得与其绕 API不如让 MCP Server 直接连百数底层的 MySQL 数据库这样查询最快、最灵活。这个方案在技术演示中可以跑通但在企业生产环境风险很高绕过平台权限模型无法复用平台的审批流和字段权限一旦 Agent 被提示词注入或误调用可能产生非预期的数据变更平台升级数据库结构时你的 SQL 也容易失效。我的建议是不要用路径 C。除非你的场景完全只读、数据已经离线备份、并且有独立的数据库账号和审计机制。3.4 选型建议落地时的判断标准可以很简单只是只读查询且字段不多路径 A 最快。需要状态判断、字段脱敏、跨表组合、写操作路径 B。高并发、多团队共享路径 B Streamable HTTP 私有化部署。任何情况避免路径 C。本文后面的代码全部采用路径 B 的思路。4. 环境准备与前置配置4.1 运行环境本文示例需要 Python 3.10 及以上版本推荐 3.11 或 3.12MCP Python SDK 对较新版本支持更积极。开发机建议使用 macOS、Linux 或 Windows命令差异我会分别标注。另外开发机需要能够访问百数开放 API也就是网络策略要放通对应域名。项目目录结构如下mcp-baishu-demo/ ├── server.py # MCP Server 入口 ├── baishu_client.py # 百数 API 客户端封装 ├── test_tool.py # 本地调用测试脚本 ├── .env # 密钥配置不要提交到仓库 └── .gitignore4.2 安装依赖推荐使用虚拟环境避免污染系统 Python。用 pip 的方式mkdir mcp-baishu-demo cd mcp-baishu-demo python -m venv .venv source .venv/bin/activate # Windows 系统执行: .venv\Scripts\activate pip install mcp[cli] requests python-dotenv如果你习惯用 uv流程更简洁uv init mcp-baishu-demo cd mcp-baishu-demo uv add mcp[cli] requests python-dotenv解释一下依赖mcp[cli]是 MCP Python SDK附带了mcp命令行工具requests用于调用百数开放 APIpython-dotenv用于读取.env中的密钥配置。4.3 获取百数开放平台凭证到百数管理后台找到开放平台或开发者中心入口具体菜单名称以官方文档为准创建一个自建应用拿到 AppID 和 API 密钥。一般需要做两件事在权限配置里为这个应用分配“客户订单”等数据表的查询或提交权限。在测试环境先用一个简单请求确认凭证有效。把凭证写入.envBAISHU_APP_IDyour_app_id BAISHU_API_KEYyour_api_key BAISHU_BASE_URLhttps://api.example.com注意.env文件不要提交到 Git 仓库在.gitignore里加一行.env。4.4 开发调试工具mcp命令自带 MCP Inspector可以可视化地查看工具列表、手动填写参数调用工具。Claude Desktop、Cherry Studio、Cursor 等支持 MCP 的客户端用于最终挂载验证。curl 或 Postman用于单独验证百数 API 是否可通这能帮你快速判断问题出在协议层还是数据源层。5. 核心流程拆解5.1 第一步锁定业务场景与数据表不要上来就写代码。先确定一个真实场景。本文以“客服查订单”为例客服人员希望用自然语言查询客户订单按订单状态或客户名称筛选并得到简洁摘要。这个场景只读、数据敏感度适中、验证成本低非常适合作为第一个 MCP 工具。确定场景后要明确工具边界只查询不修改每次最多返回 10 条只输出订单号、客户、状态、金额四个字段。边界越清晰模型越不容易误用。5.2 第二步梳理工具目录建议先在文档里建一张工具清单例如工具名描述参数返回get_orders查询客户订单列表status、customer、limit订单摘要文本get_order_detail查询订单详情order_no订单详情文本这一步看似多余实际上决定了后面的代码结构和 Agent 的使用体验。工具名称用“动词 名词”参数用下划线风格描述里说清楚“什么时候用、用什么条件查”。5.3 第三步封装百数 API 客户端不要在 MCP 工具函数里直接写 requests 调用建议先建立一个独立的客户端类。原因有三凭证统一管理不用在多个工具函数里重复读环境变量超时、重试、解码逻辑只写一处以后百数更换 SDK 或调整签名方式你只需要改一个文件。5.4 第四步编写工具函数并注册到 FastMCPFastMCP 是 MCP Python SDK 提供的高级封装它把“定义工具、注册工具、运行服务”变得很简洁。核心用法是创建一个 FastMCP 实例然后用mcp.tool()装饰一个普通 Python 函数这个函数就自动变成一个 MCP 工具。这里有一个非常容易踩坑的地方工具函数的 docstring 第一行就是模型用来判断“什么时候调用这个工具”的核心描述。写得太模糊模型会忽略它写得太长模型容易抓不住重点。推荐一句话说清用途再用 Args 段落补充参数含义。5.5 第五步本地启动与检查本地开发时可以直接python server.py启动服务看进程有没有报错。要可视化调试更推荐运行mcp dev server.py它会在浏览器打开 MCP Inspector 面板列出所有工具支持手动填参调用。特别提醒MCP 在 stdio 模式下标准输出是协议通道不能随便 print。调试输出要写日志文件或 stderr否则会破坏协议消息导致客户端无法识别。5.6 第六步挂载到智能体客户端把 MCP Server 挂到桌面客户端本质上是告诉客户端“你要以什么命令启动这个子进程”。以 Claude Desktop 为例需要修改它的claude_desktop_config.json在mcpServers节点下增加服务名、启动命令、启动参数和环境变量。配置完成后重启客户端在对话界面应该能看到工具生效。如果你用的是带图形界面的 MCP 客户端比如 Cherry Studio则通常在“设置 - MCP 服务”里选择“stdio”类型然后填写命令、参数和环境变量原理完全相同。5.7 第七步联调与发布联调时用自然语言向 Agent 提问观察它是否调用工具、参数是否正确、返回结果是否被正确组织。发现模型不调用工具优先改描述发现参数传错优先检查 JSON Schema 和类型注解发现返回内容太乱优先改工具函数的输出格式。发布到生产环境时建议从 stdio 迁移到 Streamable HTTP 部署并配置访问令牌。这样多个智能体客户端可以共享同一个 MCP 服务也可以做服务端限流和审计。6. 完整示例与代码实现6.1 示例需求我们实现一个查询类 MCP 工具get_orders查询百数中的“客户订单”数据表支持按状态和客户名称筛选最多返回 10 条订单摘要。为了让代码可运行且不依赖具体的百数接口文档我定义如下占位 API 约定关键点在于演示通用封装思路读者务必替换为真实接口接口GET/v1/form/orders/list请求头X-App-Id、X-Api-Key返回体{code: 0, data: {records: [{order_no: ..., customer_name: ..., order_status: ..., total_amount: 100.0}]}}你只需要把这四行约定替换成千百数的真实参数。下面开始写代码。6.2 baishu_client.py百数 API 客户端封装# 文件路径baishu_client.py import os import requests class BaishuClient: 百数开放接口的轻量封装。 注意URL、请求头和参数名请以百数官方开放 API 文档为准 这里用占位值演示通用封装方法。 def __init__(self, app_id: str | None None, api_key: str | None None, base_url: str | None None): self.app_id app_id or os.getenv(BAISHU_APP_ID) self.api_key api_key or os.getenv(BAISHU_API_KEY) self.base_url base_url or os.getenv(BAISHU_BASE_URL, https://api.example.com) def _request(self, method: str, path: str, params: dict | None None, json_body: dict | None None) - dict: headers { X-App-Id: self.app_id, X-Api-Key: self.api_key, Content-Type: application/json, } url f{self.base_url}{path} resp requests.request(method, url, headersheaders, paramsparams, jsonjson_body, timeout10) resp.raise_for_status() return resp.json() def list_orders(self, status: str | None None, customer: str | None None) - list[dict]: 查询订单列表返回原始记录列表。 params {} if status: params[filter[order_status]] status if customer: params[filter[customer_name]] customer data self._request(GET, /v1/form/orders/list, paramsparams) # 以下解析逻辑对应示例返回结构请按官方实际返回调整 return data.get(data, {}).get(records, [])这段代码的核心是_request方法所有对百数 API 的请求都走这一个方法。工具函数里不关心 HTTP 细节只调用list_orders。如果你以后要接入多个数据表只需要在BaishuClient里继续增加类似方法。6.3 server.pyMCP Server 定义与工具注册# 文件路径server.py import os from dotenv import load_dotenv from mcp.server.fastmcp import FastMCP from baishu_client import BaishuClient load_dotenv() mcp FastMCP(baishu-orders) client BaishuClient() mcp.tool() def get_orders(status: str | None None, customer: str | None None, limit: int 10) - str: 查询客户订单列表返回订单号、客户、状态和金额摘要。 Args: status: 订单状态筛选例如 pending、completed、cancelled。 customer: 客户名称关键字筛选。 limit: 最多返回的订单条数默认 10最大 50。 if limit 50: limit 50 try: records client.list_orders(statusstatus, customercustomer) except Exception as exc: return f查询订单失败{exc} if not records: return 未找到符合条件的订单。 lines [] for idx, record in enumerate(records[:limit], start1): lines.append( f{idx}. 订单号:{record.get(order_no, -)} f客户:{record.get(customer_name, -)} f状态:{record.get(order_status, -)} f金额:{record.get(total_amount, -)} ) return \n.join(lines) if __name__ __main__: mcp.run()这里有几个细节值得说明。第一mcp.tool()装饰器会把函数的名称、参数类型、默认值和 docstring 转换成 MCP 的 JSON Schema。所以status: str | None None这种类型注解不是可有可无它直接影响模型能否正确生成参数。第二工具函数返回str而不是直接返回list[dict]。这样模型拿到的是已经整理好的摘要文本回答时可以直接引用减少一次“把嵌套 JSON 转成自然语言”的中间步骤。第三try/except把底层异常转换成可读字符串返回而不是抛给 MCP 调用链。这样客户端界面至少能显示“查询订单失败xxx”而不是显示一个笼统的“工具调用失败”。6.4 test_tool.py本地调用测试脚本# 文件路径test_tool.py import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def main(): server_params StdioServerParameters( commandpython, args[server.py], env{ BAISHU_APP_ID: your_app_id, BAISHU_API_KEY: your_api_key, BAISHU_BASE_URL: https://api.example.com, }, ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() result await session.call_tool( get_orders, {status: pending, limit: 3}, ) for content in result.content: print(content.text) asyncio.run(main())这个脚本模拟了一个 MCP 客户端通过 stdio 拉起server.py建立会话调用get_orders工具并打印返回结果。它不依赖任何桌面客户端适合在 CI 或命令行环境做回归测试。6.5 智能体客户端挂载配置Claude Desktop 的配置示例{ mcpServers: { baishu-orders: { command: python, args: [ /absolute/path/to/server.py ], env: { BAISHU_APP_ID: your_app_id, BAISHU_API_KEY: your_api_key, BAISHU_BASE_URL: https://api.example.com } } } }这里最容易出错的是command。如果你使用了虚拟环境python可能不是你系统 PATH 里的那个建议写成虚拟环境中的绝对路径例如/path/to/.venv/bin/pythonWindows 下对应.venv\Scripts\python.exe。args必须写server.py的绝对路径否则客户端从不同工作目录启动时可能找不到文件。如果 MCP Server 以 HTTP 方式部署客户端配置更简单只需要填服务地址和一个访问令牌例如把工具类型选为“Streamable HTTP”URL 填https://your-domain.com/mcp/baishu-orders。7. 运行结果与效果验证7.1 用测试脚本验证工具层在配置好.env后运行python test_tool.py预期输出类似1. 订单号:SO-2024001 客户:张三 状态:pending 金额:2380.00 2. 订单号:SO-2024005 客户:李四 状态:pending 金额:560.50如果输出“未找到符合条件的订单”说明服务链路是通的只是筛选条件没有匹配数据。如果输出异常信息则优先检查百数 API 凭证和网络连通性。这个脚本先用起来能帮你把“MCP 协议层问题”和“百数 API 问题”快速分开。协议层有问题脚本跑不通API 凭证或参数有问题脚本能跑通但返回特定错误。7.2 用 MCP Inspector 验证参数边界运行mcp dev server.pyMCP Inspector 会在浏览器打开一个调试界面。你可以在 Tools 列表里看到get_orders手动填入statuspending、limit3点击调用查看返回内容。这里主要验证两件事JSON Schema 是否正确生成不同参数组合下工具函数是否稳定。建议测试几个异常参数比如limit999、customer传一个不存在的名称、status传空字符串。工具函数应该给出合理的返回而不是抛出未处理异常。7.3 在桌面客户端做端到端验证把 MCP Server 挂载到 Claude Desktop 或 Cherry Studio 后用自然语言提问“帮我查一下状态为 pending 的客户订单。”一个成功的表现是Agent 明确说“我将调用 get_orders 工具”然后返回订单列表最后用自然语言总结。如果模型没有调用工具优先检查工具描述。如果模型调用了但参数传错检查类型注解和默认值。如果工具调用成功但回答内容与返回不一致检查返回文本是否过长、字段是否清晰。这一步做通说明整条“智能体 - MCP Server - 百数 API - 数据表”链路已经完整可用。8. 常见问题与排查思路8.1 高频问题对照表问题现象可能原因排查方式解决方案客户端找不到 baishu-orders 工具MCP 配置路径错误或服务启动失败查看客户端日志手动运行启动命令检查绝对路径、Python 命令和依赖是否齐全调用工具提示 401 / 403API 密钥错误或没有数据表权限用 curl 单独请求百数 API重新生成密钥在开放平台分配数据表权限返回中文乱码编码不一致在终端运行 test_tool.py 确认字符串统一使用 UTF-8避免手动 encode/decode工具调用超时百数 API 响应慢或网络不通用 curl 测试接口响应时间增大 timeout精简查询条件改用异步 HTTP模型传入参数不符合预期JSON Schema 与模型理解不一致在 Inspector 中查看工具 Schema优化 docstring 和参数描述收紧类型注解stdio 模式下客户端无输出在 Server 代码里使用了 print检查 stdout 是否被业务日志污染日志写文件或 stderrstdout 只走 MCP 协议客户端重启后工具消失服务进程未重新拉起查看客户端进程列表确认 command 和 args 正确不要使用相对路径返回结果被模型转述失真返回文本过长或结构不清晰检查工具返回内容长度精简字段返回结构化 JSON 或更短摘要8.2 一套可复用的排查路径如果工具调不通不要东改一下西改一下按下面的顺序排查先运行python server.py确认进程能正常启动依赖没有缺失。再用 curl 直接请求百数 API确认凭证、URL、参数是否正确。然后运行python test_tool.py排除 MCP 协议问题。接着用mcp dev server.py调参定位是 Schema 问题还是业务逻辑问题。最后检查客户端配置重点看路径和环境变量。排查命令参考# 单独验证百数 API确认凭证有效 curl -H X-App-Id: your_app_id -H X-Api-Key: your_api_key \ https://api.example.com/v1/form/orders/list # 直接启动 MCP Server观察 stderr 日志 python server.py每改一个因素单独验证一次。不要同时改多个变量这是避免越排越乱的关键。9. 最佳实践与工程建议9.1 工具即接口描述要为模型服务MCP 工具的函数名、参数名和 docstring是模型理解工具的唯一线索。命名上使用“动词 宾语”例如get_orders、create_order描述上第一句话写清功能第二段开始写参数细节。要学会站在模型的角度审视如果它只看到这个工具的 Schema能不能准确决定何时调用、传什么参数9.2 返回结果结构化控制 Token 消耗模型每读一次工具返回都要消耗上下文窗口。工具返回的内容越长模型越容易丢失重点。建议在工具函数里就完成字段裁剪一个查询工具只返回用户真正关心的 3 到 5 个字段。如果数据量大宁可只返回前 10 条也不要让模型去截断自己看不懂的完整 JSON。9.3 权限最小化与数据安全这是企业落地 MCP 最重要的一条原则。MCP Server 暴露的是真实业务数据和操作能力必须做到三点第一给应用分配最小数据集权限不要为了省事把整张表开放第二在工具函数层再做一层参数白名单校验比如limit设置上限、status只允许固定枚举值第三涉及手机号、身份证等敏感字段时在工具层直接脱敏或禁止返回。API 密钥要放在服务端环境变量中。stdio 模式把密钥写在客户端配置里只适合个人开发调试生产环境应该走 Streamable HTTP由服务端统一持有凭证。9.4 日志、监控与审计建议在工具函数入口记录调用参数、调用耗时和调用结果。生产环境使用logging模块写入独立日志文件不要往标准输出里打印内容。如果工具涉及写操作必须记录“谁调用的工具、传了什么参数、改了什么数据”这个审计信息在排查误操作时是唯一的证据。9.5 版本兼容与依赖锁定MCP SDK 迭代速度比较快建议在requirements.txt或 pyproject 中锁定mcp包版本避免升级后接口行为变化。不同桌面客户端对 MCP 协议版本的支持也有差异交付前最好在目标客户端上做一遍完整回归。9.6 生产部署从 stdio 到 Streamable HTTPstdio 模式适合本地开发但生产环境建议迁移到 Streamable HTTP。这样多个智能体可以共享同一个 MCP 工具集可以在网关层做认证、限流和审计也方便容器化部署。迁移时需要注意HTTP 模式下要配置访问令牌工具函数逻辑不需要改动。9.7 后续学习方向本文只讲了 Tools 这一种能力MCP 还有 Resources 和 Prompts。你可以继续探索如何把百数数据表的元数据作为 Resource 暴露给模型让 Agent 理解表结构如何用 Prompt 模板把企业话术封装起来如何把多个只读工具扩展成可写工具并加上审批流。实践建议是先让一个只读查询工具跑通再用同样的套路逐步扩大工具面。这比一次性设计十个工具更稳妥也更容易沉淀出团队自己的 MCP 接入规范。建议先收藏备用真正动手时再回这篇文章对照流程和排查清单。