@@ -5,6 +5,19 @@ import * as vscode from 'vscode';
55import { Output } from '../command/output' ;
66import { 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+
821export 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