@codingame/monaco-vscode-mcp-service-override 23.2.2 → 24.1.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 (67) hide show
  1. package/index.js +19 -19
  2. package/package.json +2 -15
  3. package/vscode/src/vs/platform/mcp/common/allowedMcpServersService.d.ts +1 -1
  4. package/vscode/src/vs/platform/mcp/common/allowedMcpServersService.js +2 -2
  5. package/vscode/src/vs/platform/mcp/common/mcpGalleryService.d.ts +2 -2
  6. package/vscode/src/vs/platform/mcp/common/mcpGalleryService.js +4 -8
  7. package/vscode/src/vs/platform/mcp/common/mcpManagementIpc.d.ts +2 -2
  8. package/vscode/src/vs/platform/mcp/common/mcpManagementService.d.ts +2 -2
  9. package/vscode/src/vs/platform/mcp/common/mcpManagementService.js +3 -3
  10. package/vscode/src/vs/platform/mcp/common/mcpResourceScannerService.d.ts +2 -2
  11. package/vscode/src/vs/platform/mcp/common/mcpResourceScannerService.js +1 -1
  12. package/vscode/src/vs/workbench/contrib/mcp/browser/mcp.contribution.js +8 -8
  13. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpAddContextContribution.d.ts +3 -2
  14. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpAddContextContribution.js +43 -27
  15. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpCommands.js +70 -70
  16. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpDiscovery.js +1 -1
  17. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpElicitationService.d.ts +10 -4
  18. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpElicitationService.js +198 -35
  19. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpLanguageFeatures.js +21 -21
  20. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpMigration.js +9 -9
  21. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpResourceQuickAccess.d.ts +24 -5
  22. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpResourceQuickAccess.js +178 -51
  23. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerActions.d.ts +1 -1
  24. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerActions.js +35 -35
  25. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditor.d.ts +2 -2
  26. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditor.js +37 -37
  27. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditorInput.js +2 -2
  28. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerIcons.js +5 -5
  29. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerWidgets.d.ts +1 -1
  30. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerWidgets.js +7 -7
  31. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.d.ts +3 -3
  32. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.js +26 -26
  33. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.d.ts +3 -3
  34. package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.js +12 -12
  35. package/vscode/src/vs/workbench/contrib/mcp/browser/openPanelChatAndGetWidget.d.ts +1 -1
  36. package/vscode/src/vs/workbench/contrib/mcp/browser/openPanelChatAndGetWidget.js +1 -1
  37. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/extensionMcpDiscovery.js +5 -5
  38. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/installedMcpServersDiscovery.js +1 -1
  39. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.d.ts +1 -1
  40. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.js +2 -2
  41. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAdapters.d.ts +1 -1
  42. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAdapters.js +1 -1
  43. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpRemoteDiscovery.js +1 -1
  44. package/vscode/src/vs/workbench/contrib/mcp/common/discovery/workspaceMcpDiscoveryAdapter.js +1 -1
  45. package/vscode/src/vs/workbench/contrib/mcp/common/mcpContextKeys.js +4 -4
  46. package/vscode/src/vs/workbench/contrib/mcp/common/mcpDevMode.js +4 -2
  47. package/vscode/src/vs/workbench/contrib/mcp/common/mcpLanguageModelToolContribution.js +20 -14
  48. package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.js +14 -14
  49. package/vscode/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.d.ts +3 -1
  50. package/vscode/src/vs/workbench/contrib/mcp/common/mcpResourceFilesystem.js +19 -3
  51. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingLog.js +2 -2
  52. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingService.d.ts +1 -1
  53. package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingService.js +21 -20
  54. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServer.d.ts +6 -2
  55. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServer.js +79 -47
  56. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerConnection.d.ts +3 -1
  57. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerConnection.js +8 -6
  58. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.d.ts +47 -2
  59. package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerRequestHandler.js +229 -14
  60. package/vscode/src/vs/workbench/contrib/mcp/common/mcpService.js +2 -2
  61. package/vscode/src/vs/workbench/contrib/mcp/common/mcpTaskManager.d.ts +68 -0
  62. package/vscode/src/vs/workbench/contrib/mcp/common/mcpTaskManager.js +168 -0
  63. package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpService.js +10 -10
  64. package/vscode/src/vs/workbench/services/mcp/browser/mcpGalleryManifestService.d.ts +17 -2
  65. package/vscode/src/vs/workbench/services/mcp/browser/mcpGalleryManifestService.js +60 -10
  66. package/vscode/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.d.ts +1 -1
  67. package/vscode/src/vs/workbench/services/mcp/common/mcpWorkbenchManagementService.js +2 -2
@@ -1,18 +1,22 @@
1
1
 
2
2
  import { equals } from '@codingame/monaco-vscode-api/vscode/vs/base/common/arrays';
3
3
  import { assertNever } from '@codingame/monaco-vscode-api/vscode/vs/base/common/assert';
4
- import { IntervalTimer, DeferredPromise } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
5
- import { CancellationToken } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
4
+ import { IntervalTimer, DeferredPromise, disposableTimeout } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
5
+ import { CancellationToken, CancellationTokenSource } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
6
6
  import { CancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
7
7
  import { Emitter } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
8
8
  import { Iterable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/iterator';
9
- import { Disposable, DisposableStore } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
9
+ import { Disposable, DisposableStore, toDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
10
10
  import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
11
11
  import { LogLevel, canLog, log } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log';
12
12
  import { IProductService } from '@codingame/monaco-vscode-api/vscode/vs/platform/product/common/productService.service';
13
13
  import { McpConnectionState, MpcResponseError, McpError } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
14
+ import { isTaskResult } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypesUtils';
14
15
  import { MCP } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/modelContextProtocol';
15
16
  import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
17
+ import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
18
+ import { transaction } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/transaction';
19
+ import { ObservablePromise } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/utils/promise';
16
20
 
17
21
  class McpServerRequestHandler extends Disposable {
18
22
  set roots(roots) {
@@ -50,7 +54,15 @@ class McpServerRequestHandler extends Disposable {
50
54
  capabilities: {
51
55
  roots: { listChanged: true },
52
56
  sampling: opts.createMessageRequestHandler ? {} : undefined,
53
- elicitation: opts.elicitationRequestHandler ? {} : undefined,
57
+ elicitation: opts.elicitationRequestHandler ? { form: {}, url: {} } : undefined,
58
+ tasks: {
59
+ list: {},
60
+ cancel: {},
61
+ requests: {
62
+ sampling: opts.createMessageRequestHandler ? { createMessage: {} } : undefined,
63
+ elicitation: opts.elicitationRequestHandler ? { create: {} } : undefined,
64
+ },
65
+ },
54
66
  },
55
67
  clientInfo: {
56
68
  name: productService.nameLong,
@@ -74,7 +86,7 @@ class McpServerRequestHandler extends Disposable {
74
86
  store.dispose();
75
87
  }
76
88
  }
77
- constructor({ launch, logger, createMessageRequestHandler, elicitationRequestHandler, requestLogLevel = LogLevel.Debug, }) {
89
+ constructor({ launch, logger, createMessageRequestHandler, elicitationRequestHandler, requestLogLevel = LogLevel.Debug, taskManager, }) {
78
90
  super();
79
91
  this._nextRequestId = 1;
80
92
  this._pendingRequests = ( new Map());
@@ -84,6 +96,8 @@ class McpServerRequestHandler extends Disposable {
84
96
  this.onDidReceiveCancelledNotification = this._onDidReceiveCancelledNotification.event;
85
97
  this._onDidReceiveProgressNotification = this._register(( new Emitter()));
86
98
  this.onDidReceiveProgressNotification = this._onDidReceiveProgressNotification.event;
99
+ this._onDidReceiveElicitationCompleteNotification = this._register(( new Emitter()));
100
+ this.onDidReceiveElicitationCompleteNotification = this._onDidReceiveElicitationCompleteNotification.event;
87
101
  this._onDidChangeResourceList = this._register(( new Emitter()));
88
102
  this.onDidChangeResourceList = this._onDidChangeResourceList.event;
89
103
  this._onDidUpdateResource = this._register(( new Emitter()));
@@ -97,6 +111,16 @@ class McpServerRequestHandler extends Disposable {
97
111
  this._requestLogLevel = requestLogLevel;
98
112
  this._createMessageRequestHandler = createMessageRequestHandler;
99
113
  this._elicitationRequestHandler = elicitationRequestHandler;
114
+ this._taskManager = taskManager;
115
+ this._taskManager.setHandler(this);
116
+ this._register(this._taskManager.onDidUpdateTask(task => {
117
+ this.send({
118
+ jsonrpc: MCP.JSONRPC_VERSION,
119
+ method: 'notifications/tasks/status',
120
+ params: task
121
+ });
122
+ }));
123
+ this._register(toDisposable(() => this._taskManager.setHandler(undefined)));
100
124
  this._register(launch.onDidReceiveMessage(message => this.handleMessage(message)));
101
125
  this._register(autorun(reader => {
102
126
  const state = launch.state.read(reader).state;
@@ -201,10 +225,38 @@ class McpServerRequestHandler extends Disposable {
201
225
  response = this.handleRootsList(request);
202
226
  }
203
227
  else if (request.method === 'sampling/createMessage' && this._createMessageRequestHandler) {
204
- response = await this._createMessageRequestHandler(request.params);
228
+ if (request.params.task) {
229
+ const taskResult = this._taskManager.createTask(request.params.task.ttl ?? null, (token) => this._createMessageRequestHandler(request.params, token));
230
+ taskResult._meta ??= {};
231
+ taskResult._meta['io.modelcontextprotocol/related-task'] = { taskId: taskResult.task.taskId };
232
+ response = taskResult;
233
+ }
234
+ else {
235
+ response = await this._createMessageRequestHandler(request.params);
236
+ }
205
237
  }
206
238
  else if (request.method === 'elicitation/create' && this._elicitationRequestHandler) {
207
- response = await this._elicitationRequestHandler(request.params);
239
+ if (request.params.task) {
240
+ const taskResult = this._taskManager.createTask(request.params.task.ttl ?? null, (token) => this._elicitationRequestHandler(request.params, token));
241
+ taskResult._meta ??= {};
242
+ taskResult._meta['io.modelcontextprotocol/related-task'] = { taskId: taskResult.task.taskId };
243
+ response = taskResult;
244
+ }
245
+ else {
246
+ response = await this._elicitationRequestHandler(request.params);
247
+ }
248
+ }
249
+ else if (request.method === 'tasks/get') {
250
+ response = this._taskManager.getTask(request.params.taskId);
251
+ }
252
+ else if (request.method === 'tasks/result') {
253
+ response = await this._taskManager.getTaskResult(request.params.taskId);
254
+ }
255
+ else if (request.method === 'tasks/cancel') {
256
+ response = this._taskManager.cancelTask(request.params.taskId);
257
+ }
258
+ else if (request.method === 'tasks/list') {
259
+ response = this._taskManager.listTasks();
208
260
  }
209
261
  else {
210
262
  throw McpError.methodNotFound(request.method);
@@ -250,13 +302,21 @@ class McpServerRequestHandler extends Disposable {
250
302
  case 'notifications/prompts/list_changed':
251
303
  this._onDidChangePromptList.fire();
252
304
  return;
305
+ case 'notifications/elicitation/complete':
306
+ this._onDidReceiveElicitationCompleteNotification.fire(request);
307
+ return;
308
+ case 'notifications/tasks/status':
309
+ this._taskManager.getClientTask(request.params.taskId)?.onDidUpdateState(request.params);
310
+ return;
253
311
  }
254
312
  }
255
313
  handleCancelledNotification(request) {
256
- const pendingRequest = this._pendingRequests.get(request.params.requestId);
257
- if (pendingRequest) {
258
- this._pendingRequests.delete(request.params.requestId);
259
- pendingRequest.promise.cancel();
314
+ if (request.params.requestId) {
315
+ const pendingRequest = this._pendingRequests.get(request.params.requestId);
316
+ if (pendingRequest) {
317
+ this._pendingRequests.delete(request.params.requestId);
318
+ pendingRequest.promise.cancel();
319
+ }
260
320
  }
261
321
  }
262
322
  handleLoggingNotification(request) {
@@ -350,8 +410,17 @@ class McpServerRequestHandler extends Disposable {
350
410
  listTools(params, token) {
351
411
  return Iterable.asyncToArrayFlat(this.sendRequestPaginated('tools/list', result => result.tools, params, token));
352
412
  }
353
- callTool(params, token) {
354
- return this.sendRequest({ method: 'tools/call', params }, token);
413
+ async callTool(params, token) {
414
+ const response = await this.sendRequest({ method: 'tools/call', params }, token);
415
+ if (isTaskResult(response)) {
416
+ const task = ( new McpTask(response.task, token));
417
+ this._taskManager.adoptClientTask(task);
418
+ task.setHandler(this);
419
+ return task.result.finally(() => {
420
+ this._taskManager.abandonClientTask(task.id);
421
+ });
422
+ }
423
+ return response;
355
424
  }
356
425
  setLevel(params, token) {
357
426
  return this.sendRequest({ method: 'logging/setLevel', params }, token);
@@ -359,6 +428,152 @@ class McpServerRequestHandler extends Disposable {
359
428
  complete(params, token) {
360
429
  return this.sendRequest({ method: 'completion/complete', params }, token);
361
430
  }
431
+ getTask(params, token) {
432
+ return this.sendRequest({ method: 'tasks/get', params }, token);
433
+ }
434
+ getTaskResult(params, token) {
435
+ return this.sendRequest({ method: 'tasks/result', params }, token);
436
+ }
437
+ cancelTask(params, token) {
438
+ return this.sendRequest({ method: 'tasks/cancel', params }, token);
439
+ }
440
+ listTasks(params, token) {
441
+ return Iterable.asyncToArrayFlat(this.sendRequestPaginated('tasks/list', result => result.tasks, params, token));
442
+ }
443
+ }
444
+ function isTaskInTerminalState(task) {
445
+ return task.status === 'completed' || task.status === 'failed' || task.status === 'cancelled';
446
+ }
447
+ class McpTask extends Disposable {
448
+ get result() {
449
+ return this.promise.p;
450
+ }
451
+ get id() {
452
+ return this._task.taskId;
453
+ }
454
+ constructor(_task, _token = CancellationToken.None) {
455
+ super();
456
+ this._task = _task;
457
+ this.promise = ( new DeferredPromise());
458
+ this._handler = observableValue('mcpTaskHandler', undefined);
459
+ const expiresAt = _task.ttl ? (Date.now() + _task.ttl) : undefined;
460
+ this._lastTaskState = observableValue('lastTaskState', this._task);
461
+ const store = this._register(( new DisposableStore()));
462
+ if (_token.isCancellationRequested) {
463
+ this._lastTaskState.set({ ...this._task, status: 'cancelled' }, undefined);
464
+ }
465
+ else {
466
+ store.add(_token.onCancellationRequested(() => {
467
+ const current = this._lastTaskState.get();
468
+ if (!isTaskInTerminalState(current)) {
469
+ this._lastTaskState.set({ ...current, status: 'cancelled' }, undefined);
470
+ }
471
+ }));
472
+ }
473
+ if (expiresAt) {
474
+ const ttlTimeout = expiresAt - Date.now();
475
+ if (ttlTimeout <= 0) {
476
+ this._lastTaskState.set({ ...this._task, status: 'cancelled', statusMessage: 'Task timed out.' }, undefined);
477
+ }
478
+ else {
479
+ store.add(disposableTimeout(() => {
480
+ const current = this._lastTaskState.get();
481
+ if (!isTaskInTerminalState(current)) {
482
+ this._lastTaskState.set({ ...current, status: 'cancelled', statusMessage: 'Task timed out.' }, undefined);
483
+ }
484
+ }, ttlTimeout));
485
+ }
486
+ }
487
+ const inputRequiredLookup = observableValue('activeResultLookup', undefined);
488
+ store.add(autorun(reader => {
489
+ const current = this._lastTaskState.read(reader);
490
+ if (isTaskInTerminalState(current)) {
491
+ return;
492
+ }
493
+ const lookup = inputRequiredLookup.read(reader);
494
+ if (lookup) {
495
+ const result = lookup.promiseResult.read(reader);
496
+ return transaction(tx => {
497
+ if (!result) {
498
+ }
499
+ else if (result.data) {
500
+ inputRequiredLookup.set(undefined, tx);
501
+ this._lastTaskState.set(result.data, tx);
502
+ }
503
+ else {
504
+ inputRequiredLookup.set(undefined, tx);
505
+ if (result.error instanceof McpError && result.error.code === MCP.INVALID_PARAMS) {
506
+ this._lastTaskState.set({ ...current, status: 'cancelled' }, undefined);
507
+ }
508
+ else {
509
+ this._lastTaskState.set({ ...current, status: 'working' }, undefined);
510
+ }
511
+ }
512
+ });
513
+ }
514
+ const handler = this._handler.read(reader);
515
+ if (!handler) {
516
+ return;
517
+ }
518
+ const pollInterval = _task.pollInterval ?? 2000;
519
+ const cts = ( new CancellationTokenSource(_token));
520
+ reader.store.add(toDisposable(() => cts.dispose(true)));
521
+ reader.store.add(disposableTimeout(() => {
522
+ handler.getTask({ taskId: current.taskId }, cts.token)
523
+ .catch((e) => {
524
+ if (e instanceof McpError && e.code === MCP.INVALID_PARAMS) {
525
+ return { ...current, status: 'cancelled' };
526
+ }
527
+ else {
528
+ return { ...current };
529
+ }
530
+ })
531
+ .then(r => {
532
+ if (r && !cts.token.isCancellationRequested) {
533
+ this._lastTaskState.set(r, undefined);
534
+ }
535
+ });
536
+ }, pollInterval));
537
+ }));
538
+ const lastStatus = ( this._lastTaskState.map(task => task.status));
539
+ store.add(autorun(reader => {
540
+ const status = lastStatus.read(reader);
541
+ if (status === 'failed') {
542
+ const current = this._lastTaskState.read(undefined);
543
+ this.promise.error(( new Error(
544
+ `Task ${current.taskId} failed: ${current.statusMessage ?? 'unknown error'}`
545
+ )));
546
+ store.dispose();
547
+ }
548
+ else if (status === 'cancelled') {
549
+ this.promise.cancel();
550
+ store.dispose();
551
+ }
552
+ else if (status === 'input_required') {
553
+ const handler = this._handler.read(reader);
554
+ if (handler) {
555
+ const current = this._lastTaskState.read(undefined);
556
+ const cts = ( new CancellationTokenSource(_token));
557
+ reader.store.add(toDisposable(() => cts.dispose(true)));
558
+ inputRequiredLookup.set(( new ObservablePromise(handler.getTask({ taskId: current.taskId }, cts.token))), undefined);
559
+ }
560
+ }
561
+ else if (status === 'completed') {
562
+ const handler = this._handler.read(reader);
563
+ if (handler) {
564
+ this.promise.settleWith(handler.getTaskResult({ taskId: _task.taskId }, _token));
565
+ store.dispose();
566
+ }
567
+ }
568
+ else ;
569
+ }));
570
+ }
571
+ onDidUpdateState(task) {
572
+ this._lastTaskState.set(task, undefined);
573
+ }
574
+ setHandler(handler) {
575
+ this._handler.set(handler, undefined);
576
+ }
362
577
  }
363
578
  function mapLogLevelToMcp(logLevel) {
364
579
  switch (logLevel) {
@@ -379,4 +594,4 @@ function mapLogLevelToMcp(logLevel) {
379
594
  }
380
595
  }
381
596
 
382
- export { McpServerRequestHandler };
597
+ export { McpServerRequestHandler, McpTask };
@@ -7,12 +7,12 @@ import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/in
7
7
  import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
8
8
  import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
9
9
  import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
10
- import { mcpAutoStartConfig, McpAutoStartValue } from '@codingame/monaco-vscode-dc3fa21d-a483-5b99-a7ab-173235644a34-common/vscode/vs/platform/mcp/common/mcpManagement';
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
12
  import { IMcpRegistry } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpRegistryTypes.service';
13
13
  import { McpServerMetadataCache, McpServer } from './mcpServer.js';
14
14
  import { IAutostartResult, McpConnectionState, McpServerCacheState, McpStartServerInteraction, UserInteractionRequiredError, McpServerDefinition, McpToolName } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
15
- import { startServerAndWaitForLiveTools } from '@codingame/monaco-vscode-08fd81c0-7fd8-5f7c-9776-f918dd532714-common/vscode/vs/workbench/contrib/mcp/common/mcpTypesUtils';
15
+ import { startServerAndWaitForLiveTools } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypesUtils';
16
16
  import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
17
17
  import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
18
18
  import { transaction } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/transaction';
@@ -0,0 +1,68 @@
1
+ import { CancellationToken } from "@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation";
2
+ import { Disposable, IDisposable } from "@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle";
3
+ import type { McpServerRequestHandler } from "./mcpServerRequestHandler.js";
4
+ import { MCP } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/modelContextProtocol";
5
+ export interface IMcpTaskInternal extends IDisposable {
6
+ readonly id: string;
7
+ onDidUpdateState(task: MCP.Task): void;
8
+ setHandler(handler: McpServerRequestHandler | undefined): void;
9
+ }
10
+ /**
11
+ * Manages in-memory task state for server-side MCP tasks (sampling and elicitation).
12
+ * Also tracks client-side tasks to survive handler reconnections.
13
+ * Lifecycle is tied to the McpServer instance.
14
+ */
15
+ export declare class McpTaskManager extends Disposable {
16
+ private readonly _serverTasks;
17
+ private readonly _clientTasks;
18
+ private readonly _onDidUpdateTask;
19
+ readonly onDidUpdateTask: import("@codingame/monaco-vscode-api/vscode/vs/base/common/event").Event<MCP.Task>;
20
+ /**
21
+ * Attach a new handler to this task manager.
22
+ * Updates all client tasks to use the new handler.
23
+ */
24
+ setHandler(handler: McpServerRequestHandler | undefined): void;
25
+ /**
26
+ * Get a client task by ID for status notification handling.
27
+ */
28
+ getClientTask(taskId: string): IMcpTaskInternal | undefined;
29
+ /**
30
+ * Track a new client task.
31
+ */
32
+ adoptClientTask(task: IMcpTaskInternal): void;
33
+ /**
34
+ * Untracks a client task.
35
+ */
36
+ abandonClientTask(taskId: string): void;
37
+ /**
38
+ * Create a new task and execute it asynchronously.
39
+ * Returns the task immediately while execution continues in the background.
40
+ */
41
+ createTask<TResult extends MCP.Result>(ttl: number | null, executor: (token: CancellationToken) => Promise<TResult>): MCP.CreateTaskResult;
42
+ /**
43
+ * Execute a task asynchronously and update its state.
44
+ */
45
+ private _executeTask;
46
+ /**
47
+ * Update task status and optionally store result or error.
48
+ */
49
+ private _updateTaskStatus;
50
+ /**
51
+ * Get the current state of a task.
52
+ * Returns an error if the task doesn't exist or has expired.
53
+ */
54
+ getTask(taskId: string): MCP.GetTaskResult;
55
+ /**
56
+ * Get the result of a completed task.
57
+ * Blocks until the task completes if it's still in progress.
58
+ */
59
+ getTaskResult(taskId: string): Promise<MCP.GetTaskPayloadResult>;
60
+ /**
61
+ * Cancel a task.
62
+ */
63
+ cancelTask(taskId: string): MCP.CancelTaskResult;
64
+ /**
65
+ * List all tasks.
66
+ */
67
+ listTasks(): MCP.ListTasksResult;
68
+ }
@@ -0,0 +1,168 @@
1
+
2
+ import { disposableTimeout } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
3
+ import { CancellationTokenSource } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
4
+ import { CancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
5
+ import { Emitter } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
6
+ import { Disposable, DisposableMap, DisposableStore, toDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
7
+ import { generateUuid } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uuid';
8
+ import { McpError } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes';
9
+ import { MCP } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/modelContextProtocol';
10
+
11
+ class McpTaskManager extends Disposable {
12
+ constructor() {
13
+ super(...arguments);
14
+ this._serverTasks = this._register(( new DisposableMap()));
15
+ this._clientTasks = this._register(( new DisposableMap()));
16
+ this._onDidUpdateTask = this._register(( new Emitter()));
17
+ this.onDidUpdateTask = this._onDidUpdateTask.event;
18
+ }
19
+ setHandler(handler) {
20
+ for (const task of ( this._clientTasks.values())) {
21
+ task.setHandler(handler);
22
+ }
23
+ }
24
+ getClientTask(taskId) {
25
+ return this._clientTasks.get(taskId);
26
+ }
27
+ adoptClientTask(task) {
28
+ this._clientTasks.set(task.id, task);
29
+ }
30
+ abandonClientTask(taskId) {
31
+ this._clientTasks.deleteAndDispose(taskId);
32
+ }
33
+ createTask(ttl, executor) {
34
+ const taskId = generateUuid();
35
+ const createdAt = ( new Date()).toISOString();
36
+ const createdAtTime = Date.now();
37
+ const task = {
38
+ taskId,
39
+ status: 'working',
40
+ createdAt,
41
+ ttl,
42
+ pollInterval: 1000,
43
+ };
44
+ const store = ( new DisposableStore());
45
+ const cts = ( new CancellationTokenSource());
46
+ store.add(toDisposable(() => cts.dispose(true)));
47
+ const executionPromise = this._executeTask(taskId, executor, cts.token);
48
+ if (ttl) {
49
+ store.add(disposableTimeout(() => this._serverTasks.deleteAndDispose(taskId), ttl));
50
+ }
51
+ else {
52
+ executionPromise.finally(() => {
53
+ const timeout = this._register(disposableTimeout(() => {
54
+ this._serverTasks.deleteAndDispose(taskId);
55
+ this._store.delete(timeout);
56
+ }, 60_000));
57
+ });
58
+ }
59
+ this._serverTasks.set(taskId, {
60
+ task,
61
+ cts,
62
+ dispose: () => store.dispose(),
63
+ createdAtTime,
64
+ executionPromise,
65
+ });
66
+ return { task };
67
+ }
68
+ async _executeTask(taskId, executor, token) {
69
+ try {
70
+ const result = await executor(token);
71
+ this._updateTaskStatus(taskId, 'completed', undefined, result);
72
+ }
73
+ catch (error) {
74
+ if (error instanceof CancellationError) {
75
+ this._updateTaskStatus(taskId, 'cancelled', 'Task was cancelled by the client');
76
+ }
77
+ else if (error instanceof McpError) {
78
+ this._updateTaskStatus(taskId, 'failed', error.message, undefined, {
79
+ code: error.code,
80
+ message: error.message,
81
+ data: error.data,
82
+ });
83
+ }
84
+ else if (error instanceof Error) {
85
+ this._updateTaskStatus(taskId, 'failed', error.message, undefined, {
86
+ code: MCP.INTERNAL_ERROR,
87
+ message: error.message,
88
+ });
89
+ }
90
+ else {
91
+ this._updateTaskStatus(taskId, 'failed', 'Unknown error', undefined, {
92
+ code: MCP.INTERNAL_ERROR,
93
+ message: 'Unknown error',
94
+ });
95
+ }
96
+ }
97
+ }
98
+ _updateTaskStatus(taskId, status, statusMessage, result, error) {
99
+ const entry = this._serverTasks.get(taskId);
100
+ if (!entry) {
101
+ return;
102
+ }
103
+ entry.task.status = status;
104
+ if (statusMessage !== undefined) {
105
+ entry.task.statusMessage = statusMessage;
106
+ }
107
+ if (result !== undefined) {
108
+ entry.result = result;
109
+ }
110
+ if (error !== undefined) {
111
+ entry.error = error;
112
+ }
113
+ this._onDidUpdateTask.fire({ ...entry.task });
114
+ }
115
+ getTask(taskId) {
116
+ const entry = this._serverTasks.get(taskId);
117
+ if (!entry) {
118
+ throw ( new McpError(MCP.INVALID_PARAMS, `Task not found: ${taskId}`));
119
+ }
120
+ return { ...entry.task };
121
+ }
122
+ async getTaskResult(taskId) {
123
+ const entry = this._serverTasks.get(taskId);
124
+ if (!entry) {
125
+ throw ( new McpError(MCP.INVALID_PARAMS, `Task not found: ${taskId}`));
126
+ }
127
+ if (entry.task.status === 'working' || entry.task.status === 'input_required') {
128
+ await entry.executionPromise;
129
+ }
130
+ const updatedEntry = this._serverTasks.get(taskId);
131
+ if (!updatedEntry) {
132
+ throw ( new McpError(MCP.INVALID_PARAMS, `Task not found: ${taskId}`));
133
+ }
134
+ if (updatedEntry.error) {
135
+ throw ( new McpError(
136
+ updatedEntry.error.code,
137
+ updatedEntry.error.message,
138
+ updatedEntry.error.data
139
+ ));
140
+ }
141
+ if (!updatedEntry.result) {
142
+ throw ( new McpError(MCP.INTERNAL_ERROR, 'Task completed but no result available'));
143
+ }
144
+ return updatedEntry.result;
145
+ }
146
+ cancelTask(taskId) {
147
+ const entry = this._serverTasks.get(taskId);
148
+ if (!entry) {
149
+ throw ( new McpError(MCP.INVALID_PARAMS, `Task not found: ${taskId}`));
150
+ }
151
+ if (entry.task.status === 'completed' || entry.task.status === 'failed' || entry.task.status === 'cancelled') {
152
+ throw ( new McpError(MCP.INVALID_PARAMS, `Cannot cancel task in ${entry.task.status} status`));
153
+ }
154
+ entry.task.status = 'cancelled';
155
+ entry.task.statusMessage = 'Task was cancelled by the client';
156
+ entry.cts.cancel();
157
+ return { ...entry.task };
158
+ }
159
+ listTasks() {
160
+ const tasks = [];
161
+ for (const entry of ( this._serverTasks.values())) {
162
+ tasks.push({ ...entry.task });
163
+ }
164
+ return { tasks };
165
+ }
166
+ }
167
+
168
+ export { McpTaskManager };
@@ -11,7 +11,7 @@ import '@codingame/monaco-vscode-api/vscode/vs/platform/notification/common/noti
11
11
  import { IQuickInputService } from '@codingame/monaco-vscode-api/vscode/vs/platform/quickinput/common/quickInput.service';
12
12
  import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
13
13
  import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service';
14
- import { NumberBadge } from '@codingame/monaco-vscode-3b5a5cd1-d4ff-500a-b609-57e0cd4afa0a-common/vscode/vs/workbench/services/activity/common/activity';
14
+ import { NumberBadge } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/activity/common/activity';
15
15
  import { IActivityService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/activity/common/activity.service';
16
16
  import { IAuthenticationMcpAccessService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/browser/authenticationMcpAccessService.service';
17
17
  import { IAuthenticationMcpUsageService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/authentication/browser/authenticationMcpUsageService.service';
@@ -112,7 +112,7 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
112
112
  numberOfRequests += ( Object.keys(accessRequest)).length;
113
113
  });
114
114
  if (numberOfRequests > 0) {
115
- const badge = ( new NumberBadge(numberOfRequests, () => ( localize(13527, "Sign in requested"))));
115
+ const badge = ( new NumberBadge(numberOfRequests, () => ( localize(13669, "Sign in requested"))));
116
116
  this._accountBadgeDisposable.value = this.activityService.showAccountsActivity({ badge });
117
117
  }
118
118
  }
@@ -173,7 +173,7 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
173
173
  const { result } = await this.dialogService.prompt({
174
174
  type: Severity.Info,
175
175
  message: ( localize(
176
- 13528,
176
+ 13670,
177
177
  "The MCP server '{0}' wants to access the {1} account '{2}'.",
178
178
  mcpServerName,
179
179
  provider.label,
@@ -181,11 +181,11 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
181
181
  )),
182
182
  buttons: [
183
183
  {
184
- label: ( localize(13529, "&&Allow")),
184
+ label: ( localize(13671, "&&Allow")),
185
185
  run: () => SessionPromptChoice.Allow
186
186
  },
187
187
  {
188
- label: ( localize(13530, "&&Deny")),
188
+ label: ( localize(13672, "&&Deny")),
189
189
  run: () => SessionPromptChoice.Deny
190
190
  }
191
191
  ],
@@ -221,16 +221,16 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
221
221
  items.push({ label: account.label, account });
222
222
  }
223
223
  });
224
- items.push({ label: ( localize(13531, "Sign in to another account")) });
224
+ items.push({ label: ( localize(13673, "Sign in to another account")) });
225
225
  quickPick.items = items;
226
226
  quickPick.title = ( localize(
227
- 13532,
227
+ 13674,
228
228
  "The MCP server '{0}' wants to access a {1} account",
229
229
  mcpServerName,
230
230
  this._authenticationService.getProvider(providerId).label
231
231
  ));
232
232
  quickPick.placeholder = ( localize(
233
- 13533,
233
+ 13675,
234
234
  "Select an account for '{0}' to use or Esc to cancel",
235
235
  mcpServerName
236
236
  ));
@@ -302,7 +302,7 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
302
302
  group: '3_accessRequests',
303
303
  command: {
304
304
  id: `${providerId}${mcpServerId}Access`,
305
- title: ( localize(13534, "Grant access to {0} for {1}... (1)", provider.label, mcpServerName))
305
+ title: ( localize(13676, "Grant access to {0} for {1}... (1)", provider.label, mcpServerName))
306
306
  }
307
307
  }));
308
308
  const accessCommand = CommandsRegistry.registerCommand({
@@ -346,7 +346,7 @@ let AuthenticationMcpService = class AuthenticationMcpService extends Disposable
346
346
  group: '2_signInRequests',
347
347
  command: {
348
348
  id: commandId,
349
- title: ( localize(13535, "Sign in with {0} to use {1} (1)", provider.label, mcpServerName))
349
+ title: ( localize(13677, "Sign in with {0} to use {1} (1)", provider.label, mcpServerName))
350
350
  }
351
351
  }));
352
352
  const signInCommand = CommandsRegistry.registerCommand({