红帽可信配置文件分析器(TPA)和 Trustify的工程团队决定试验模型上下文协议(MCP)。本文将带您了解我们在此过程中遇到的挑战,希望我们的经验能为具有类似尝试的团队提供参考。
首先介绍下背景:红帽可信配置文件分析器(TPA)是一款用于软件物料清单(SBOM)管理的红帽产品,它可以存储 SBOM,并将 SBOM 中的软件包与已知的公共漏洞关联起来。它基于上游项目 Trustify 构建。
从总体上来看,它的架构设计相当“传统”:
- 前端使用 React 和 PatternFly 组件(trustify-ui)开发
- 后端使用 Rust 开发,它连接到数据库实例,并将 SBOM 存储在与 S3 兼容的存储中
我们采取的主要步骤包括:
- 设计 MCP 服务器与 TPA/Trustify 的集成方案
- 定义 MCP 服务器的工具描述
- 设计 MCP 服务器的工具参数
本文将探讨每个阶段的注意事项,最终成果是现已在 GitHub 上发布的 MCP 服务器。
设计 MCP 服务器与 TPA/Trustify 的集成方案
在讨论如何定义 MCP 服务器和 Trustify 之间的集成之前,我们面临着软件工程师常会遇到的经典难题:我该为这个项目选用哪个库?我是否应该从头开始并自行完成所有开发工作?
作为开源的忠实拥护者,我们全面考察了可用于实施 MCP 服务器的 Rust 库(Trustify 主要使用 Rust 开发,因此 Rust 库是我们的首选)的当前状况。
搜索过程并未耗时太久,因为我们发现 MCP 在其 GitHub 组织中提供了一些官方库,其中包含一个使用 Rust 开发的库。
该库不仅包含支持 MCP 服务器开发所需的代码,还提供了一组出色的示例供您开始使用。
我们很快意识到,除了需要明确运行 MCP 服务器、定义可用工具及其参数这些库相关的具体细节外,我们还必须决定 MCP 服务器如何访问“后端”数据。
我们评估了两种不同的方案。MCP 服务器可以通过以下任一方式检索数据:
- 直接连接到 Trustify 后端存储数据的数据库(DB);
- 调用 Trustify 后端提供的 REST 端点
正如您所想象的那样,两者各有利弊,这引发了一场热烈的讨论,我将在此进行总结。
直接连接到数据库的优势:
- 高效访问数据
- 可采用文本转 SQL 的方法
劣势:
- MCP 服务器必须与后端处于相同的架构级别
- 相较于后端现有代码,需要重新编写代码以管理数据访问
- 需要进行数据格式管理以定义 MCP 工具调用的输出
调用 REST 端点的优势:
- 调用遵循后端 API 现有的身份验证和授权机制
- MCP 服务器提供的数据将与 UI 中的数据完全一致,因为两者使用相同的数据源
- 只需发送从后端 API 返回的输出,即可免费获取 JSON 输出
劣势:
- 需要经过更多架构层级,导致性能下降
最终,我们决定从 MCP 服务器的工具中调用 REST 端点,因为必须将 MCP 服务器与后端部署在同一位置且需“足够接近”数据库这一缺点,确实可能成为潜在阻碍,尤其是当 MCP 服务器采用 stdio 传输协议并在开发人员主机上本地执行时。
在此初始开发阶段,还有一个优势是能够将所有数据“免费”格式化为 JSON 响应。
定义 MCP 服务器的工具描述
在确定 MCP 服务器的工具将调用后端 API 后,我们必须决定如何描述不同的工具。在首次迭代中,我们希望每个 MCP 工具都能调用单个后端 API 端点。
考虑到 Trustify 使用 OpenAPI openapi.yaml 文件记录可用的端点,我们决定直接采用 OpenAPI 端点的描述和定义作为 MCP 工具的描述,以便评估这些端点文档对用户的实际帮助程度。这实际上使我们的代理式 AI 成为我们自有 API 的“零号客户”。
所有这些都是通过持续改进方法实现:如果 Trustify API 的描述足够清晰,使 LLM 能够进行管理,那么我们的用户也应当能理解这些文档。
这种方法不仅帮助我们优化每个端点,也促使我们做出了下一项设计决策。
设计 MCP 服务器的工具参数
此时,我们遇到了与工具调用输入参数相关的问题,为了深入理解这个问题,我们需要先回顾下背景。Trustify 用于检索实体列表的端点接受 q 查询参数。此参数允许用户根据 OpenAPI 规范中定义的语法指定查询。
我们有以下选择:
- 直接公开端点的 q 路径参数作为 MCP 工具输入参数
- 公开可用于构建 q 参数查询值的内部字段,作为 MCP 工具的输入参数
我们对这两种方法都进行了测试。
第一种方法需要对查询参数提供严格且详尽的描述,而 OpenAPI 规范目前尚未提供相关说明。我们认为,完整的可查询字段列表应是文档的必需组成部分,而非可选内容。让所有用户都能访问这些信息将会非常有价值。
第二种方法简化了 AI 代理的流程。通过明确列出要查询的参数(如漏洞严重性、发布日期或描述),可以使 LLM 更加轻松地处理这些信息。这样一来,LLM 就不需要首先解析查询语法,而这一环节在第一种方法中可能相当复杂。
另一个考虑因素是,在 MCP 工具上明确列出所有可用参数,这需要持续投入工作,以与实际后端端点实施保持一致。反之,仅公开部分可用参数,则会降低工具的多功能性,且无法保证能减少维护开销。
我们决定继续针对 MCP 工具使用 q 查询参数,并将在 OpenAPI 定义中完善其描述,使所有用户都能从中受益。
结语
在设计 MCP 服务器时,我们采用了以下方法:
- MCP 服务器利用现有的 API
- MCP 服务器利用现有的 OpenAPI 文档
- MCP 服务器工具公开远程 API 端点期望的相同参数
如前所述,最终成果已在 GitHub 上发布。