Skip to content

Commit ee632f7

Browse files
owenrumneyCopilot
andauthored
fix: MCP Install in a remote dev env (#146)
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
1 parent 327ee91 commit ee632f7

File tree

3 files changed

+99
-35
lines changed

3 files changed

+99
-35
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# Change Log
22

3+
## 1.8.10
4+
5+
- Fix the MCP Server configuration when using a remote development config
6+
37
## 1.8.9
48

59
- Add support for custom proxy server and CA certificate provision

package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
"publisher": "AquaSecurityOfficial",
55
"description": "Find vulnerabilities, misconfigurations and exposed secrets in your code",
66
"icon": "images/icon.png",
7-
"version": "1.8.9",
7+
"version": "1.8.10",
88
"engines": {
99
"vscode": "^1.56.0"
1010
},
@@ -568,7 +568,7 @@
568568
},
569569
{
570570
"submenu": "trivyMcpMenu",
571-
"when": "view == trivyIssueViewer && trivy.mcpServerInstalled",
571+
"when": "view == trivyIssueViewer",
572572
"group": "5_trivyMcp@1"
573573
},
574574
{

src/mcp/install.ts

Lines changed: 93 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,19 @@ import * as vscode from 'vscode';
55
import { Output } from '../command/output';
66
import { openSettingsJsonAtSection } from '../utils';
77

8+
interface McpServerConfig {
9+
type: string;
10+
command: string;
11+
args: string[];
12+
}
13+
14+
interface McpJsonConfig {
15+
mcp?: {
16+
servers?: Record<string, McpServerConfig>;
17+
};
18+
servers?: Record<string, McpServerConfig>;
19+
}
20+
821
export function isTrivyMCPInstalled(): boolean {
922
const mcpConfig = vscode.workspace.getConfiguration('mcp');
1023
const mcpServers = mcpConfig.get('servers') as Record<string, object>;
@@ -49,6 +62,16 @@ export async function installTrivyMCPServer(): Promise<void> {
4962

5063
const trivyConfig = vscode.workspace.getConfiguration('trivy');
5164
const trivyBinary = trivyConfig.get<string>('binaryPath', 'trivy');
65+
const isRemote = Boolean(vscode.env.remoteName);
66+
const settingsTarget = isRemote
67+
? vscode.ConfigurationTarget.Workspace
68+
: vscode.ConfigurationTarget.Global;
69+
70+
if (isRemote) {
71+
Output.getInstance().appendLineWithTimestamp(
72+
'Remote workspace detected. Trivy MCP settings will be written to the current workspace so they stay alongside the remote binary.'
73+
);
74+
}
5275

5376
// make required changes to chat config
5477
const chatConfig = vscode.workspace.getConfiguration('chat');
@@ -58,11 +81,7 @@ export async function installTrivyMCPServer(): Promise<void> {
5881
'Enabling the agent in chat configuration to allow Trivy MCP server installation.'
5982
);
6083
// Enable the agent if it is not already enabled
61-
await chatConfig.update(
62-
'agent.enabled',
63-
true,
64-
vscode.ConfigurationTarget.Global
65-
);
84+
await chatConfig.update('agent.enabled', true, settingsTarget);
6685
}
6786

6887
const mcpDiscoveryEnabled = chatConfig.get<boolean>(
@@ -74,22 +93,7 @@ export async function installTrivyMCPServer(): Promise<void> {
7493
'Enabling MCP discovery in chat configuration to allow Trivy MCP server installation.'
7594
);
7695
// Enable MCP discovery if it is not already enabled
77-
await chatConfig.update(
78-
'mcp.discovery.enabled',
79-
true,
80-
vscode.ConfigurationTarget.Global
81-
);
82-
}
83-
84-
const mcpConfig = vscode.workspace.getConfiguration('mcp');
85-
let mcpServers = mcpConfig.get('servers') as Record<string, object>;
86-
if (!mcpServers || typeof mcpServers !== 'object') {
87-
Output.getInstance().appendLineWithTimestamp(
88-
'No MCP servers configured. Initializing with an empty object.'
89-
);
90-
// Initialize mcpServers if it is not defined or not an object
91-
await mcpConfig.update('servers', {}, vscode.ConfigurationTarget.Global);
92-
mcpServers = {};
96+
await chatConfig.update('mcp.discovery.enabled', true, settingsTarget);
9397
}
9498

9599
// Ensure trivy plugin installed
@@ -98,32 +102,88 @@ export async function installTrivyMCPServer(): Promise<void> {
98102
Output.getInstance().appendLineWithTimestamp(
99103
'Trivy plugin is not installed. Please install it before configuring the MCP server.'
100104
);
101-
return; // Exit if plugin is not installed
105+
return;
102106
}
107+
103108
const useAquaPlatform = trivyConfig.get('useAquaPlatform', false);
104109
const args = ['mcp', '--trivy-binary', trivyBinary];
105110
if (useAquaPlatform) {
106111
args.push('--use-aqua-platform');
107112
}
108113

109-
mcpServers['trivy'] = {
114+
const trivyServer: McpServerConfig = {
110115
type: 'stdio',
111-
command: 'trivy',
116+
command: trivyBinary,
112117
args,
113118
};
114119

115-
await vscode.workspace
116-
.getConfiguration('mcp')
117-
.update('servers', mcpServers, vscode.ConfigurationTarget.Global);
120+
// Open the MCP JSON file first to get the document
121+
const openCommand = isRemote
122+
? 'workbench.mcp.openRemoteUserMcpJson'
123+
: 'workbench.mcp.openUserMcpJson';
118124

119-
Output.getInstance().appendLineWithTimestamp(
120-
'Trivy MCP server has been successfully installed and configured.'
125+
await vscode.commands.executeCommand(openCommand);
126+
127+
// Wait for the editor to open
128+
await new Promise((resolve) => setTimeout(resolve, 100));
129+
130+
const editor = vscode.window.activeTextEditor;
131+
if (!editor) {
132+
Output.getInstance().appendLineWithTimestamp(
133+
'Failed to open MCP configuration file.'
134+
);
135+
return;
136+
}
137+
138+
const document = editor.document;
139+
if (!document.fileName.endsWith('mcp.json')) {
140+
Output.getInstance().appendLineWithTimestamp(
141+
'Unexpected file opened. Expected MCP configuration file.'
142+
);
143+
return;
144+
}
145+
const text = document.getText();
146+
147+
let config: McpJsonConfig = {};
148+
try {
149+
if (text.trim()) {
150+
config = JSON.parse(text);
151+
}
152+
} catch {
153+
Output.getInstance().appendLineWithTimestamp(
154+
'Failed to parse existing MCP configuration, creating new one.'
155+
);
156+
}
157+
158+
// Handle both possible structures: { servers: {} } or { mcp: { servers: {} } }
159+
if (config.mcp?.servers !== undefined) {
160+
config.mcp.servers['trivy'] = trivyServer;
161+
} else if (config.servers !== undefined) {
162+
config.servers['trivy'] = trivyServer;
163+
} else {
164+
config.servers = { trivy: trivyServer };
165+
}
166+
167+
const newContent = JSON.stringify(config, null, '\t');
168+
169+
const fullRange = new vscode.Range(
170+
document.positionAt(0),
171+
document.positionAt(text.length)
121172
);
122173

123-
// Open the user configuration file to show the changes
124-
await openSettingsJsonAtSection(
125-
'mcp.servers',
126-
'workbench.mcp.openUserMcpJson'
174+
try {
175+
await editor.edit((editBuilder) => {
176+
editBuilder.replace(fullRange, newContent);
177+
});
178+
await document.save();
179+
} catch (error) {
180+
Output.getInstance().appendLineWithTimestamp(
181+
`Failed to update MCP configuration: ${error instanceof Error ? error.message : String(error)}`
182+
);
183+
return;
184+
}
185+
Output.getInstance().appendLineWithTimestamp(
186+
'Trivy MCP server has been successfully installed and configured.'
127187
);
128188
}
129189

0 commit comments

Comments
 (0)