@aws/lsp-codewhisperer 0.0.65 → 0.0.67
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +56 -0
- package/README.md +5 -0
- package/out/language-server/agenticChat/agenticChatController.d.ts +9 -2
- package/out/language-server/agenticChat/agenticChatController.js +512 -136
- package/out/language-server/agenticChat/agenticChatController.js.map +1 -1
- package/out/language-server/agenticChat/constants/constants.d.ts +17 -0
- package/out/language-server/agenticChat/constants/constants.js +79 -1
- package/out/language-server/agenticChat/constants/constants.js.map +1 -1
- package/out/language-server/agenticChat/constants/toolConstants.d.ts +24 -0
- package/out/language-server/agenticChat/constants/toolConstants.js +35 -0
- package/out/language-server/agenticChat/constants/toolConstants.js.map +1 -0
- package/out/language-server/agenticChat/context/additionalContextProvider.d.ts +9 -1
- package/out/language-server/agenticChat/context/additionalContextProvider.js +92 -34
- package/out/language-server/agenticChat/context/additionalContextProvider.js.map +1 -1
- package/out/language-server/agenticChat/context/agenticChatTriggerContext.d.ts +11 -2
- package/out/language-server/agenticChat/context/agenticChatTriggerContext.js +36 -2
- package/out/language-server/agenticChat/context/agenticChatTriggerContext.js.map +1 -1
- package/out/language-server/agenticChat/context/contextCommandsProvider.js +1 -1
- package/out/language-server/agenticChat/context/contextCommandsProvider.js.map +1 -1
- package/out/language-server/agenticChat/context/contextUtils.d.ts +16 -0
- package/out/language-server/agenticChat/context/contextUtils.js +29 -0
- package/out/language-server/agenticChat/context/contextUtils.js.map +1 -1
- package/out/language-server/agenticChat/qAgenticChatServer.d.ts +2 -0
- package/out/language-server/agenticChat/qAgenticChatServer.js +18 -2
- package/out/language-server/agenticChat/qAgenticChatServer.js.map +1 -1
- package/out/language-server/agenticChat/tools/chatDb/chatDb.d.ts +11 -3
- package/out/language-server/agenticChat/tools/chatDb/chatDb.js +115 -31
- package/out/language-server/agenticChat/tools/chatDb/chatDb.js.map +1 -1
- package/out/language-server/agenticChat/tools/chatDb/util.d.ts +15 -1
- package/out/language-server/agenticChat/tools/chatDb/util.js +17 -0
- package/out/language-server/agenticChat/tools/chatDb/util.js.map +1 -1
- package/out/language-server/agenticChat/tools/executeBash.d.ts +0 -11
- package/out/language-server/agenticChat/tools/executeBash.js +16 -35
- package/out/language-server/agenticChat/tools/executeBash.js.map +1 -1
- package/out/language-server/agenticChat/tools/grepSearch.js +3 -1
- package/out/language-server/agenticChat/tools/grepSearch.js.map +1 -1
- package/out/language-server/agenticChat/tools/mcp/mcpEventHandler.js +208 -170
- package/out/language-server/agenticChat/tools/mcp/mcpEventHandler.js.map +1 -1
- package/out/language-server/agenticChat/tools/mcp/mcpManager.d.ts +12 -18
- package/out/language-server/agenticChat/tools/mcp/mcpManager.js +353 -216
- package/out/language-server/agenticChat/tools/mcp/mcpManager.js.map +1 -1
- package/out/language-server/agenticChat/tools/mcp/mcpTypes.d.ts +29 -0
- package/out/language-server/agenticChat/tools/mcp/mcpTypes.js +60 -1
- package/out/language-server/agenticChat/tools/mcp/mcpTypes.js.map +1 -1
- package/out/language-server/agenticChat/tools/mcp/mcpUtils.d.ts +27 -4
- package/out/language-server/agenticChat/tools/mcp/mcpUtils.js +464 -2
- package/out/language-server/agenticChat/tools/mcp/mcpUtils.js.map +1 -1
- package/out/language-server/agenticChat/tools/toolServer.js +8 -10
- package/out/language-server/agenticChat/tools/toolServer.js.map +1 -1
- package/out/language-server/agenticChat/tools/toolShared.js +6 -2
- package/out/language-server/agenticChat/tools/toolShared.js.map +1 -1
- package/out/language-server/chat/chatController.d.ts +1 -1
- package/out/language-server/chat/chatController.js.map +1 -1
- package/out/language-server/chat/chatSessionService.d.ts +1 -0
- package/out/language-server/chat/chatSessionService.js +5 -2
- package/out/language-server/chat/chatSessionService.js.map +1 -1
- package/out/language-server/chat/contexts/triggerContext.js +11 -2
- package/out/language-server/chat/contexts/triggerContext.js.map +1 -1
- package/out/language-server/chat/quickActions.d.ts +7 -1
- package/out/language-server/chat/quickActions.js +7 -1
- package/out/language-server/chat/quickActions.js.map +1 -1
- package/out/language-server/chat/telemetry/chatTelemetryController.d.ts +1 -0
- package/out/language-server/chat/telemetry/chatTelemetryController.js +9 -0
- package/out/language-server/chat/telemetry/chatTelemetryController.js.map +1 -1
- package/out/language-server/configuration/qConfigurationServer.d.ts +2 -0
- package/out/language-server/configuration/qConfigurationServer.js.map +1 -1
- package/out/language-server/inline-completion/auto-trigger/autoTrigger.d.ts +3 -0
- package/out/language-server/inline-completion/auto-trigger/autoTrigger.js +105 -1
- package/out/language-server/inline-completion/auto-trigger/autoTrigger.js.map +1 -1
- package/out/language-server/inline-completion/auto-trigger/editPredictionAutoTrigger.js +6 -1
- package/out/language-server/inline-completion/auto-trigger/editPredictionAutoTrigger.js.map +1 -1
- package/out/language-server/inline-completion/auto-trigger/editPredictionConfig.d.ts +1 -0
- package/out/language-server/inline-completion/auto-trigger/editPredictionConfig.js +1 -0
- package/out/language-server/inline-completion/auto-trigger/editPredictionConfig.js.map +1 -1
- package/out/language-server/inline-completion/codeWhispererServer.js +53 -52
- package/out/language-server/inline-completion/codeWhispererServer.js.map +1 -1
- package/out/language-server/workspaceContext/dependency/dependencyDiscoverer.d.ts +4 -1
- package/out/language-server/workspaceContext/dependency/dependencyDiscoverer.js +36 -2
- package/out/language-server/workspaceContext/dependency/dependencyDiscoverer.js.map +1 -1
- package/out/language-server/workspaceContext/dependency/dependencyEventBundler.d.ts +11 -5
- package/out/language-server/workspaceContext/dependency/dependencyEventBundler.js +37 -10
- package/out/language-server/workspaceContext/dependency/dependencyEventBundler.js.map +1 -1
- package/out/language-server/workspaceContext/dependency/dependencyHandler/JSTSDependencyHandler.d.ts +1 -1
- package/out/language-server/workspaceContext/dependency/dependencyHandler/JSTSDependencyHandler.js +8 -3
- package/out/language-server/workspaceContext/dependency/dependencyHandler/JSTSDependencyHandler.js.map +1 -1
- package/out/language-server/workspaceContext/dependency/dependencyHandler/JavaDependencyHandler.js +3 -4
- package/out/language-server/workspaceContext/dependency/dependencyHandler/JavaDependencyHandler.js.map +1 -1
- package/out/language-server/workspaceContext/dependency/dependencyHandler/LanguageDependencyHandler.d.ts +4 -3
- package/out/language-server/workspaceContext/dependency/dependencyHandler/LanguageDependencyHandler.js +5 -9
- package/out/language-server/workspaceContext/dependency/dependencyHandler/LanguageDependencyHandler.js.map +1 -1
- package/out/language-server/workspaceContext/dependency/dependencyHandler/PythonDependencyHandler.js +3 -4
- package/out/language-server/workspaceContext/dependency/dependencyHandler/PythonDependencyHandler.js.map +1 -1
- package/out/language-server/workspaceContext/workspaceContextServer.js +12 -8
- package/out/language-server/workspaceContext/workspaceContextServer.js.map +1 -1
- package/out/shared/activeUserTracker.d.ts +52 -0
- package/out/shared/activeUserTracker.js +164 -0
- package/out/shared/activeUserTracker.js.map +1 -0
- package/out/shared/amazonQServiceManager/configurationUtils.d.ts +4 -0
- package/out/shared/amazonQServiceManager/configurationUtils.js +6 -0
- package/out/shared/amazonQServiceManager/configurationUtils.js.map +1 -1
- package/out/shared/codeWhispererService.js +3 -1
- package/out/shared/codeWhispererService.js.map +1 -1
- package/out/shared/streamingClientService.js +12 -1
- package/out/shared/streamingClientService.js.map +1 -1
- package/out/shared/telemetry/telemetryService.js +1 -2
- package/out/shared/telemetry/telemetryService.js.map +1 -1
- package/out/shared/telemetry/types.d.ts +7 -1
- package/out/shared/telemetry/types.js +1 -0
- package/out/shared/telemetry/types.js.map +1 -1
- package/out/shared/utils.d.ts +1 -7
- package/out/shared/utils.js +39 -36
- package/out/shared/utils.js.map +1 -1
- package/package.json +7 -6
|
@@ -6,15 +6,13 @@
|
|
|
6
6
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
7
|
exports.McpManager = exports.AGENT_TOOLS_CHANGED = exports.MCP_SERVER_STATUS_CHANGED = void 0;
|
|
8
8
|
const types_1 = require("../../../../shared/telemetry/types");
|
|
9
|
-
const mcpUtils_1 = require("./mcpUtils");
|
|
10
9
|
const index_js_1 = require("@modelcontextprotocol/sdk/client/index.js");
|
|
11
10
|
const stdio_js_1 = require("@modelcontextprotocol/sdk/client/stdio.js");
|
|
12
11
|
const mcpTypes_1 = require("./mcpTypes");
|
|
13
|
-
const
|
|
12
|
+
const mcpUtils_1 = require("./mcpUtils");
|
|
14
13
|
const errors_1 = require("../../errors");
|
|
15
14
|
const events_1 = require("events");
|
|
16
15
|
const async_mutex_1 = require("async-mutex");
|
|
17
|
-
const path = require("path");
|
|
18
16
|
const vscode_uri_1 = require("vscode-uri");
|
|
19
17
|
exports.MCP_SERVER_STATUS_CHANGED = 'mcpServerStatusChanged';
|
|
20
18
|
exports.AGENT_TOOLS_CHANGED = 'agentToolsChanged';
|
|
@@ -22,8 +20,7 @@ exports.AGENT_TOOLS_CHANGED = 'agentToolsChanged';
|
|
|
22
20
|
* Manages MCP servers and their tools
|
|
23
21
|
*/
|
|
24
22
|
class McpManager {
|
|
25
|
-
|
|
26
|
-
personaPaths;
|
|
23
|
+
agentPaths;
|
|
27
24
|
features;
|
|
28
25
|
static #instance;
|
|
29
26
|
clients;
|
|
@@ -37,9 +34,9 @@ class McpManager {
|
|
|
37
34
|
static personaMutex = new async_mutex_1.Mutex();
|
|
38
35
|
toolNameMapping;
|
|
39
36
|
serverNameMapping;
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
this.
|
|
37
|
+
agentConfig;
|
|
38
|
+
constructor(agentPaths, features) {
|
|
39
|
+
this.agentPaths = agentPaths;
|
|
43
40
|
this.features = features;
|
|
44
41
|
this.mcpTools = [];
|
|
45
42
|
this.clients = new Map();
|
|
@@ -48,21 +45,21 @@ class McpManager {
|
|
|
48
45
|
this.configLoadErrors = new Map();
|
|
49
46
|
this.mcpServerPermissions = new Map();
|
|
50
47
|
this.events = new events_1.EventEmitter({ captureRejections: true }).on('error', console.error);
|
|
51
|
-
this.features.logging.info(`MCP manager: initialized with ${
|
|
48
|
+
this.features.logging.info(`MCP manager: initialized with ${agentPaths.length} configs`);
|
|
52
49
|
this.toolNameMapping = new Map();
|
|
53
50
|
this.serverNameMapping = new Map();
|
|
54
51
|
}
|
|
55
|
-
static async init(
|
|
52
|
+
static async init(agentPaths, features) {
|
|
56
53
|
if (!McpManager.#instance) {
|
|
57
|
-
const mgr = new McpManager(
|
|
54
|
+
const mgr = new McpManager(agentPaths, features);
|
|
58
55
|
McpManager.#instance = mgr;
|
|
59
56
|
await mgr.discoverAllServers();
|
|
60
57
|
features.logging.info(`MCP: discovered ${mgr.mcpTools.length} tools across all servers`);
|
|
61
58
|
// Emit MCP configuration metrics
|
|
62
59
|
const serverConfigs = mgr.getAllServerConfigs();
|
|
63
|
-
const activeServers = Array.from(serverConfigs.entries())
|
|
60
|
+
const activeServers = Array.from(serverConfigs.entries());
|
|
64
61
|
// Count global vs project servers
|
|
65
|
-
const globalServers = Array.from(serverConfigs.entries()).filter(([_, config]) => config?.__configPath__ === (0, mcpUtils_1.
|
|
62
|
+
const globalServers = Array.from(serverConfigs.entries()).filter(([_, config]) => config?.__configPath__ === (0, mcpUtils_1.getGlobalAgentConfigPath)(features.workspace.fs.getUserHomeDir())).length;
|
|
66
63
|
const projectServers = serverConfigs.size - globalServers;
|
|
67
64
|
// Count tools by permission
|
|
68
65
|
let toolsAlwaysAllowed = 0;
|
|
@@ -118,30 +115,69 @@ class McpManager {
|
|
|
118
115
|
* Load configurations and initialize each enabled server.
|
|
119
116
|
*/
|
|
120
117
|
async discoverAllServers() {
|
|
121
|
-
|
|
122
|
-
this.
|
|
123
|
-
|
|
124
|
-
this.
|
|
125
|
-
this.
|
|
118
|
+
// Load agent config
|
|
119
|
+
const result = await (0, mcpUtils_1.loadAgentConfig)(this.features.workspace, this.features.logging, this.agentPaths);
|
|
120
|
+
// Extract agent config and other data
|
|
121
|
+
this.agentConfig = result.agentConfig;
|
|
122
|
+
this.mcpServers = result.servers;
|
|
123
|
+
this.serverNameMapping = result.serverNameMapping;
|
|
126
124
|
// Reset the configuration errors after every refresh.
|
|
127
125
|
this.configLoadErrors.clear();
|
|
128
126
|
// Store any config load errors
|
|
129
|
-
errors.forEach((errorMsg, key) => {
|
|
127
|
+
result.errors.forEach((errorMsg, key) => {
|
|
130
128
|
this.configLoadErrors.set(key, errorMsg);
|
|
131
129
|
});
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
130
|
+
this.features.logging.info('Using agent configuration');
|
|
131
|
+
// Reset permissions map
|
|
132
|
+
this.mcpServerPermissions.clear();
|
|
133
|
+
// Initialize permissions for servers from agent config
|
|
134
|
+
for (const [sanitizedName, _] of this.mcpServers.entries()) {
|
|
135
|
+
const name = this.serverNameMapping.get(sanitizedName) || sanitizedName;
|
|
136
|
+
// Set server status to UNINITIALIZED initially
|
|
137
|
+
this.setState(sanitizedName, mcpTypes_1.McpServerStatus.UNINITIALIZED, 0);
|
|
138
|
+
// Initialize permissions for this server
|
|
139
|
+
const serverPrefix = `@${name}`;
|
|
140
|
+
// Extract tool permissions from agent config
|
|
141
|
+
const toolPerms = {};
|
|
142
|
+
// Check if the server is enabled as a whole (@server) or just specific tools (@server/tool)
|
|
143
|
+
const isWholeServerEnabled = this.agentConfig.tools.includes(serverPrefix);
|
|
144
|
+
if (isWholeServerEnabled) {
|
|
145
|
+
// Check for specific tools in allowedTools
|
|
146
|
+
this.agentConfig.allowedTools.forEach(allowedTool => {
|
|
147
|
+
if (allowedTool.startsWith(serverPrefix + '/')) {
|
|
148
|
+
const toolName = allowedTool.substring(serverPrefix.length + 1);
|
|
149
|
+
if (toolName) {
|
|
150
|
+
// This specific tool is in allowedTools
|
|
151
|
+
toolPerms[toolName] = mcpTypes_1.McpPermissionType.alwaysAllow;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
else {
|
|
157
|
+
// Only specific tools are enabled
|
|
158
|
+
this.agentConfig.tools.forEach(tool => {
|
|
159
|
+
if (tool.startsWith(serverPrefix + '/')) {
|
|
160
|
+
const toolName = tool.substring(serverPrefix.length + 1);
|
|
161
|
+
if (toolName) {
|
|
162
|
+
// Check if tool is in allowedTools
|
|
163
|
+
if (this.agentConfig.allowedTools.includes(tool)) {
|
|
164
|
+
toolPerms[toolName] = mcpTypes_1.McpPermissionType.alwaysAllow;
|
|
165
|
+
}
|
|
166
|
+
else {
|
|
167
|
+
toolPerms[toolName] = mcpTypes_1.McpPermissionType.ask;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
this.mcpServerPermissions.set(sanitizedName, {
|
|
174
|
+
enabled: true,
|
|
175
|
+
toolPerms,
|
|
176
|
+
});
|
|
135
177
|
}
|
|
136
178
|
// Get all servers that need to be initialized
|
|
137
179
|
const serversToInit = [];
|
|
138
180
|
for (const [name, cfg] of this.mcpServers.entries()) {
|
|
139
|
-
if (this.isServerDisabled(name)) {
|
|
140
|
-
this.features.logging.info(`MCP: server '${name}' is disabled by persona settings, skipping`);
|
|
141
|
-
this.setState(name, mcpTypes_1.McpServerStatus.DISABLED, 0);
|
|
142
|
-
this.emitToolsChanged(name);
|
|
143
|
-
continue;
|
|
144
|
-
}
|
|
145
181
|
serversToInit.push([name, cfg]);
|
|
146
182
|
}
|
|
147
183
|
// Process servers in batches of 5 at a time
|
|
@@ -171,7 +207,7 @@ class McpManager {
|
|
|
171
207
|
const mergedEnv = {
|
|
172
208
|
...process.env,
|
|
173
209
|
// Make sure we do not have empty key and value in mergedEnv, or adding server through UI will fail on Windows
|
|
174
|
-
...(cfg.env && !(0,
|
|
210
|
+
...(cfg.env && !(0, mcpUtils_1.isEmptyEnv)(cfg.env)
|
|
175
211
|
? Object.fromEntries(Object.entries(cfg.env).filter(([key]) => key && key.trim() !== ''))
|
|
176
212
|
: {}),
|
|
177
213
|
};
|
|
@@ -208,8 +244,8 @@ class McpManager {
|
|
|
208
244
|
}
|
|
209
245
|
throw new errors_1.AgenticChatError(`MCP: server '${serverName}' failed to connect: ${errorMessage}`, 'MCPServerConnectionFailed');
|
|
210
246
|
});
|
|
211
|
-
// 0 -> no timeout
|
|
212
|
-
if (cfg.initializationTimeout === 0) {
|
|
247
|
+
// 0 or undefined -> no timeout
|
|
248
|
+
if (cfg.initializationTimeout === 0 || cfg.initializationTimeout === undefined) {
|
|
213
249
|
await connectPromise;
|
|
214
250
|
}
|
|
215
251
|
else {
|
|
@@ -273,34 +309,73 @@ class McpManager {
|
|
|
273
309
|
* Return a list of all enabled tools.
|
|
274
310
|
*/
|
|
275
311
|
getEnabledTools() {
|
|
276
|
-
return this.mcpTools.filter(t => !this.
|
|
312
|
+
return this.mcpTools.filter(t => !this.isToolDisabled(t.serverName, t.toolName));
|
|
277
313
|
}
|
|
278
314
|
/**
|
|
279
315
|
* Returns true if the given tool on the given server is currently disabled.
|
|
280
316
|
*/
|
|
281
317
|
isToolDisabled(server, tool) {
|
|
282
|
-
|
|
318
|
+
// built-in tools cannot be disabled
|
|
319
|
+
if (server === 'builtIn') {
|
|
320
|
+
return false;
|
|
321
|
+
}
|
|
322
|
+
// Check if the server is enabled as a whole (@server)
|
|
323
|
+
const serverPrefix = `@${server}`;
|
|
324
|
+
const isWholeServerEnabled = this.agentConfig.tools.includes(serverPrefix);
|
|
325
|
+
// Check if the specific tool is enabled
|
|
326
|
+
const toolId = `${serverPrefix}/${tool}`;
|
|
327
|
+
const isSpecificToolEnabled = this.agentConfig.tools.includes(toolId);
|
|
328
|
+
// If server is enabled as a whole, all tools are enabled
|
|
329
|
+
if (isWholeServerEnabled) {
|
|
330
|
+
return false;
|
|
331
|
+
}
|
|
332
|
+
// Otherwise, check if this specific tool is enabled
|
|
333
|
+
return !isSpecificToolEnabled;
|
|
283
334
|
}
|
|
284
335
|
/**
|
|
285
336
|
* Returns true if the given server is currently disabled.
|
|
286
337
|
*/
|
|
287
|
-
isServerDisabled(name) {
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
338
|
+
// public isServerDisabled(name: string): boolean {
|
|
339
|
+
// // Check if any tool from this server is enabled
|
|
340
|
+
// return !this.agentConfig.tools.some(tool => {
|
|
341
|
+
// if (tool.startsWith('@')) {
|
|
342
|
+
// // Check if it's the server itself or a tool from the server
|
|
343
|
+
// return tool === `@${name}` || tool.startsWith(`@${name}/`)
|
|
344
|
+
// }
|
|
345
|
+
// return false
|
|
346
|
+
// })
|
|
347
|
+
// }
|
|
292
348
|
/**
|
|
293
349
|
* Returns tool permission type for a given tool.
|
|
294
350
|
*/
|
|
295
351
|
getToolPerm(server, tool) {
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
352
|
+
// For built-in tools, check directly without prefix
|
|
353
|
+
if (server === 'Built-in') {
|
|
354
|
+
return this.agentConfig.allowedTools.includes(tool) ? mcpTypes_1.McpPermissionType.alwaysAllow : mcpTypes_1.McpPermissionType.ask;
|
|
355
|
+
}
|
|
356
|
+
// Check if the server is enabled as a whole (@server)
|
|
357
|
+
const serverPrefix = `@${server}`;
|
|
358
|
+
const isWholeServerEnabled = this.agentConfig.tools.includes(serverPrefix);
|
|
359
|
+
// Check if the specific tool is enabled
|
|
360
|
+
const toolId = `${serverPrefix}/${tool}`;
|
|
361
|
+
const isSpecificToolEnabled = this.agentConfig.tools.includes(toolId);
|
|
362
|
+
// If the tool is not enabled, return deny
|
|
363
|
+
if (!isWholeServerEnabled && !isSpecificToolEnabled) {
|
|
364
|
+
return mcpTypes_1.McpPermissionType.deny;
|
|
365
|
+
}
|
|
366
|
+
// If server is enabled as a whole, check if the server itself is in allowedTools
|
|
367
|
+
if (isWholeServerEnabled) {
|
|
368
|
+
// If server is in allowedTools, all tools are alwaysAllow
|
|
369
|
+
if (this.agentConfig.allowedTools.includes(serverPrefix)) {
|
|
370
|
+
return mcpTypes_1.McpPermissionType.alwaysAllow;
|
|
371
|
+
}
|
|
372
|
+
// Otherwise, check if specific tool is in allowedTools
|
|
373
|
+
return this.agentConfig.allowedTools.includes(toolId)
|
|
374
|
+
? mcpTypes_1.McpPermissionType.alwaysAllow
|
|
375
|
+
: mcpTypes_1.McpPermissionType.ask;
|
|
376
|
+
}
|
|
377
|
+
// For specific tools, check if it's in allowedTools
|
|
378
|
+
return this.agentConfig.allowedTools.includes(toolId) ? mcpTypes_1.McpPermissionType.alwaysAllow : mcpTypes_1.McpPermissionType.ask;
|
|
304
379
|
}
|
|
305
380
|
/**
|
|
306
381
|
* Return a list of all server configurations.
|
|
@@ -308,9 +383,6 @@ class McpManager {
|
|
|
308
383
|
getAllServerConfigs() {
|
|
309
384
|
return new Map(this.mcpServers);
|
|
310
385
|
}
|
|
311
|
-
getAllPermissions() {
|
|
312
|
-
return new Map(this.mcpServerPermissions);
|
|
313
|
-
}
|
|
314
386
|
/**
|
|
315
387
|
* Map server names to their available tool names.
|
|
316
388
|
*/
|
|
@@ -331,8 +403,7 @@ class McpManager {
|
|
|
331
403
|
const cfg = this.mcpServers.get(server);
|
|
332
404
|
if (!cfg)
|
|
333
405
|
throw new Error(`MCP: server '${server}' is not configured`);
|
|
334
|
-
if (this.isServerDisabled(server))
|
|
335
|
-
throw new Error(`MCP: server '${server}' is disabled`);
|
|
406
|
+
// if (this.isServerDisabled(server)) throw new Error(`MCP: server '${server}' is disabled`)
|
|
336
407
|
const available = this.getEnabledTools()
|
|
337
408
|
.filter(t => t.serverName === server)
|
|
338
409
|
.map(t => t.toolName);
|
|
@@ -366,43 +437,46 @@ class McpManager {
|
|
|
366
437
|
/**
|
|
367
438
|
* Add a new server: persist config, register in memory, and initialize.
|
|
368
439
|
*/
|
|
369
|
-
async addServer(serverName, cfg,
|
|
440
|
+
async addServer(serverName, cfg, agentPath) {
|
|
370
441
|
try {
|
|
371
|
-
const sanitizedName = (0,
|
|
372
|
-
if (this.mcpServers.has(sanitizedName)
|
|
442
|
+
const sanitizedName = (0, mcpUtils_1.sanitizeName)(serverName);
|
|
443
|
+
if (this.mcpServers.has(sanitizedName) &&
|
|
444
|
+
this.getServerState(sanitizedName)?.status == mcpTypes_1.McpServerStatus.ENABLED) {
|
|
373
445
|
throw new Error(`MCP: server '${sanitizedName}' already exists`);
|
|
374
446
|
}
|
|
375
|
-
|
|
376
|
-
|
|
447
|
+
// Add server to agent config
|
|
448
|
+
const serverConfig = {
|
|
449
|
+
command: cfg.command,
|
|
450
|
+
initializationTimeout: cfg.initializationTimeout,
|
|
451
|
+
};
|
|
452
|
+
// Only add timeout to agent config if it's not 0
|
|
453
|
+
if (cfg.timeout !== 0) {
|
|
454
|
+
serverConfig.timeout = cfg.timeout;
|
|
455
|
+
}
|
|
456
|
+
if (cfg.args && cfg.args.length > 0) {
|
|
457
|
+
serverConfig.args = cfg.args;
|
|
377
458
|
}
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
serverConfig.args = cfg.args;
|
|
386
|
-
}
|
|
387
|
-
if (cfg.env && !(0, mcpUtils_2.isEmptyEnv)(cfg.env)) {
|
|
388
|
-
serverConfig.env = cfg.env;
|
|
389
|
-
}
|
|
390
|
-
json.mcpServers[serverName] = serverConfig;
|
|
391
|
-
});
|
|
392
|
-
const newCfg = { ...cfg, __configPath__: configPath };
|
|
459
|
+
if (cfg.env && !(0, mcpUtils_1.isEmptyEnv)(cfg.env)) {
|
|
460
|
+
serverConfig.env = cfg.env;
|
|
461
|
+
}
|
|
462
|
+
// Add to agent config
|
|
463
|
+
this.agentConfig.mcpServers[serverName] = serverConfig;
|
|
464
|
+
// We don't need to store configPath anymore as we're using agent config
|
|
465
|
+
const newCfg = { ...cfg, __configPath__: agentPath };
|
|
393
466
|
this.mcpServers.set(sanitizedName, newCfg);
|
|
394
467
|
this.serverNameMapping.set(sanitizedName, serverName);
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
const
|
|
398
|
-
|
|
399
|
-
if (
|
|
400
|
-
|
|
401
|
-
this.
|
|
402
|
-
}
|
|
403
|
-
else {
|
|
404
|
-
await this.initOneServer(sanitizedName, newCfg);
|
|
468
|
+
// Check if the server already has permissions in the agent config
|
|
469
|
+
const serverPrefix = `@${serverName}`;
|
|
470
|
+
const hasServerInTools = this.agentConfig.tools.some(tool => tool === serverPrefix || tool.startsWith(`${serverPrefix}/`));
|
|
471
|
+
// Only set permissions if the server doesn't already have them
|
|
472
|
+
if (!hasServerInTools) {
|
|
473
|
+
// Enable the server as a whole rather than individual tools
|
|
474
|
+
this.agentConfig.tools.push(serverPrefix);
|
|
405
475
|
}
|
|
476
|
+
// Save agent config once with all changes
|
|
477
|
+
await (0, mcpUtils_1.saveAgentConfig)(this.features.workspace, this.features.logging, this.agentConfig, agentPath);
|
|
478
|
+
// Add server tools to tools list after initialization
|
|
479
|
+
await this.initOneServer(sanitizedName, newCfg);
|
|
406
480
|
}
|
|
407
481
|
catch (err) {
|
|
408
482
|
this.features.logging.error(`Failed to add MCP server '${serverName}': ${err instanceof Error ? err.message : String(err)}`);
|
|
@@ -420,8 +494,6 @@ class McpManager {
|
|
|
420
494
|
if (!cfg || !cfg.__configPath__) {
|
|
421
495
|
throw new Error(`MCP: server '${serverName}' not found`);
|
|
422
496
|
}
|
|
423
|
-
// Capture the remaining server keys before deletion for persona file update
|
|
424
|
-
const remainingServer = Array.from(this.mcpServers.keys()).filter(key => key !== serverName);
|
|
425
497
|
const client = this.clients.get(serverName);
|
|
426
498
|
if (client) {
|
|
427
499
|
await client.close();
|
|
@@ -429,38 +501,54 @@ class McpManager {
|
|
|
429
501
|
}
|
|
430
502
|
this.mcpTools = this.mcpTools.filter(t => t.serverName !== serverName);
|
|
431
503
|
this.mcpServerStates.delete(serverName);
|
|
432
|
-
// Remove from config
|
|
433
|
-
if (unsanitizedName) {
|
|
434
|
-
|
|
435
|
-
|
|
504
|
+
// Remove from agent config
|
|
505
|
+
if (unsanitizedName && this.agentConfig) {
|
|
506
|
+
// Remove server from mcpServers
|
|
507
|
+
delete this.agentConfig.mcpServers[unsanitizedName];
|
|
508
|
+
// Remove server tools from tools list
|
|
509
|
+
this.agentConfig.tools = this.agentConfig.tools.filter(tool => {
|
|
510
|
+
if (tool.startsWith('@')) {
|
|
511
|
+
if (tool === `@${unsanitizedName}`) {
|
|
512
|
+
return false;
|
|
513
|
+
}
|
|
514
|
+
if (tool.startsWith(`@${unsanitizedName}/`)) {
|
|
515
|
+
return false;
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
return true;
|
|
436
519
|
});
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
520
|
+
// Remove server tools from allowedTools
|
|
521
|
+
this.agentConfig.allowedTools = this.agentConfig.allowedTools.filter(tool => {
|
|
522
|
+
if (tool.startsWith('@')) {
|
|
523
|
+
if (tool === `@${unsanitizedName}`) {
|
|
524
|
+
return false;
|
|
525
|
+
}
|
|
526
|
+
if (tool.startsWith(`@${unsanitizedName}/`)) {
|
|
527
|
+
return false;
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
return true;
|
|
531
|
+
});
|
|
532
|
+
// Save agent config
|
|
533
|
+
await (0, mcpUtils_1.saveAgentConfig)(this.features.workspace, this.features.logging, this.agentConfig, cfg.__configPath__);
|
|
441
534
|
}
|
|
442
535
|
this.mcpServers.delete(serverName);
|
|
443
536
|
this.serverNameMapping.delete(serverName);
|
|
444
|
-
this.mcpServerPermissions.delete(serverName);
|
|
445
|
-
this.mcpServerPermissions = await (0, mcpUtils_2.loadPersonaPermissions)(this.features.workspace, this.features.logging, this.personaPaths);
|
|
446
537
|
this.emitToolsChanged(serverName);
|
|
447
538
|
}
|
|
448
539
|
/**
|
|
449
540
|
* Update a server: persist changes, teardown old client/tools, and re-init if enabled.
|
|
450
541
|
*/
|
|
451
|
-
async updateServer(serverName, configUpdates,
|
|
542
|
+
async updateServer(serverName, configUpdates, agentPath) {
|
|
452
543
|
try {
|
|
453
|
-
if (!configPath) {
|
|
454
|
-
throw new Error(`Missing configPath for '${serverName}'`);
|
|
455
|
-
}
|
|
456
544
|
const oldCfg = this.mcpServers.get(serverName);
|
|
457
|
-
if (!oldCfg
|
|
545
|
+
if (!oldCfg) {
|
|
458
546
|
throw new Error(`MCP: server '${serverName}' not found`);
|
|
459
547
|
}
|
|
460
548
|
const unsanitizedServerName = this.serverNameMapping.get(serverName);
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
const updatedConfig = { ...(
|
|
549
|
+
// Update agent config
|
|
550
|
+
if (this.agentConfig && unsanitizedServerName) {
|
|
551
|
+
const updatedConfig = { ...(this.agentConfig.mcpServers[unsanitizedServerName] || {}) };
|
|
464
552
|
if (configUpdates.command !== undefined)
|
|
465
553
|
updatedConfig.command = configUpdates.command;
|
|
466
554
|
if (configUpdates.initializationTimeout !== undefined)
|
|
@@ -476,19 +564,20 @@ class McpManager {
|
|
|
476
564
|
}
|
|
477
565
|
}
|
|
478
566
|
if (configUpdates.env !== undefined) {
|
|
479
|
-
if (!(0,
|
|
567
|
+
if (!(0, mcpUtils_1.isEmptyEnv)(configUpdates.env)) {
|
|
480
568
|
updatedConfig.env = configUpdates.env;
|
|
481
569
|
}
|
|
482
570
|
else {
|
|
483
571
|
delete updatedConfig.env;
|
|
484
572
|
}
|
|
485
573
|
}
|
|
486
|
-
|
|
487
|
-
|
|
574
|
+
this.agentConfig.mcpServers[unsanitizedServerName] = updatedConfig;
|
|
575
|
+
// Save agent config
|
|
576
|
+
await (0, mcpUtils_1.saveAgentConfig)(this.features.workspace, this.features.logging, this.agentConfig, agentPath);
|
|
577
|
+
}
|
|
488
578
|
const newCfg = {
|
|
489
579
|
...oldCfg,
|
|
490
580
|
...configUpdates,
|
|
491
|
-
__configPath__: configPath,
|
|
492
581
|
};
|
|
493
582
|
const oldClient = this.clients.get(serverName);
|
|
494
583
|
if (oldClient) {
|
|
@@ -498,13 +587,13 @@ class McpManager {
|
|
|
498
587
|
this.mcpTools = this.mcpTools.filter(t => t.serverName !== serverName);
|
|
499
588
|
this.mcpServers.set(serverName, newCfg);
|
|
500
589
|
this.serverNameMapping.set(serverName, unsanitizedServerName);
|
|
501
|
-
if (this.isServerDisabled(serverName)) {
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
590
|
+
// if (this.isServerDisabled(serverName)) {
|
|
591
|
+
// this.setState(serverName, McpServerStatus.DISABLED, 0)
|
|
592
|
+
// this.emitToolsChanged(serverName)
|
|
593
|
+
// } else {
|
|
594
|
+
// await this.initOneServer(serverName, newCfg)
|
|
595
|
+
// }
|
|
596
|
+
await this.initOneServer(serverName, newCfg);
|
|
508
597
|
}
|
|
509
598
|
catch (err) {
|
|
510
599
|
this.handleError(serverName, err);
|
|
@@ -529,6 +618,17 @@ class McpManager {
|
|
|
529
618
|
this.mcpTools = [];
|
|
530
619
|
this.mcpServers.clear();
|
|
531
620
|
this.mcpServerStates.clear();
|
|
621
|
+
this.agentConfig = {
|
|
622
|
+
name: 'default-agent',
|
|
623
|
+
version: '1.0.0',
|
|
624
|
+
description: 'Agent configuration',
|
|
625
|
+
mcpServers: {},
|
|
626
|
+
tools: [],
|
|
627
|
+
allowedTools: [],
|
|
628
|
+
toolsSettings: {},
|
|
629
|
+
includedFiles: [],
|
|
630
|
+
resources: [],
|
|
631
|
+
};
|
|
532
632
|
if (!keepInstance) {
|
|
533
633
|
McpManager.#instance = undefined;
|
|
534
634
|
}
|
|
@@ -559,49 +659,106 @@ class McpManager {
|
|
|
559
659
|
*/
|
|
560
660
|
async updateServerPermission(serverName, perm) {
|
|
561
661
|
try {
|
|
562
|
-
const
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
662
|
+
const unsanitizedServerName = this.serverNameMapping.get(serverName) || serverName;
|
|
663
|
+
// Get server config
|
|
664
|
+
// const serverConfig = this.mcpServers.get(serverName)
|
|
665
|
+
// if (!serverConfig) {
|
|
666
|
+
// throw new Error(`Server '${serverName}' not found`)
|
|
667
|
+
// }
|
|
668
|
+
const serverPrefix = `@${unsanitizedServerName}`;
|
|
669
|
+
// Track tools that should be enabled
|
|
670
|
+
const toolsToEnable = new Set();
|
|
671
|
+
const toolsToAlwaysAllow = new Set();
|
|
672
|
+
// Check if server is enabled as a whole
|
|
673
|
+
const isWholeServerEnabled = this.agentConfig.tools.includes(serverPrefix);
|
|
674
|
+
// Process each tool permission
|
|
675
|
+
for (const [toolName, permission] of Object.entries(perm.toolPerms || {})) {
|
|
676
|
+
const toolId = (unsanitizedServerName !== 'Built-in' ? `${serverPrefix}/` : '') + `${toolName}`;
|
|
677
|
+
if (permission === mcpTypes_1.McpPermissionType.deny) {
|
|
678
|
+
// For deny: if server is enabled as a whole, we need to switch to individual tools
|
|
679
|
+
if (isWholeServerEnabled) {
|
|
680
|
+
// Get all tools for this server
|
|
681
|
+
const serverTools = this.mcpTools.filter(t => t.serverName === serverName);
|
|
682
|
+
// Remove server prefix from tools
|
|
683
|
+
this.agentConfig.tools = this.agentConfig.tools.filter(t => t !== serverPrefix);
|
|
684
|
+
// Add all tools except the denied one
|
|
685
|
+
for (const t of serverTools) {
|
|
686
|
+
if (t.toolName !== toolName) {
|
|
687
|
+
const tid = `${serverPrefix}/${t.toolName}`;
|
|
688
|
+
if (!this.agentConfig.tools.includes(tid)) {
|
|
689
|
+
this.agentConfig.tools.push(tid);
|
|
690
|
+
}
|
|
691
|
+
toolsToEnable.add(tid);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
else {
|
|
696
|
+
// Just remove the specific tool
|
|
697
|
+
this.agentConfig.tools = this.agentConfig.tools.filter(t => t !== toolId);
|
|
698
|
+
}
|
|
699
|
+
// Always remove from allowedTools
|
|
700
|
+
this.agentConfig.allowedTools = this.agentConfig.allowedTools.filter(t => t !== toolId);
|
|
583
701
|
}
|
|
584
702
|
else {
|
|
585
|
-
|
|
703
|
+
// For ask or alwaysAllow: add to tools
|
|
704
|
+
toolsToEnable.add(toolId);
|
|
705
|
+
// For alwaysAllow: also add to allowedTools
|
|
706
|
+
if (permission === mcpTypes_1.McpPermissionType.alwaysAllow) {
|
|
707
|
+
toolsToAlwaysAllow.add(toolId);
|
|
708
|
+
}
|
|
709
|
+
else {
|
|
710
|
+
// For ask: remove from allowedTools if present
|
|
711
|
+
this.agentConfig.allowedTools = this.agentConfig.allowedTools.filter(t => t !== toolId);
|
|
712
|
+
}
|
|
586
713
|
}
|
|
587
|
-
}
|
|
588
|
-
|
|
589
|
-
this.
|
|
590
|
-
//
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
714
|
+
}
|
|
715
|
+
// If all tools are enabled, use @serverName instead of individual tools
|
|
716
|
+
const allTools = this.mcpTools.filter(t => t.serverName === serverName).map(t => t.toolName);
|
|
717
|
+
// Check if all tools are enabled, considering both:
|
|
718
|
+
// 1. The server might already be enabled as a whole (isWholeServerEnabled)
|
|
719
|
+
// 2. All tools might be individually enabled in toolsToEnable
|
|
720
|
+
const allToolsEnabled = allTools.length > 0 &&
|
|
721
|
+
// If server is already enabled as a whole and no tools are being denied
|
|
722
|
+
((isWholeServerEnabled && !Object.values(perm.toolPerms || {}).includes(mcpTypes_1.McpPermissionType.deny)) ||
|
|
723
|
+
// Or if all tools are individually enabled
|
|
724
|
+
allTools.every(toolName => toolsToEnable.has(`${serverPrefix}/${toolName}`) ||
|
|
725
|
+
!Object.keys(perm.toolPerms || {}).includes(toolName)));
|
|
726
|
+
// Update tools list
|
|
727
|
+
if (allToolsEnabled) {
|
|
728
|
+
// Remove individual tool entries
|
|
729
|
+
this.agentConfig.tools = this.agentConfig.tools.filter(t => !t.startsWith(`${serverPrefix}/`));
|
|
730
|
+
// Add server prefix if not already there
|
|
731
|
+
if (!this.agentConfig.tools.includes(serverPrefix)) {
|
|
732
|
+
this.agentConfig.tools.push(serverPrefix);
|
|
596
733
|
}
|
|
597
|
-
this.setState(serverName, mcpTypes_1.McpServerStatus.DISABLED, 0);
|
|
598
734
|
}
|
|
599
735
|
else {
|
|
600
|
-
if
|
|
601
|
-
|
|
736
|
+
// Remove server prefix if present
|
|
737
|
+
this.agentConfig.tools = this.agentConfig.tools.filter(t => t !== serverPrefix);
|
|
738
|
+
// Add individual tools
|
|
739
|
+
for (const toolId of toolsToEnable) {
|
|
740
|
+
if (!this.agentConfig.tools.includes(toolId)) {
|
|
741
|
+
this.agentConfig.tools.push(toolId);
|
|
742
|
+
}
|
|
602
743
|
}
|
|
603
744
|
}
|
|
604
|
-
|
|
745
|
+
// Update allowedTools list
|
|
746
|
+
for (const toolId of toolsToAlwaysAllow) {
|
|
747
|
+
if (!this.agentConfig.allowedTools.includes(toolId)) {
|
|
748
|
+
this.agentConfig.allowedTools.push(toolId);
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
// Save agent config
|
|
752
|
+
const agentPath = perm.__configPath__;
|
|
753
|
+
if (agentPath) {
|
|
754
|
+
await (0, mcpUtils_1.saveAgentConfig)(this.features.workspace, this.features.logging, this.agentConfig, agentPath);
|
|
755
|
+
}
|
|
756
|
+
// Update mcpServerPermissions map
|
|
757
|
+
this.mcpServerPermissions.set(serverName, {
|
|
758
|
+
enabled: perm.enabled,
|
|
759
|
+
toolPerms: perm.toolPerms || {},
|
|
760
|
+
});
|
|
761
|
+
this.features.logging.info(`Permissions updated for '${serverName}' in agent config`);
|
|
605
762
|
this.emitToolsChanged(serverName);
|
|
606
763
|
}
|
|
607
764
|
catch (err) {
|
|
@@ -609,73 +766,13 @@ class McpManager {
|
|
|
609
766
|
return;
|
|
610
767
|
}
|
|
611
768
|
}
|
|
612
|
-
/**
|
|
613
|
-
* Read, mutate, and write the MCP JSON config at the given path.
|
|
614
|
-
* @private
|
|
615
|
-
*/
|
|
616
|
-
async mutateConfigFile(configPath, mutator) {
|
|
617
|
-
return McpManager.configMutex
|
|
618
|
-
.runExclusive(async () => {
|
|
619
|
-
let json = { mcpServers: {} };
|
|
620
|
-
try {
|
|
621
|
-
const raw = await this.features.workspace.fs.readFile(configPath);
|
|
622
|
-
this.features.logging.info(`Updating MCP config file: ${configPath}`);
|
|
623
|
-
const existing = JSON.parse(raw.toString());
|
|
624
|
-
json = { mcpServers: {}, ...existing };
|
|
625
|
-
}
|
|
626
|
-
catch (err) {
|
|
627
|
-
// ignore fire not exist error
|
|
628
|
-
if (err?.code !== 'ENOENT')
|
|
629
|
-
throw err;
|
|
630
|
-
}
|
|
631
|
-
mutator(json);
|
|
632
|
-
let fsPath;
|
|
633
|
-
try {
|
|
634
|
-
const uri = vscode_uri_1.URI.parse(configPath);
|
|
635
|
-
fsPath = uri.scheme === 'file' ? uri.fsPath : configPath;
|
|
636
|
-
}
|
|
637
|
-
catch {
|
|
638
|
-
fsPath = configPath;
|
|
639
|
-
}
|
|
640
|
-
fsPath = path.normalize(fsPath);
|
|
641
|
-
const dir = path.dirname(fsPath);
|
|
642
|
-
await this.features.workspace.fs.mkdir(dir, { recursive: true });
|
|
643
|
-
await this.features.workspace.fs.writeFile(fsPath, JSON.stringify(json, null, 2));
|
|
644
|
-
this.features.logging.debug(`MCP config file write complete: ${configPath}`);
|
|
645
|
-
})
|
|
646
|
-
.catch((e) => {
|
|
647
|
-
this.features.logging.error(`MCP: failed to update config at ${configPath}: ${e.message}`);
|
|
648
|
-
throw e;
|
|
649
|
-
});
|
|
650
|
-
}
|
|
651
|
-
/**
|
|
652
|
-
* Read, mutate, and write the Persona YAML config at the given path.
|
|
653
|
-
* @private
|
|
654
|
-
*/
|
|
655
|
-
async mutatePersonaFile(personaPath, mutator) {
|
|
656
|
-
await McpManager.personaMutex
|
|
657
|
-
.runExclusive(async () => {
|
|
658
|
-
this.features.logging.info(`Updating persona file: ${personaPath}`);
|
|
659
|
-
let raw = '';
|
|
660
|
-
try {
|
|
661
|
-
raw = (await this.features.workspace.fs.readFile(personaPath)).toString();
|
|
662
|
-
}
|
|
663
|
-
catch { }
|
|
664
|
-
const model = mcpTypes_1.PersonaModel.fromJson(raw ? JSON.parse(raw) : {});
|
|
665
|
-
mutator(model);
|
|
666
|
-
await this.features.workspace.fs.writeFile(personaPath, JSON.stringify(model.toJson(), null, 2));
|
|
667
|
-
this.features.logging.debug(`Persona file write complete: ${personaPath}`);
|
|
668
|
-
})
|
|
669
|
-
.catch((e) => {
|
|
670
|
-
this.features.logging.error(`MCP: failed to update persona file at ${personaPath}: ${e.message}`);
|
|
671
|
-
throw e;
|
|
672
|
-
});
|
|
673
|
-
}
|
|
674
769
|
/**
|
|
675
770
|
* Check if a tool requires approval.
|
|
676
771
|
*/
|
|
677
772
|
requiresApproval(server, tool) {
|
|
678
|
-
|
|
773
|
+
// For built-in tools, check directly without prefix
|
|
774
|
+
const toolId = server === 'Built-in' ? tool : `@${server}/${tool}`;
|
|
775
|
+
return !this.agentConfig.allowedTools.includes(toolId);
|
|
679
776
|
}
|
|
680
777
|
/**
|
|
681
778
|
* Updates the runtime state for a given server, including status, tool count, and optional error message.
|
|
@@ -723,7 +820,7 @@ class McpManager {
|
|
|
723
820
|
.join('\n\n');
|
|
724
821
|
}
|
|
725
822
|
/**
|
|
726
|
-
* Remove a server from the config file but keep it in memory.
|
|
823
|
+
* Remove a server from the agent config file but keep it in memory.
|
|
727
824
|
* This is used when there's a server status error during initialization.
|
|
728
825
|
*/
|
|
729
826
|
async removeServerFromConfigFile(serverName) {
|
|
@@ -733,13 +830,41 @@ class McpManager {
|
|
|
733
830
|
this.features.logging.warn(`Cannot remove config for server '${serverName}': Config not found or missing path`);
|
|
734
831
|
return;
|
|
735
832
|
}
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
833
|
+
const unsanitizedName = this.serverNameMapping.get(serverName) || serverName;
|
|
834
|
+
// Remove from agent config
|
|
835
|
+
if (unsanitizedName && this.agentConfig) {
|
|
836
|
+
// Remove server from mcpServers
|
|
837
|
+
delete this.agentConfig.mcpServers[unsanitizedName];
|
|
838
|
+
// Remove server tools from tools list
|
|
839
|
+
this.agentConfig.tools = this.agentConfig.tools.filter(tool => {
|
|
840
|
+
if (tool.startsWith('@')) {
|
|
841
|
+
if (tool === `@${unsanitizedName}`) {
|
|
842
|
+
return false;
|
|
843
|
+
}
|
|
844
|
+
if (tool.startsWith(`@${unsanitizedName}/`)) {
|
|
845
|
+
return false;
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
return true;
|
|
849
|
+
});
|
|
850
|
+
// Remove server tools from allowedTools
|
|
851
|
+
this.agentConfig.allowedTools = this.agentConfig.allowedTools.filter(tool => {
|
|
852
|
+
if (tool.startsWith('@')) {
|
|
853
|
+
if (tool === `@${unsanitizedName}`) {
|
|
854
|
+
return false;
|
|
855
|
+
}
|
|
856
|
+
if (tool.startsWith(`@${unsanitizedName}/`)) {
|
|
857
|
+
return false;
|
|
858
|
+
}
|
|
859
|
+
}
|
|
860
|
+
return true;
|
|
861
|
+
});
|
|
862
|
+
// Save agent config
|
|
863
|
+
await (0, mcpUtils_1.saveAgentConfig)(this.features.workspace, this.features.logging, this.agentConfig, cfg.__configPath__);
|
|
864
|
+
}
|
|
740
865
|
}
|
|
741
866
|
catch (err) {
|
|
742
|
-
this.features.logging.error(`Error removing server '${serverName}' from config file: ${err}`);
|
|
867
|
+
this.features.logging.error(`Error removing server '${serverName}' from agent config file: ${err}`);
|
|
743
868
|
}
|
|
744
869
|
}
|
|
745
870
|
getOriginalToolNames(namespacedName) {
|
|
@@ -751,6 +876,18 @@ class McpManager {
|
|
|
751
876
|
getToolNameMapping() {
|
|
752
877
|
return new Map(this.toolNameMapping);
|
|
753
878
|
}
|
|
879
|
+
/**
|
|
880
|
+
* Determines if a server is global or workspace-specific
|
|
881
|
+
* @param serverName The name of the server to check
|
|
882
|
+
* @returns true if the server is global, false if workspace-specific
|
|
883
|
+
*/
|
|
884
|
+
isServerGlobal(serverName) {
|
|
885
|
+
const config = this.mcpServers.get(serverName);
|
|
886
|
+
if (!config)
|
|
887
|
+
return false;
|
|
888
|
+
const globalAgentPath = (0, mcpUtils_1.getGlobalAgentConfigPath)(this.features.workspace.fs.getUserHomeDir());
|
|
889
|
+
return config.__configPath__ === globalAgentPath;
|
|
890
|
+
}
|
|
754
891
|
setToolNameMapping(mapping) {
|
|
755
892
|
this.toolNameMapping = new Map(mapping);
|
|
756
893
|
}
|