@codingame/monaco-vscode-mcp-service-override 26.2.2 → 27.0.0
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/index.js +8 -2
- package/package.json +2 -2
- package/vscode/src/vs/base/common/jsonRpcProtocol.d.ts +66 -0
- package/vscode/src/vs/base/common/jsonRpcProtocol.js +216 -0
- package/vscode/src/vs/platform/mcp/common/allowedMcpServersService.js +1 -1
- package/vscode/src/vs/platform/mcp/common/mcpGalleryService.js +2 -2
- package/vscode/src/vs/platform/mcp/common/mcpGateway.d.ts +39 -0
- package/vscode/src/vs/platform/mcp/common/mcpGateway.js +6 -0
- package/vscode/src/vs/platform/mcp/common/mcpResourceScannerService.d.ts +2 -1
- package/vscode/src/vs/platform/mcp/common/mcpResourceScannerService.js +12 -6
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcp.contribution.js +15 -5
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpAddContextContribution.js +2 -2
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpCommands.js +58 -58
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpElicitationService.js +27 -28
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpGatewayService.d.ts +18 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpGatewayService.js +34 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpGatewayToolBrokerContribution.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpGatewayToolBrokerContribution.js +15 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpLanguageFeatures.js +18 -18
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpMigration.js +4 -4
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpResourceQuickAccess.js +8 -8
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.d.ts +4 -1
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.js +42 -24
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.js +13 -12
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/extensionMcpDiscovery.js +4 -4
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/installedMcpServersDiscovery.js +2 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.js +1 -1
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/pluginMcpDiscovery.d.ts +15 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/pluginMcpDiscovery.js +106 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpContextKeys.js +4 -4
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpGatewayToolBrokerChannel.d.ts +23 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpGatewayToolBrokerChannel.js +202 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpLanguageModelToolContribution.js +25 -17
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.d.ts +3 -5
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.js +27 -32
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingLog.js +1 -1
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingService.js +11 -11
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSandboxService.d.ts +34 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSandboxService.js +233 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerConnection.js +3 -3
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.d.ts +1 -18
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.js +88 -142
- package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpService.js +9 -9
- package/vscode/src/vs/workbench/services/mcp/browser/mcpWorkbenchManagementService.d.ts +1 -1
- package/vscode/src/vs/workbench/services/mcp/browser/mcpWorkbenchManagementService.js +2 -2
- package/vscode/src/vs/platform/mcp/common/mcpManagementIpc.d.ts +0 -42
- package/vscode/src/vs/platform/mcp/common/mcpManagementIpc.js +0 -105
- package/vscode/src/vs/platform/mcp/common/mcpManagementService.d.ts +0 -130
- package/vscode/src/vs/platform/mcp/common/mcpManagementService.js +0 -665
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerActions.d.ts +0 -259
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerActions.js +0 -1225
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditor.d.ts +0 -72
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditor.js +0 -996
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditorInput.d.ts +0 -17
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditorInput.js +0 -49
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerIcons.d.ts +0 -5
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerIcons.js +0 -12
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerWidgets.d.ts +0 -88
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerWidgets.js +0 -464
- package/vscode/src/vs/workbench/contrib/mcp/browser/media/mcpServerEditor.css +0 -94
- package/vscode/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.d.ts +0 -87
- package/vscode/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.js +0 -702
|
@@ -24,15 +24,15 @@ import { INotificationService } from '@codingame/monaco-vscode-api/vscode/vs/pla
|
|
|
24
24
|
import { observableConfigValue } from '@codingame/monaco-vscode-api/vscode/vs/platform/observable/common/platformObservableUtils';
|
|
25
25
|
import { IQuickInputService } from '@codingame/monaco-vscode-api/vscode/vs/platform/quickinput/common/quickInput.service';
|
|
26
26
|
import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
|
|
27
|
-
import { IWorkspaceTrustManagementService, IWorkspaceTrustRequestService } from '@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspaceTrust.service';
|
|
28
27
|
import { IConfigurationResolverService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/configurationResolver/common/configurationResolver.service';
|
|
29
28
|
import { ConfigurationResolverExpression } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/configurationResolver/common/configurationResolverExpression';
|
|
30
29
|
import { AUX_WINDOW_GROUP } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService';
|
|
31
30
|
import { IEditorService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service';
|
|
32
31
|
import { IMcpDevModeDebugging } from './mcpDevMode.service.js';
|
|
33
32
|
import { McpRegistryInputStorage } from './mcpRegistryInputStorage.js';
|
|
33
|
+
import { IMcpSandboxService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpSandboxService.service';
|
|
34
34
|
import { McpServerConnection } from './mcpServerConnection.js';
|
|
35
|
-
import { LazyCollectionState,
|
|
35
|
+
import { LazyCollectionState, McpServerTrust, UserInteractionRequiredError, McpStartServerInteraction } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
|
|
36
36
|
import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity';
|
|
37
37
|
import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
|
|
38
38
|
import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
|
|
@@ -53,8 +53,7 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
53
53
|
_quickInputService,
|
|
54
54
|
_labelService,
|
|
55
55
|
_logService,
|
|
56
|
-
|
|
57
|
-
_workspaceTrustRequestService
|
|
56
|
+
_mcpSandboxService
|
|
58
57
|
) {
|
|
59
58
|
super();
|
|
60
59
|
this._instantiationService = _instantiationService;
|
|
@@ -65,8 +64,7 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
65
64
|
this._quickInputService = _quickInputService;
|
|
66
65
|
this._labelService = _labelService;
|
|
67
66
|
this._logService = _logService;
|
|
68
|
-
this.
|
|
69
|
-
this._workspaceTrustRequestService = _workspaceTrustRequestService;
|
|
67
|
+
this._mcpSandboxService = _mcpSandboxService;
|
|
70
68
|
this._collections = observableValue("collections", []);
|
|
71
69
|
this._delegates = observableValue("delegates", []);
|
|
72
70
|
this.collections = derived(reader => {
|
|
@@ -220,15 +218,6 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
220
218
|
errorOnUserInteraction = false
|
|
221
219
|
}
|
|
222
220
|
) {
|
|
223
|
-
if (collection.scope === StorageScope.WORKSPACE && !this._workspaceTrustManagementService.isWorkspaceTrusted()) {
|
|
224
|
-
if (errorOnUserInteraction) {
|
|
225
|
-
throw ( new UserInteractionRequiredError("workspaceTrust"));
|
|
226
|
-
} else if (!(await this._workspaceTrustRequestService.requestWorkspaceTrust({
|
|
227
|
-
message: ( localize(9539, "This MCP server definition is defined in your workspace files."))
|
|
228
|
-
}))) {
|
|
229
|
-
return false;
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
221
|
if (collection.trustBehavior === McpServerTrust.Kind.Trusted) {
|
|
233
222
|
this._logService.trace(`MCP server ${definition.id} is trusted, no trust prompt needed`);
|
|
234
223
|
return true;
|
|
@@ -302,7 +291,7 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
302
291
|
const originURI = r.definition.presentation?.origin?.uri || r.collection.presentation?.origin;
|
|
303
292
|
let labelWithOrigin = originURI ? `[\`${r.definition.label}\`](${originURI})` : "`" + r.definition.label + "`";
|
|
304
293
|
if (r.collection.source instanceof ExtensionIdentifier) {
|
|
305
|
-
labelWithOrigin += ` (${( localize(
|
|
294
|
+
labelWithOrigin += ` (${( localize(10243, "from {0}", r.collection.source.value))})`;
|
|
306
295
|
}
|
|
307
296
|
return labelWithOrigin;
|
|
308
297
|
}
|
|
@@ -312,12 +301,12 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
312
301
|
const {
|
|
313
302
|
result
|
|
314
303
|
} = await this._dialogService.prompt({
|
|
315
|
-
message: ( localize(
|
|
304
|
+
message: ( localize(10244, "Trust and run MCP server {0}?", def.definition.label)),
|
|
316
305
|
custom: {
|
|
317
306
|
icon: Codicon.shield,
|
|
318
307
|
markdownDetails: [{
|
|
319
308
|
markdown: ( new MarkdownString(( localize(
|
|
320
|
-
|
|
309
|
+
10245,
|
|
321
310
|
"The MCP server {0} was updated. MCP servers may add context to your chat session and lead to unexpected behavior. Do you want to trust and run this server?",
|
|
322
311
|
labelFor(def)
|
|
323
312
|
)))),
|
|
@@ -330,10 +319,10 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
330
319
|
}]
|
|
331
320
|
},
|
|
332
321
|
buttons: [{
|
|
333
|
-
label: ( localize(
|
|
322
|
+
label: ( localize(10246, "Trust")),
|
|
334
323
|
run: () => true
|
|
335
324
|
}, {
|
|
336
|
-
label: ( localize(
|
|
325
|
+
label: ( localize(10247, "Do not trust")),
|
|
337
326
|
run: () => false
|
|
338
327
|
}]
|
|
339
328
|
});
|
|
@@ -343,12 +332,12 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
343
332
|
const {
|
|
344
333
|
result
|
|
345
334
|
} = await this._dialogService.prompt({
|
|
346
|
-
message: ( localize(
|
|
335
|
+
message: ( localize(10248, "Trust and run {0} MCP servers?", definitions.length)),
|
|
347
336
|
custom: {
|
|
348
337
|
icon: Codicon.shield,
|
|
349
338
|
markdownDetails: [{
|
|
350
339
|
markdown: ( new MarkdownString(( localize(
|
|
351
|
-
|
|
340
|
+
10249,
|
|
352
341
|
"Several updated MCP servers were discovered:\n\n{0}\n\n MCP servers may add context to your chat session and lead to unexpected behavior. Do you want to trust and run these server?",
|
|
353
342
|
list
|
|
354
343
|
)))),
|
|
@@ -361,13 +350,13 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
361
350
|
}]
|
|
362
351
|
},
|
|
363
352
|
buttons: [{
|
|
364
|
-
label: ( localize(
|
|
353
|
+
label: ( localize(10246, "Trust")),
|
|
365
354
|
run: () => "all"
|
|
366
355
|
}, {
|
|
367
|
-
label: ( localize(
|
|
356
|
+
label: ( localize(10250, "Pick Trusted")),
|
|
368
357
|
run: () => "pick"
|
|
369
358
|
}, {
|
|
370
|
-
label: ( localize(
|
|
359
|
+
label: ( localize(10247, "Do not trust")),
|
|
371
360
|
run: () => "none"
|
|
372
361
|
}]
|
|
373
362
|
});
|
|
@@ -423,13 +412,13 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
423
412
|
}
|
|
424
413
|
}));
|
|
425
414
|
return ( new Promise(resolve => {
|
|
426
|
-
picker.onDidAccept(() => {
|
|
415
|
+
store.add(picker.onDidAccept(() => {
|
|
427
416
|
resolve(( picker.selectedItems.map(item => item.definitonId)));
|
|
428
417
|
picker.hide();
|
|
429
|
-
});
|
|
430
|
-
picker.onDidHide(() => {
|
|
418
|
+
}));
|
|
419
|
+
store.add(picker.onDidHide(() => {
|
|
431
420
|
resolve(undefined);
|
|
432
|
-
});
|
|
421
|
+
}));
|
|
433
422
|
picker.show();
|
|
434
423
|
})).finally(() => store.dispose());
|
|
435
424
|
}
|
|
@@ -518,20 +507,26 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
518
507
|
accessor => accessor.get(IMcpDevModeDebugging).transform(definition, launch)
|
|
519
508
|
);
|
|
520
509
|
}
|
|
510
|
+
launch = await this._mcpSandboxService.launchInSandboxIfEnabled(
|
|
511
|
+
definition,
|
|
512
|
+
launch,
|
|
513
|
+
collection.remoteAuthority ?? undefined,
|
|
514
|
+
collection.configTarget
|
|
515
|
+
);
|
|
521
516
|
} catch (e) {
|
|
522
517
|
if (e instanceof UserInteractionRequiredError) {
|
|
523
518
|
throw e;
|
|
524
519
|
}
|
|
525
520
|
this._notificationService.notify({
|
|
526
521
|
severity: Severity.Error,
|
|
527
|
-
message: ( localize(
|
|
522
|
+
message: ( localize(10251, "Error starting {0}: {1}", definition.label, String(e))),
|
|
528
523
|
actions: {
|
|
529
524
|
primary: collection.presentation?.origin && [{
|
|
530
525
|
id: "mcp.launchError.openConfig",
|
|
531
526
|
class: undefined,
|
|
532
527
|
enabled: true,
|
|
533
528
|
tooltip: "",
|
|
534
|
-
label: ( localize(
|
|
529
|
+
label: ( localize(10252, "Open Configuration")),
|
|
535
530
|
run: () => this._editorService.openEditor({
|
|
536
531
|
resource: collection.presentation.origin,
|
|
537
532
|
options: {
|
|
@@ -555,6 +550,6 @@ let McpRegistry = class McpRegistry extends Disposable {
|
|
|
555
550
|
);
|
|
556
551
|
}
|
|
557
552
|
};
|
|
558
|
-
McpRegistry = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, IConfigurationResolverService)), ( __param(2, IDialogService)), ( __param(3, INotificationService)), ( __param(4, IEditorService)), ( __param(5, IConfigurationService)), ( __param(6, IQuickInputService)), ( __param(7, ILabelService)), ( __param(8, ILogService)), ( __param(9,
|
|
553
|
+
McpRegistry = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, IConfigurationResolverService)), ( __param(2, IDialogService)), ( __param(3, INotificationService)), ( __param(4, IEditorService)), ( __param(5, IConfigurationService)), ( __param(6, IQuickInputService)), ( __param(7, ILabelService)), ( __param(8, ILogService)), ( __param(9, IMcpSandboxService))], McpRegistry));
|
|
559
554
|
|
|
560
555
|
export { McpRegistry };
|
|
@@ -41,7 +41,7 @@ let McpSamplingLog = class McpSamplingLog extends Disposable {
|
|
|
41
41
|
}
|
|
42
42
|
const parts = [];
|
|
43
43
|
const total = record.bins.reduce((sum, value) => sum + value, 0);
|
|
44
|
-
parts.push(( localize(
|
|
44
|
+
parts.push(( localize(10253, "{0} total requests in the last 7 days.", total)));
|
|
45
45
|
parts.push(this._formatRecentRequests(record));
|
|
46
46
|
return parts.join("\n");
|
|
47
47
|
}
|
|
@@ -132,11 +132,11 @@ let McpSamplingService = class McpSamplingService extends Disposable {
|
|
|
132
132
|
return this._getMatchingModel(opts);
|
|
133
133
|
}
|
|
134
134
|
const retry = await this._showContextual(opts.isDuringToolCall, ( localize(
|
|
135
|
-
|
|
135
|
+
10254,
|
|
136
136
|
"Allow MCP tools from \"{0}\" to make LLM requests?",
|
|
137
137
|
opts.server.definition.label
|
|
138
138
|
)), ( localize(
|
|
139
|
-
|
|
139
|
+
10255,
|
|
140
140
|
"The MCP server \"{0}\" has issued a request to make a language model call. Do you want to allow it to make requests during chat?",
|
|
141
141
|
opts.server.definition.label
|
|
142
142
|
)), this.allowButtons(opts.server, "allowedDuringChat"));
|
|
@@ -150,11 +150,11 @@ let McpSamplingService = class McpSamplingService extends Disposable {
|
|
|
150
150
|
return this._getMatchingModel(opts);
|
|
151
151
|
}
|
|
152
152
|
const retry = await this._showContextual(opts.isDuringToolCall, ( localize(
|
|
153
|
-
|
|
153
|
+
10256,
|
|
154
154
|
"Allow MCP server \"{0}\" to make LLM requests?",
|
|
155
155
|
opts.server.definition.label
|
|
156
156
|
)), ( localize(
|
|
157
|
-
|
|
157
|
+
10257,
|
|
158
158
|
"The MCP server \"{0}\" has issued a request to make a language model call. Do you want to allow it to make requests, outside of tool calls during chat?",
|
|
159
159
|
opts.server.definition.label
|
|
160
160
|
)), this.allowButtons(opts.server, "allowedOutsideChat"));
|
|
@@ -166,12 +166,12 @@ let McpSamplingService = class McpSamplingService extends Disposable {
|
|
|
166
166
|
throw McpError.notAllowed();
|
|
167
167
|
} else if (model === ModelMatch.NoMatchingModel) {
|
|
168
168
|
const newlyPickedModels = opts.isDuringToolCall ? await this._commandService.executeCommand(McpCommandIds.ConfigureSamplingModels, opts.server) : await this._notify(( localize(
|
|
169
|
-
|
|
169
|
+
10258,
|
|
170
170
|
"MCP server \"{0}\" triggered a language model request, but it has no allowlisted models.",
|
|
171
171
|
opts.server.definition.label
|
|
172
172
|
)), {
|
|
173
|
-
[( localize(
|
|
174
|
-
[( localize(
|
|
173
|
+
[( localize(10259, "Configure"))]: () => this._commandService.executeCommand(McpCommandIds.ConfigureSamplingModels, opts.server),
|
|
174
|
+
[( localize(10260, "Cancel"))]: () => Promise.resolve(undefined)
|
|
175
175
|
});
|
|
176
176
|
if (newlyPickedModels) {
|
|
177
177
|
return this._getMatchingModel(opts);
|
|
@@ -182,19 +182,19 @@ let McpSamplingService = class McpSamplingService extends Disposable {
|
|
|
182
182
|
}
|
|
183
183
|
allowButtons(server, key) {
|
|
184
184
|
return {
|
|
185
|
-
[( localize(
|
|
185
|
+
[( localize(10261, "Allow in this Session"))]: async () => {
|
|
186
186
|
this._sessionSets[key].set(server.definition.id, true);
|
|
187
187
|
return true;
|
|
188
188
|
},
|
|
189
|
-
[( localize(
|
|
189
|
+
[( localize(10262, "Always"))]: async () => {
|
|
190
190
|
await this.updateConfig(server, c => c[key] = true);
|
|
191
191
|
return true;
|
|
192
192
|
},
|
|
193
|
-
[( localize(
|
|
193
|
+
[( localize(10263, "Not Now"))]: async () => {
|
|
194
194
|
this._sessionSets[key].set(server.definition.id, false);
|
|
195
195
|
return false;
|
|
196
196
|
},
|
|
197
|
-
[( localize(
|
|
197
|
+
[( localize(10264, "Never"))]: async () => {
|
|
198
198
|
await this.updateConfig(server, c => c[key] = false);
|
|
199
199
|
return false;
|
|
200
200
|
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { Disposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
|
|
2
|
+
import { ConfigurationTarget } from "@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration";
|
|
3
|
+
import { IEnvironmentService } from "@codingame/monaco-vscode-api/vscode/vs/platform/environment/common/environment.service";
|
|
4
|
+
import { IFileService } from "@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service";
|
|
5
|
+
import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
|
|
6
|
+
import { IRemoteAgentService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/services/remote/common/remoteAgentService.service";
|
|
7
|
+
import { McpServerDefinition, McpServerLaunch } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes";
|
|
8
|
+
import { IMcpSandboxService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpSandboxService.service";
|
|
9
|
+
export declare class McpSandboxService extends Disposable implements IMcpSandboxService {
|
|
10
|
+
private readonly _fileService;
|
|
11
|
+
private readonly _environmentService;
|
|
12
|
+
private readonly _logService;
|
|
13
|
+
private readonly _remoteAgentService;
|
|
14
|
+
readonly _serviceBrand: undefined;
|
|
15
|
+
private _sandboxSettingsId;
|
|
16
|
+
private _remoteEnvDetailsPromise;
|
|
17
|
+
private readonly _defaultAllowedDomains;
|
|
18
|
+
private _sandboxConfigPerConfigurationTarget;
|
|
19
|
+
constructor(_fileService: IFileService, _environmentService: IEnvironmentService, _logService: ILogService, _remoteAgentService: IRemoteAgentService);
|
|
20
|
+
isEnabled(serverDef: McpServerDefinition, remoteAuthority?: string): Promise<boolean>;
|
|
21
|
+
launchInSandboxIfEnabled(serverDef: McpServerDefinition, launch: McpServerLaunch, remoteAuthority: string | undefined, configTarget: ConfigurationTarget): Promise<McpServerLaunch>;
|
|
22
|
+
private _resolveSandboxLaunchDetails;
|
|
23
|
+
private _getExecPath;
|
|
24
|
+
private _getSandboxEnvVariables;
|
|
25
|
+
private _getSandboxCommandArgs;
|
|
26
|
+
private _getRemoteEnv;
|
|
27
|
+
private _getOperatingSystem;
|
|
28
|
+
private _getAppRoot;
|
|
29
|
+
private _getTempDir;
|
|
30
|
+
private _updateSandboxConfig;
|
|
31
|
+
private _withDefaultSandboxConfig;
|
|
32
|
+
private _getDefaultAllowWrite;
|
|
33
|
+
private _pathJoin;
|
|
34
|
+
}
|
|
@@ -0,0 +1,233 @@
|
|
|
1
|
+
|
|
2
|
+
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
|
|
3
|
+
import { VSBuffer } from '@codingame/monaco-vscode-api/vscode/vs/base/common/buffer';
|
|
4
|
+
import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
5
|
+
import { FileAccess } from '@codingame/monaco-vscode-api/vscode/vs/base/common/network';
|
|
6
|
+
import { win32, posix, dirname } from '@codingame/monaco-vscode-api/vscode/vs/base/common/path';
|
|
7
|
+
import { OperatingSystem, OS } from '@codingame/monaco-vscode-api/vscode/vs/base/common/platform';
|
|
8
|
+
import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
|
|
9
|
+
import { generateUuid } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uuid';
|
|
10
|
+
import { ConfigurationTargetToString } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration';
|
|
11
|
+
import { IEnvironmentService } from '@codingame/monaco-vscode-api/vscode/vs/platform/environment/common/environment.service';
|
|
12
|
+
import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
|
|
13
|
+
import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
|
|
14
|
+
import { IRemoteAgentService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/remote/common/remoteAgentService.service';
|
|
15
|
+
import { McpServerTransportType } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
|
|
16
|
+
|
|
17
|
+
let McpSandboxService = class McpSandboxService extends Disposable {
|
|
18
|
+
constructor(_fileService, _environmentService, _logService, _remoteAgentService) {
|
|
19
|
+
super();
|
|
20
|
+
this._fileService = _fileService;
|
|
21
|
+
this._environmentService = _environmentService;
|
|
22
|
+
this._logService = _logService;
|
|
23
|
+
this._remoteAgentService = _remoteAgentService;
|
|
24
|
+
this._defaultAllowedDomains = ["*.npmjs.org"];
|
|
25
|
+
this._sandboxConfigPerConfigurationTarget = ( new Map());
|
|
26
|
+
this._pathJoin = (os, ...segments) => {
|
|
27
|
+
const path = os === OperatingSystem.Windows ? win32 : posix;
|
|
28
|
+
return path.join(...segments);
|
|
29
|
+
};
|
|
30
|
+
this._sandboxSettingsId = generateUuid();
|
|
31
|
+
this._remoteEnvDetailsPromise = this._remoteAgentService.getEnvironment();
|
|
32
|
+
}
|
|
33
|
+
async isEnabled(serverDef, remoteAuthority) {
|
|
34
|
+
const os = await this._getOperatingSystem(remoteAuthority);
|
|
35
|
+
if (os === OperatingSystem.Windows) {
|
|
36
|
+
return false;
|
|
37
|
+
}
|
|
38
|
+
return !!serverDef.sandboxEnabled;
|
|
39
|
+
}
|
|
40
|
+
async launchInSandboxIfEnabled(serverDef, launch, remoteAuthority, configTarget) {
|
|
41
|
+
if (launch.type !== McpServerTransportType.Stdio) {
|
|
42
|
+
return launch;
|
|
43
|
+
}
|
|
44
|
+
if (await this.isEnabled(serverDef, remoteAuthority)) {
|
|
45
|
+
this._logService.trace(`McpSandboxService: Launching with config target ${configTarget}`);
|
|
46
|
+
const launchDetails = await this._resolveSandboxLaunchDetails(configTarget, remoteAuthority, serverDef.sandbox);
|
|
47
|
+
const sandboxArgs = this._getSandboxCommandArgs(launch.command, launch.args, launchDetails.sandboxConfigPath);
|
|
48
|
+
const sandboxEnv = this._getSandboxEnvVariables(launchDetails.tempDir, remoteAuthority);
|
|
49
|
+
if (launchDetails.srtPath) {
|
|
50
|
+
const envWithSandbox = sandboxEnv ? {
|
|
51
|
+
...launch.env,
|
|
52
|
+
...sandboxEnv
|
|
53
|
+
} : launch.env;
|
|
54
|
+
if (launchDetails.execPath) {
|
|
55
|
+
return {
|
|
56
|
+
...launch,
|
|
57
|
+
command: launchDetails.execPath,
|
|
58
|
+
args: [launchDetails.srtPath, ...sandboxArgs],
|
|
59
|
+
env: envWithSandbox,
|
|
60
|
+
type: McpServerTransportType.Stdio
|
|
61
|
+
};
|
|
62
|
+
} else {
|
|
63
|
+
return {
|
|
64
|
+
...launch,
|
|
65
|
+
command: launchDetails.srtPath,
|
|
66
|
+
args: sandboxArgs,
|
|
67
|
+
env: envWithSandbox,
|
|
68
|
+
type: McpServerTransportType.Stdio
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
if (!launchDetails.execPath) {
|
|
73
|
+
this._logService.warn(
|
|
74
|
+
"McpSandboxService: execPath is unavailable, launching without sandbox runtime wrapper"
|
|
75
|
+
);
|
|
76
|
+
}
|
|
77
|
+
this._logService.debug(
|
|
78
|
+
`McpSandboxService: launch details for server ${serverDef.label} - command: ${launch.command}, args: ${launch.args.join(" ")}`
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
return launch;
|
|
82
|
+
}
|
|
83
|
+
async _resolveSandboxLaunchDetails(configTarget, remoteAuthority, sandboxConfig) {
|
|
84
|
+
const os = await this._getOperatingSystem(remoteAuthority);
|
|
85
|
+
if (os === OperatingSystem.Windows) {
|
|
86
|
+
return {
|
|
87
|
+
execPath: undefined,
|
|
88
|
+
srtPath: undefined,
|
|
89
|
+
sandboxConfigPath: undefined,
|
|
90
|
+
tempDir: undefined
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const appRoot = await this._getAppRoot(remoteAuthority);
|
|
94
|
+
const execPath = await this._getExecPath(os, appRoot, remoteAuthority);
|
|
95
|
+
const tempDir = await this._getTempDir(remoteAuthority);
|
|
96
|
+
const srtPath = this._pathJoin(
|
|
97
|
+
os,
|
|
98
|
+
appRoot,
|
|
99
|
+
"node_modules",
|
|
100
|
+
"@anthropic-ai",
|
|
101
|
+
"sandbox-runtime",
|
|
102
|
+
"dist",
|
|
103
|
+
"cli.js"
|
|
104
|
+
);
|
|
105
|
+
const sandboxConfigPath = tempDir ? await this._updateSandboxConfig(tempDir, configTarget, sandboxConfig) : undefined;
|
|
106
|
+
this._logService.debug(`McpSandboxService: Updated sandbox config path: ${sandboxConfigPath}`);
|
|
107
|
+
return {
|
|
108
|
+
execPath,
|
|
109
|
+
srtPath,
|
|
110
|
+
sandboxConfigPath,
|
|
111
|
+
tempDir
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
async _getExecPath(os, appRoot, remoteAuthority) {
|
|
115
|
+
if (remoteAuthority) {
|
|
116
|
+
return this._pathJoin(os, appRoot, "node");
|
|
117
|
+
}
|
|
118
|
+
return undefined;
|
|
119
|
+
}
|
|
120
|
+
_getSandboxEnvVariables(tempDir, remoteAuthority) {
|
|
121
|
+
let env = {};
|
|
122
|
+
if (tempDir) {
|
|
123
|
+
env = {
|
|
124
|
+
TMPDIR: tempDir.path,
|
|
125
|
+
SRT_DEBUG: "true"
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
if (!remoteAuthority) {
|
|
129
|
+
env = {
|
|
130
|
+
...env,
|
|
131
|
+
ELECTRON_RUN_AS_NODE: "1"
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
env["VSCODE_INSPECTOR_OPTIONS"] = null;
|
|
135
|
+
return env;
|
|
136
|
+
}
|
|
137
|
+
_getSandboxCommandArgs(command, args, sandboxConfigPath) {
|
|
138
|
+
const result = [];
|
|
139
|
+
if (sandboxConfigPath) {
|
|
140
|
+
result.push("--settings", sandboxConfigPath);
|
|
141
|
+
}
|
|
142
|
+
result.push(command, ...args);
|
|
143
|
+
return result;
|
|
144
|
+
}
|
|
145
|
+
async _getRemoteEnv(remoteAuthority) {
|
|
146
|
+
if (!remoteAuthority) {
|
|
147
|
+
return null;
|
|
148
|
+
}
|
|
149
|
+
return this._remoteEnvDetailsPromise;
|
|
150
|
+
}
|
|
151
|
+
async _getOperatingSystem(remoteAuthority) {
|
|
152
|
+
const remoteEnv = await this._getRemoteEnv(remoteAuthority);
|
|
153
|
+
if (remoteEnv) {
|
|
154
|
+
return remoteEnv.os;
|
|
155
|
+
}
|
|
156
|
+
return OS;
|
|
157
|
+
}
|
|
158
|
+
async _getAppRoot(remoteAuthority) {
|
|
159
|
+
const remoteEnv = await this._getRemoteEnv(remoteAuthority);
|
|
160
|
+
if (remoteEnv) {
|
|
161
|
+
return remoteEnv.appRoot.path;
|
|
162
|
+
}
|
|
163
|
+
return dirname(( FileAccess.asFileUri("")).path);
|
|
164
|
+
}
|
|
165
|
+
async _getTempDir(remoteAuthority) {
|
|
166
|
+
const remoteEnv = await this._getRemoteEnv(remoteAuthority);
|
|
167
|
+
if (remoteEnv) {
|
|
168
|
+
return remoteEnv.tmpDir;
|
|
169
|
+
}
|
|
170
|
+
const environmentService = this._environmentService;
|
|
171
|
+
const tempDir = environmentService.tmpDir;
|
|
172
|
+
if (!tempDir) {
|
|
173
|
+
this._logService.warn(
|
|
174
|
+
"McpSandboxService: Cannot create sandbox settings file because no tmpDir is available in this environment"
|
|
175
|
+
);
|
|
176
|
+
}
|
|
177
|
+
return tempDir;
|
|
178
|
+
}
|
|
179
|
+
async _updateSandboxConfig(tempDir, configTarget, sandboxConfig) {
|
|
180
|
+
const normalizedSandboxConfig = this._withDefaultSandboxConfig(sandboxConfig);
|
|
181
|
+
let configFileUri;
|
|
182
|
+
const configTargetKey = ConfigurationTargetToString(configTarget);
|
|
183
|
+
if (( this._sandboxConfigPerConfigurationTarget.has(configTargetKey))) {
|
|
184
|
+
configFileUri = ( URI.parse(this._sandboxConfigPerConfigurationTarget.get(configTargetKey)));
|
|
185
|
+
} else {
|
|
186
|
+
configFileUri = URI.joinPath(
|
|
187
|
+
tempDir,
|
|
188
|
+
`vscode-${configTargetKey}-mcp-sandbox-settings-${this._sandboxSettingsId}.json`
|
|
189
|
+
);
|
|
190
|
+
this._sandboxConfigPerConfigurationTarget.set(configTargetKey, ( configFileUri.toString()));
|
|
191
|
+
}
|
|
192
|
+
await this._fileService.createFile(
|
|
193
|
+
configFileUri,
|
|
194
|
+
VSBuffer.fromString(JSON.stringify(normalizedSandboxConfig, null, "\t")),
|
|
195
|
+
{
|
|
196
|
+
overwrite: true
|
|
197
|
+
}
|
|
198
|
+
);
|
|
199
|
+
return configFileUri.path;
|
|
200
|
+
}
|
|
201
|
+
_withDefaultSandboxConfig(sandboxConfig) {
|
|
202
|
+
const mergedAllowWrite = ( new Set(sandboxConfig?.filesystem?.allowWrite ?? []));
|
|
203
|
+
for (const defaultAllowWrite of this._getDefaultAllowWrite()) {
|
|
204
|
+
if (defaultAllowWrite) {
|
|
205
|
+
mergedAllowWrite.add(defaultAllowWrite);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
const mergedAllowedDomains = ( new Set(sandboxConfig?.network?.allowedDomains ?? []));
|
|
209
|
+
for (const defaultAllowedDomain of this._defaultAllowedDomains) {
|
|
210
|
+
if (defaultAllowedDomain) {
|
|
211
|
+
mergedAllowedDomains.add(defaultAllowedDomain);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
return {
|
|
215
|
+
...sandboxConfig,
|
|
216
|
+
network: {
|
|
217
|
+
allowedDomains: [...mergedAllowedDomains],
|
|
218
|
+
deniedDomains: sandboxConfig?.network?.deniedDomains ?? []
|
|
219
|
+
},
|
|
220
|
+
filesystem: {
|
|
221
|
+
allowWrite: [...mergedAllowWrite],
|
|
222
|
+
denyRead: sandboxConfig?.filesystem?.denyRead ?? [],
|
|
223
|
+
denyWrite: sandboxConfig?.filesystem?.denyWrite ?? []
|
|
224
|
+
}
|
|
225
|
+
};
|
|
226
|
+
}
|
|
227
|
+
_getDefaultAllowWrite() {
|
|
228
|
+
return ["~/.npm"];
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
McpSandboxService = ( __decorate([( __param(0, IFileService)), ( __param(1, IEnvironmentService)), ( __param(2, ILogService)), ( __param(3, IRemoteAgentService))], McpSandboxService));
|
|
232
|
+
|
|
233
|
+
export { McpSandboxService };
|
|
@@ -49,7 +49,7 @@ let McpServerConnection = class McpServerConnection extends Disposable {
|
|
|
49
49
|
this._state.set({
|
|
50
50
|
state: McpConnectionState.Kind.Starting
|
|
51
51
|
}, undefined);
|
|
52
|
-
this._logger.info(( localize(
|
|
52
|
+
this._logger.info(( localize(10274, "Starting server {0}", this.definition.label)));
|
|
53
53
|
try {
|
|
54
54
|
const launch = this._delegate.start(this._collection, this.definition, this.launchDefinition, {
|
|
55
55
|
errorOnUserInteraction: this._errorOnUserInteraction
|
|
@@ -82,7 +82,7 @@ let McpServerConnection = class McpServerConnection extends Disposable {
|
|
|
82
82
|
store.add(autorun(reader => {
|
|
83
83
|
const state = launch.state.read(reader);
|
|
84
84
|
this._state.set(state, undefined);
|
|
85
|
-
this._logger.info(( localize(
|
|
85
|
+
this._logger.info(( localize(10275, "Connection state: {0}", (McpConnectionState.toString(state)))));
|
|
86
86
|
if (state.state === McpConnectionState.Kind.Running && !didStart) {
|
|
87
87
|
didStart = true;
|
|
88
88
|
McpServerRequestHandler.create(this._instantiationService, {
|
|
@@ -121,7 +121,7 @@ let McpServerConnection = class McpServerConnection extends Disposable {
|
|
|
121
121
|
};
|
|
122
122
|
}
|
|
123
123
|
async stop() {
|
|
124
|
-
this._logger.info(( localize(
|
|
124
|
+
this._logger.info(( localize(10276, "Stopping server {0}", this.definition.label)));
|
|
125
125
|
this._launch.value?.object.stop();
|
|
126
126
|
await this._waitForState(McpConnectionState.Kind.Stopped, McpConnectionState.Kind.Error);
|
|
127
127
|
}
|
|
@@ -27,8 +27,7 @@ export interface IMcpServerRequestHandlerOptions extends IMcpClientMethods {
|
|
|
27
27
|
* handling of ping requests and typed client request methods.
|
|
28
28
|
*/
|
|
29
29
|
export declare class McpServerRequestHandler extends Disposable {
|
|
30
|
-
private
|
|
31
|
-
private readonly _pendingRequests;
|
|
30
|
+
private readonly _rpc;
|
|
32
31
|
private _hasAnnouncedRoots;
|
|
33
32
|
private _roots;
|
|
34
33
|
set roots(roots: MCP.Root[]);
|
|
@@ -83,18 +82,6 @@ export declare class McpServerRequestHandler extends Disposable {
|
|
|
83
82
|
*/
|
|
84
83
|
private sendRequestPaginated;
|
|
85
84
|
private sendNotification;
|
|
86
|
-
/**
|
|
87
|
-
* Handle incoming messages from the server
|
|
88
|
-
*/
|
|
89
|
-
private handleMessage;
|
|
90
|
-
/**
|
|
91
|
-
* Handle successful responses
|
|
92
|
-
*/
|
|
93
|
-
private handleResult;
|
|
94
|
-
/**
|
|
95
|
-
* Handle error responses
|
|
96
|
-
*/
|
|
97
|
-
private handleError;
|
|
98
85
|
/**
|
|
99
86
|
* Handle incoming server requests
|
|
100
87
|
*/
|
|
@@ -105,10 +92,6 @@ export declare class McpServerRequestHandler extends Disposable {
|
|
|
105
92
|
private handleServerNotification;
|
|
106
93
|
private handleCancelledNotification;
|
|
107
94
|
private handleLoggingNotification;
|
|
108
|
-
/**
|
|
109
|
-
* Send a generic response to a request
|
|
110
|
-
*/
|
|
111
|
-
private respondToRequest;
|
|
112
95
|
/**
|
|
113
96
|
* Send a response to a ping request
|
|
114
97
|
*/
|