工具权限与评分实战:scope拦截+健康度指标(MCP实战手记·篇12 延伸)

MCP工具权限 / 工具评分 / 可观测性

本篇是《MCP实战手记》篇12(企业级Toolbox治理)的延伸篇,只拆「权限拦截 + 健康度评分」两个点:把篇12 §3 两层 scope 拦截和 §7 看板指标拆开------scope 聚合防爆炸(踩坑5)、成功率/P99/报错率告警阈值给落地值,并接篇9 身份、篇13 多租户。仓库(tag v12):Gitee

0. 为什么权限和评分要一起讲

篇12 开篇六类事故里,「权限泛滥」和「质量失控」是慢性毒:前者越权调工具,后者不知道哪个工具稳、哪个天天 500。

权限解决"谁能调",评分解决"调得稳不稳"------治理层两端:发现/调用之前先过权限,调用之后用指标反向淘汰劣质工具。

本文只做 caller+scope 两层拦截 + 健康度指标采集(代码量中,只给变化部分);真实 IdP、治理 UI 标待生产,见篇13。

1. 两层拦截:发现层 + 调用层

篇12 §3 已定:①发现层 list() 按 caller 过滤可见 Toolbox(看不到无权工具);②调用层实际调前校验 requiredScope(调了不该调的被拦)。管理器只给元数据+查询 API,拦截发生在分发层/网关层。

java 复制代码
// 发现层:caller 看不到它无 scope 的工具
List<ToolboxDefinition> list(String callerId, List<String> scopes, Filters f) {
    return registry.list(f).stream()
        .filter(def -> scopes.containsAll(def.getRequiredScope())) // 可见需持有全部 requiredScope
        .toList();
}
// 调用层:resolve 时再拦一次
ToolboxDefinition resolve(String callerId, List<String> scopes, ToolboxId id, String v) {
    ToolboxDefinition def = registry.resolve(id, v);
    if (!scopes.containsAll(def.getRequiredScope()))            // ② 调用层 scope 拦截
        throw new AccessDeniedException("缺 scope: " + def.getRequiredScope());
    return def;
}

两层都要有:发现层防"看见不该看的",调用层防"绕过列表直接调"。

默认最小权限:工具若未配 requiredScope 视为公开(可见可调)。生产建议反设为"无 scope 不可见",公开工具显式打标,避免漏配变成越权。

2. scope 聚合:别让每工具一个 scope(踩坑5)

踩坑5原文:每工具一个 scope,配置膨胀难维护。例子:get_report 配 scope:report:gen、query_store 配 scope:store:query...... 工具 50 个就 50 个 scope,运维者记不住、配错就大面积 403。

修法------角色级 scope 聚合:把业务相近的工具归到一个角色 scope。

复制代码
治理前(每工具一 scope,爆炸):
  get_report   -> scope:report:gen
  query_store  -> scope:store:query
  export_csv   -> scope:report:export
  ...(50 个工具 = 50 个 scope)

治理后(角色级 scope,收敛):
  get_report / query_store / export_csv  -> scope:toolbox:retail   # 零售工具一组
  audit_log                              -> scope:toolbox:admin    # 管理面单独一组
java 复制代码
// 注册时把工具归到角色 scope,而非逐个细粒度
void register(ToolboxDefinition def, String roleScope) {
    def.setRequiredScope(List.of(roleScope));   // 角色级,而非 scope:report:gen
    registry.register(def);
}

caller 拿到 scope:toolbox:retail 就能调零售组全部工具,新增同组工具无需改 caller 授权------权限随工具规模线性收敛。

3. 健康度指标:成功率/P99/报错率

篇12 §7 看板给过阈值(参考值,按业务调):成功率<99%告警、P99>3s告警、报错率>1%告警。采集点在调用拦截处埋点:

java 复制代码
// 埋点挂在【实际工具执行】处(MCP 分发层拦截器 / AOP 包裹 @Tool 方法),
// 不要只挂在 resolve------resolve 只选定义不执行,否则成功率/P99 统计失真
void afterCall(ToolboxId id, long costMs, boolean ok) {
    metrics.timer("toolbox.call", id).record(costMs);
    if (!ok) metrics.counter("toolbox.error", id).increment();
    // 成功率 = 1 - 报错数 / 调用数,Prometheus 滑动窗口(如 5m)算
}

告警阈值(与篇14 全链路监控打通):

复制代码
指标        阈值            含义
成功率      < 99%           接口不稳定,需排查
P99 耗时    > 3s            慢调用拖累调用方
报错率      > 1%            异常偏多,可能要 deprecate

> 阈值需配「持续 5min 超阈 + 告警静默」再触发,避免瞬时抖动误报;窗口按业务调。

低于阈值的工具在 §7 看板标红,配合 §6 弃用流程------质量差的先标期下线,形成"指标驱动治理"闭环。

4. 与篇9身份 / 篇13多租户衔接

  • caller 身份来自篇9 身份透传(open_id/user_id),scopes 由 IdP 下发;本期用内存 caller→scope 映射模拟,真实集成待生产。
  • tenantId 字段篇12 已落库并 list()/resolve() 过滤就位,多租户隔离标待篇13 消费------权限与隔离在同一分发层叠加,互不打架。

5. 岗位对照

复制代码
本篇能力                   -> 对应岗位 / 方向
scope 两层拦截             -> IAM / 权限管理 / 零信任
角色级 scope 聚合          -> 平台权限治理
健康度评分 + 告警阈值      -> SRE / 可观测性
指标驱动弃用闭环          -> 平台稳定性

6. 边界声明

  • 本机已验证:两层拦截(list 过滤 + resolve 拦 scope)、角色级 scope 聚合、指标采集埋点逻辑。
  • 待生产验证:真实 IdP caller/scope 下发(篇9)、治理 UI、与篇14 监控告警链路。
  • 本文只拆权限 + 评分两点;治理层总览见篇12 深度文。

同专题推荐:

相关推荐
南归北隐14 小时前
Spring AI Alibaba Graph框架实现MCP数据库查询实战
java·后端·spring ai·mcp·spring ai mcp
古法老登瞎折腾14 小时前
大数据智能运维实战(九):让 AI 查日志——找到异常,也保留上下文
java·大数据·运维·人工智能·spring ai·mcp
李小轰_Rex17 小时前
用一个小项目,学会开发 MCP
aigc·mcp
古法老登瞎折腾20 小时前
大数据智能运维实战(八):从调度任务追到计算引擎——补齐排查链路
java·大数据·运维·spring ai·mcp
用户029537195052 天前
给 AI 编程助手造一个本地凭据库:MCP 工具设计、密钥注入和输出打码的工程细节
mcp
jerrywus2 天前
chrome-devtools-mcp 总弹授权、抢标签页?我是这样一步步配好的
前端·agent·mcp
大连好光景2 天前
Claude Code Agent SDK详解
lsp·hooks·mcp·claudecode·skills·mcp命名规范与调用权限
小易老师AI实战2 天前
MCP服务快速实现智能体/RAG项目的插拔功能
agent·rag·mcp·fastmcp·大模型工具调用·streamable‑http
Maiko Star2 天前
*【HM-LC】LangChain MCP详解:核心概念、外部服务连接与自定义服务
langchain·mcp