Skip to content

Commit 8ec73aa

Browse files
authored
feat: file definitions for other code assistants like Cline, Windsurf… (#32)
1 parent f0466f6 commit 8ec73aa

File tree

2 files changed

+75
-3
lines changed

2 files changed

+75
-3
lines changed

src/main.ts

Lines changed: 57 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,11 @@ type MCPFileGroupsResultRecord = Record<string, MCPFileGroupsResult>
4343

4444
const osSpecificPaths: { [key: string]: MCPFilePath[] } = {
4545
claude: [],
46-
cursor: []
46+
cursor: [],
47+
vscode: [],
48+
cline: [],
49+
windsurf: [],
50+
roo: []
4751
}
4852

4953
if (platform() === 'win32') {
@@ -54,6 +58,21 @@ if (platform() === 'win32') {
5458
{ filePath: `${process.env.HOME}\\.cursor\\mcp.json`, type: 'global' },
5559
{ filePath: '.cursor\\mcp.json', type: 'local' }
5660
]
61+
osSpecificPaths['vscode'] = [
62+
{ filePath: '.vscode\\mcp.json', type: 'local' },
63+
{ filePath: `${process.env.APPDATA}\\Code\\User\\settings.json`, type: 'global' },
64+
{ filePath: `${process.env.APPDATA}\\Code - Insiders\\User\\settings.json`, type: 'global' },
65+
]
66+
osSpecificPaths['cline'] = [
67+
{ filePath: `${process.env.APPDATA}\\Code\\User\\globalStorage\\saoudrizwan.claude-dev\\settings\\cline_mcp_settings.json`, type: 'global' },
68+
{ filePath: `${process.env.APPDATA}\\Code - Insiders\\User\\globalStorage\\saoudrizwan.claude-dev\\settings\\cline_mcp_settings.json`, type: 'global' }
69+
]
70+
osSpecificPaths['windsurf'] = [
71+
{ filePath: '.codeium\\windsurf\\mcp_config.json', type: 'local' },
72+
]
73+
osSpecificPaths['roo'] = [
74+
{ filePath: `${process.env.APPDATA}\\Code\\User\\globalStorage\\rooveterinaryinc.roo-cline\\settings\\cline_mcp_settings.json`, type: 'global' },
75+
{ filePath: `${process.env.APPDATA}\\Code - Insiders\\User\\globalStorage\\rooveterinaryinc.roo-cline\\settings\\cline_mcp_settings.json`, type: 'global' },]
5776
} else {
5877
osSpecificPaths['claude'] = [
5978
{ filePath: '~/Library/Application Support/Claude/claude_desktop_config.json', type: 'global' }
@@ -62,6 +81,22 @@ if (platform() === 'win32') {
6281
{ filePath: '~/.cursor/mcp.json', type: 'global' },
6382
{ filePath: '.cursor/mcp.json', type: 'local' }
6483
]
84+
osSpecificPaths['vscode'] = [
85+
{ filePath: '.vscode/mcp.json', type: 'local' },
86+
{ filePath: '~/Library/Application Support/Code/User/settings.json', type: 'global' },
87+
{ filePath: '~/Library/Application Support/Code - Insiders/User/settings.json', type: 'global' },
88+
]
89+
osSpecificPaths['cline'] = [
90+
{ filePath: '~/Library/Application Support/Code/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json', type: 'global' },
91+
{ filePath: '~/Library/Application Support/Code - Insiders/User/globalStorage/saoudrizwan.claude-dev/settings/cline_mcp_settings.json', type: 'global' }
92+
]
93+
osSpecificPaths['windsurf'] = [
94+
{ filePath: '.codeium/windsurf/mcp_config.json', type: 'local' },
95+
]
96+
osSpecificPaths['roo'] = [
97+
{ filePath: '~/Library/Application Support/Code/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json', type: 'global' },
98+
{ filePath: '~/Library/Application Support/Code - Insiders/User/globalStorage/rooveterinaryinc.roo-cline/settings/cline_mcp_settings.json', type: 'global' },
99+
]
65100
}
66101

67102
export class MCPFiles {
@@ -75,6 +110,26 @@ export class MCPFiles {
75110
name: 'cursor',
76111
friendlyName: 'Cursor',
77112
paths: osSpecificPaths['cursor']
113+
},
114+
vscode: {
115+
name: 'vscode',
116+
friendlyName: 'VS Code',
117+
paths: osSpecificPaths['vscode']
118+
},
119+
cline: {
120+
name: 'cline',
121+
friendlyName: 'Cline',
122+
paths: osSpecificPaths['cline']
123+
},
124+
windsurf: {
125+
name: 'windsurf',
126+
friendlyName: 'Windsurf',
127+
paths: osSpecificPaths['windsurf']
128+
},
129+
roo: {
130+
name: 'roo',
131+
friendlyName: 'Roo',
132+
paths: osSpecificPaths['roo']
78133
}
79134
}
80135

@@ -111,6 +166,7 @@ export class MCPFiles {
111166
const parsable = await MCPConfigLinter.isValidSyntax()
112167
filePathData.parsable = parsable
113168

169+
// @TODO if file isn't parsable we should skip the following logic here
114170
const mcpServersData: MCPServerInfo[] = []
115171
const mcpServersFromConfig = await MCPConfigLinter.getMCPServers()
116172
// let's iterate over the mcpServer Record and access the server objects

src/services/mcp-config-linter-service.ts

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,27 @@ export class MCPConfigLinterService {
2626

2727
async getMCPServers (): Promise<Record<string, object>> {
2828
const fileContentRaw = await this.getFileContent()
29+
30+
// @TODO parse this file that may have comments inside it
31+
// can use comment-json npm package or similar
2932
const fileContentsData = JSON.parse(fileContentRaw)
3033

31-
const mcpServers = fileContentsData?.mcpServers
34+
// VS Code uses `servers`
35+
if (fileContentsData?.servers) {
36+
return fileContentsData.servers
37+
}
38+
39+
// VS Code global settings.json file uses `mcp` -> `servers`
40+
if (fileContentsData?.mcp?.servers) {
41+
return fileContentsData.mcp.servers
42+
}
43+
44+
// Claude and Cursor use the `mcpServers` key
45+
if (fileContentsData?.mcpServers) {
46+
return fileContentsData.mcpServers
47+
}
3248

33-
return mcpServers
49+
return {}
3450
}
3551

3652
async getFileContent (): Promise<string> {

0 commit comments

Comments
 (0)