Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 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-20250909-163330.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
kind: ENHANCEMENTS
body: Configuration option `terraform.mcp.server.enabled` to enable or disable HashiCorp Terraform MCP Server integration
time: 2025-09-09T16:33:30.998854+05:30
custom:
Issue: "2106"
Repository: vscode-terraform
23 changes: 23 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -499,6 +499,13 @@
"scope": "machine",
"type": "string",
"markdownDescription": "Path to a file (`TF_LOG_PATH`) for Terraform executions to be logged used by the the Terraform Language Server. Support for variables (e.g. timestamp, pid, ppid) via Go template syntax `{{varName}}`"
},
"terraform.mcp.server.enabled": {
"order": 3,
"scope": "window",
"type": "boolean",
"default": true,
"description": "Enable HashiCorp Terraform MCP Server integration"
}
}
},
Expand Down Expand Up @@ -534,6 +541,14 @@
"command": "terraform.disableLanguageServer",
"title": "HashiCorp Terraform: Disable Language Server"
},
{
"command": "terraform.enableMcpServer",
"title": "HashiCorp Terraform: Enable MCP Server"
},
{
"command": "terraform.disableMcpServer",
"title": "HashiCorp Terraform: Disable MCP Server"
},
{
"command": "terraform.init",
"title": "HashiCorp Terraform: init"
Expand Down Expand Up @@ -646,6 +661,14 @@
"command": "terraform.disableLanguageServer",
"when": "config.terraform.languageServer.enable == true"
},
{
"command": "terraform.enableMcpServer",
"when": "config.terraform.mcp.server.enabled == false"
},
{
"command": "terraform.disableMcpServer",
"when": "config.terraform.mcp.server.enabled == true"
},
{
"command": "terraform.init",
"when": "config.terraform.languageServer.enable == true"
Expand Down
34 changes: 34 additions & 0 deletions src/commands/mcpServer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* Copyright (c) HashiCorp, Inc.
* SPDX-License-Identifier: MPL-2.0
*/

import * as vscode from 'vscode';
import { config, getScope } from '../utils/vscode';

export class McpServerCommands implements vscode.Disposable {
constructor(private context: vscode.ExtensionContext) {
this.context.subscriptions.push(
vscode.commands.registerCommand('terraform.enableMcpServer', async () => {
if (config('terraform').get('mcp.server.enabled') === true) {
return;
}

const scope: vscode.ConfigurationTarget = getScope('terraform', 'mcp.server.enabled');
await config('terraform').update('mcp.server.enabled', true, scope);
}),
vscode.commands.registerCommand('terraform.disableMcpServer', async () => {
if (config('terraform').get('mcp.server.enabled') === false) {
return;
}

const scope: vscode.ConfigurationTarget = getScope('terraform', 'mcp.server.enabled');
await config('terraform').update('mcp.server.enabled', false, scope);
}),
);
}

dispose(): void {
// context.subscriptions will be disposed by the extension, so any explicit code should not be required.
}
}
2 changes: 1 addition & 1 deletion src/commands/terraformls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ export class TerraformLSCommands implements vscode.Disposable {
this.context.subscriptions.push(
vscode.workspace.onDidChangeConfiguration(async (event: vscode.ConfigurationChangeEvent) => {
if (event.affectsConfiguration('terraform') || event.affectsConfiguration('terraform-ls')) {
const reloadMsg = 'Reload VSCode window to apply language server changes';
const reloadMsg = 'Reload VSCode window to apply configuration changes';
const selected = await vscode.window.showInformationMessage(reloadMsg, 'Reload');
if (selected === 'Reload') {
vscode.commands.executeCommand('workbench.action.reloadWindow');
Expand Down
4 changes: 3 additions & 1 deletion src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import { LanguageStatusFeature } from './features/languageStatus';
import { getInitializationOptions } from './settings';
import { TerraformLSCommands } from './commands/terraformls';
import { TerraformCommands } from './commands/terraform';
import { McpServerCommands } from './commands/mcpServer';
import * as lsStatus from './status/language';
import { TerraformCloudFeature } from './features/terraformCloud';
import { setupMockServer, stopMockServer } from './test/e2e/specs/mocks/server';
Expand Down Expand Up @@ -71,7 +72,8 @@ export async function activate(context: vscode.ExtensionContext): Promise<void>

context.subscriptions.push(new TerraformCloudFeature(context, reporter, tfcOutputChannel));

// Register MCP server feature
// Register MCP server commands and feature
context.subscriptions.push(new McpServerCommands(context));
context.subscriptions.push(new McpServerFeature(context, reporter, outputChannel));

if (config('terraform').get<boolean>('languageServer.enable') === false) {
Expand Down
19 changes: 18 additions & 1 deletion src/features/mcpServer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import TelemetryReporter from '@vscode/extension-telemetry';
import { exec } from 'child_process';
import { promisify } from 'util';
import * as vscode from 'vscode';
import { config } from '../utils/vscode';

const execAsync = promisify(exec);

Expand Down Expand Up @@ -55,7 +56,19 @@ export class McpServerFeature {
private isMcpApiAvailable(): boolean {
// Check if VS Code has the MCP API available
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return typeof (vscode as any).lm?.registerMcpServerDefinitionProvider === 'function';
const available = typeof (vscode as any).lm?.registerMcpServerDefinitionProvider === 'function';
if (!available) {
this.outputChannel.appendLine(`Terraform MCP API is not available in current VS Code version ${vscode.version}`);
}
return available;
}

private isMcpServerEnabled(): boolean {
const isEnabled = config('terraform').get<boolean>('mcp.server.enabled') === true;
if (!isEnabled) {
this.outputChannel.appendLine('HashiCorp Terraform MCP Server integration is disabled by configuration');
}
return isEnabled;
}

private registerMcpServerProvider(): vscode.Disposable | undefined {
Expand All @@ -81,6 +94,10 @@ export class McpServerFeature {
// Just provide the available MCP server definitions
private provideMcpServerDefinitions(): McpServerDefinition[] {
try {
if (!this.isMcpServerEnabled()) {
return [];
}

const server: McpServerDefinition = {
label: 'HashiCorp Terraform MCP Server',
command: 'docker',
Expand Down
Loading