From ce3f794bb5695fdf9bde5afcc4dcf6c9c37a8fad Mon Sep 17 00:00:00 2001 From: Phorcys Date: Tue, 24 Feb 2026 02:16:43 +0000 Subject: [PATCH 1/8] feat: add `mcp_config` input variable to vscode-desktop-core module --- .../coder/modules/vscode-desktop-core/main.tf | 44 ++++++++++++++----- 1 file changed, 33 insertions(+), 11 deletions(-) diff --git a/registry/coder/modules/vscode-desktop-core/main.tf b/registry/coder/modules/vscode-desktop-core/main.tf index 9a7da34c1..ad203a2b7 100644 --- a/registry/coder/modules/vscode-desktop-core/main.tf +++ b/registry/coder/modules/vscode-desktop-core/main.tf @@ -26,11 +26,22 @@ variable "open_recent" { default = false } +variable "mcp_config" { + type = string + description = "JSON-encoded string to configure MCP servers for the IDE. When set, writes mcp_config.json in var.config_folder." + default = "" +} + variable "protocol" { type = string description = "The URI protocol the IDE." } +variable "config_folder" { + type = string + description = "The path of the IDE's configuration folder." +} + variable "coder_app_icon" { type = string description = "The icon of the coder_app." @@ -85,18 +96,29 @@ resource "coder_app" "vscode-desktop" { data.coder_workspace.me.access_url, "&token=$SESSION_TOKEN", ]) +} - /* - url = join("", [ - "vscode://coder.coder-remote/open", - "?owner=${data.coder_workspace_owner.me.name}", - "&workspace=${data.coder_workspace.me.name}", - var.folder != "" ? join("", ["&folder=", var.folder]) : "", - var.open_recent ? "&openRecent" : "", - "&url=${data.coder_workspace.me.access_url}", - "&token=$SESSION_TOKEN", - ]) - */ +resource "coder_script" "vscode-desktop-mcp" { + agent_id = var.agent_id + count = var.mcp_config != "" ? 1 : 0 + + icon = var.coder_app_icon + display_name = "${var.coder_app_display_name} MCP" + + run_on_start = true + start_blocks_login = false + + script = <<-EOT + #!/bin/sh + set -euo pipefail + + IDE_CONFIG_FOLDER="${var.config_folder}" + IDE_MCP_CONFIG_PATH="$IDE_CONFIG_FOLDER/mcp_config.json" + + mkdir -p "$IDE_CONFIG_FOLDER" + echo -n "${base64encode(var.mcp_config)}" | base64 -d > "$IDE_MCP_CONFIG_PATH" + chmod 600 "$IDE_MCP_CONFIG_PATH" + EOT } output "ide_uri" { From bec945775d7ec586ef5df9ca556f3f16f9d33ebe Mon Sep 17 00:00:00 2001 From: Phorcys Date: Tue, 24 Feb 2026 02:43:59 +0000 Subject: [PATCH 2/8] fix: add tests --- .../modules/vscode-desktop-core/main.test.ts | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/registry/coder/modules/vscode-desktop-core/main.test.ts b/registry/coder/modules/vscode-desktop-core/main.test.ts index 87674f32d..692a5e584 100644 --- a/registry/coder/modules/vscode-desktop-core/main.test.ts +++ b/registry/coder/modules/vscode-desktop-core/main.test.ts @@ -3,6 +3,11 @@ import { runTerraformApply, runTerraformInit, testRequiredVariables, + runContainer, + execContainer, + removeContainer, + findResourceInstance, + readFileContainer, } from "~test"; // hardcoded coder_app name in main.tf @@ -16,6 +21,7 @@ const defaultVariables = { coder_app_display_name: "VS Code Desktop", protocol: "vscode", + config_folder: "$HOME/.vscode" }; describe("vscode-desktop-core", async () => { @@ -134,4 +140,41 @@ describe("vscode-desktop-core", async () => { expect(coder_app?.instances[0].attributes.group).toBe("web-app-group"); }); }); + + it("writes mcp_config.json when mcp_config variable provided", async () => { + const id = await runContainer("alpine"); + + try { + const mcp_config = JSON.stringify({ + servers: { demo: { url: "http://localhost:1234" } }, + }); + + const state = await runTerraformApply(import.meta.dir, { + ...defaultVariables, + + mcp_config, + }); + + const script = findResourceInstance( + state, + "coder_script", + "vscode-desktop-mcp", + ).script; + + const resp = await execContainer(id, ["sh", "-c", script]); + if (resp.exitCode !== 0) { + console.log(resp.stdout); + console.log(resp.stderr); + } + expect(resp.exitCode).toBe(0); + + const content = await readFileContainer( + id, + `${defaultVariables.config_folder.replace("$HOME", "/root")}/mcp_config.json`, + ); + expect(content).toBe(mcp_config); + } finally { + await removeContainer(id); + } + }, 10000); }); From 1bfe6a57e8dd2febe0cab7eceef43e91464e4ebe Mon Sep 17 00:00:00 2001 From: Phorcys Date: Tue, 24 Feb 2026 02:52:06 +0000 Subject: [PATCH 3/8] chore: `bun fmt` --- registry/coder/modules/vscode-desktop-core/main.test.ts | 2 +- registry/coder/modules/vscode-desktop-core/main.tf | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/registry/coder/modules/vscode-desktop-core/main.test.ts b/registry/coder/modules/vscode-desktop-core/main.test.ts index 692a5e584..2db12a2d0 100644 --- a/registry/coder/modules/vscode-desktop-core/main.test.ts +++ b/registry/coder/modules/vscode-desktop-core/main.test.ts @@ -21,7 +21,7 @@ const defaultVariables = { coder_app_display_name: "VS Code Desktop", protocol: "vscode", - config_folder: "$HOME/.vscode" + config_folder: "$HOME/.vscode", }; describe("vscode-desktop-core", async () => { diff --git a/registry/coder/modules/vscode-desktop-core/main.tf b/registry/coder/modules/vscode-desktop-core/main.tf index ad203a2b7..4d16420f0 100644 --- a/registry/coder/modules/vscode-desktop-core/main.tf +++ b/registry/coder/modules/vscode-desktop-core/main.tf @@ -108,7 +108,7 @@ resource "coder_script" "vscode-desktop-mcp" { run_on_start = true start_blocks_login = false - script = <<-EOT + script = <<-EOT #!/bin/sh set -euo pipefail @@ -124,4 +124,4 @@ resource "coder_script" "vscode-desktop-mcp" { output "ide_uri" { value = coder_app.vscode-desktop.url description = "IDE URI." -} \ No newline at end of file +} From 909016687412fda7455828febb4a41074d793dfd Mon Sep 17 00:00:00 2001 From: Phorcys Date: Tue, 24 Feb 2026 02:58:14 +0000 Subject: [PATCH 4/8] feat: make `mcp_config` type `map(any)` to enforce valid JSON and prevent mistakes --- registry/coder/modules/vscode-desktop-core/main.tf | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/registry/coder/modules/vscode-desktop-core/main.tf b/registry/coder/modules/vscode-desktop-core/main.tf index 4d16420f0..416d03bd4 100644 --- a/registry/coder/modules/vscode-desktop-core/main.tf +++ b/registry/coder/modules/vscode-desktop-core/main.tf @@ -27,9 +27,9 @@ variable "open_recent" { } variable "mcp_config" { - type = string - description = "JSON-encoded string to configure MCP servers for the IDE. When set, writes mcp_config.json in var.config_folder." - default = "" + type = map(any) + description = "MCP server configuration for the IDE. When set, writes mcp_config.json in var.config_folder." + default = null } variable "protocol" { @@ -100,7 +100,7 @@ resource "coder_app" "vscode-desktop" { resource "coder_script" "vscode-desktop-mcp" { agent_id = var.agent_id - count = var.mcp_config != "" ? 1 : 0 + count = var.mcp_config != null ? 1 : 0 icon = var.coder_app_icon display_name = "${var.coder_app_display_name} MCP" @@ -116,7 +116,7 @@ resource "coder_script" "vscode-desktop-mcp" { IDE_MCP_CONFIG_PATH="$IDE_CONFIG_FOLDER/mcp_config.json" mkdir -p "$IDE_CONFIG_FOLDER" - echo -n "${base64encode(var.mcp_config)}" | base64 -d > "$IDE_MCP_CONFIG_PATH" + echo -n "${base64encode(jsonencode(var.mcp_config))}" | base64 -d > "$IDE_MCP_CONFIG_PATH" chmod 600 "$IDE_MCP_CONFIG_PATH" EOT } From 6840be6315921951d0f9c08d02a8d11335aa0448 Mon Sep 17 00:00:00 2001 From: Phorcys Date: Tue, 24 Feb 2026 14:33:38 +0000 Subject: [PATCH 5/8] feat: add symlink to `mcp.json` in vscode-desktop-core --- registry/coder/modules/vscode-desktop-core/main.tf | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/registry/coder/modules/vscode-desktop-core/main.tf b/registry/coder/modules/vscode-desktop-core/main.tf index 416d03bd4..9ea962886 100644 --- a/registry/coder/modules/vscode-desktop-core/main.tf +++ b/registry/coder/modules/vscode-desktop-core/main.tf @@ -116,8 +116,12 @@ resource "coder_script" "vscode-desktop-mcp" { IDE_MCP_CONFIG_PATH="$IDE_CONFIG_FOLDER/mcp_config.json" mkdir -p "$IDE_CONFIG_FOLDER" + echo -n "${base64encode(jsonencode(var.mcp_config))}" | base64 -d > "$IDE_MCP_CONFIG_PATH" chmod 600 "$IDE_MCP_CONFIG_PATH" + + # Cursor/Windsurf use this config instead, no need for chmod as symlinks do not have modes + ln -s "$IDE_MCP_CONFIG_PATH" "$IDE_CONFIG_FOLDER/mcp.json" EOT } From a13bc1ce481336014314acd94a05b926947edb63 Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 17:48:40 +0000 Subject: [PATCH 6/8] =?UTF-8?q?chore:=20bump=20vscode-desktop-core=20versi?= =?UTF-8?q?on=20(minor)=20v1.0.2=20=E2=86=92=20v1.1.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- registry/coder/modules/vscode-desktop-core/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/coder/modules/vscode-desktop-core/README.md b/registry/coder/modules/vscode-desktop-core/README.md index 1b86783ad..837ff3491 100644 --- a/registry/coder/modules/vscode-desktop-core/README.md +++ b/registry/coder/modules/vscode-desktop-core/README.md @@ -16,7 +16,7 @@ The VSCode Desktop Core module is a building block for modules that need to expo ```tf module "vscode-desktop-core" { source = "registry.coder.com/coder/vscode-desktop-core/coder" - version = "1.0.2" + version = "1.1.0" agent_id = var.agent_id From ebecd1d16d73ab623584c364e7c1bf57841a254e Mon Sep 17 00:00:00 2001 From: DevCats Date: Wed, 11 Mar 2026 12:54:59 -0500 Subject: [PATCH 7/8] Apply suggestion from @DevelopmentCats --- registry/coder/modules/vscode-desktop-core/main.tf | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/registry/coder/modules/vscode-desktop-core/main.tf b/registry/coder/modules/vscode-desktop-core/main.tf index 9ea962886..ba4111e60 100644 --- a/registry/coder/modules/vscode-desktop-core/main.tf +++ b/registry/coder/modules/vscode-desktop-core/main.tf @@ -37,7 +37,7 @@ variable "protocol" { description = "The URI protocol the IDE." } -variable "config_folder" { +variable "config_dir" { type = string description = "The path of the IDE's configuration folder." } From 4f3a8814bd7c1f39a3efbf0bbd7934d74fcf51ea Mon Sep 17 00:00:00 2001 From: "blink-so[bot]" <211532188+blink-so[bot]@users.noreply.github.com> Date: Wed, 11 Mar 2026 17:58:03 +0000 Subject: [PATCH 8/8] fix: rename config_folder to config_dir in vscode-desktop-core --- registry/coder/modules/vscode-desktop-core/main.test.ts | 4 ++-- registry/coder/modules/vscode-desktop-core/main.tf | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/registry/coder/modules/vscode-desktop-core/main.test.ts b/registry/coder/modules/vscode-desktop-core/main.test.ts index 2db12a2d0..436159784 100644 --- a/registry/coder/modules/vscode-desktop-core/main.test.ts +++ b/registry/coder/modules/vscode-desktop-core/main.test.ts @@ -21,7 +21,7 @@ const defaultVariables = { coder_app_display_name: "VS Code Desktop", protocol: "vscode", - config_folder: "$HOME/.vscode", + config_dir: "$HOME/.vscode", }; describe("vscode-desktop-core", async () => { @@ -170,7 +170,7 @@ describe("vscode-desktop-core", async () => { const content = await readFileContainer( id, - `${defaultVariables.config_folder.replace("$HOME", "/root")}/mcp_config.json`, + `${defaultVariables.config_dir.replace("$HOME", "/root")}/mcp_config.json`, ); expect(content).toBe(mcp_config); } finally { diff --git a/registry/coder/modules/vscode-desktop-core/main.tf b/registry/coder/modules/vscode-desktop-core/main.tf index ba4111e60..055647d2c 100644 --- a/registry/coder/modules/vscode-desktop-core/main.tf +++ b/registry/coder/modules/vscode-desktop-core/main.tf @@ -28,7 +28,7 @@ variable "open_recent" { variable "mcp_config" { type = map(any) - description = "MCP server configuration for the IDE. When set, writes mcp_config.json in var.config_folder." + description = "MCP server configuration for the IDE. When set, writes mcp_config.json in var.config_dir." default = null } @@ -112,7 +112,7 @@ resource "coder_script" "vscode-desktop-mcp" { #!/bin/sh set -euo pipefail - IDE_CONFIG_FOLDER="${var.config_folder}" + IDE_CONFIG_FOLDER="${var.config_dir}" IDE_MCP_CONFIG_PATH="$IDE_CONFIG_FOLDER/mcp_config.json" mkdir -p "$IDE_CONFIG_FOLDER"