fix(policy): honor wildcard mcp deny diagnostics

This commit is contained in:
Gio Della-Libera
2026-06-16 13:20:04 -07:00
parent 30cfdc0a64
commit 3f8628b4fd
2 changed files with 34 additions and 11 deletions

View File

@@ -25,32 +25,27 @@ function denylistBlocksName(name: string, denylist: ToolDenylist): boolean {
return normalized ? matchesAnyGlobPattern(normalized, denylist) : false;
}
function denylistContainsMcpServerEntry(params: {
function denylistBlocksMcpServerNamespace(params: {
safeServerName: string;
rawDenylist?: string[];
denylist: ToolDenylist;
}): boolean {
const serverPrefix = normalizeToolName(params.safeServerName + TOOL_NAME_SEPARATOR);
if (!serverPrefix) {
return false;
}
const serverWideEntry = serverPrefix + "*";
return (params.rawDenylist ?? []).some((entry) => {
const normalized = normalizeToolName(entry);
return normalized === serverWideEntry;
});
return matchesAnyGlobPattern(serverPrefix, params.denylist);
}
function denylistBlocksMcpServer(params: {
safeServerName: string;
rawDenylist?: string[];
denylist: ToolDenylist;
}): boolean {
return (
denylistBlocksName("bundle-mcp", params.denylist) ||
matchesAnyGlobPattern("group:plugins", params.denylist) ||
denylistContainsMcpServerEntry({
denylistBlocksMcpServerNamespace({
safeServerName: params.safeServerName,
rawDenylist: params.rawDenylist,
denylist: params.denylist,
})
);
}
@@ -89,7 +84,6 @@ function collectConfiguredMcpServerNames(params: {
if (
denylistBlocksMcpServer({
safeServerName,
rawDenylist: params.toolDenylist,
denylist,
})
) {

View File

@@ -336,6 +336,35 @@ describe("tool-policy-pipeline", () => {
]);
});
test("warns when broad MCP server wildcard deny covers an allowlisted namespace", () => {
const warnings: string[] = [];
const declared = buildDeclaredToolAllowlistContext({
config: {
mcp: { servers: { paperless: { command: "paperless-mcp" } } },
},
workspaceDir: process.cwd(),
toolDenylist: ["paperless*"],
});
applyToolPolicyPipeline({
tools: [{ name: "exec" }] as any,
toolMeta: () => undefined,
warn: (msg) => warnings.push(msg),
declaredToolAllowlist: declared,
steps: [
{
policy: { allow: ["paperless__*"] },
label: "tools.allow",
stripPluginOnlyAllowlist: true,
},
],
});
expect(warnings).toEqual([
"tools: tools.allow allowlist contains unknown entries (paperless__*). These entries won't match any tool unless the plugin is enabled.",
]);
});
test("does not warn for MCP server namespace allowlist when one exact server tool is denied", () => {
const warnings: string[] = [];
const declared = buildDeclaredToolAllowlistContext({