@codingame/monaco-vscode-mcp-service-override 17.2.0 → 18.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 (64) hide show
  1. package/index.js +20 -2
  2. package/package.json +14 -5
  3. package/vscode/src/vs/platform/mcp/common/mcpGalleryService.d.ts +26 -0
  4. package/vscode/src/vs/platform/mcp/common/mcpGalleryService.js +170 -0
  5. package/vscode/src/vs/platform/mcp/common/mcpManagementService.d.ts +35 -0
  6. package/vscode/src/vs/platform/mcp/common/mcpManagementService.js +292 -0
  7. package/vscode/src/vs/platform/mcp/common/mcpPlatformTypes.d.ts +65 -0
  8. package/vscode/src/vs/platform/mcp/common/mcpPlatformTypes.js +9 -0
  9. package/vscode/src/vs/workbench/contrib/mcp/browser/mcp.contribution.js +64 -5
  10. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpAddContextContribution.d.ts +12 -0
  11. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpAddContextContribution.js +76 -0
  12. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpDiscovery.js +2 -2
  13. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpLanguageFeatures.js +73 -27
  14. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerActions.d.ts +106 -0
  15. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerActions.js +423 -0
  16. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditor.d.ts +61 -0
  17. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditor.js +542 -0
  18. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditorInput.d.ts +17 -0
  19. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditorInput.js +45 -0
  20. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerWidgets.d.ts +54 -0
  21. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerWidgets.js +272 -0
  22. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.d.ts +24 -0
  23. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.js +193 -0
  24. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.d.ts +56 -0
  25. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.js +176 -0
  26. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/configMcpDiscovery.d.ts +3 -1
  27. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/configMcpDiscovery.js +27 -6
  28. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/extensionMcpDiscovery.js +8 -6
  29. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.d.ts +1 -1
  30. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.js +6 -4
  31. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAdapters.d.ts +1 -1
  32. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAdapters.js +2 -2
  33. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/workspaceMcpDiscoveryAdapter.js +4 -2
  34. package/vscode/src/vs/workbench/contrib/mcp/common/mcpConfigPathsService.js +4 -4
  35. package/vscode/src/vs/workbench/contrib/mcp/common/mcpDevMode.d.ts +23 -0
  36. package/vscode/src/vs/workbench/contrib/mcp/common/mcpDevMode.js +89 -0
  37. package/vscode/src/vs/workbench/contrib/mcp/common/mcpDevMode.service.d.ts +6 -0
  38. package/vscode/src/vs/workbench/contrib/mcp/common/mcpDevMode.service.js +6 -0
  39. package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.d.ts +8 -6
  40. package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.js +30 -47
  41. package/vscode/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.d.ts +35 -0
  42. package/vscode/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.js +206 -0
  43. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingLog.d.ts +26 -0
  44. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingLog.js +110 -0
  45. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingService.d.ts +38 -0
  46. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingService.js +256 -0
  47. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServer.d.ts +29 -13
  48. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServer.js +313 -116
  49. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerConnection.d.ts +2 -2
  50. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerConnection.js +15 -17
  51. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.d.ts +16 -7
  52. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.js +58 -39
  53. package/vscode/src/vs/workbench/contrib/mcp/common/mcpService.d.ts +1 -1
  54. package/vscode/src/vs/workbench/contrib/mcp/common/mcpService.js +109 -46
  55. package/vscode/src/vs/workbench/contrib/mcp/common/uriTemplate.d.ts +25 -0
  56. package/vscode/src/vs/workbench/contrib/mcp/common/uriTemplate.js +296 -0
  57. package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpAccessService.d.ts +27 -0
  58. package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpAccessService.js +73 -0
  59. package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpService.d.ts +51 -0
  60. package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpService.js +391 -0
  61. package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpUsageService.d.ts +27 -0
  62. package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpUsageService.js +105 -0
  63. package/vscode/src/vs/workbench/contrib/mcp/common/modelContextProtocol.d.ts +0 -395
  64. package/vscode/src/vs/workbench/contrib/mcp/common/modelContextProtocol.js +0 -14
@@ -1,10 +1,11 @@
1
1
 
2
2
  import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
- import { Sequencer, raceCancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
4
- import { CancellationTokenSource, CancellationToken } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
3
+ import { raceCancellationError, Sequencer, AsyncIterableObject } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
4
+ import { CancellationToken, CancellationTokenSource } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
5
5
  import { parseTree, findNodeAtOffset, getNodePath } from '@codingame/monaco-vscode-api/vscode/vs/base/common/json';
6
6
  import { Disposable, toDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
7
7
  import { LRUCache } from '@codingame/monaco-vscode-api/vscode/vs/base/common/map';
8
+ import { mapValues } from '@codingame/monaco-vscode-api/vscode/vs/base/common/objects';
8
9
  import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
9
10
  import { basename } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
10
11
  import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
@@ -23,16 +24,21 @@ import { IWorkspaceContextService } from '@codingame/monaco-vscode-api/vscode/vs
23
24
  import { IEditorService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/editor/common/editorService.service';
24
25
  import { IExtensionService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/extensions/common/extensions.service';
25
26
  import { IOutputService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/output/common/output.service';
26
- import { mcpActivationEvent } from '@codingame/monaco-vscode-1cb11a73-359e-5a2f-9e95-6989cc9858ee-common/vscode/vs/workbench/contrib/mcp/common/mcpConfiguration';
27
+ import { mcpActivationEvent } from '@codingame/monaco-vscode-aa9ead53-dfd3-59da-b9e7-f163d201de8d-common/vscode/vs/workbench/contrib/mcp/common/mcpConfiguration';
28
+ import { McpDevModeServerAttache } from './mcpDevMode.js';
27
29
  import { IMcpRegistry } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpRegistryTypes.service';
28
- import { McpConnectionState, McpServerToolsState, extensionMcpCollectionPrefix, McpServerTransportType, McpConnectionFailedError } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
30
+ import { McpConnectionState, McpConnectionFailedError, McpServerCacheState, extensionMcpCollectionPrefix, McpServerTransportType, mcpPromptReplaceSpecialChars, McpCapability, McpToolName, McpResourceURI } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
31
+ import { IMcpSamplingService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes.service';
32
+ import { UriTemplate } from './uriTemplate.js';
29
33
  import Severity from '@codingame/monaco-vscode-api/vscode/vs/base/common/severity';
30
- import { disposableObservableValue, observableValue, transaction } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/base';
31
- import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/derived';
32
- import { observableFromEvent } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/utils';
33
- import { autorunWithStore, autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/autorun';
34
- import { ObservablePromise } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/promise';
34
+ import { observableValue, disposableObservableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
35
+ import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
36
+ import { observableFromEvent } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableFromEvent';
37
+ import { autorun, autorunWithStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
38
+ import { transaction } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/transaction';
39
+ import { ObservablePromise } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/utils/promise';
35
40
 
41
+ var McpServer_1;
36
42
  const toolInvalidCharRe = /[^a-z0-9_-]/gi;
37
43
  let McpServerMetadataCache = class McpServerMetadataCache extends Disposable {
38
44
  constructor(scope, storageService) {
@@ -63,11 +69,11 @@ let McpServerMetadataCache = class McpServerMetadataCache extends Disposable {
63
69
  this.extensionServers.clear();
64
70
  this.didChange = true;
65
71
  }
66
- getTools(definitionId) {
72
+ get(definitionId) {
67
73
  return this.cache.get(definitionId);
68
74
  }
69
- storeTools(definitionId, nonce, tools) {
70
- this.cache.set(definitionId, { ...this.cache.get(definitionId), nonce, tools });
75
+ store(definitionId, entry) {
76
+ this.cache.set(definitionId, entry);
71
77
  this.didChange = true;
72
78
  }
73
79
  getServers(collectionId) {
@@ -86,19 +92,75 @@ let McpServerMetadataCache = class McpServerMetadataCache extends Disposable {
86
92
  McpServerMetadataCache = ( __decorate([
87
93
  ( __param(1, IStorageService))
88
94
  ], McpServerMetadataCache));
89
- let McpServer = class McpServer extends Disposable {
90
- get toolsFromCache() {
91
- return this._toolCache.getTools(this.definition.id);
95
+ class CachedPrimitive {
96
+ constructor(_definitionId, _cache, _fromCache, _toT) {
97
+ this._definitionId = _definitionId;
98
+ this._cache = _cache;
99
+ this._fromCache = _fromCache;
100
+ this._toT = _toT;
101
+ this.fromServerPromise = observableValue(this, undefined);
102
+ this.fromServer = derived(reader => this.fromServerPromise.read(reader)?.promiseResult.read(reader)?.data);
103
+ this.value = derived(reader => {
104
+ const serverTools = this.fromServer.read(reader);
105
+ const definitions = serverTools?.data ?? this.fromCache?.data ?? [];
106
+ return this._toT(definitions, reader);
107
+ });
108
+ }
109
+ get fromCache() {
110
+ const c = this._cache.get(this._definitionId);
111
+ return c ? { data: this._fromCache(c), nonce: c.nonce } : undefined;
112
+ }
113
+ }
114
+ let McpServer = McpServer_1 = class McpServer extends Disposable {
115
+ static async callOn(server, fn, token = CancellationToken.None) {
116
+ await server.start();
117
+ let ranOnce = false;
118
+ let d;
119
+ const callPromise = ( new Promise((resolve, reject) => {
120
+ d = autorun(reader => {
121
+ const connection = server.connection.read(reader);
122
+ if (!connection || ranOnce) {
123
+ return;
124
+ }
125
+ const handler = connection.handler.read(reader);
126
+ if (!handler) {
127
+ const state = connection.state.read(reader);
128
+ if (state.state === McpConnectionState.Kind.Error) {
129
+ reject(( new McpConnectionFailedError(`MCP server could not be started: ${state.message}`)));
130
+ return;
131
+ }
132
+ else if (state.state === McpConnectionState.Kind.Stopped) {
133
+ reject(( new McpConnectionFailedError('MCP server has stopped')));
134
+ return;
135
+ }
136
+ else {
137
+ return;
138
+ }
139
+ }
140
+ resolve(fn(handler));
141
+ ranOnce = true;
142
+ });
143
+ }));
144
+ return raceCancellationError(callPromise, token).finally(() => d.dispose());
145
+ }
146
+ get capabilities() {
147
+ return this._capabilities;
148
+ }
149
+ get tools() {
150
+ return this._tools.value;
151
+ }
152
+ get prompts() {
153
+ return this._prompts.value;
92
154
  }
93
155
  get trusted() {
94
156
  return this._mcpRegistry.getTrust(this.collection);
95
157
  }
96
- constructor(collection, definition, explicitRoots, _requiresExtensionActivation, _toolCache, _mcpRegistry, workspacesService, _extensionService, _loggerService, _outputService, _telemetryService, _commandService, _instantiationService, _notificationService, _openerService) {
158
+ constructor(collection, definition, explicitRoots, _requiresExtensionActivation, _primitiveCache, toolPrefix, _mcpRegistry, workspacesService, _extensionService, _loggerService, _outputService, _telemetryService, _commandService, _instantiationService, _notificationService, _openerService, _samplingService) {
97
159
  super();
98
160
  this.collection = collection;
99
161
  this.definition = definition;
100
162
  this._requiresExtensionActivation = _requiresExtensionActivation;
101
- this._toolCache = _toolCache;
163
+ this._primitiveCache = _primitiveCache;
102
164
  this._mcpRegistry = _mcpRegistry;
103
165
  this._extensionService = _extensionService;
104
166
  this._loggerService = _loggerService;
@@ -108,41 +170,42 @@ let McpServer = class McpServer extends Disposable {
108
170
  this._instantiationService = _instantiationService;
109
171
  this._notificationService = _notificationService;
110
172
  this._openerService = _openerService;
173
+ this._samplingService = _samplingService;
111
174
  this._connectionSequencer = ( new Sequencer());
112
175
  this._connection = this._register(disposableObservableValue(this, undefined));
113
176
  this.connection = this._connection;
114
177
  this.connectionState = derived(reader => this._connection.read(reader)?.state.read(reader) ?? { state: McpConnectionState.Kind.Stopped });
115
- this.toolsFromServerPromise = observableValue(this, undefined);
116
- this.toolsFromServer = derived(reader => this.toolsFromServerPromise.read(reader)?.promiseResult.read(reader)?.data);
117
- this.toolsState = derived(reader => {
118
- const currentNonce = () => this._mcpRegistry.collections.read(reader)
119
- .find(c => c.id === this.collection.id)
120
- ?.serverDefinitions.read(reader)
121
- .find(d => d.id === this.definition.id)
122
- ?.cacheNonce;
178
+ this._capabilities = observableValue('mcpserver.capabilities', undefined);
179
+ this.cacheState = derived(reader => {
180
+ const currentNonce = () => this._fullDefinitions.read(reader)?.server?.cacheNonce;
123
181
  const stateWhenServingFromCache = () => {
124
- if (!this.toolsFromCache) {
125
- return McpServerToolsState.Unknown;
182
+ if (!this._tools.fromCache) {
183
+ return McpServerCacheState.Unknown;
126
184
  }
127
- return currentNonce() === this.toolsFromCache.nonce ? McpServerToolsState.Cached : McpServerToolsState.Outdated;
185
+ return currentNonce() === this._tools.fromCache.nonce ? McpServerCacheState.Cached : McpServerCacheState.Outdated;
128
186
  };
129
- const fromServer = this.toolsFromServerPromise.read(reader);
187
+ const fromServer = this._tools.fromServerPromise.read(reader);
130
188
  const connectionState = this.connectionState.read(reader);
131
- const isIdle = McpConnectionState.canBeStarted(connectionState.state) && !fromServer;
189
+ const isIdle = McpConnectionState.canBeStarted(connectionState.state) || !fromServer;
132
190
  if (isIdle) {
133
191
  return stateWhenServingFromCache();
134
192
  }
135
193
  const fromServerResult = fromServer?.promiseResult.read(reader);
136
194
  if (!fromServerResult) {
137
- return this.toolsFromCache ? McpServerToolsState.RefreshingFromCached : McpServerToolsState.RefreshingFromUnknown;
195
+ return this._tools.fromCache ? McpServerCacheState.RefreshingFromCached : McpServerCacheState.RefreshingFromUnknown;
138
196
  }
139
197
  if (fromServerResult.error) {
140
198
  return stateWhenServingFromCache();
141
199
  }
142
- return fromServerResult.data?.nonce === currentNonce() ? McpServerToolsState.Live : McpServerToolsState.Outdated;
200
+ return fromServerResult.data?.nonce === currentNonce() ? McpServerCacheState.Live : McpServerCacheState.Outdated;
143
201
  });
202
+ this._lastModeDebugged = false;
203
+ this.runningToolCalls = 0;
204
+ this._fullDefinitions = this._mcpRegistry.getServerDefinition(this.collection, this.definition);
144
205
  this._loggerId = `mcpServer.${definition.id}`;
145
206
  this._logger = this._register(_loggerService.createLogger(this._loggerId, { hidden: true, name: `MCP: ${definition.label}` }));
207
+ const that = this;
208
+ this._register(this._instantiationService.createInstance(McpDevModeServerAttache, this, { get lastModeDebugged() { return that._lastModeDebugged; } }));
146
209
  this._register(toDisposable(() => _loggerService.deregisterLogger(this._loggerId)));
147
210
  const workspaces = explicitRoots
148
211
  ? observableValue(this, ( explicitRoots.map(uri => ({ uri, name: basename(uri) }))))
@@ -163,28 +226,56 @@ let McpServer = class McpServer extends Disposable {
163
226
  if (handler) {
164
227
  this.populateLiveData(handler, cnx?.definition.cacheNonce, store);
165
228
  }
166
- else {
229
+ else if (this._tools) {
167
230
  this.resetLiveData();
168
231
  }
169
232
  }));
170
- const toolPrefix = this._mcpRegistry.collectionToolPrefix(this.collection);
171
- this.tools = derived(reader => {
172
- const serverTools = this.toolsFromServer.read(reader);
173
- const definitions = serverTools?.tools ?? this.toolsFromCache?.tools ?? [];
174
- const prefix = toolPrefix.read(reader);
175
- return ( definitions.map(def => ( new McpTool(this, prefix, def)))).sort((a, b) => a.compare(b));
176
- });
233
+ this._tools = ( new CachedPrimitive(
234
+ this.definition.id,
235
+ this._primitiveCache,
236
+ (entry) => entry.tools,
237
+ (entry) => ( entry.map(def => ( new McpTool(this, toolPrefix, def)))).sort((a, b) => a.compare(b))
238
+ ));
239
+ this._prompts = ( new CachedPrimitive(
240
+ this.definition.id,
241
+ this._primitiveCache,
242
+ (entry) => entry.prompts || [],
243
+ (entry) => ( entry.map(e => ( new McpPrompt(this, e))))
244
+ ));
245
+ this._capabilities.set(this._primitiveCache.get(this.definition.id)?.capabilities, undefined);
246
+ }
247
+ readDefinitions() {
248
+ return this._fullDefinitions;
177
249
  }
178
250
  showOutput() {
179
251
  this._loggerService.setVisibility(this._loggerId, true);
180
252
  this._outputService.showChannel(this._loggerId);
181
253
  }
182
- start(isFromInteraction) {
254
+ resources(token) {
255
+ const cts = ( new CancellationTokenSource(token));
256
+ return ( new AsyncIterableObject(async (emitter) => {
257
+ await McpServer_1.callOn(this, async (handler) => {
258
+ for await (const resource of handler.listResourcesIterable({}, cts.token)) {
259
+ emitter.emitOne(( resource.map(r => ( new McpResource(this, r)))));
260
+ if (cts.token.isCancellationRequested) {
261
+ return;
262
+ }
263
+ }
264
+ });
265
+ }, () => cts.dispose(true)));
266
+ }
267
+ resourceTemplates(token) {
268
+ return McpServer_1.callOn(this, async (handler) => {
269
+ const templates = await handler.listResourceTemplates({}, token);
270
+ return ( templates.map(t => ( new McpResourceTemplate(this, t))));
271
+ }, token);
272
+ }
273
+ start({ isFromInteraction, debug } = {}) {
183
274
  return this._connectionSequencer.queue(async () => {
184
275
  const activationEvent = mcpActivationEvent(this.collection.id.slice(extensionMcpCollectionPrefix.length));
185
276
  if (this._requiresExtensionActivation && !this._extensionService.activationEventIsDone(activationEvent)) {
186
277
  await this._extensionService.activateByEvent(activationEvent);
187
- await Promise.all(( this._mcpRegistry.delegates
278
+ await Promise.all(( this._mcpRegistry.delegates.get()
188
279
  .map(r => r.waitForInitialProviderPromises())));
189
280
  if (this._store.isDisposed) {
190
281
  return { state: McpConnectionState.Kind.Stopped };
@@ -197,11 +288,13 @@ let McpServer = class McpServer extends Disposable {
197
288
  this._connection.set(connection, undefined);
198
289
  }
199
290
  if (!connection) {
291
+ this._lastModeDebugged = !!debug;
200
292
  connection = await this._mcpRegistry.resolveConnection({
201
293
  logger: this._logger,
202
294
  collectionRef: this.collection,
203
295
  definitionRef: this.definition,
204
296
  forceTrust: isFromInteraction,
297
+ debug,
205
298
  });
206
299
  if (!connection) {
207
300
  return { state: McpConnectionState.Kind.Stopped };
@@ -212,19 +305,28 @@ let McpServer = class McpServer extends Disposable {
212
305
  }
213
306
  this._connection.set(connection, undefined);
214
307
  }
308
+ if (isFromInteraction && connection.definition.devMode) {
309
+ this.showOutput();
310
+ }
215
311
  const start = Date.now();
216
- const state = await connection.start();
312
+ const state = await connection.start({
313
+ createMessageRequestHandler: params => this._samplingService.sample({
314
+ isDuringToolCall: true,
315
+ server: this,
316
+ params,
317
+ }).then(r => r.sample)
318
+ });
217
319
  this._telemetryService.publicLog2('mcp/serverBootState', {
218
320
  state: McpConnectionState.toKindString(state.state),
219
321
  time: Date.now() - start,
220
322
  });
221
323
  if (state.state === McpConnectionState.Kind.Error && isFromInteraction) {
222
- this.showInteractiveError(connection, state);
324
+ this.showInteractiveError(connection, state, debug);
223
325
  }
224
326
  return state;
225
327
  });
226
328
  }
227
- showInteractiveError(cnx, error) {
329
+ showInteractiveError(cnx, error, debug) {
228
330
  if (error.code === 'ENOENT' && cnx.launchDefinition.type === McpServerTransportType.Stdio) {
229
331
  let docsLink;
230
332
  switch (cnx.launchDefinition.command) {
@@ -236,17 +338,29 @@ let McpServer = class McpServer extends Disposable {
236
338
  break;
237
339
  }
238
340
  const options = [{
239
- label: ( localize(7743, "Show Output")),
341
+ label: ( localize(7968, "Show Output")),
240
342
  run: () => this.showOutput(),
241
343
  }];
344
+ if (cnx.definition.devMode?.debug?.type === 'debugpy' && debug) {
345
+ this._notificationService.prompt(Severity.Error, ( localize(
346
+ 7969,
347
+ 'The command "{0}" was not found. You can specify the path to debugpy in the `dev.debug.debugpyPath` option.',
348
+ cnx.launchDefinition.command,
349
+ cnx.definition.label
350
+ )), [...options, {
351
+ label: ( localize(7970, 'View Docs')),
352
+ run: () => this._openerService.open(( URI.parse('https://aka.ms/vscode-mcp-install/debugpy'))),
353
+ }]);
354
+ return;
355
+ }
242
356
  if (docsLink) {
243
357
  options.push({
244
- label: ( localize(7744, 'Install {0}', cnx.launchDefinition.command)),
358
+ label: ( localize(7971, 'Install {0}', cnx.launchDefinition.command)),
245
359
  run: () => this._openerService.open(( URI.parse(docsLink))),
246
360
  });
247
361
  }
248
362
  this._notificationService.prompt(Severity.Error, ( localize(
249
- 7745,
363
+ 7972,
250
364
  'The command "{0}" needed to run {1} was not found.',
251
365
  cnx.launchDefinition.command,
252
366
  cnx.definition.label
@@ -254,7 +368,7 @@ let McpServer = class McpServer extends Disposable {
254
368
  }
255
369
  else {
256
370
  this._notificationService.warn(( localize(
257
- 7746,
371
+ 7973,
258
372
  'The MCP server {0} could not be started: {1}',
259
373
  cnx.definition.label,
260
374
  error.message
@@ -266,7 +380,8 @@ let McpServer = class McpServer extends Disposable {
266
380
  }
267
381
  resetLiveData() {
268
382
  transaction(tx => {
269
- this.toolsFromServerPromise.set(undefined, tx);
383
+ this._tools.fromServerPromise.set(undefined, tx);
384
+ this._prompts.fromServerPromise.set(undefined, tx);
270
385
  });
271
386
  }
272
387
  async _normalizeTool(originalTool) {
@@ -304,7 +419,7 @@ let McpServer = class McpServer extends Disposable {
304
419
  const validated = [];
305
420
  for (const [i, result] of validations.entries()) {
306
421
  if ('error' in result) {
307
- error += ( localize(7747, 'Tool `{0}` has invalid JSON parameters:', tools[i].name)) + '\n';
422
+ error += ( localize(7974, 'Tool `{0}` has invalid JSON parameters:', tools[i].name)) + '\n';
308
423
  for (const message of result.error) {
309
424
  error += `\t- ${message}\n`;
310
425
  }
@@ -327,93 +442,143 @@ let McpServer = class McpServer extends Disposable {
327
442
  const toolPromise = handler.capabilities.tools ? handler.listTools({}, cts.token) : Promise.resolve([]);
328
443
  const toolPromiseSafe = toolPromise.then(async (tools) => {
329
444
  handler.logger.info(`Discovered ${tools.length} tools`);
330
- return { tools: await this._getValidatedTools(handler, tools), nonce: cacheNonce };
445
+ return { data: await this._getValidatedTools(handler, tools), nonce: cacheNonce };
331
446
  });
332
- this.toolsFromServerPromise.set(( new ObservablePromise(toolPromiseSafe)), tx);
333
- return [toolPromiseSafe];
447
+ this._tools.fromServerPromise.set(( new ObservablePromise(toolPromiseSafe)), tx);
448
+ return toolPromiseSafe;
449
+ };
450
+ const updatePrompts = (tx) => {
451
+ const promptsPromise = handler.capabilities.prompts ? handler.listPrompts({}, cts.token) : Promise.resolve([]);
452
+ const promptsPromiseSafe = promptsPromise.then(data => ({ data, nonce: cacheNonce }));
453
+ this._prompts.fromServerPromise.set(( new ObservablePromise(promptsPromiseSafe)), tx);
454
+ return promptsPromiseSafe;
334
455
  };
335
456
  store.add(handler.onDidChangeToolList(() => {
336
457
  handler.logger.info('Tool list changed, refreshing tools...');
337
458
  updateTools(undefined);
338
459
  }));
339
- let promises;
460
+ store.add(handler.onDidChangePromptList(() => {
461
+ handler.logger.info('Prompts list changed, refreshing prompts...');
462
+ updatePrompts(undefined);
463
+ }));
340
464
  transaction(tx => {
341
- promises = updateTools(tx);
342
- });
343
- Promise.all(promises).then(([{ tools }]) => {
344
- this._toolCache.storeTools(this.definition.id, cacheNonce, tools);
345
- this._telemetryService.publicLog2('mcp/serverBoot', {
346
- supportsLogging: !!handler.capabilities.logging,
347
- supportsPrompts: !!handler.capabilities.prompts,
348
- supportsResources: !!handler.capabilities.resources,
349
- toolCount: tools.length,
350
- serverName: handler.serverInfo.name,
351
- serverVersion: handler.serverInfo.version,
465
+ const capabilities = encodeCapabilities(handler.capabilities);
466
+ this._capabilities.set(capabilities, tx);
467
+ Promise.all([updateTools(tx), updatePrompts(tx)]).then(([{ data: tools }, { data: prompts }]) => {
468
+ this._primitiveCache.store(this.definition.id, {
469
+ nonce: cacheNonce,
470
+ tools,
471
+ prompts,
472
+ capabilities,
473
+ });
474
+ this._telemetryService.publicLog2('mcp/serverBoot', {
475
+ supportsLogging: !!handler.capabilities.logging,
476
+ supportsPrompts: !!handler.capabilities.prompts,
477
+ supportsResources: !!handler.capabilities.resources,
478
+ toolCount: tools.length,
479
+ serverName: handler.serverInfo.name,
480
+ serverVersion: handler.serverInfo.version,
481
+ });
352
482
  });
353
483
  });
354
484
  }
355
- async callOn(fn, token = CancellationToken.None) {
356
- await this.start();
357
- let ranOnce = false;
358
- let d;
359
- const callPromise = ( new Promise((resolve, reject) => {
360
- d = autorun(reader => {
361
- const connection = this._connection.read(reader);
362
- if (!connection || ranOnce) {
363
- return;
364
- }
365
- const handler = connection.handler.read(reader);
366
- if (!handler) {
367
- const state = connection.state.read(reader);
368
- if (state.state === McpConnectionState.Kind.Error) {
369
- reject(( new McpConnectionFailedError(`MCP server could not be started: ${state.message}`)));
370
- return;
371
- }
372
- else if (state.state === McpConnectionState.Kind.Stopped) {
373
- reject(( new McpConnectionFailedError('MCP server has stopped')));
374
- return;
375
- }
376
- else {
377
- return;
378
- }
379
- }
380
- resolve(fn(handler));
381
- ranOnce = true;
382
- });
383
- }));
384
- return raceCancellationError(callPromise, token).finally(() => d.dispose());
385
- }
386
485
  };
387
- McpServer = ( __decorate([
388
- ( __param(5, IMcpRegistry)),
389
- ( __param(6, IWorkspaceContextService)),
390
- ( __param(7, IExtensionService)),
391
- ( __param(8, ILoggerService)),
392
- ( __param(9, IOutputService)),
393
- ( __param(10, ITelemetryService)),
394
- ( __param(11, ICommandService)),
395
- ( __param(12, IInstantiationService)),
396
- ( __param(13, INotificationService)),
397
- ( __param(14, IOpenerService))
486
+ McpServer = McpServer_1 = ( __decorate([
487
+ ( __param(6, IMcpRegistry)),
488
+ ( __param(7, IWorkspaceContextService)),
489
+ ( __param(8, IExtensionService)),
490
+ ( __param(9, ILoggerService)),
491
+ ( __param(10, IOutputService)),
492
+ ( __param(11, ITelemetryService)),
493
+ ( __param(12, ICommandService)),
494
+ ( __param(13, IInstantiationService)),
495
+ ( __param(14, INotificationService)),
496
+ ( __param(15, IOpenerService)),
497
+ ( __param(16, IMcpSamplingService))
398
498
  ], McpServer));
499
+ class McpPrompt {
500
+ constructor(_server, _definition) {
501
+ this._server = _server;
502
+ this._definition = _definition;
503
+ this.id = mcpPromptReplaceSpecialChars(this._server.definition.label + '.' + _definition.name);
504
+ this.name = _definition.name;
505
+ this.description = _definition.description;
506
+ this.arguments = _definition.arguments || [];
507
+ }
508
+ async resolve(args, token) {
509
+ const result = await McpServer.callOn(this._server, h => h.getPrompt({ name: this._definition.name, arguments: args }, token), token);
510
+ return result.messages;
511
+ }
512
+ async complete(argument, prefix, token) {
513
+ const result = await McpServer.callOn(this._server, h => h.complete({
514
+ ref: { type: 'ref/prompt', name: this._definition.name },
515
+ argument: { name: argument, value: prefix, }
516
+ }, token), token);
517
+ return result.completion.values;
518
+ }
519
+ }
520
+ function encodeCapabilities(cap) {
521
+ let out = 0;
522
+ if (cap.logging) {
523
+ out |= McpCapability.Logging;
524
+ }
525
+ if (cap.completions) {
526
+ out |= McpCapability.Completions;
527
+ }
528
+ if (cap.prompts) {
529
+ out |= McpCapability.Prompts;
530
+ if (cap.prompts.listChanged) {
531
+ out |= McpCapability.PromptsListChanged;
532
+ }
533
+ }
534
+ if (cap.resources) {
535
+ out |= McpCapability.Resources;
536
+ if (cap.resources.subscribe) {
537
+ out |= McpCapability.ResourcesSubscribe;
538
+ }
539
+ if (cap.resources.listChanged) {
540
+ out |= McpCapability.ResourcesListChanged;
541
+ }
542
+ }
543
+ if (cap.tools) {
544
+ out |= McpCapability.Tools;
545
+ if (cap.tools.listChanged) {
546
+ out |= McpCapability.ToolsListChanged;
547
+ }
548
+ }
549
+ return out;
550
+ }
399
551
  class McpTool {
400
552
  get definition() { return this._definition; }
401
553
  constructor(_server, idPrefix, _definition) {
402
554
  this._server = _server;
403
555
  this._definition = _definition;
404
- this.id = (idPrefix + _definition.name).replaceAll('.', '_');
556
+ this.referenceName = _definition.name.replaceAll('.', '_');
557
+ this.id = (idPrefix + _definition.name).replaceAll('.', '_').slice(0, McpToolName.MaxLength);
405
558
  }
406
- call(params, token) {
559
+ async call(params, token) {
407
560
  const name = this._definition.serverToolName ?? this._definition.name;
408
- return this._server.callOn(h => h.callTool({ name, arguments: params }, token), token);
561
+ this._server.runningToolCalls++;
562
+ try {
563
+ return await McpServer.callOn(this._server, h => h.callTool({ name, arguments: params }, token), token);
564
+ }
565
+ finally {
566
+ this._server.runningToolCalls--;
567
+ }
409
568
  }
410
- callWithProgress(params, progress, token) {
411
- return this._callWithProgress(params, progress, token);
569
+ async callWithProgress(params, progress, token) {
570
+ this._server.runningToolCalls++;
571
+ try {
572
+ return await this._callWithProgress(params, progress, token);
573
+ }
574
+ finally {
575
+ this._server.runningToolCalls--;
576
+ }
412
577
  }
413
578
  _callWithProgress(params, progress, token, allowRetry = true) {
414
579
  const name = this._definition.serverToolName ?? this._definition.name;
415
580
  const progressToken = generateUuid();
416
- return this._server.callOn(h => {
581
+ return McpServer.callOn(this._server, h => {
417
582
  let lastProgressN = 0;
418
583
  const listener = h.onDidReceiveProgressNotification((e) => {
419
584
  if (e.params.progressToken === progressToken) {
@@ -449,7 +614,7 @@ function warnInvalidTools(instaService, serverName, errorText) {
449
614
  notificationService.notify({
450
615
  severity: Severity.Warning,
451
616
  message: ( localize(
452
- 7748,
617
+ 7975,
453
618
  'MCP server `{0}` has tools with invalid parameters which will be omitted.',
454
619
  serverName
455
620
  )),
@@ -459,7 +624,7 @@ function warnInvalidTools(instaService, serverName, errorText) {
459
624
  enabled: true,
460
625
  id: 'mcpBadSchema.show',
461
626
  tooltip: '',
462
- label: ( localize(7749, 'Show')),
627
+ label: ( localize(7976, 'Show')),
463
628
  run: () => {
464
629
  editorService.openEditor({
465
630
  resource: undefined,
@@ -471,5 +636,37 @@ function warnInvalidTools(instaService, serverName, errorText) {
471
636
  });
472
637
  });
473
638
  }
639
+ class McpResource {
640
+ constructor(server, original) {
641
+ this.mcpUri = original.uri;
642
+ this.uri = McpResourceURI.fromServer(server.definition, original.uri);
643
+ this.name = original.name;
644
+ this.description = original.description;
645
+ this.mimeType = original.mimeType;
646
+ this.sizeInBytes = original.size;
647
+ }
648
+ }
649
+ class McpResourceTemplate {
650
+ constructor(_server, _definition) {
651
+ this._server = _server;
652
+ this._definition = _definition;
653
+ this.name = _definition.name;
654
+ this.description = _definition.description;
655
+ this.mimeType = _definition.mimeType;
656
+ this.template = UriTemplate.parse(_definition.uriTemplate);
657
+ }
658
+ resolveURI(vars) {
659
+ const serverUri = this.template.resolve(vars);
660
+ return McpResourceURI.fromServer(this._server.definition, serverUri);
661
+ }
662
+ async complete(templatePart, prefix, alreadyResolved, token) {
663
+ const result = await McpServer.callOn(this._server, h => h.complete({
664
+ ref: { type: 'ref/resource', uri: this._definition.uriTemplate },
665
+ argument: { name: templatePart, value: prefix },
666
+ resolved: mapValues(alreadyResolved, v => Array.isArray(v) ? v.join('/') : v),
667
+ }, token), token);
668
+ return result.completion.values;
669
+ }
670
+ }
474
671
 
475
672
  export { McpServer, McpServerMetadataCache, McpTool };
@@ -4,7 +4,7 @@ import { IInstantiationService } from "@codingame/monaco-vscode-api/vscode/vs/pl
4
4
  import { ILogger } from "@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log";
5
5
  import { IMcpHostDelegate } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpRegistryTypes";
6
6
  import { McpServerRequestHandler } from "./mcpServerRequestHandler.js";
7
- import { IMcpServerConnection, McpCollectionDefinition, McpConnectionState, McpServerDefinition, McpServerLaunch } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes";
7
+ import { IMcpClientMethods, IMcpServerConnection, McpCollectionDefinition, McpConnectionState, McpServerDefinition, McpServerLaunch } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes";
8
8
  export declare class McpServerConnection extends Disposable implements IMcpServerConnection {
9
9
  private readonly _collection;
10
10
  readonly definition: McpServerDefinition;
@@ -18,7 +18,7 @@ export declare class McpServerConnection extends Disposable implements IMcpServe
18
18
  readonly state: IObservable<McpConnectionState>;
19
19
  readonly handler: IObservable<McpServerRequestHandler | undefined>;
20
20
  constructor(_collection: McpCollectionDefinition, definition: McpServerDefinition, _delegate: IMcpHostDelegate, launchDefinition: McpServerLaunch, _logger: ILogger, _instantiationService: IInstantiationService);
21
- start(): Promise<McpConnectionState>;
21
+ start(methods: IMcpClientMethods): Promise<McpConnectionState>;
22
22
  private adoptLaunch;
23
23
  stop(): Promise<void>;
24
24
  dispose(): void;