Skip to content

Commit f462d2d

Browse files
authored
adopt to mcp servers cdn url (#252451)
1 parent dfac64c commit f462d2d

File tree

10 files changed

+200
-81
lines changed

10 files changed

+200
-81
lines changed

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "code-oss-dev",
33
"version": "1.102.0",
4-
"distro": "79cbb0dbbd5ce21e68ca577799774080a568f496",
4+
"distro": "4b888f68839a0c5dc8dd79e00bf18e6670f3cdd7",
55
"author": {
66
"name": "Microsoft Corporation"
77
},
@@ -234,4 +234,4 @@
234234
"optionalDependencies": {
235235
"windows-foreground-love": "0.5.0"
236236
}
237-
}
237+
}

src/vs/base/common/product.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ export interface IProductConfiguration {
9797
readonly extensionsGallery?: {
9898
readonly serviceUrl: string;
9999
readonly controlUrl: string;
100+
readonly mcpUrl: string;
100101
readonly extensionUrlTemplate: string;
101102
readonly resourceUrlTemplate: string;
102103
readonly nlsBaseUrl: string;

src/vs/platform/mcp/common/mcpGalleryService.ts

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
*--------------------------------------------------------------------------------------------*/
55

66
import { CancellationToken } from '../../../base/common/cancellation.js';
7+
import { MarkdownString } from '../../../base/common/htmlContent.js';
78
import { Disposable } from '../../../base/common/lifecycle.js';
89
import { Schemas } from '../../../base/common/network.js';
910
import { dirname, joinPath } from '../../../base/common/resources.js';
1011
import { uppercaseFirstLetter } from '../../../base/common/strings.js';
12+
import { isString } from '../../../base/common/types.js';
1113
import { URI } from '../../../base/common/uri.js';
1214
import { localize } from '../../../nls.js';
1315
import { IConfigurationService } from '../../configuration/common/configuration.js';
@@ -21,17 +23,20 @@ interface IRawGalleryServersResult {
2123
readonly servers: readonly IRawGalleryMcpServer[];
2224
}
2325

24-
2526
interface IRawGalleryMcpServer {
26-
readonly id: string;
27+
readonly id?: string;
2728
readonly name: string;
2829
readonly description: string;
2930
readonly displayName?: string;
30-
readonly repository: {
31+
readonly iconUrl?: string;
32+
readonly iconUrlDark?: string;
33+
readonly iconUrlLight?: string;
34+
readonly codicon?: string;
35+
readonly repository?: {
3136
readonly url: string;
3237
readonly source: string;
3338
};
34-
readonly version_detail: {
39+
readonly version_detail?: {
3540
readonly version: string;
3641
readonly release_date: string;
3742
readonly is_latest: boolean;
@@ -43,6 +48,7 @@ interface IRawGalleryMcpServer {
4348
readonly is_verified: boolean;
4449
};
4550
readonly package_types?: readonly PackageType[];
51+
readonly manifest?: IMcpServerManifest;
4652
}
4753

4854
type RawGalleryMcpServerManifest = IRawGalleryMcpServer & IMcpServerManifest;
@@ -81,7 +87,26 @@ export class McpGalleryService extends Disposable implements IMcpGalleryService
8187
return galleryServers;
8288
}
8389

90+
async getMcpServer(name: string): Promise<IGalleryMcpServer | undefined> {
91+
const mcpUrl = this.getMcpGalleryUrl() ?? this.productService.extensionsGallery?.mcpUrl;
92+
if (!mcpUrl) {
93+
return undefined;
94+
}
95+
96+
const { servers } = await this.fetchGallery(mcpUrl, CancellationToken.None);
97+
const server = servers.find(item => item.name === name);
98+
return server ? this.toGalleryMcpServer(server) : undefined;
99+
}
100+
84101
async getManifest(gallery: IGalleryMcpServer, token: CancellationToken): Promise<IMcpServerManifest> {
102+
if (gallery.manifest) {
103+
return gallery.manifest;
104+
}
105+
106+
if (!gallery.manifestUrl) {
107+
throw new Error(`No manifest URL found for ${gallery.name}`);
108+
}
109+
85110
const uri = URI.parse(gallery.manifestUrl);
86111
if (uri.scheme === Schemas.file) {
87112
try {
@@ -125,6 +150,10 @@ export class McpGalleryService extends Disposable implements IMcpGalleryService
125150
}
126151
}
127152

153+
if (uri.authority !== 'raw.githubusercontent.com') {
154+
return new MarkdownString(localize('readme.viewInBrowser', "You can find information about this server [here]({0})", readmeUrl)).value;
155+
}
156+
128157
const context = await this.requestService.request({
129158
type: 'GET',
130159
url: readmeUrl,
@@ -149,14 +178,15 @@ export class McpGalleryService extends Disposable implements IMcpGalleryService
149178
}
150179

151180
return {
152-
id: item.id,
181+
id: item.id ?? item.name,
153182
name: item.name,
154183
displayName: item.displayName ?? nameParts[nameParts.length - 1].split('-').map(s => uppercaseFirstLetter(s)).join(' '),
155-
url: item.repository.url,
184+
url: item.repository?.url,
156185
description: item.description,
157-
version: item.version_detail.version,
158-
lastUpdated: Date.parse(item.version_detail.release_date),
159-
repositoryUrl: item.repository.url,
186+
version: item.version_detail?.version,
187+
lastUpdated: item.version_detail ? Date.parse(item.version_detail.release_date) : undefined,
188+
repositoryUrl: item.repository?.url,
189+
codicon: item.codicon,
160190
readmeUrl: item.readmeUrl,
161191
manifestUrl: this.getManifestUrl(item),
162192
packageTypes: item.package_types ?? [],
@@ -166,15 +196,19 @@ export class McpGalleryService extends Disposable implements IMcpGalleryService
166196
link: item.publisher.url,
167197
verified: item.publisher.is_verified,
168198
} : undefined,
199+
manifest: item.manifest
169200
};
170201
}
171202

172-
private async fetchGallery(token: CancellationToken): Promise<IRawGalleryServersResult> {
173-
const mcpGalleryUrl = this.getMcpGalleryUrl();
203+
private async fetchGallery(token: CancellationToken): Promise<IRawGalleryServersResult>;
204+
private async fetchGallery(url: string, token: CancellationToken): Promise<IRawGalleryServersResult>;
205+
private async fetchGallery(arg1: any, arg2?: any): Promise<IRawGalleryServersResult> {
206+
const mcpGalleryUrl = isString(arg1) ? arg1 : this.getMcpGalleryUrl();
174207
if (!mcpGalleryUrl) {
175208
return Promise.resolve({ servers: [] });
176209
}
177210

211+
const token = isString(arg1) ? arg2 : arg1;
178212
const uri = URI.parse(mcpGalleryUrl);
179213
if (uri.scheme === Schemas.file) {
180214
try {
@@ -195,16 +229,16 @@ export class McpGalleryService extends Disposable implements IMcpGalleryService
195229
return result || { servers: [] };
196230
}
197231

198-
private getManifestUrl(item: IRawGalleryMcpServer): string {
232+
private getManifestUrl(item: IRawGalleryMcpServer): string | undefined {
199233
const mcpGalleryUrl = this.getMcpGalleryUrl();
200234

201235
if (!mcpGalleryUrl) {
202-
return item.repository.url;
236+
return undefined;
203237
}
204238

205239
const uri = URI.parse(mcpGalleryUrl);
206240
if (uri.scheme === Schemas.file) {
207-
return joinPath(dirname(uri), item.id).fsPath;
241+
return joinPath(dirname(uri), item.id ?? item.name).fsPath;
208242
}
209243

210244
return `${mcpGalleryUrl}/${item.id}`;

src/vs/platform/mcp/common/mcpManagement.ts

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ export interface IScannedMcpServers {
1919
export interface IScannedMcpServer {
2020
readonly id: string;
2121
readonly name: string;
22-
readonly version: string;
22+
readonly version?: string;
2323
readonly gallery?: boolean;
2424
readonly config: IMcpServerConfiguration;
2525
}
@@ -38,7 +38,11 @@ export interface ILocalMcpServer {
3838
readonly readmeUrl?: URI;
3939
readonly publisher?: string;
4040
readonly publisherDisplayName?: string;
41-
readonly iconUrl?: string;
41+
readonly icon?: {
42+
readonly dark: string;
43+
readonly light: string;
44+
};
45+
readonly codicon?: string;
4246
readonly manifest?: IMcpServerManifest;
4347
}
4448

@@ -84,7 +88,7 @@ export const enum PackageType {
8488

8589
export interface IMcpServerPackage {
8690
readonly name: string;
87-
readonly version: string;
91+
readonly version?: string;
8892
readonly registry_name: PackageType;
8993
readonly package_arguments?: readonly IMcpServerArgument[];
9094
readonly runtime_arguments?: readonly IMcpServerArgument[];
@@ -93,31 +97,36 @@ export interface IMcpServerPackage {
9397

9498
export interface IMcpServerRemote {
9599
readonly url: string;
96-
readonly transport_type: 'streamable' | 'sse';
97-
readonly headers: ReadonlyArray<IMcpServerKeyValueInput>;
100+
readonly transport_type?: 'streamable' | 'sse';
101+
readonly headers?: ReadonlyArray<IMcpServerKeyValueInput>;
98102
}
99103

100104
export interface IMcpServerManifest {
101-
readonly packages: readonly IMcpServerPackage[];
102-
readonly remotes: readonly IMcpServerRemote[];
105+
readonly packages?: readonly IMcpServerPackage[];
106+
readonly remotes?: readonly IMcpServerRemote[];
103107
}
104108

105109
export interface IGalleryMcpServer {
106110
readonly id: string;
107111
readonly name: string;
108112
readonly displayName: string;
109-
readonly url: string;
113+
readonly url?: string;
114+
readonly icon?: {
115+
readonly dark: string;
116+
readonly light: string;
117+
};
110118
readonly description: string;
111-
readonly version: string;
112-
readonly lastUpdated: number;
113-
readonly repositoryUrl: string;
114-
readonly manifestUrl: string;
119+
readonly version?: string;
120+
readonly lastUpdated?: number;
121+
readonly repositoryUrl?: string;
122+
readonly manifestUrl?: string;
123+
readonly manifest?: IMcpServerManifest;
115124
readonly packageTypes: readonly PackageType[];
116125
readonly readmeUrl?: string;
117126
readonly publisher: string;
118127
readonly publisherDisplayName?: string;
119128
readonly publisherDomain?: { link: string; verified: boolean };
120-
readonly iconUrl?: string;
129+
readonly codicon?: string;
121130
readonly licenseUrl?: string;
122131
readonly installCount?: number;
123132
readonly rating?: number;
@@ -138,6 +147,7 @@ export interface IMcpGalleryService {
138147
readonly _serviceBrand: undefined;
139148
isEnabled(): boolean;
140149
query(options?: IQueryOptions, token?: CancellationToken): Promise<IGalleryMcpServer[]>;
150+
getMcpServer(server: string): Promise<IGalleryMcpServer | undefined>;
141151
getManifest(extension: IGalleryMcpServer, token: CancellationToken): Promise<IMcpServerManifest>;
142152
getReadme(extension: IGalleryMcpServer, token: CancellationToken): Promise<string>;
143153
}

0 commit comments

Comments
 (0)