fix(mcp): 绑定配置同时启用被停用的工具(解释"绑了仍 PERMISSION_DENIED")
现象:sync 作用域绑定 4 个工具后,3 个可用,district.paper.statistics.query 仍报 PERMISSION_DENIED。 原因推断:该工具在 tool 表 status != 1(停用),作用域解析会过滤掉它, 于是"绑定存在但工具不可用"。ToolSyncService 按设计保留管理员设置的状态, 所以不会纠正。 修复:ScopeToolSyncService 把绑定配置视为显式授权,遇到 status != 1 时 启用并 WARN 记录(原 status),避免静默失败。新增单测覆盖该场景(5 例全过)。
This commit is contained in:
@@ -93,6 +93,15 @@ public class ScopeToolSyncService implements ApplicationRunner {
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
// 绑定配置本身就是一次显式授权:若该工具在 tool 表被停用(status != 1),
|
||||
// 作用域解析会把它过滤掉,表现为"绑了却仍 PERMISSION_DENIED"。
|
||||
// 这里按配置启用并告警,避免这种"看起来绑上了其实用不了"的静默失败。
|
||||
if (tool.getStatus() == null || tool.getStatus() != 1) {
|
||||
Byte oldStatus = tool.getStatus();
|
||||
tool.setStatus((byte) 1);
|
||||
toolMapper.updateById(tool);
|
||||
log.warn("scope-tool binding 启用工具 name={} 原 status={}", toolName, oldStatus);
|
||||
}
|
||||
Long existing = scopeToolMapper.selectCount(new LambdaQueryWrapper<ScopeTool>()
|
||||
.eq(ScopeTool::getScopeId, scope.getId()).eq(ScopeTool::getToolId, tool.getId()));
|
||||
if (existing != null && existing > 0) {
|
||||
|
||||
@@ -65,6 +65,27 @@ class ScopeToolSyncServiceTest {
|
||||
verify(scopeToolMapper, times(1)).insert(any(ScopeTool.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void enablesDisabledToolWhenBindingConfigDeclaresIt() {
|
||||
service.rawBindings = "sync=tool.d";
|
||||
AgentScope scope = new AgentScope();
|
||||
scope.setId(4L);
|
||||
scope.setCode("sync");
|
||||
when(scopeMapper.selectOne(any())).thenReturn(scope);
|
||||
Tool toolD = new Tool();
|
||||
toolD.setId(13L);
|
||||
toolD.setName("tool.d");
|
||||
toolD.setStatus((byte) 0); // 停用
|
||||
when(toolMapper.selectOne(any())).thenReturn(toolD);
|
||||
when(scopeToolMapper.selectCount(any())).thenReturn(0L);
|
||||
|
||||
service.run(null);
|
||||
|
||||
assertEquals((byte) 1, toolD.getStatus(), "绑定配置应启用被停用的工具");
|
||||
verify(toolMapper, times(1)).updateById(toolD);
|
||||
verify(scopeToolMapper, times(1)).insert(any(ScopeTool.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
void bindsToolWhoseSoftDeleteColumnIsNull() {
|
||||
service.rawBindings = "sync=tool.c";
|
||||
|
||||
Reference in New Issue
Block a user