@codingame/monaco-vscode-mcp-service-override 36.2.6 → 37.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/vscode/src/vs/base/common/jsonRpcProtocol.d.ts +2 -2
- package/vscode/src/vs/platform/mcp/common/allowedMcpServers.d.ts +52 -0
- package/vscode/src/vs/platform/mcp/common/allowedMcpServers.js +180 -0
- package/vscode/src/vs/platform/mcp/common/allowedMcpServersService.d.ts +4 -0
- package/vscode/src/vs/platform/mcp/common/allowedMcpServersService.js +68 -12
- package/vscode/src/vs/platform/mcp/common/mcpGalleryService.d.ts +5 -1
- package/vscode/src/vs/platform/mcp/common/mcpGalleryService.js +200 -92
- package/vscode/src/vs/platform/mcp/common/mcpResourceScannerService.js +3 -2
- package/vscode/src/vs/platform/mcp/common/nativeMcpDiscoveryHelper.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcp.contribution.js +3 -3
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpAddContextContribution.js +2 -2
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpCommands.d.ts +10 -3
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpCommands.js +357 -121
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpElicitationService.js +25 -25
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpLanguageFeatures.d.ts +11 -1
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpLanguageFeatures.js +409 -145
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpMigration.js +4 -4
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpResourceQuickAccess.js +8 -8
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditor.js +37 -37
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerEditorInput.js +2 -2
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerIcons.js +5 -5
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServerWidgets.js +5 -5
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpServersView.js +18 -18
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.d.ts +12 -0
- package/vscode/src/vs/workbench/contrib/mcp/browser/mcpWorkbenchService.js +279 -72
- package/vscode/src/vs/workbench/contrib/mcp/browser/media/mcpServersView.css +1 -1
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/extensionMcpDiscovery.js +6 -5
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/installedMcpServersDiscovery.js +9 -16
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.d.ts +4 -4
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAbstract.js +7 -3
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAdapters.d.ts +14 -6
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/nativeMcpDiscoveryAdapters.js +32 -9
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/workspaceDotMcpDiscovery.d.ts +2 -2
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/workspaceDotMcpDiscovery.js +20 -6
- package/vscode/src/vs/workbench/contrib/mcp/common/discovery/workspaceMcpDiscoveryAdapter.js +9 -5
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpContextKeys.js +4 -4
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpEditorAffordanceState.d.ts +13 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpEditorAffordanceState.js +36 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpLanguageModelToolContribution.js +6 -6
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.d.ts +2 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpRegistry.js +51 -19
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingLog.js +1 -1
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSamplingService.js +11 -11
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSandboxService.d.ts +4 -0
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpSandboxService.js +42 -6
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpServerConnection.js +3 -3
- package/vscode/src/vs/workbench/contrib/mcp/common/mcpService.js +6 -3
- package/vscode/src/vs/workbench/services/authentication/browser/authenticationMcpService.js +9 -9
|
@@ -9,14 +9,60 @@ import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
|
|
|
9
9
|
import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
10
10
|
import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
|
|
11
11
|
import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
|
|
12
|
-
import { asText, asJson } from '@codingame/monaco-vscode-api/vscode/vs/platform/request/common/request';
|
|
12
|
+
import { asText, isSuccess, asJson } from '@codingame/monaco-vscode-api/vscode/vs/platform/request/common/request';
|
|
13
13
|
import { IRequestService } from '@codingame/monaco-vscode-api/vscode/vs/platform/request/common/request.service';
|
|
14
|
-
import { TransportType,
|
|
15
|
-
import {
|
|
14
|
+
import { RegistryType, TransportType, McpGalleryResolveStatus, GalleryMcpServerStatus } from '@codingame/monaco-vscode-api/vscode/vs/platform/mcp/common/mcpManagement';
|
|
15
|
+
import { getMcpGalleryManifestResourceUri, McpGalleryResourceType, McpGalleryManifestStatus } from '@codingame/monaco-vscode-api/vscode/vs/platform/mcp/common/mcpGalleryManifest';
|
|
16
16
|
import { IMcpGalleryManifestService } from '@codingame/monaco-vscode-api/vscode/vs/platform/mcp/common/mcpGalleryManifest.service';
|
|
17
17
|
import { CancellationError, isCancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
|
|
18
18
|
import { isString, isObject } from '@codingame/monaco-vscode-api/vscode/vs/base/common/types';
|
|
19
19
|
|
|
20
|
+
function toSupportedPackageRegistryType(input) {
|
|
21
|
+
switch (input) {
|
|
22
|
+
case "npm":
|
|
23
|
+
return RegistryType.NODE;
|
|
24
|
+
case "docker":
|
|
25
|
+
case "docker-hub":
|
|
26
|
+
case "oci":
|
|
27
|
+
return RegistryType.DOCKER;
|
|
28
|
+
case "pypi":
|
|
29
|
+
return RegistryType.PYTHON;
|
|
30
|
+
case "nuget":
|
|
31
|
+
return RegistryType.NUGET;
|
|
32
|
+
default:
|
|
33
|
+
return undefined;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
function filterMcpPackages(packages, getRegistryType, convert) {
|
|
37
|
+
if (!packages) {
|
|
38
|
+
return undefined;
|
|
39
|
+
}
|
|
40
|
+
const result = [];
|
|
41
|
+
for (const serverPackage of packages) {
|
|
42
|
+
const registryType = toSupportedPackageRegistryType(getRegistryType(serverPackage));
|
|
43
|
+
if (registryType) {
|
|
44
|
+
result.push(convert(serverPackage, registryType));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return result;
|
|
48
|
+
}
|
|
49
|
+
function getMcpServerUrlInGallery(mcpServerUrl, mcpGalleryManifest) {
|
|
50
|
+
const mcpGalleryUrl = getMcpGalleryManifestResourceUri(mcpGalleryManifest, McpGalleryResourceType.McpServersQueryService) ?? mcpGalleryManifest.url;
|
|
51
|
+
try {
|
|
52
|
+
const serverUrl = ( new URL(mcpServerUrl));
|
|
53
|
+
const galleryUrl = ( new URL(mcpGalleryUrl));
|
|
54
|
+
if ((serverUrl.protocol !== `${Schemas.http}:` && serverUrl.protocol !== `${Schemas.https}:`) || serverUrl.username || serverUrl.password || galleryUrl.username || galleryUrl.password || serverUrl.origin !== galleryUrl.origin) {
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
const galleryPath = galleryUrl.pathname.replace(/\/+$/, "");
|
|
58
|
+
if (serverUrl.pathname !== galleryPath && !serverUrl.pathname.startsWith(`${galleryPath}/`)) {
|
|
59
|
+
return undefined;
|
|
60
|
+
}
|
|
61
|
+
return serverUrl.href;
|
|
62
|
+
} catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
}
|
|
20
66
|
var IconMimeType;
|
|
21
67
|
(function(IconMimeType) {
|
|
22
68
|
IconMimeType["PNG"] = "image/png";
|
|
@@ -44,7 +90,7 @@ var McpServerSchemaVersion_v2025_07_09;
|
|
|
44
90
|
for (const server of from.servers) {
|
|
45
91
|
const rawServer = this.toRawGalleryMcpServer(server);
|
|
46
92
|
if (!rawServer) {
|
|
47
|
-
|
|
93
|
+
continue;
|
|
48
94
|
}
|
|
49
95
|
servers.push(rawServer);
|
|
50
96
|
}
|
|
@@ -133,23 +179,26 @@ var McpServerSchemaVersion_v2025_07_09;
|
|
|
133
179
|
};
|
|
134
180
|
}
|
|
135
181
|
}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
}
|
|
182
|
+
const packages = filterMcpPackages(
|
|
183
|
+
from.packages,
|
|
184
|
+
serverPackage => serverPackage.registry_type ?? serverPackage.registry_name,
|
|
185
|
+
(serverPackage, registryType) => ({
|
|
186
|
+
identifier: serverPackage.identifier ?? serverPackage.name,
|
|
187
|
+
registryType,
|
|
188
|
+
version: serverPackage.version,
|
|
189
|
+
fileSha256: serverPackage.file_sha256,
|
|
190
|
+
registryBaseUrl: serverPackage.registry_base_url,
|
|
191
|
+
transport: serverPackage.transport ? convertTransport(serverPackage.transport) : {
|
|
192
|
+
type: TransportType.STDIO
|
|
193
|
+
},
|
|
194
|
+
packageArguments: serverPackage.package_arguments?.map(convertServerArgument),
|
|
195
|
+
runtimeHint: serverPackage.runtime_hint,
|
|
196
|
+
runtimeArguments: serverPackage.runtime_arguments?.map(convertServerArgument),
|
|
197
|
+
environmentVariables: serverPackage.environment_variables?.map(convertKeyValueInput)
|
|
198
|
+
})
|
|
199
|
+
);
|
|
200
|
+
if (!packages?.length && !from.remotes?.length) {
|
|
201
|
+
return undefined;
|
|
153
202
|
}
|
|
154
203
|
const gitHubInfo = from._meta["io.modelcontextprotocol.registry/publisher-provided"]?.github;
|
|
155
204
|
return {
|
|
@@ -165,20 +214,7 @@ var McpServerSchemaVersion_v2025_07_09;
|
|
|
165
214
|
version: from.version,
|
|
166
215
|
createdAt: from.created_at,
|
|
167
216
|
updatedAt: from.updated_at,
|
|
168
|
-
packages
|
|
169
|
-
identifier: p.identifier ?? p.name,
|
|
170
|
-
registryType: convertRegistryType(p.registry_type ?? p.registry_name),
|
|
171
|
-
version: p.version,
|
|
172
|
-
fileSha256: p.file_sha256,
|
|
173
|
-
registryBaseUrl: p.registry_base_url,
|
|
174
|
-
transport: p.transport ? convertTransport(p.transport) : {
|
|
175
|
-
type: TransportType.STDIO
|
|
176
|
-
},
|
|
177
|
-
packageArguments: p.package_arguments?.map(convertServerArgument),
|
|
178
|
-
runtimeHint: p.runtime_hint,
|
|
179
|
-
runtimeArguments: p.runtime_arguments?.map(convertServerArgument),
|
|
180
|
-
environmentVariables: p.environment_variables?.map(convertKeyValueInput)
|
|
181
|
-
})),
|
|
217
|
+
packages,
|
|
182
218
|
remotes: from.remotes?.map(remote => {
|
|
183
219
|
const type = remote.type ?? remote.transport_type ?? remote.transport;
|
|
184
220
|
return {
|
|
@@ -227,11 +263,7 @@ var McpServerSchemaVersion_v0_1;
|
|
|
227
263
|
for (const server of from.servers) {
|
|
228
264
|
const rawServer = this.toRawGalleryMcpServer(server);
|
|
229
265
|
if (!rawServer) {
|
|
230
|
-
|
|
231
|
-
return undefined;
|
|
232
|
-
} else {
|
|
233
|
-
continue;
|
|
234
|
-
}
|
|
266
|
+
continue;
|
|
235
267
|
}
|
|
236
268
|
servers.push(rawServer);
|
|
237
269
|
}
|
|
@@ -253,6 +285,17 @@ var McpServerSchemaVersion_v0_1;
|
|
|
253
285
|
...apicInfo
|
|
254
286
|
} = from._meta;
|
|
255
287
|
const githubInfo = from.server._meta?.["io.modelcontextprotocol.registry/publisher-provided"]?.github;
|
|
288
|
+
const packages = filterMcpPackages(
|
|
289
|
+
from.server.packages,
|
|
290
|
+
serverPackage => serverPackage.registryType,
|
|
291
|
+
(serverPackage, registryType) => ({
|
|
292
|
+
...serverPackage,
|
|
293
|
+
registryType
|
|
294
|
+
})
|
|
295
|
+
);
|
|
296
|
+
if (!packages?.length && !from.server.remotes?.length) {
|
|
297
|
+
return undefined;
|
|
298
|
+
}
|
|
256
299
|
return {
|
|
257
300
|
name: from.server.name,
|
|
258
301
|
description: from.server.description,
|
|
@@ -266,7 +309,7 @@ var McpServerSchemaVersion_v0_1;
|
|
|
266
309
|
readme: githubInfo?.readme,
|
|
267
310
|
icons: from.server.icons,
|
|
268
311
|
websiteUrl: from.server.websiteUrl,
|
|
269
|
-
packages
|
|
312
|
+
packages,
|
|
270
313
|
remotes: from.server.remotes,
|
|
271
314
|
status: registryInfo?.status,
|
|
272
315
|
registryInfo,
|
|
@@ -281,28 +324,38 @@ var McpServerSchemaVersion_v0;
|
|
|
281
324
|
(function(McpServerSchemaVersion_v0) {
|
|
282
325
|
McpServerSchemaVersion_v0.VERSION = "v0";
|
|
283
326
|
class Serializer {
|
|
284
|
-
constructor() {
|
|
285
|
-
this.galleryMcpServerDataSerializers = [];
|
|
286
|
-
this.galleryMcpServerDataSerializers.push(McpServerSchemaVersion_v0_1.SERIALIZER);
|
|
287
|
-
this.galleryMcpServerDataSerializers.push(McpServerSchemaVersion_v2025_07_09.SERIALIZER);
|
|
288
|
-
}
|
|
289
327
|
toRawGalleryMcpServerResult(input) {
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
328
|
+
if (!isObject(input)) {
|
|
329
|
+
return undefined;
|
|
330
|
+
}
|
|
331
|
+
const candidate = input;
|
|
332
|
+
if (!Array.isArray(candidate.servers) || !isObject(candidate.metadata)) {
|
|
333
|
+
return undefined;
|
|
334
|
+
}
|
|
335
|
+
const metadata = candidate.metadata;
|
|
336
|
+
if (metadata.count !== undefined && typeof metadata.count !== "number") {
|
|
337
|
+
return undefined;
|
|
338
|
+
}
|
|
339
|
+
const servers = [];
|
|
340
|
+
for (const server of candidate.servers) {
|
|
341
|
+
const rawServer = this.toRawGalleryMcpServer(server);
|
|
342
|
+
if (rawServer) {
|
|
343
|
+
servers.push(rawServer);
|
|
294
344
|
}
|
|
295
345
|
}
|
|
296
|
-
return
|
|
346
|
+
return {
|
|
347
|
+
metadata: {
|
|
348
|
+
count: metadata.count ?? 0,
|
|
349
|
+
nextCursor: isString(metadata.nextCursor) ? metadata.nextCursor : isString(metadata.next_cursor) ? metadata.next_cursor : undefined
|
|
350
|
+
},
|
|
351
|
+
servers
|
|
352
|
+
};
|
|
297
353
|
}
|
|
298
354
|
toRawGalleryMcpServer(input) {
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
if (result) {
|
|
302
|
-
return result;
|
|
303
|
-
}
|
|
355
|
+
if (isObject(input) && isObject(input.server)) {
|
|
356
|
+
return McpServerSchemaVersion_v0_1.SERIALIZER.toRawGalleryMcpServer(input);
|
|
304
357
|
}
|
|
305
|
-
return
|
|
358
|
+
return McpServerSchemaVersion_v2025_07_09.SERIALIZER.toRawGalleryMcpServer(input);
|
|
306
359
|
}
|
|
307
360
|
}
|
|
308
361
|
McpServerSchemaVersion_v0.SERIALIZER = ( new Serializer());
|
|
@@ -410,18 +463,43 @@ let McpGalleryService = class McpGalleryService extends Disposable {
|
|
|
410
463
|
};
|
|
411
464
|
}
|
|
412
465
|
async getMcpServersFromGallery(infos) {
|
|
466
|
+
const resolved = await this.resolveMcpServersFromGallery(infos);
|
|
467
|
+
const mcpServers = [];
|
|
468
|
+
for (const result of ( resolved.values())) {
|
|
469
|
+
if (result.status === McpGalleryResolveStatus.Found) {
|
|
470
|
+
mcpServers.push(result.server);
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
return mcpServers;
|
|
474
|
+
}
|
|
475
|
+
async resolveMcpServersFromGallery(infos) {
|
|
476
|
+
const result = ( new Map());
|
|
413
477
|
const mcpGalleryManifest = await this.mcpGalleryManifestService.getMcpGalleryManifest();
|
|
414
478
|
if (!mcpGalleryManifest) {
|
|
415
|
-
|
|
479
|
+
for (const info of infos) {
|
|
480
|
+
result.set(info.name, {
|
|
481
|
+
status: McpGalleryResolveStatus.Failed
|
|
482
|
+
});
|
|
483
|
+
}
|
|
484
|
+
return result;
|
|
416
485
|
}
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
486
|
+
await Promise.all(( infos.map(async info => {
|
|
487
|
+
try {
|
|
488
|
+
const mcpServer = await this.getMcpServerByName(info, mcpGalleryManifest);
|
|
489
|
+
result.set(info.name, mcpServer ? {
|
|
490
|
+
status: McpGalleryResolveStatus.Found,
|
|
491
|
+
server: mcpServer
|
|
492
|
+
} : {
|
|
493
|
+
status: McpGalleryResolveStatus.NotFound
|
|
494
|
+
});
|
|
495
|
+
} catch (error) {
|
|
496
|
+
this.logService.warn(`Failed to resolve MCP server '${info.name}' from gallery: ${error}`);
|
|
497
|
+
result.set(info.name, {
|
|
498
|
+
status: McpGalleryResolveStatus.Failed
|
|
499
|
+
});
|
|
422
500
|
}
|
|
423
501
|
})));
|
|
424
|
-
return
|
|
502
|
+
return result;
|
|
425
503
|
}
|
|
426
504
|
async getMcpServerByName(
|
|
427
505
|
{
|
|
@@ -430,33 +508,44 @@ let McpGalleryService = class McpGalleryService extends Disposable {
|
|
|
430
508
|
},
|
|
431
509
|
mcpGalleryManifest
|
|
432
510
|
) {
|
|
433
|
-
const
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
511
|
+
const urls = [
|
|
512
|
+
this.getLatestServerVersionUrl(name, mcpGalleryManifest),
|
|
513
|
+
this.getNamedServerUrl(name, mcpGalleryManifest),
|
|
514
|
+
id ? this.getServerIdUrl(id, mcpGalleryManifest) : undefined
|
|
515
|
+
];
|
|
516
|
+
let attempted = false;
|
|
517
|
+
let lastError;
|
|
518
|
+
for (const url of urls) {
|
|
519
|
+
if (!url) {
|
|
520
|
+
continue;
|
|
438
521
|
}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
522
|
+
attempted = true;
|
|
523
|
+
try {
|
|
524
|
+
const mcpServer = await this.getMcpServer(url, mcpGalleryManifest);
|
|
525
|
+
if (mcpServer) {
|
|
526
|
+
if (mcpServer.name === name) {
|
|
527
|
+
return mcpServer;
|
|
528
|
+
}
|
|
529
|
+
lastError = ( new Error(`MCP server lookup for '${name}' returned '${mcpServer.name}'`));
|
|
530
|
+
}
|
|
531
|
+
} catch (error) {
|
|
532
|
+
lastError = error;
|
|
445
533
|
}
|
|
446
534
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
535
|
+
if (!attempted) {
|
|
536
|
+
throw ( new Error(
|
|
537
|
+
`Cannot resolve MCP server '${name}': registry manifest has no server lookup endpoint`
|
|
538
|
+
));
|
|
539
|
+
}
|
|
540
|
+
if (lastError !== undefined) {
|
|
541
|
+
throw lastError;
|
|
453
542
|
}
|
|
454
543
|
return undefined;
|
|
455
544
|
}
|
|
456
545
|
async getReadme(gallery, token) {
|
|
457
546
|
const readmeUrl = gallery.readmeUrl;
|
|
458
547
|
if (!readmeUrl) {
|
|
459
|
-
return Promise.resolve(( localize(
|
|
548
|
+
return Promise.resolve(( localize(2355, "No README available")));
|
|
460
549
|
}
|
|
461
550
|
const uri = ( URI.parse(readmeUrl));
|
|
462
551
|
if (uri.scheme === Schemas.file) {
|
|
@@ -468,7 +557,7 @@ let McpGalleryService = class McpGalleryService extends Disposable {
|
|
|
468
557
|
}
|
|
469
558
|
}
|
|
470
559
|
if (uri.authority !== "raw.githubusercontent.com") {
|
|
471
|
-
return ( new MarkdownString(( localize(
|
|
560
|
+
return ( new MarkdownString(( localize(2356, "You can find information about this server [here]({0})", readmeUrl)))).value;
|
|
472
561
|
}
|
|
473
562
|
const context = await this.requestService.request({
|
|
474
563
|
type: "GET",
|
|
@@ -615,6 +704,15 @@ let McpGalleryService = class McpGalleryService extends Disposable {
|
|
|
615
704
|
}
|
|
616
705
|
};
|
|
617
706
|
}
|
|
707
|
+
if (!isSuccess(context)) {
|
|
708
|
+
this.logService.error(`Failed to query MCP gallery: Server returned ${context.res.statusCode}`);
|
|
709
|
+
return {
|
|
710
|
+
servers: [],
|
|
711
|
+
metadata: {
|
|
712
|
+
count: 0
|
|
713
|
+
}
|
|
714
|
+
};
|
|
715
|
+
}
|
|
618
716
|
const data = await asJson(context);
|
|
619
717
|
if (!data) {
|
|
620
718
|
return {
|
|
@@ -631,27 +729,37 @@ let McpGalleryService = class McpGalleryService extends Disposable {
|
|
|
631
729
|
return result;
|
|
632
730
|
}
|
|
633
731
|
async getMcpServer(mcpServerUrl, mcpGalleryManifest) {
|
|
732
|
+
const manifest = mcpGalleryManifest ?? (await this.mcpGalleryManifestService.getMcpGalleryManifest());
|
|
733
|
+
if (!manifest) {
|
|
734
|
+
throw ( new Error("Cannot fetch MCP server because no MCP gallery is configured"));
|
|
735
|
+
}
|
|
736
|
+
const validatedMcpServerUrl = getMcpServerUrlInGallery(mcpServerUrl, manifest);
|
|
737
|
+
if (!validatedMcpServerUrl) {
|
|
738
|
+
throw ( new Error("Cannot fetch MCP server from outside the configured MCP gallery"));
|
|
739
|
+
}
|
|
634
740
|
const context = await this.requestService.request({
|
|
635
741
|
type: "GET",
|
|
636
|
-
url:
|
|
742
|
+
url: validatedMcpServerUrl,
|
|
743
|
+
followRedirects: 0,
|
|
637
744
|
callSite: "mcpGalleryService.getMcpServer"
|
|
638
745
|
}, CancellationToken.None);
|
|
639
|
-
if (context.res.statusCode
|
|
746
|
+
if (context.res.statusCode === 404) {
|
|
640
747
|
return undefined;
|
|
641
748
|
}
|
|
749
|
+
if (!isSuccess(context)) {
|
|
750
|
+
throw ( new Error(
|
|
751
|
+
`Failed to fetch MCP server from ${mcpServerUrl}: server responded with ${context.res.statusCode}`
|
|
752
|
+
));
|
|
753
|
+
}
|
|
642
754
|
const data = await asJson(context);
|
|
643
755
|
if (!data) {
|
|
644
|
-
|
|
645
|
-
}
|
|
646
|
-
if (!mcpGalleryManifest) {
|
|
647
|
-
mcpGalleryManifest = await this.mcpGalleryManifestService.getMcpGalleryManifest();
|
|
756
|
+
throw ( new Error(`Failed to fetch MCP server from ${mcpServerUrl}: empty response`));
|
|
648
757
|
}
|
|
649
|
-
|
|
650
|
-
const server = this.serializeMcpServer(data, mcpGalleryManifest);
|
|
758
|
+
const server = this.serializeMcpServer(data, manifest);
|
|
651
759
|
if (!server) {
|
|
652
760
|
throw ( new Error(`Failed to serialize MCP server from ${mcpServerUrl}`, data));
|
|
653
761
|
}
|
|
654
|
-
return this.toGalleryMcpServer(server,
|
|
762
|
+
return this.toGalleryMcpServer(server, manifest);
|
|
655
763
|
}
|
|
656
764
|
serializeMcpServer(data, mcpGalleryManifest) {
|
|
657
765
|
return this.getSerializer(mcpGalleryManifest)?.toRawGalleryMcpServer(data);
|
|
@@ -4,6 +4,7 @@ import { assertNever } from '@codingame/monaco-vscode-api/vscode/vs/base/common/
|
|
|
4
4
|
import { Queue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
|
|
5
5
|
import { VSBuffer } from '@codingame/monaco-vscode-api/vscode/vs/base/common/buffer';
|
|
6
6
|
import { parse } from '@codingame/monaco-vscode-api/vscode/vs/base/common/json';
|
|
7
|
+
import { getParseErrorMessage } from '@codingame/monaco-vscode-api/vscode/vs/base/common/jsonErrorMessages';
|
|
7
8
|
import { Disposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
8
9
|
import { ResourceMap } from '@codingame/monaco-vscode-api/vscode/vs/base/common/map';
|
|
9
10
|
import { ConfigurationTarget, ConfigurationTargetToString } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration';
|
|
@@ -72,7 +73,7 @@ let McpResourceScannerService = class McpResourceScannerService extends Disposab
|
|
|
72
73
|
allowEmptyContent: true
|
|
73
74
|
}) || {};
|
|
74
75
|
if (errors.length > 0) {
|
|
75
|
-
throw ( new Error("Failed to parse scanned MCP servers: " + errors.join(", ")));
|
|
76
|
+
throw ( new Error("Failed to parse scanned MCP servers: " + ( errors.map(e => `[${e.offset}, ${e.length}] ${getParseErrorMessage(e.error)}`)).join(", ")));
|
|
76
77
|
}
|
|
77
78
|
if (target === ConfigurationTarget.USER) {
|
|
78
79
|
scannedMcpServers = this.fromUserMcpServers(result);
|
|
@@ -130,7 +131,7 @@ let McpResourceScannerService = class McpResourceScannerService extends Disposab
|
|
|
130
131
|
allowEmptyContent: true
|
|
131
132
|
});
|
|
132
133
|
if (errors.length > 0) {
|
|
133
|
-
throw ( new Error("Failed to parse scanned MCP servers: " + errors.join(", ")));
|
|
134
|
+
throw ( new Error("Failed to parse scanned MCP servers: " + ( errors.map(e => `[${e.offset}, ${e.length}] ${getParseErrorMessage(e.error)}`)).join(", ")));
|
|
134
135
|
}
|
|
135
136
|
} catch (error) {
|
|
136
137
|
if (toFileOperationResult(error) !== FileOperationResult.FILE_NOT_FOUND) {
|
|
@@ -113,16 +113,16 @@ registerWorkbenchContribution2(
|
|
|
113
113
|
const jsonRegistry = ( Registry.as(Extensions.JSONContribution));
|
|
114
114
|
jsonRegistry.registerSchema(mcpSchemaId, mcpServerSchema);
|
|
115
115
|
( Registry.as(EditorExtensions.EditorPane)).registerEditorPane(
|
|
116
|
-
EditorPaneDescriptor.create(McpServerEditor, McpServerEditor.ID, ( localize(
|
|
116
|
+
EditorPaneDescriptor.create(McpServerEditor, McpServerEditor.ID, ( localize(13506, "MCP Server"))),
|
|
117
117
|
[( new SyncDescriptor(McpServerEditorInput))]
|
|
118
118
|
);
|
|
119
119
|
( Registry.as(Extensions$1.Quickaccess)).registerQuickAccessProvider({
|
|
120
120
|
ctor: McpResourceQuickAccess,
|
|
121
121
|
prefix: McpResourceQuickAccess.PREFIX,
|
|
122
122
|
when: ChatContextKeys.enabled,
|
|
123
|
-
placeholder: ( localize(
|
|
123
|
+
placeholder: ( localize(13507, "Filter to an MCP resource")),
|
|
124
124
|
helpEntries: [{
|
|
125
|
-
description: ( localize(
|
|
125
|
+
description: ( localize(13508, "MCP Server Resources")),
|
|
126
126
|
commandId: McpCommandIds.AddConfiguration
|
|
127
127
|
}]
|
|
128
128
|
});
|
|
@@ -43,7 +43,7 @@ let McpAddContextContribution = class McpAddContextContribution extends Disposab
|
|
|
43
43
|
_registerAddContextMenu() {
|
|
44
44
|
this._addContextMenu.value = this._chatContextPickService.registerChatContextItem({
|
|
45
45
|
type: "pickerPick",
|
|
46
|
-
label: ( localize(
|
|
46
|
+
label: ( localize(13509, "MCP Resources...")),
|
|
47
47
|
icon: Codicon.mcp,
|
|
48
48
|
isEnabled(widget) {
|
|
49
49
|
return !!widget.attachmentCapabilities.supportsMCPAttachments;
|
|
@@ -51,7 +51,7 @@ let McpAddContextContribution = class McpAddContextContribution extends Disposab
|
|
|
51
51
|
asPicker: () => {
|
|
52
52
|
const helper = this._instantiationService.createInstance(McpResourcePickHelper);
|
|
53
53
|
return {
|
|
54
|
-
placeholder: ( localize(
|
|
54
|
+
placeholder: ( localize(13510, "Select MCP Resource...")),
|
|
55
55
|
picks: (_query, token) => this._getResourcePicks(token, helper),
|
|
56
56
|
goBack: () => {
|
|
57
57
|
return helper.navigateBack();
|
|
@@ -8,6 +8,7 @@ import { IConfigurationService } from "@codingame/monaco-vscode-api/vscode/vs/pl
|
|
|
8
8
|
import { IInstantiationService, ServicesAccessor } from "@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation";
|
|
9
9
|
import { StorageScope } from "@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage";
|
|
10
10
|
import { IWorkbenchContribution } from "@codingame/monaco-vscode-api/vscode/vs/workbench/common/contributions";
|
|
11
|
+
import { IAgentHostCustomizationService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostCustomizationService.service";
|
|
11
12
|
import { IChatElicitationRequest, IChatToolInvocation } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatService/chatService";
|
|
12
13
|
import { IMcpServer, IMcpServerStartOpts } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes";
|
|
13
14
|
import { IMcpService } from "@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/mcp/common/mcpTypes.service";
|
|
@@ -18,6 +19,8 @@ export declare class ListMcpServerCommand extends Action2 {
|
|
|
18
19
|
private _runLocal;
|
|
19
20
|
private _runAgentHost;
|
|
20
21
|
}
|
|
22
|
+
type IAgentHostMcpServer = ReturnType<IAgentHostCustomizationService["getMcpServers"]>[number];
|
|
23
|
+
export declare function findLocalMcpServer(mcpService: IMcpService, server: IAgentHostMcpServer): IMcpServer | undefined;
|
|
21
24
|
export declare class McpAgentHostServerOptionsCommand extends Action2 {
|
|
22
25
|
constructor();
|
|
23
26
|
run(accessor: ServicesAccessor, agentHostSession: URI, customizationId: string): Promise<void>;
|
|
@@ -71,19 +74,23 @@ export declare class ShowOutput extends Action2 {
|
|
|
71
74
|
constructor();
|
|
72
75
|
run(accessor: ServicesAccessor, serverId: string): void;
|
|
73
76
|
}
|
|
77
|
+
interface IAgentHostMcpServerCommandArg {
|
|
78
|
+
readonly agentHostSession: URI;
|
|
79
|
+
readonly serverId: string;
|
|
80
|
+
}
|
|
74
81
|
export declare class RestartServer extends Action2 {
|
|
75
82
|
constructor();
|
|
76
|
-
run(accessor: ServicesAccessor, serverId: string, opts?: IMcpServerStartOpts): Promise<void>;
|
|
83
|
+
run(accessor: ServicesAccessor, serverId: string | IAgentHostMcpServerCommandArg, opts?: IMcpServerStartOpts): Promise<void>;
|
|
77
84
|
}
|
|
78
85
|
export declare class StartServer extends Action2 {
|
|
79
86
|
constructor();
|
|
80
|
-
run(accessor: ServicesAccessor, serverId: string, opts?: IMcpServerStartOpts & {
|
|
87
|
+
run(accessor: ServicesAccessor, serverId: string | IAgentHostMcpServerCommandArg, opts?: IMcpServerStartOpts & {
|
|
81
88
|
waitForLiveTools?: boolean;
|
|
82
89
|
}): Promise<void>;
|
|
83
90
|
}
|
|
84
91
|
export declare class StopServer extends Action2 {
|
|
85
92
|
constructor();
|
|
86
|
-
run(accessor: ServicesAccessor, serverId: string): Promise<void>;
|
|
93
|
+
run(accessor: ServicesAccessor, serverId: string | IAgentHostMcpServerCommandArg): Promise<void>;
|
|
87
94
|
}
|
|
88
95
|
export declare class McpBrowseCommand extends Action2 {
|
|
89
96
|
constructor();
|