2
>
* Copyright (c) Microsoft Corporation. All rights reserved.
3
>
* Licensed under the MIT License. See License.txt in the project root for license information.
4
>
*--------------------------------------------------------------------------------------------*/
5
>
6
>
import { VSBuffer } from '../../../../../base/common/buffer.js';
7
>
import { Platform } from '../../../../../base/common/platform.js';
8
>
import { Mutable } from '../../../../../base/common/types.js';
9
>
import { URI } from '../../../../../base/common/uri.js';
10
>
import { INativeMcpDiscoveryData } from '../../../../../platform/mcp/common/nativeMcpDiscoveryHelper.js';
11
>
import { DiscoverySource } from '../mcpConfiguration.js';
12
>
import { McpCollectionSortOrder, McpServerDefinition, McpServerLaunch, McpServerTransportType } from '../mcpTypes.js';
13
>
14
>
export interface NativeMpcDiscoveryAdapter {
15
>
readonly remoteAuthority: string | null;
16
>
readonly id: string;
17
>
readonly order: number;
18
>
readonly discoverySource: DiscoverySource;
19
>
20
>
getFilePath(details: INativeMcpDiscoveryData): URI | undefined;
21
>
adaptFile(contents: VSBuffer, details: INativeMcpDiscoveryData): Promise<McpServerDefinition[] | undefined>;
22
>
}
23
>
24
>
export async function claudeConfigToServerDefinition(idPrefix: string, contents: VSBuffer, cwd?: URI) {
25
>
let parsed: {
26
>
mcpServers: Record<string, {
27
>
command: string;
28
>
args?: string[];
29
>
env?: Record<string, string>;
30
>
url?: string;
31
>
headers?: Record<string, string>;
32
>
}>;
33
>
};
34
>
35
>
try {
36
>
parsed = JSON.parse(contents.toString());
37
>
} catch {
38
return;
39
}
41
>
return Promise.all(Object.entries(parsed.mcpServers).map(async ([name, server]): Promise<Mutable<McpServerDefinition>> => {
42
>
const launch: McpServerLaunch = server.url ? {
43
>
type: McpServerTransportType.HTTP,
44
>
uri: URI.parse(server.url),
45
>
headers: Object.entries(server.headers ?? {}),
46
>
} : {
47
>
type: McpServerTransportType.Stdio,
48
>
args: server.args || [],
49
>
command: server.command,
50
>
env: server.env || {},
51
>
envFile: undefined,
52
>
cwd: cwd?.fsPath,
53
>
sandbox: undefined
54
>
};
55
>
56
>
return {
57
>
id: `${idPrefix}.${name}`,
58
>
label: name,
59
>
launch,
60
>
cacheNonce: await McpServerLaunch.hash(launch),
61
>
};
62
>
}));
63
>
}
64
>
65
>
export class ClaudeDesktopMpcDiscoveryAdapter implements NativeMpcDiscoveryAdapter {
66
>
public id: string;
67
>
public readonly order = McpCollectionSortOrder.Filesystem;
68
>
public readonly discoverySource: DiscoverySource = DiscoverySource.ClaudeDesktop;
69
>
70
>
constructor(public readonly remoteAuthority: string | null) {
71
this.id = `claude-desktop.${this.remoteAuthority}`;
72
}
74
>
getFilePath({ platform, winAppData, xdgHome, homedir }: INativeMcpDiscoveryData): URI | undefined {
75
if (platform === Platform.Windows) {
76
const appData = winAppData || URI.joinPath(homedir, 'AppData', 'Roaming');