MCP 不只是工具调用:从能力暴露到业务边界的服务设计
# MCP 不只是工具调用:从能力暴露到业务边界的服务设计
本文是可复现的工程设计笔记,不对应某个已上线的个人项目。
把 MCP 理解成“模型调用工具”并不算错,但这只描述了表层现象。真正要解决的问题是:如何把业务能力以稳定、可理解、可约束的方式交给 AI 应用使用。
一个常见的结构可以写成:
MCP Host / Client
│
▼
MCP Server
┌──────┼────────┐
▼ ▼ ▼
Tools Resources Prompts
│ │ │
▼ ▼ ▼
业务服务、知识资料、任务模板
MCP Server 提供能力,Client 负责连接、展示和调用,Host 则是承载模型交互的应用。服务端不应该假设“模型说要做”就等于“用户允许做”。
# 先判断:它应该是什么能力
设计前先给能力分类,比直接写接口更重要。
| 类型 | 适合承载什么 | 例子 |
|---|---|---|
| Tool | 一次有明确输入、明确结果的查询或动作 | 查询工单状态、创建审批草稿 |
| Resource | 可被读取和引用的上下文资料 | 产品说明、项目规范、知识库条目 |
| Prompt | 可复用的用户交互模板 | 故障排查、日报总结的任务骨架 |
如果只是让模型理解一份资料,把它做成 Resource 通常比“搜索文件工具”更自然;如果需要用户补充变量并形成固定任务,可优先考虑 Prompt;只有确实需要按参数获取或改变外部状态时,再设计 Tool。
# 一个好的 Tool 应该足够小
不要一开始提供一个万能 manage_system 工具。它会让模型、用户和日志都难以理解正在发生什么。更好的拆法是把能力按业务意图切开。
例如“查询某张工单状态”可以设计为:
名称:get_ticket_status
输入:ticket_id(字符串,必填)
输出:status、owner、updated_at、summary
副作用:无
权限:只读
这样做带来三个好处:
- 模型更容易选择正确能力,参数也更少歧义。
- 用户可以一眼看懂调用会发生什么。
- 服务端可以对每个能力单独做授权、限流和审计。
Tool 的名称、描述和输入 Schema 是模型理解能力的主要依据。描述应说清适用范围、限制和返回信息;输入应尽量严格,例如限制枚举值、必填字段与格式,不要把“自由文本里猜参数”的责任留给服务端。
# 把“读”和“写”分开
最容易失控的设计,是把查询和修改混在一个工具里。例如 update_customer 同时支持查找、修改、发送通知,调用前很难判断后果。
建议采用下面的演进顺序:
只读查询 → 生成草稿 / 预览 → 人工确认 → 有副作用的执行
以“通知负责人”为例:先由 Tool 生成待发送的内容和收件范围,再由客户端展示给用户确认;确认后才进入真正的发送能力。对金额、权限、数据删除、外部通知等高影响操作,这个边界尤其重要。
# 服务端必须承担的责任
MCP 连接不是绕开后端治理的捷径。Server 至少应处理以下事项:
- 对输入进行类型、格式和业务规则校验;不要相信模型生成的参数。
- 在服务端执行身份识别与权限判断;工具描述不是访问控制。
- 让结果可机器处理,例如返回稳定字段和可区分的错误码。
- 设置超时、输出大小限制和必要的幂等机制,避免一次调用拖垮下游服务。
- 记录谁在何时通过哪个工具请求了什么,以及最终是成功、失败还是等待确认。
工具列表也应保持小而稳定。不同用户或不同授权范围可以看到不同工具,但同一授权上下文中的顺序和描述最好保持确定,便于客户端缓存、测试和排错。
# 一个可以落地的最小版本
初次接入不需要接管整个业务系统。可以从一个只读服务开始:提供一项查询 Tool、一份项目说明 Resource、一个“如何提问”的 Prompt。验证模型能否选对工具、输入是否稳定、返回是否可读后,再逐步增加审批草稿和写操作。
这种由小到大的方式,比先接入数据库、文件系统或全量后台接口更容易发现边界问题,也更适合企业 AI 应用逐步上线。
# 延伸阅读
- 01
- AI 应用前端:把生成结果做成可理解、可确认的交互09-24
- 02
- Docker 实战:让服务从本地可运行走向可交付09-24
- 03
- Linux 服务部署与排障:一份从症状到证据的清单09-24