跳到主要内容

openapi-to-mcp

openapi-to-mcp 插件使网关能够充当 OpenAPI 规范与 MCP (Model Context Protocol) 服务器之间的桥梁。通过此插件,你可以通过 MCP 接口暴露现有的基于 OpenAPI 的服务,使其可供 AI 模型和客户端访问。

该插件的工作原理是将你的 OpenAPI 规范转换为 MCP 格式,并通过 MCP 服务器接口提供服务。来自 AI 客户端的请求随后会被代理到你的上游服务,支持自定义请求头以及两种用于流式响应的传输方法:streamable HTTP 和 Server-Sent Events (SSE),从而实现灵活且可靠的实时通信。

下图展示了 MCP 客户端、API7 网关和上游 OpenAPI 服务之间的交互。路径和数据仅为演示用的示例值。


示例

以下示例演示了如何在不同场景下配置 openapi-to-mcp 插件。

启用对 Petstore API 的 MCP 访问

以下示例演示了如何通过 MCP 协议暴露 Petstore API,允许 AI 模型和客户端与 Petstore 服务进行交互。

使用 openapi-to-mcp 插件创建一个路由:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "openapi-to-mcp-route",
"uri": "/mcp",
// Annotate 1
"methods": ["GET", "POST"],
"plugins": {
"openapi-to-mcp": {
// Annotate 2
"transport": "streamable_http",
// Annotate 3
"base_url": "https://petstore3.swagger.io/api/v3",
// Annotate 4
"headers": {
"Authorization": "special-key"
},
// Annotate 5
"openapi_url": "https://petstore3.swagger.io/api/v3/openapi.json"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
// Annotate 6
"httpbin.org": 1
}
}
}'

❶ 配置路由允许 GET 和 POST 方法。GET 方法用于工具发现和响应流式传输 (SSE),而 POST 方法用于执行和操作功能 (messages)。

❷ 配置传输方法为 streamable_http(生产环境推荐)。

❸ 配置 Petstore API 地址。

❹ 配置 Petstore API 凭证。

❺ 配置 Petstore OpenAPI 文档 URL。

❻ 为上游节点配置任意值。上游地址不会用于实际的请求转发。

在你的 AI 客户端(如 Cursor)中,使用你的 API7 网关地址更新 MCP 设置,并附加之前创建的路由路径。例如:

mcp.json
{
"mcpServers": {
"api7-petstore-mcp": {
"url": "http://123.123.123.123:9080/mcp"
}
}
}

如果配置成功,你应该能看到可用的工具(通过 MCP 暴露给 AI 客户端的外部函数或服务)。

现在,你可以直接从 AI 客户端的聊天窗口与 API7 企业版 进行交互。例如,试着问:“How many pets are there in the petstore?”

AI client interaction with Petstore

为 MCP 路由配置身份验证

以下示例演示了当路由受到身份验证方法(如 key-auth)保护时,如何通过 MCP 协议暴露 Petstore API。

创建一个消费者 johndoe

curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "johndoe"
}'

johndoe 配置 key-auth 凭证:

curl "http://127.0.0.1:9180/apisix/admin/consumers/johndoe/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-john-key-auth",
"plugins": {
"key-auth": {
"key": "john-key"
}
}
}'

创建一个包含 openapi-to-mcpkey-auth 插件的路由:

curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "openapi-to-mcp-route",
"uri": "/mcp",
"methods": ["GET", "POST"],
"plugins": {
"openapi-to-mcp": {
"transport": "streamable_http",
"base_url": "https://petstore3.swagger.io/api/v3",
"headers": {
"Authorization": "special-key"
},
"openapi_url": "https://petstore3.swagger.io/api/v3/openapi.json"
},
"key-auth": {
"header": "apikey"
}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"httpbin.org": 1
}
}
}'

当 MCP 服务器需要身份验证时,你可以在 mcp.json 配置中指定请求头。请参阅你的 AI 客户端文档以确认是否支持请求头。

如果支持请求头

例如,在 Cursor 中,你可以使用你的 API7 网关地址更新 MCP 设置,附加之前创建的路由路径,并包含 key-auth 所需的请求头:

mcp.json
{
"mcpServers": {
"api7-petstore-mcp": {
"url": "http://123.123.123.123:9080/mcp",
"headers": {
"apikey": "john-key"
}
}
}
}

配置的请求头将被添加到 GET 和 POST 请求中。

如果配置成功,你应该能看到可用的工具(通过 MCP 暴露给 AI 客户端的外部函数或服务)。然后,你可以直接从 AI 客户端的聊天窗口与 Petstore 进行交互。

如果未在 mcp.json 中配置身份验证头,AI 客户端将无法从 MCP 服务器加载工具。

如果不支持请求头

如果你的 AI 客户端不支持在 mcp.json 中配置请求头,你可以将身份验证凭证包含在 MCP URL 查询参数中,因为 key-auth 支持从 URL 查询中获取凭证。

更新路由上的 key-auth 配置如下:

curl "http://127.0.0.1:9180/apisix/admin/routes/openapi-to-mcp-route" -X PATCH \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"plugins": {
"key-auth": {
"_meta": {
// Annotate 1
"filter": [
[
"request_method",
"==",
"GET"
]
]
},
// Annotate 2
"query": "apikey"
}
}
}'

❶ 仅将 key-auth 应用于 GET 请求。这是因为查询参数中配置的 apikey 仅随 GET 请求发送到 SSE 端点,而不会包含在后续的 POST 消息请求中。因此,如果未应用过滤器,消息请求将被 key-auth 插件阻止。

❷ 配置插件从查询参数中获取身份验证密钥。

在你的 AI 客户端中,将凭证包含在 API7 网关地址的查询参数中:

mcp.json
{
"mcpServers": {
"api7-petstore-mcp": {
"url": "http://123.123.123.123:9080/mcp?apikey=john-key"
}
}
}

如果配置成功,你应该能看到可用的工具(通过 MCP 暴露给 AI 客户端的外部函数或服务)。然后,你可以直接从 AI 客户端的聊天窗口与 Petstore 进行交互。

如果未在 MCP 服务器 URL 查询中配置身份验证凭证,AI 客户端将无法从 MCP 服务器加载工具。

扁平化工具架构参数

以下示例演示了 flatten_parameters 如何影响生成的 MCP 工具输入架构中查询和路径参数的结构。

完成[上一个示例](#启用对 Petstore API 的 MCP 访问)以设置对 Petstore API 的 MCP 访问。虽然配置没有显式设置 flatten_parameters,但该参数默认为 false

在你的 AI 客户端(如 Cursor)中,检查工具输入架构。你应该看到参数嵌套在 pathParametersqueryParameters 下:

{
"operations": {
...,
"getPetById": {
"method": "GET",
"path": "/pet/{petId}",
"pathParameters": {
"type": "object",
"required": ["petId"],
"properties": {
"petId": {
"type": "integer",
"description": "ID of pet to return"
}
},
"additionalProperties": false
}
},
"findPetsByStatus": {
"method": "GET",
"path": "/pet/findByStatus",
"queryParameters": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["available", "pending", "sold"],
"description": "Status values that need to be considered for filter",
"default": "available"
}
},
"additionalProperties": false
}
}
}
}

更新插件以扁平化查询和路径参数:

curl "http://127.0.0.1:9180/apisix/admin/routes/openapi-to-mcp-route" -X PATCH \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"plugins": {
"openapi-to-mcp": {
"flatten_parameters": true
}
}
}'

在你的 AI 客户端(如 Cursor)中,检查工具输入架构。你应该看到像 status 这样的参数不再嵌套在 pathParametersqueryParameters 下:

{
"operations": {
...,
"getPetById": {
"parameters": {
"type": "object",
"required": ["petId"],
"properties": {
"petId": {
"type": "integer",
"description": "ID of pet to return"
}
},
"additionalProperties": false
}
},
"findPetsByStatus": {
"parameters": {
"type": "object",
"properties": {
"status": {
"type": "string",
"enum": ["available", "pending", "sold"],
"description": "Status values that need to be considered for filter",
"default": "available"
}
},
"additionalProperties": false
}
}
}
}

故障排除

要诊断问题,请检查网关容器或 Pod 中 /usr/local/openapi2mcp/error.log 处的 openapi-to-mcp 错误日志。请注意,此日志与网关的错误日志是分开的。

已知问题

  1. 错误 Cannot use 'in' operator to search for '$ref' in undefined 通常发生在 openapi_url 中使用 OpenAPI v2 文档时。该插件仅支持 openapi_url 中的 OpenAPI v3 文档。

  2. 该插件在处理从 openapi_url 获取的 OpenAPI v3 文档中的 oneOf 架构时存在已知的解析问题。在这种情况下,MCP 客户端将在加载工具时卡住。