@codingame/monaco-vscode-mcp-service-override 28.4.0 → 29.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.
Files changed (35) hide show
  1. package/package.json +2 -2
  2. package/vscode/src/vs/base/common/jsonRpcProtocol.d.ts +13 -1
  3. package/vscode/src/vs/base/common/jsonRpcProtocol.js +26 -13
  4. package/vscode/src/vs/platform/mcp/common/allowedMcpServersService.js +1 -1
  5. package/vscode/src/vs/platform/mcp/common/mcpGalleryManifestService.js +2 -1
  6. package/vscode/src/vs/platform/mcp/common/mcpGalleryService.js +8 -5
  7. package/vscode/src/vs/platform/mcp/common/mcpGateway.d.ts +49 -18
  8. package/vscode/src/vs/workbench/contrib/mcp/browser/mcp.contribution.js +3 -3
  9. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpAddContextContribution.js +2 -2
  10. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpCommands.js +81 -67
  11. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpElicitationService.d.ts +11 -0
  12. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpElicitationService.js +267 -50
  13. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpGatewayService.js +17 -3
  14. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpLanguageFeatures.js +24 -21
  15. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpMigration.js +4 -4
  16. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpResourceQuickAccess.js +8 -8
  17. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.js +18 -18
  18. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.js +37 -9
  19. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/extensionMcpDiscovery.js +4 -4
  20. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.js +1 -1
  21. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/pluginMcpDiscovery.js +11 -3
  22. package/vscode/src/vs/workbench/contrib/mcp/common/mcpContextKeys.js +4 -4
  23. package/vscode/src/vs/workbench/contrib/mcp/common/mcpGatewayToolBrokerChannel.d.ts +8 -9
  24. package/vscode/src/vs/workbench/contrib/mcp/common/mcpGatewayToolBrokerChannel.js +147 -132
  25. package/vscode/src/vs/workbench/contrib/mcp/common/mcpLanguageModelToolContribution.js +10 -6
  26. package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.js +14 -14
  27. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingLog.js +1 -1
  28. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingService.js +11 -11
  29. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSandboxService.d.ts +2 -0
  30. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSandboxService.js +15 -8
  31. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerConnection.js +7 -22
  32. package/vscode/src/vs/workbench/contrib/mcp/common/mcpService.d.ts +4 -1
  33. package/vscode/src/vs/workbench/contrib/mcp/common/mcpService.js +16 -4
  34. package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpService.js +9 -9
  35. package/vscode/src/vs/workbench/services/mcp/browser/mcpGalleryManifestService.js +2 -2
@@ -31,6 +31,7 @@ let McpSandboxService = class McpSandboxService extends Disposable {
31
31
  this._mcpResourceScannerService = _mcpResourceScannerService;
32
32
  this._remoteAgentService = _remoteAgentService;
33
33
  this._defaultAllowedDomains = ["registry.npmjs.org"];
34
+ this._defaultAllowWritePaths = ["~/.npm"];
34
35
  this._sandboxConfigPerConfigurationTarget = ( new Map());
35
36
  this._pathJoin = (os, ...segments) => {
36
37
  const path = os === OperatingSystem.Windows ? win32 : posix;
@@ -57,7 +58,9 @@ let McpSandboxService = class McpSandboxService extends Disposable {
57
58
  if (await this.isEnabled(serverDef, remoteAuthority)) {
58
59
  this._logService.trace(`McpSandboxService: Launching with config target ${configTarget}`);
59
60
  const launchDetails = await this._resolveSandboxLaunchDetails(configTarget, remoteAuthority, launch.sandbox, launch.cwd);
60
- const sandboxArgs = this._getSandboxCommandArgs(launch.command, launch.args, launchDetails.sandboxConfigPath);
61
+ const quotedCommand = this._quoteShellArgument(launch.command);
62
+ const quotedArgs = ( launch.args.map(arg => this._quoteShellArgument(arg)));
63
+ const sandboxArgs = this._getSandboxCommandArgs(quotedCommand, quotedArgs, launchDetails.sandboxConfigPath);
61
64
  const sandboxEnv = await this._getSandboxEnvVariables(launch.env, launchDetails.tempDir, launchDetails.rgPath, remoteAuthority);
62
65
  if (launchDetails.srtPath) {
63
66
  if (launchDetails.execPath) {
@@ -99,11 +102,11 @@ let McpSandboxService = class McpSandboxService extends Disposable {
99
102
  const suggestionLines = [];
100
103
  if (allowedDomainsList.length) {
101
104
  const shown = ( allowedDomainsList.map(domain => `"${domain}"`)).join(", ");
102
- suggestionLines.push(( localize(10452, "Add to `sandbox.network.allowedDomains`: {0}", shown)));
105
+ suggestionLines.push(( localize(10702, "Add to `sandbox.network.allowedDomains`: {0}", shown)));
103
106
  }
104
107
  if (allowWriteList.length) {
105
108
  const shown = ( allowWriteList.map(path => `"${path}"`)).join(", ");
106
- suggestionLines.push(( localize(10453, "Add to `sandbox.filesystem.allowWrite`: {0}", shown)));
109
+ suggestionLines.push(( localize(10703, "Add to `sandbox.filesystem.allowWrite`: {0}", shown)));
107
110
  }
108
111
  const sandboxConfig = {};
109
112
  if (allowedDomainsList.length) {
@@ -118,7 +121,7 @@ let McpSandboxService = class McpSandboxService extends Disposable {
118
121
  }
119
122
  return {
120
123
  message: ( localize(
121
- 10454,
124
+ 10704,
122
125
  "The MCP server {0} reported potential sandbox blocks. VS Code found possible sandbox configuration updates:\n{1}",
123
126
  serverLabel,
124
127
  suggestionLines.join("\n")
@@ -261,7 +264,8 @@ let McpSandboxService = class McpSandboxService extends Disposable {
261
264
  env = {
262
265
  ...env,
263
266
  TMPDIR: tempDir.path,
264
- SRT_DEBUG: "true"
267
+ SRT_DEBUG: "true",
268
+ NODE_USE_ENV_PROXY: "1"
265
269
  };
266
270
  }
267
271
  if (rgPath) {
@@ -283,6 +287,7 @@ let McpSandboxService = class McpSandboxService extends Disposable {
283
287
  const result = [];
284
288
  if (sandboxConfigPath) {
285
289
  result.push("--settings", sandboxConfigPath);
290
+ result.push("--");
286
291
  }
287
292
  result.push(command, ...args);
288
293
  return result;
@@ -370,14 +375,16 @@ let McpSandboxService = class McpSandboxService extends Disposable {
370
375
  };
371
376
  }
372
377
  _getDefaultAllowWrite(directories) {
373
- const defaultAllowWrite = ["~/.npm"];
374
378
  for (const launchCwd of directories ?? []) {
375
379
  const trimmed = launchCwd.trim();
376
380
  if (trimmed) {
377
- defaultAllowWrite.push(trimmed);
381
+ this._defaultAllowWritePaths.push(trimmed);
378
382
  }
379
383
  }
380
- return defaultAllowWrite;
384
+ return this._defaultAllowWritePaths;
385
+ }
386
+ _quoteShellArgument(value) {
387
+ return `'${value.replace(/'/g, `'\\''`)}'`;
381
388
  }
382
389
  };
383
390
  McpSandboxService = ( __decorate([( __param(0, IFileService)), ( __param(1, IEnvironmentService)), ( __param(2, ILogService)), ( __param(3, IMcpResourceScannerService)), ( __param(4, IRemoteAgentService))], McpSandboxService));
@@ -52,7 +52,7 @@ let McpServerConnection = class McpServerConnection extends Disposable {
52
52
  this._state.set({
53
53
  state: McpConnectionState.Kind.Starting
54
54
  }, undefined);
55
- this._logger.info(( localize(10470, "Starting server {0}", this.definition.label)));
55
+ this._logger.info(( localize(10720, "Starting server {0}", this.definition.label)));
56
56
  try {
57
57
  const launch = this._delegate.start(this._collection, this.definition, this.launchDefinition, {
58
58
  errorOnUserInteraction: this._errorOnUserInteraction
@@ -89,7 +89,7 @@ let McpServerConnection = class McpServerConnection extends Disposable {
89
89
  store.add(autorun(reader => {
90
90
  const state = launch.state.read(reader);
91
91
  this._state.set(state, undefined);
92
- this._logger.info(( localize(10471, "Connection state: {0}", (McpConnectionState.toString(state)))));
92
+ this._logger.info(( localize(10721, "Connection state: {0}", (McpConnectionState.toString(state)))));
93
93
  if (state.state === McpConnectionState.Kind.Running && !didStart) {
94
94
  didStart = true;
95
95
  McpServerRequestHandler.create(this._instantiationService, {
@@ -128,7 +128,7 @@ let McpServerConnection = class McpServerConnection extends Disposable {
128
128
  };
129
129
  }
130
130
  async stop() {
131
- this._logger.info(( localize(10472, "Stopping server {0}", this.definition.label)));
131
+ this._logger.info(( localize(10722, "Stopping server {0}", this.definition.label)));
132
132
  this._launch.value?.object.stop();
133
133
  await this._waitForState(McpConnectionState.Kind.Stopped, McpConnectionState.Kind.Error);
134
134
  }
@@ -165,14 +165,7 @@ let McpServerConnection = class McpServerConnection extends Disposable {
165
165
  host: this._extractSandboxHost(message)
166
166
  };
167
167
  }
168
- if (/\b(?:EAI_AGAIN|ENOTFOUND)\b/i.test(message)) {
169
- return {
170
- kind: "network",
171
- message,
172
- host: this._extractSandboxHost(message)
173
- };
174
- }
175
- if (/(?:\b(?:EACCES|EPERM|ENOENT|fail(?:ed|ure)?)\b|not accessible)/i.test(message)) {
168
+ if (/(?:\b(?:EACCES|EPERM|ENOENT|EROFS|fail(?:ed|ure)?)\b|not accessible|read[- ]only)/i.test(message)) {
176
169
  return {
177
170
  kind: "filesystem",
178
171
  message,
@@ -186,7 +179,7 @@ let McpServerConnection = class McpServerConnection extends Disposable {
186
179
  if (bracketedPath?.[1]) {
187
180
  return bracketedPath[1].trim();
188
181
  }
189
- const quotedPath = line.match(/["'](\/[^"']+)["']/);
182
+ const quotedPath = line.match(/["'`](\/[^"'`]+)["'`]/);
190
183
  if (quotedPath?.[1]) {
191
184
  return quotedPath[1];
192
185
  }
@@ -194,16 +187,8 @@ let McpServerConnection = class McpServerConnection extends Disposable {
194
187
  return trailingPath?.[1]?.trim();
195
188
  }
196
189
  _extractSandboxHost(value) {
197
- const deniedMatch = value.match(/No matching config rule, denying:\s+(.+)$/i);
198
- const matchTarget = deniedMatch?.[1] ?? value;
199
- const trimmed = matchTarget.trim().replace(/^["'`]+|["'`,.;]+$/g, "");
200
- if (!trimmed) {
201
- return undefined;
202
- }
203
- const withoutProtocol = trimmed.replace(/^[a-z][a-z0-9+.-]*:\/\//i, "");
204
- const firstToken = withoutProtocol.split(/[\s/]/, 1)[0] ?? "";
205
- const host = firstToken.replace(/:\d+$/, "");
206
- return host || undefined;
190
+ const match = value.match(/No matching config rule, denying:\s+(?<host>[^:\s]+):\d+\.?$/i);
191
+ return match?.groups?.host;
207
192
  }
208
193
  };
209
194
  McpServerConnection = ( __decorate([( __param(7, IInstantiationService))], McpServerConnection));
@@ -4,6 +4,8 @@ import { IObservable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/
4
4
  import { IConfigurationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service";
5
5
  import { IInstantiationService } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
6
6
  import { ILogService } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service";
7
+ import { IStorageService } from "@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service";
8
+ import { EnablementModel } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/enablement";
7
9
  import { IMcpRegistry } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpRegistryTypes.service";
8
10
  import { McpServerMetadataCache } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpServer";
9
11
  import { IAutostartResult, IMcpServer, McpCollectionDefinition } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes";
@@ -21,9 +23,10 @@ export declare class McpService extends Disposable implements IMcpService {
21
23
  state: import("@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes").LazyCollectionState;
22
24
  collections: McpCollectionDefinition[];
23
25
  }>;
26
+ readonly enablementModel: EnablementModel;
24
27
  protected readonly userCache: McpServerMetadataCache;
25
28
  protected readonly workspaceCache: McpServerMetadataCache;
26
- constructor(_instantiationService: IInstantiationService, _mcpRegistry: IMcpRegistry, _logService: ILogService, configurationService: IConfigurationService);
29
+ constructor(_instantiationService: IInstantiationService, _mcpRegistry: IMcpRegistry, _logService: ILogService, configurationService: IConfigurationService, storageService: IStorageService);
27
30
  cancelAutostart(): void;
28
31
  autostart(_token?: CancellationToken): IObservable<IAutostartResult>;
29
32
  private _autostart;
@@ -9,6 +9,8 @@ import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/pl
9
9
  import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
10
10
  import { mcpAutoStartConfig, McpAutoStartValue } from '@codingame/monaco-vscode-api/vscode/vs/platform/mcp/common/mcpManagement';
11
11
  import { StorageScope } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
12
+ import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service';
13
+ import { EnablementModel, isContributionEnabled } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/enablement';
12
14
  import { IMcpRegistry } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpRegistryTypes.service';
13
15
  import { McpServerMetadataCache, McpServer } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpServer';
14
16
  import { IAutostartResult, McpConnectionState, McpServerCacheState, McpStartServerInteraction, UserInteractionRequiredError, McpServerDefinition, McpToolName } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
@@ -21,7 +23,13 @@ let McpService = class McpService extends Disposable {
21
23
  get lazyCollectionState() {
22
24
  return this._mcpRegistry.lazyCollectionState;
23
25
  }
24
- constructor(_instantiationService, _mcpRegistry, _logService, configurationService) {
26
+ constructor(
27
+ _instantiationService,
28
+ _mcpRegistry,
29
+ _logService,
30
+ configurationService,
31
+ storageService
32
+ ) {
25
33
  super();
26
34
  this._instantiationService = _instantiationService;
27
35
  this._mcpRegistry = _mcpRegistry;
@@ -30,6 +38,7 @@ let McpService = class McpService extends Disposable {
30
38
  this._currentAutoStarts = ( new Set());
31
39
  this._servers = observableValue(this, []);
32
40
  this.servers = ( this._servers.map(servers => ( servers.map(s => s.object))));
41
+ this.enablementModel = this._register(( new EnablementModel("mcp.enablement", storageService)));
33
42
  this.userCache = this._register(
34
43
  _instantiationService.createInstance(McpServerMetadataCache, StorageScope.PROFILE)
35
44
  );
@@ -79,7 +88,9 @@ let McpService = class McpService extends Disposable {
79
88
  if (token.isCancellationRequested) {
80
89
  return;
81
90
  }
82
- const candidates = this.servers.get().filter(s => s.connectionState.get().state !== McpConnectionState.Kind.Error);
91
+ const candidates = this.servers.get().filter(
92
+ s => s.connectionState.get().state !== McpConnectionState.Kind.Error && isContributionEnabled(s.enablement.get())
93
+ );
83
94
  let todo = ( new Set());
84
95
  if (autoStartConfig === McpAutoStartValue.OnlyNew) {
85
96
  todo = ( new Set(candidates.filter(s => s.cacheState.get() === McpServerCacheState.Unknown)));
@@ -178,7 +189,8 @@ let McpService = class McpService extends Disposable {
178
189
  def.serverDefinition.roots,
179
190
  !!def.collectionDefinition.lazy,
180
191
  def.collectionDefinition.scope === StorageScope.WORKSPACE ? this.workspaceCache : this.userCache,
181
- def.toolPrefix
192
+ def.toolPrefix,
193
+ this.enablementModel
182
194
  );
183
195
  nextServers.push({
184
196
  object,
@@ -194,7 +206,7 @@ let McpService = class McpService extends Disposable {
194
206
  super.dispose();
195
207
  }
196
208
  };
197
- McpService = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, IMcpRegistry)), ( __param(2, ILogService)), ( __param(3, IConfigurationService))], McpService));
209
+ McpService = ( __decorate([( __param(0, IInstantiationService)), ( __param(1, IMcpRegistry)), ( __param(2, ILogService)), ( __param(3, IConfigurationService)), ( __param(4, IStorageService))], McpService));
198
210
  function defsEqual(server, def) {
199
211
  return server.collection.id === def.collectionDefinition.id && server.definition.id === def.serverDefinition.id;
200
212
  }
@@ -120,7 +120,7 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
120
120
  numberOfRequests += ( Object.keys(accessRequest)).length;
121
121
  });
122
122
  if (numberOfRequests > 0) {
123
- const badge = ( new NumberBadge(numberOfRequests, () => ( localize(15424, "Sign in requested"))));
123
+ const badge = ( new NumberBadge(numberOfRequests, () => ( localize(15720, "Sign in requested"))));
124
124
  this._accountBadgeDisposable.value = this.activityService.showAccountsActivity({
125
125
  badge
126
126
  });
@@ -194,17 +194,17 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
194
194
  } = await this.dialogService.prompt({
195
195
  type: Severity.Info,
196
196
  message: ( localize(
197
- 15425,
197
+ 15721,
198
198
  "The MCP server '{0}' wants to access the {1} account '{2}'.",
199
199
  mcpServerName,
200
200
  provider.label,
201
201
  accountName
202
202
  )),
203
203
  buttons: [{
204
- label: ( localize(15426, "&&Allow")),
204
+ label: ( localize(15722, "&&Allow")),
205
205
  run: () => SessionPromptChoice.Allow
206
206
  }, {
207
- label: ( localize(15427, "&&Deny")),
207
+ label: ( localize(15723, "&&Deny")),
208
208
  run: () => SessionPromptChoice.Deny
209
209
  }],
210
210
  cancelButton: {
@@ -246,17 +246,17 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
246
246
  }
247
247
  });
248
248
  items.push({
249
- label: ( localize(15428, "Sign in to another account"))
249
+ label: ( localize(15724, "Sign in to another account"))
250
250
  });
251
251
  quickPick.items = items;
252
252
  quickPick.title = ( localize(
253
- 15429,
253
+ 15725,
254
254
  "The MCP server '{0}' wants to access a {1} account",
255
255
  mcpServerName,
256
256
  this._authenticationService.getProvider(providerId).label
257
257
  ));
258
258
  quickPick.placeholder = ( localize(
259
- 15430,
259
+ 15726,
260
260
  "Select an account for '{0}' to use or Esc to cancel",
261
261
  mcpServerName
262
262
  ));
@@ -336,7 +336,7 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
336
336
  group: "3_accessRequests",
337
337
  command: {
338
338
  id: `${providerId}${mcpServerId}Access`,
339
- title: ( localize(15431, "Grant access to {0} for {1}... (1)", provider.label, mcpServerName))
339
+ title: ( localize(15727, "Grant access to {0} for {1}... (1)", provider.label, mcpServerName))
340
340
  }
341
341
  }));
342
342
  const accessCommand = CommandsRegistry.registerCommand({
@@ -380,7 +380,7 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
380
380
  group: "2_signInRequests",
381
381
  command: {
382
382
  id: commandId,
383
- title: ( localize(15432, "Sign in with {0} to use {1} (1)", provider.label, mcpServerName))
383
+ title: ( localize(15728, "Sign in with {0} to use {1} (1)", provider.label, mcpServerName))
384
384
  }
385
385
  }));
386
386
  const signInCommand = CommandsRegistry.registerCommand({
@@ -71,9 +71,9 @@ let WorkbenchMcpGalleryManifestService = class WorkbenchMcpGalleryManifestServic
71
71
  }
72
72
  this.mcpGalleryManifest = manifest;
73
73
  if (this.mcpGalleryManifest) {
74
- this.logService.info("MCP Registry configured:", this.mcpGalleryManifest.url);
74
+ this.logService.trace("MCP Registry configured:", this.mcpGalleryManifest.url);
75
75
  } else {
76
- this.logService.info("No MCP Registry configured");
76
+ this.logService.trace("No MCP Registry configured");
77
77
  }
78
78
  this.currentStatus = this.mcpGalleryManifest ? McpGalleryManifestStatus.Available : McpGalleryManifestStatus.Unavailable;
79
79
  this._onDidChangeMcpGalleryManifest.fire(this.mcpGalleryManifest);