mcp-tools-acl
mcp-tools-acl 插件用于控制每个消费者在 openapi-to-mcp 路由上可以调用或发现哪些 MCP 工具。该插件提供两种限制方式:
tools/call拦截 — 拒绝消费者调用被禁止的工具,返回 HTTP 错误响应。tools/list过滤 — 从返回给客户端的工具列表中移除被禁止的工具,使 MCP 客户端感知不到这些工具的存在。此过滤同时适用于 JSON 响应和 SSE(Server-Sent Events)流式响应。
该插件采用基于规则的配置方式,每条规则指定白名单或黑名单,并可选配表达式条件。规则按顺序执行——第一条条件匹配的规则生效,其余规则跳过。
此插件自 API7 Enterprise 3.9.8 版本起可用,APISIX 中尚不可用。
使用此插件前,请确保:
- 路由上已启用
openapi-to-mcp插件。 - 路由上已配置认证插件(如
key-auth)。若请求未携带已认证 的消费者身份,mcp-tools-acl将放行所有流量(不做任何拦截)。
示例
以下示例展示了如何在不同场景下使用 mcp-tools-acl 插件。
使用白名单限制工具访问
以下示例展示了如何通过白名单配置,只允许消费者调用指定的 MCP 工具。
创建消费者 alice:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "alice"
}'
为 alice 创建 key-auth 凭证:
curl "http://127.0.0.1:9180/apisix/admin/consumers/alice/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-alice-key-auth",
"plugins": {
"key-auth": {
"key": "alice-key"
}
}
}'
在消费者 alice 上配置 mcp-tools-acl 插件:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "alice",
"plugins": {
"mcp-tools-acl": {
"rules": [
{
"allow_tools": ["get_weather", "list_cities"]
}
]
}
}
}'
❶ 只允许消费者 alice 调用 get_weather 和 list_cities 两个工具;其余工具均被拦截,且不会出现在工具列表中。
mcp-tools-acl 应配置在消费者(或消费者组)上,以实现按消费者粒度的工具访问控制。路由上只需配置 openapi-to-mcp 和认证插件。
当消费者和路由上同时配置了该插件时,消费者配置优先生效,路由级配置对该消费者不生效。若消费者未配置 mcp-tools-acl,则以路由上的配置作为兜底。
创建启用了 openapi-to-mcp 和 key-auth 的路由:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "mcp-tools-acl-route",
"uri": "/mcp",
"methods": ["GET", "POST"],
"plugins": {
"openapi-to-mcp": {
"openapi_url": "http://your-service/openapi.json",
"base_url": "http://your-service"
},
"key-auth": {}
},
"upstream": {
"type": "roundrobin",
"nodes": {
"your-service:80": 1
}
}
}'
以消费者 alice 的身份发送 tools/list 请求:
curl -s "http://127.0.0.1:9080/mcp" \
-H "apikey: alice-key" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
你应该看到响应中只包含 get_weather 和 list_cities 两个工具,其他工具已被过滤。
以消费者 alice 的身份调用一个不在白名单中的工具:
curl -i "http://127.0.0.1:9080/mcp" \
-H "apikey: alice-key" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"delete_record","arguments":{}}}'
你应该看到 HTTP/1.1 403 Forbidden 响应,表明该工具调用被拦截。
使用黑名单限制工具访问
以下示例展示如何通过黑名单配置,禁止消费者调用特定工具,其余工具均可正常访问。
基于上一个示例,为消费者 bob 配置黑名单:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "bob",
"plugins": {
"mcp-tools-acl": {
"rules": [
{
"deny_tools": ["delete_record"]
}
]
}
}
}'
❶ 禁止消费者 bob 调用 delete_record 工具;其余所有工具均可正常访问。
为 bob 创建 key-auth 凭证:
curl "http://127.0.0.1:9180/apisix/admin/consumers/bob/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-bob-key-auth",
"plugins": {
"key-auth": {
"key": "bob-key"
}
}
}'
以消费者 bob 的身份发送 tools/list 请求:
curl -s "http://127.0.0.1:9080/mcp" \
-H "apikey: bob-key" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
你应该看到响应中不包含 delete_record,其余工具均正常列出。
调用被禁止的工具:
curl -i "http://127.0.0.1:9080/mcp" \
-H "apikey: bob-key" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"delete_record","arguments":{}}}'
你应该看到 HTTP/1.1 403 Forbidden 响应。
基于路由条件应用不同规则
以下示例展示了如何使用表达式条件(expr),根据请求上下文(如访问的路由)应用不同的 ACL 规则。
此示例适用于 API7 Enterprise 3.9.8 及更高版本。不适用于 APISIX,因为 mcp-tools-acl 插件尚不可用。
创建消费者 grace,配置条件规则:
curl "http://127.0.0.1:9180/apisix/admin/consumers" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"username": "grace",
"plugins": {
"mcp-tools-acl": {
"rules": [
{
"expr": [["route_id", "==", "route-pets"]],
"allow_tools": ["findPetsByStatus"]
},
{
"allow_tools": ["addPet"]
}
]
}
}
}'
❶ 规则 1:当请求命中路由 route-pets 时,仅允许 findPetsByStatus。
❷ 规则 2:兜底规则(无 expr)——对于其他所有路由,仅允许 addPet。此规则仅在规则 1 不匹配时才生效。
为 grace 创建 key-auth 凭据:
curl "http://127.0.0.1:9180/apisix/admin/consumers/grace/credentials" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "cred-grace-key-auth",
"plugins": {
"key-auth": {
"key": "grace-key"
}
}
}'
创建两个配置了 openapi-to-mcp 和 key-auth 的路由:
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "route-pets",
"uri": "/mcp",
"methods": ["GET", "POST"],
"plugins": {
"openapi-to-mcp": { "openapi_url": "http://petstore/openapi.json", "base_url": "http://petstore" },
"key-auth": {}
},
"upstream": { "type": "roundrobin", "nodes": { "petstore:80": 1 } }
}'
curl "http://127.0.0.1:9180/apisix/admin/routes" -X PUT \
-H "X-API-KEY: ${ADMIN_API_KEY}" \
-d '{
"id": "route-inventory",
"uri": "/mcp2",
"methods": ["GET", "POST"],
"plugins": {
"openapi-to-mcp": { "openapi_url": "http://inventory/openapi.json", "base_url": "http://inventory" },
"key-auth": {}
},
"upstream": { "type": "roundrobin", "nodes": { "inventory:80": 1 } }
}'
当 grace 访问 route-pets 时,规则 1 匹配,仅允许 findPetsByStatus:
curl -i "http://127.0.0.1:9080/mcp" \
-H "apikey: grace-key" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"findPetsByStatus","arguments":{}}}'
你应该看到 HTTP/1.1 202 Accepted 响应,表明该工具调用已被 MCP 服务器接受。
当 grace 访问 route-inventory 时,规则 1 不匹配(route_id 不同),因此兜底规则 2 生效——仅允许 addPet:
curl -i "http://127.0.0.1:9080/mcp2" \
-H "apikey: grace-key" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"addPet","arguments":{}}}'
你应该看到 HTTP/1.1 202 Accepted 响应,表明该工具调用已被 MCP 服务器接受。
规则从上到下依次匹配。第一条匹配的规则生效,后续规则均被跳过。应将更具体的规则(带 expr)放在前面,将范围更广的兜底规则(不带 expr)放在后面。
如果没有任何规则匹配(所有规则都设置了 expr 条件且均未求值为 true),插件不执行任何访问控制——所有工具均直接放行。
故障排除
插件不生效
检查路由上是否已启用 openapi-to-mcp 插件,以及是否配置了认证插件(如 key-auth)。若请求未携带已认证的消费者身份,mcp-tools-acl 将放行所有流量(这是设计行为)。
tools/call 返回 400
请求体是合法的 JSON,但 params 字段缺失或 params.name 不是字符串,插件会返回 {"message": "Invalid MCP tools/call request"} 和 HTTP 400。这与配置的 rejected_code(针对被拒绝工具)不同,表明 MCP 客户端发送了格式错误的请求。
allow_tools: [] 导致所有工具均被拒绝
空数组是合法的配置,会拒绝所有工具调用,且 tools/list 返回空列表。如需允许访问某些工具,请确保数组非空。