Browse Source

fix: scope agent MCP permissions to merged config (#223)

Simon Klakegg 2 weeks ago
parent
commit
7eec5f7e26
3 changed files with 36 additions and 3 deletions
  1. 32 0
      src/config/agent-mcps.test.ts
  2. 1 1
      src/config/agent-mcps.ts
  3. 3 2
      src/index.ts

+ 32 - 0
src/config/agent-mcps.test.ts

@@ -0,0 +1,32 @@
+import { describe, expect, test } from 'bun:test';
+import { parseList } from './agent-mcps';
+
+describe('parseList', () => {
+  test('empty list returns empty array', () => {
+    expect(parseList([], ['mcp1', 'mcp2'])).toEqual([]);
+  });
+
+  test('wildcard includes all available', () => {
+    expect(parseList(['*'], ['mcp1', 'mcp2', 'mcp3'])).toEqual(['mcp1', 'mcp2', 'mcp3']);
+  });
+
+  test('wildcard with exclusions', () => {
+    expect(parseList(['*', '!mcp2'], ['mcp1', 'mcp2', 'mcp3'])).toEqual(['mcp1', 'mcp3']);
+  });
+
+  test('exclude wildcard returns empty', () => {
+    expect(parseList(['!*'], ['mcp1', 'mcp2'])).toEqual([]);
+  });
+
+  test('specific items only', () => {
+    expect(parseList(['mcp1', 'mcp3'], ['mcp1', 'mcp2', 'mcp3', 'mcp4'])).toEqual(['mcp1', 'mcp3']);
+  });
+
+  test('specific items with exclusions', () => {
+    expect(parseList(['mcp1', 'mcp3', '!mcp3'], ['mcp1', 'mcp2', 'mcp3'])).toEqual(['mcp1']);
+  });
+
+  test('exclusions without matching allows', () => {
+    expect(parseList(['!mcp2'], ['mcp1', 'mcp2', 'mcp3'])).toEqual([]);
+  });
+});

+ 1 - 1
src/config/agent-mcps.ts

@@ -38,7 +38,7 @@ export function parseList(items: string[], allAvailable: string[]): string[] {
     return allAvailable.filter((item) => !deny.includes(item));
   }
 
-  return allow.filter((item) => !deny.includes(item));
+  return allow.filter((item) => !deny.includes(item) && allAvailable.includes(item));
 }
 
 /**

+ 3 - 2
src/index.ts

@@ -289,8 +289,9 @@ const OhMyOpenCodeLite: Plugin = async (ctx) => {
         Object.assign(configMcp, mcps);
       }
 
-      // Get all MCP names from our config
-      const allMcpNames = Object.keys(mcps);
+      // Get all MCP names from the merged config (built-in + custom)
+      const mergedMcpConfig = opencodeConfig.mcp as Record<string, unknown> | undefined;
+      const allMcpNames = Object.keys(mergedMcpConfig ?? mcps);
 
       // For each agent, create permission rules based on their mcps list
       for (const [agentName, agentConfig] of Object.entries(agents)) {