diff --git a/mcp/src/tools/permissions.test.ts b/mcp/src/tools/permissions.test.ts index 7977f879..a9ac2a31 100644 --- a/mcp/src/tools/permissions.test.ts +++ b/mcp/src/tools/permissions.test.ts @@ -155,8 +155,39 @@ describe("permission tools", () => { action: "getResourcePermission", resourceType: "noSqlDatabase", resourceId: "todos", + AclTag: "READONLY", + aclTag: "READONLY", + acl_tag: "READONLY", + requestId: "req-resource-perm", + totalCount: 1, }, }); + expect(payload.data.permissionList).toEqual([ + expect.objectContaining({ + Resource: "todos", + Permission: "READONLY", + }), + ]); + }); + + it("queryPermissions(action=listResourcePermissions) should expose compatibility aliases", async () => { + const result = await tools.queryPermissions.handler({ + action: "listResourcePermissions", + resourceType: "noSqlDatabase", + resourceIds: ["todos"], + }); + const payload = JSON.parse(result.content[0].text); + + expect(payload.data).toMatchObject({ + requestId: "req-resource-perm", + totalCount: 1, + }); + expect(payload.data.permissionList).toEqual([ + expect.objectContaining({ + Resource: "todos", + Permission: "READONLY", + }), + ]); }); it("queryPermissions(action=getResourcePermission) should return a doc-id write hint for risky custom rules", async () => { diff --git a/mcp/src/tools/permissions.ts b/mcp/src/tools/permissions.ts index ac13c97b..2de1d6a9 100644 --- a/mcp/src/tools/permissions.ts +++ b/mcp/src/tools/permissions.ts @@ -36,6 +36,19 @@ type ToolEnvelope = { message: string; }; +type PermissionListItem = { + Resource?: string; + Permission?: string; +}; + +type DescribeResourcePermissionResult = { + RequestId?: string; + Data?: { + TotalCount?: number; + PermissionList?: PermissionListItem[]; + }; +}; + function buildWriteVerificationHint(resourceId: string) { return `对于 ${resourceId} 这类有后端权限控制的集合,前端调用 .doc(id).update() / .doc(id).remove() 后,不能只看是否没有抛异常。请显式检查返回结果中的 updated / deleted 是否大于 0;如果 result.code、result.message 存在,或 updated / deleted 为 0,要把它当作真实失败并向上抛错。`; } @@ -92,6 +105,35 @@ function buildEnvelope(data: Record, message: string): ToolEnve }; } +function buildPermissionResultCompatibilityFields( + result: DescribeResourcePermissionResult, + permissions: PermissionListItem[], +) { + return { + permissionList: permissions, + requestId: result.RequestId ?? null, + totalCount: result.Data?.TotalCount ?? permissions.length, + }; +} + +function buildAclTagCompatibilityFields( + permissions: PermissionListItem[], + resourceId?: string, +) { + const matchedPermission = + permissions.find((item) => item.Resource === resourceId)?.Permission ?? permissions[0]?.Permission; + + if (!matchedPermission) { + return {}; + } + + return { + AclTag: matchedPermission, + aclTag: matchedPermission, + acl_tag: matchedPermission, + }; +} + function buildErrorEnvelope(error: unknown): ToolEnvelope { return { success: false, @@ -391,6 +433,8 @@ export function registerPermissionTools(server: ExtendedMcpServer) { resourceType, resourceId, permissions, + ...buildPermissionResultCompatibilityFields(result, permissions), + ...buildAclTagCompatibilityFields(permissions, resourceId), hints, raw: result, }, @@ -425,6 +469,7 @@ export function registerPermissionTools(server: ExtendedMcpServer) { permissions, resourceHints, total: result.Data.TotalCount ?? 0, + ...buildPermissionResultCompatibilityFields(result, permissions), raw: result, }, "资源权限列表查询成功",