Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .changes/unreleased/ENHANCEMENTS-20250905-233003.yaml
Original file line number Diff line number Diff line change
@@ -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
71 changes: 21 additions & 50 deletions src/features/mcpServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -68,41 +67,47 @@ export class McpServerFeature {
provideMcpServerDefinitions: () => {
return this.provideMcpServerDefinitions();
},
resolveMcpServerDefinition: (definition: McpServerDefinition) => {
return this.resolveMcpServerDefinition(definition);
},
});
} catch (error) {
this.logError('Error registering MCP server provider', error);
return undefined;
}
}

private async provideMcpServerDefinitions(): Promise<McpServerDefinition[]> {
// 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',
args: ['run', '-i', '--rm', 'hashicorp/terraform-mcp-server'],
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<McpServerDefinition> {
const dockerAvailable = await this.dockerValidations();
if (!dockerAvailable) {
throw new Error('Docker is required but not available or running');
}

return definition;
}

private async dockerValidations(): Promise<boolean> {
try {
if (!(await this.checkDockerAvailability())) {
return false;
}

if (!(await this.checkDockerRunning())) {
return false;
}
Expand All @@ -114,36 +119,16 @@ export class McpServerFeature {
}
}

private async checkDockerAvailability(): Promise<boolean> {
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<boolean> {
try {
await execAsync('docker info', { timeout: 5000 });
return true;
} 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/'));
Expand All @@ -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.
}
Expand Down
Loading