diff --git a/.changes/unreleased/ENHANCEMENTS-20250905-233003.yaml b/.changes/unreleased/ENHANCEMENTS-20250905-233003.yaml new file mode 100644 index 0000000000..ebe0e44165 --- /dev/null +++ b/.changes/unreleased/ENHANCEMENTS-20250905-233003.yaml @@ -0,0 +1,6 @@ +kind: ENHANCEMENTS +body: Improve Terraform Configuration for MCP Server using resolveMcpServerDefinition. The documentation states that user interactions should happen in the resolveMcpServerDefinition function, so the Docker check is moved over here. The check just sees if the docker info command works. If it fails, it means Docker isn't installed or isn't running. +time: 2025-09-05T23:30:03.885514+05:30 +custom: + Issue: "2102" + Repository: vscode-terraform diff --git a/src/features/mcpServer.ts b/src/features/mcpServer.ts index 4ce65920db..483717b3d9 100644 --- a/src/features/mcpServer.ts +++ b/src/features/mcpServer.ts @@ -7,7 +7,6 @@ import TelemetryReporter from '@vscode/extension-telemetry'; import { exec } from 'child_process'; import { promisify } from 'util'; import * as vscode from 'vscode'; -import which from 'which'; const execAsync = promisify(exec); @@ -68,6 +67,9 @@ export class McpServerFeature { provideMcpServerDefinitions: () => { return this.provideMcpServerDefinitions(); }, + resolveMcpServerDefinition: (definition: McpServerDefinition) => { + return this.resolveMcpServerDefinition(definition); + }, }); } catch (error) { this.logError('Error registering MCP server provider', error); @@ -75,13 +77,10 @@ export class McpServerFeature { } } - private async provideMcpServerDefinitions(): Promise { + // According to VS Code API docs, no user interaction should happen here + // Just provide the available MCP server definitions + private provideMcpServerDefinitions(): McpServerDefinition[] { try { - const dockerAvailable = await this.dockerValidations(); - if (!dockerAvailable) { - return []; - } - const server: McpServerDefinition = { label: 'HashiCorp Terraform MCP Server', command: 'docker', @@ -89,20 +88,26 @@ export class McpServerFeature { env: {}, }; - this.showMcpServerInfoMessage(); - return [server]; } catch (error) { this.logError('Error providing MCP server definitions', error); return []; } } + + // All user interactions should happen here + // Should return resolved server definition if server should be started + private async resolveMcpServerDefinition(definition: McpServerDefinition): Promise { + const dockerAvailable = await this.dockerValidations(); + if (!dockerAvailable) { + throw new Error('Docker is required but not available or running'); + } + + return definition; + } + private async dockerValidations(): Promise { try { - if (!(await this.checkDockerAvailability())) { - return false; - } - if (!(await this.checkDockerRunning())) { return false; } @@ -114,25 +119,8 @@ export class McpServerFeature { } } - private async checkDockerAvailability(): Promise { - try { - await which('docker'); - return true; - } catch { - void vscode.window - .showWarningMessage( - 'Docker is required to run the Terraform MCP Server. Please install Docker to use this feature.', - 'Learn More', - ) - .then((selection) => { - if (selection === 'Learn More') { - void vscode.env.openExternal(vscode.Uri.parse('https://docs.docker.com/get-docker/')); - } - }); - return false; - } - } - + // Check if container runtime is available and running + // The 'docker info' command validates both installation and daemon status private async checkDockerRunning(): Promise { try { await execAsync('docker info', { timeout: 5000 }); @@ -140,10 +128,7 @@ export class McpServerFeature { } catch (error) { this.logError('Docker daemon check failed', error); void vscode.window - .showWarningMessage( - 'Docker is installed but not running. Please start Docker to use the Terraform MCP Server.', - 'Learn More', - ) + .showWarningMessage('Please install and start a Docker compatible runtime to use this feature.', 'Learn More') .then((selection) => { if (selection === 'Learn More') { void vscode.env.openExternal(vscode.Uri.parse('https://docs.docker.com/get-started/')); @@ -153,20 +138,6 @@ export class McpServerFeature { } } - private showMcpServerInfoMessage(): void { - const message = 'Terraform MCP Server is now available for GitHub Copilot integration.'; - const startAction = 'Start MCP Server'; - const learnMoreAction = 'Learn More'; - - void vscode.window.showInformationMessage(message, startAction, learnMoreAction).then((selection) => { - if (selection === startAction) { - void vscode.commands.executeCommand('workbench.action.quickOpen', '>MCP: List Servers'); - } else if (selection === learnMoreAction) { - void vscode.env.openExternal(vscode.Uri.parse('https://github.com/hashicorp/terraform-mcp-server')); - } - }); - } - dispose(): void { // context.subscriptions will be disposed by the extension, so any explicit code should not be required. }