跳到主要内容
版本:3.9.x

将 REST API 暴露为 AI Agent 的 MCP 工具

本指南介绍如何使用 openapi-to-mcp 插件将现有 REST API 暴露为 MCP 工具。该插件会将 MCP 流量转发到与网关一同部署的 OpenAPI-to-MCP 服务。该服务读取 OpenAPI 定义,将每个操作暴露为工具,并将工具调用发送到上游 REST API。

概览

模型上下文协议(Model Context Protocol,MCP)是一种连接 Agent 与外部工具的开放协议。如果没有 MCP,Agent 与 REST API 的集成通常需要定制且较为脆弱。openapi-to-mcp 插件及其配套服务会将 OpenAPI 3.x 操作转换为 MCP 工具定义。

采用此方式后:

  • 现有 REST API 无需修改。
  • Agent 通过 MCP 动态发现工具。
  • OpenAPI-to-MCP 服务(MCP 边车)将工具调用转换为上游 HTTP 请求。

MCP 网关的工作原理

请求路径如下:

AI Agent(AI 智能体)-> MCP 客户端 -> API7 网关 -> OpenAPI-to-MCP 服务 -> 上游 REST API

该插件不会启动 MCP 服务器,而是将请求代理到单独部署的 OpenAPI-to-MCP 服务,默认地址为 127.0.0.1:3000。该服务必须与网关共享网络命名空间,并提供两种传输模式:

  • sse(默认):
    • 通过 GET /.api7_mcp/sse 获取事件流
    • 向 MCP 消息端点发送 POST 消息
  • streamable_http
    • 无状态 POST /.api7_mcp/mcp_stateless

对于 SSE 连接请求和 Streamable HTTP 请求,插件都会在将请求转发到 MCP 边车之前,根据插件配置自动注入 x-openapi2mcp-base-urlx-openapi2mcp-openapi-spec 请求头,无需手动设置。

前置条件

开始前,请确保具备:

  • 一个正在运行的 API7 企业版网关(openapi-to-mcp 仅企业版提供)。

  • 将 OpenAPI-to-MCP 服务部署在与网关相同的网络命名空间中。如果使用 Helm 部署,设置 openapiToMcp.enabled: true。如果使用 Docker 或裸机部署,请参阅部署和兼容性指南

  • 从控制台获取令牌,并保存到环境变量:

    export API_KEY=your-dashboard-token   # 请替换为你的控制台令牌
  • {gateway_group_id} 替换为网关组 ID。如果正在按照快速入门操作,请使用 default

  • 如果使用 Admin API 示例,请创建或复用一个服务。如果尚无服务,请按照创建或复用服务操作,然后保存其 ID:

    export SERVICE_ID=your-service-id         # 请替换为你的服务 ID
  • 一个提供有效 OpenAPI 3.x 规范的上游服务。

  • 用于验证的 MCP 客户端,例如 Claude Desktop 或其他 MCP 兼容客户端。

配置 MCP 网关

配置一个启用 openapi-to-mcp 插件的路由。以下示例使用公开的 Petstore 服务:

{
"openapi_url": "https://petstore3.swagger.io/api/v3/openapi.json",
"base_url": "https://petstore3.swagger.io/api/v3",
"transport": "sse",
"headers": {},
"flatten_parameters": false
}
curl -k "https://localhost:7443/apisix/admin/routes?gateway_group_id={gateway_group_id}" -X PUT \
-H "X-API-KEY: ${API_KEY}" \
-d '{
"id": "openapi-to-mcp-route",
"service_id": "'"$SERVICE_ID"'",
"paths": ["/.api7_mcp/*"],
"plugins": {
"openapi-to-mcp": {
"openapi_url": "https://petstore3.swagger.io/api/v3/openapi.json",
"base_url": "https://petstore3.swagger.io/api/v3",
"transport": "sse",
"headers": {},
"flatten_parameters": false
}
}
}'

openapi_url 指向 OpenAPI 3.x 文档。OpenAPI-to-MCP 服务解析此规范,并根据其中的操作构建 MCP 工具。

base_url 是调用工具时使用的上游 REST API 基础地址。

transport 选择 MCP 传输方式,可使用 sse(默认)或 streamable_http

flatten_parameters 用于控制生成工具输入 Schema 时是否展平嵌套参数。

使用 MCP 客户端验证

第 1 步:连接并发现工具

SSE 模式

将 MCP 客户端连接到 SSE 端点:

curl -N "http://127.0.0.1:9080/.api7_mcp/sse"

连接成功后会返回事件流,其中包含会话专用端点:

event: endpoint
data: /.api7_mcp/sse?sessionId=abc123xyz

sessionId 值标识由 MCP 边车创建的 SSE 会话。请使用事件流返回的会话专用端点,而不是网关上配置的路由模式。

Streamable HTTP 模式

同一路由上的两种传输模式互斥。在使用以下 Streamable HTTP 示例之前,请先将前文路由配置中的 transportsse 改为 streamable_http,再通过 Admin API 或 adc sync 重新应用配置。

发送 tools/list 请求以发现可用工具:

curl -s "http://127.0.0.1:9080/.api7_mcp/mcp_stateless" \
-X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'

响应(HTTP 200) — 发现 19 个工具:

event: message
data: {
"result": {
"tools": [
{"name": "updatePet", "description": "Update an existing pet by Id"},
{"name": "addPet", "description": "Add a new pet to the store"},
{"name": "findPetsByStatus", "description": "Multiple status values can be provided with comma separated strings"},
{"name": "findPetsByTags", "description": "Multiple tags can be provided with comma separated strings"},
{"name": "getPetById", "description": "Returns a single pet"},
{"name": "updatePetWithForm", "description": "Updates a pet in the store with form data"},
{"name": "deletePet", "description": "Deletes a pet"},
{"name": "uploadFile", "description": "Uploads a file"},
{"name": "getInventory", "description": "Returns a map of status codes to quantities"},
{"name": "placeOrder", "description": "Place a new order in the store"},
{"name": "getOrderById", "description": "For valid response try integer IDs with value <= 5 or > 10"},
{"name": "deleteOrder", "description": "For valid response try integer IDs with positive integer value"},
{"name": "createUser", "description": "This can only be done by the logged in user"},
{"name": "createUsersWithListInput", "description": "Creates list of users with given input array"},
{"name": "loginUser", "description": "Logs user into the system"},
{"name": "logoutUser", "description": "Logs out current logged in user session"},
{"name": "getUserByName", "description": "Get user by user name"},
{"name": "updateUser", "description": "This can only be done by the logged in user"},
{"name": "deleteUser", "description": "This can only be done by the logged in user"}
]
},
"jsonrpc": "2.0",
"id": 2
}

第 2 步:调用工具

确保路由已配置为 streamable_http 后,调用工具以验证端到端 REST 转发。以下示例调用需要路径参数 petIdgetPetById。由于 flatten_parametersfalse,请将该参数放在 pathParameters 下。

curl -s "http://127.0.0.1:9080/.api7_mcp/mcp_stateless" \
-X POST \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{
"jsonrpc": "2.0",
"id": 4,
"method": "tools/call",
"params": {
"name": "getPetById",
"arguments": {
"pathParameters": {
"petId": 1
}
}
}
}'

调用成功后会返回 HTTP 200,MCP 结果中包含 ID 为 1 的 Petstore 资源。由于公开 Petstore 的数据可变,其他资源字段可能不同。根据已部署的 OpenAPI-to-MCP 服务版本,资源可能位于 JSON 编码的上游响应封装中,也可能直接出现在结果中,包括作为 structuredContent 返回。

安全注意事项

将 API 暴露为 MCP 工具时,应实施与生产 API 流量相同的控制:

  • 身份认证:在 MCP 工具调用到达上游服务前,强制执行 API Key(API 密钥)、JSON Web Token(JWT)、双向 TLS(mTLS)等网关身份认证机制。
  • 授权:限制 Agent 身份可以访问的路由和操作。
  • 限流:应用基于请求或 Token 的限制,防止滥用或失控的 Agent 流量。
  • 边车出站流量:限制 OpenAPI-to-MCP 服务的网络出站流量,因为它会获取 OpenAPI 文档并直接发送上游请求。当 base_url 包含变量时,请配置 allowed_hosts

后续步骤