From 6d5aa1f5146592e6fbff0368f8597ee0b2cee191 Mon Sep 17 00:00:00 2001 From: Kevin Vo Date: Fri, 19 Sep 2025 17:12:29 -0700 Subject: [PATCH 1/4] MCP setup bug on empty JSON file --- src/pkg/mcp/setup.go | 24 ++++++++++++++++++------ src/pkg/mcp/setup_test.go | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 53 insertions(+), 7 deletions(-) diff --git a/src/pkg/mcp/setup.go b/src/pkg/mcp/setup.go index 04a866551..9bb6868fc 100644 --- a/src/pkg/mcp/setup.go +++ b/src/pkg/mcp/setup.go @@ -259,9 +259,15 @@ func handleVSCodeConfig(configPath string) error { // Check if the file exists if data, err := os.ReadFile(configPath); err == nil { - // File exists, parse it - if err := json.Unmarshal(data, &existingData); err != nil { - return fmt.Errorf("failed to unmarshal existing vscode config %w", err) + // Check if file is empty or only contains whitespace + if len(strings.TrimSpace(string(data))) == 0 { + // File is empty, treat as new config + existingData = make(map[string]any) + } else { + // File exists, parse it + if err := json.Unmarshal(data, &existingData); err != nil { + return fmt.Errorf("failed to unmarshal existing vscode config: %w", err) + } } // Check if "servers" section exists @@ -310,9 +316,15 @@ func handleStandardConfig(configPath string) error { // Check if the file exists if data, err := os.ReadFile(configPath); err == nil { - // Parse the JSON into a generic map to preserve all settings - if err := json.Unmarshal(data, &existingData); err != nil { - return fmt.Errorf("failed to unmarshal existing config: %w", err) + // Check if file is empty or only contains whitespace + if len(strings.TrimSpace(string(data))) == 0 { + // File is empty, treat as new config + existingData = make(map[string]any) + } else { + // Parse the JSON into a generic map to preserve all settings + if err := json.Unmarshal(data, &existingData); err != nil { + return fmt.Errorf("failed to unmarshal existing config: %w", err) + } } // Try to extract MCPServers from existing data diff --git a/src/pkg/mcp/setup_test.go b/src/pkg/mcp/setup_test.go index d35382774..6ea2a86b0 100644 --- a/src/pkg/mcp/setup_test.go +++ b/src/pkg/mcp/setup_test.go @@ -445,7 +445,25 @@ func TestWriteConfig(t *testing.T) { expectedError: true, }, { - name: "standard_config_new_file", + name: "vscode_config_new_file_empty", + fileExists: true, + vscodeConfig: true, + existingData: "", + expectedData: `{ + "servers": { + "defang": { + "args": [ + "mcp", + "serve" + ], + "command": %s, + "type": "stdio" + } + } +}`, + }, + { + name: "standard_config_new_file_non_empty", fileExists: false, existingData: "", expectedData: `{ @@ -593,6 +611,22 @@ func TestWriteConfig(t *testing.T) { existingData: `{"mcpServers": "not an object}`, expectedError: true, }, + { + name: "standard_config_new_file_empty", + fileExists: true, + existingData: "", + expectedData: `{ + "mcpServers": { + "defang": { + "command": %s, + "args": [ + "mcp", + "serve" + ] + } + } +}`, + }, } for _, tt := range test { t.Run(tt.name, func(t *testing.T) { From 338efb5b5e76c07b951d55ec56c4ca3b69eb0b55 Mon Sep 17 00:00:00 2001 From: Kevin Vo Date: Fri, 19 Sep 2025 17:25:38 -0700 Subject: [PATCH 2/4] Update src/pkg/mcp/setup.go --- src/pkg/mcp/setup.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkg/mcp/setup.go b/src/pkg/mcp/setup.go index 9bb6868fc..44c9952ee 100644 --- a/src/pkg/mcp/setup.go +++ b/src/pkg/mcp/setup.go @@ -264,7 +264,7 @@ func handleVSCodeConfig(configPath string) error { // File is empty, treat as new config existingData = make(map[string]any) } else { - // File exists, parse it + // File is not empty, attempt to parse it if err := json.Unmarshal(data, &existingData); err != nil { return fmt.Errorf("failed to unmarshal existing vscode config: %w", err) } From 13b057f07c431c9a512ea90b19f569acae1b8024 Mon Sep 17 00:00:00 2001 From: Kevin Vo Date: Fri, 19 Sep 2025 17:31:44 -0700 Subject: [PATCH 3/4] revert test naming --- src/pkg/mcp/setup_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pkg/mcp/setup_test.go b/src/pkg/mcp/setup_test.go index 6ea2a86b0..606b5c67a 100644 --- a/src/pkg/mcp/setup_test.go +++ b/src/pkg/mcp/setup_test.go @@ -463,7 +463,7 @@ func TestWriteConfig(t *testing.T) { }`, }, { - name: "standard_config_new_file_non_empty", + name: "standard_config_new_file", fileExists: false, existingData: "", expectedData: `{ From 12ff5e7b46d43acf2b1d89e8cd1c7cc58bb0dcdc Mon Sep 17 00:00:00 2001 From: Kevin Vo Date: Fri, 19 Sep 2025 17:42:41 -0700 Subject: [PATCH 4/4] Added update suggestion --- src/cmd/cli/command/mcp.go | 1 - src/pkg/mcp/setup.go | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/cmd/cli/command/mcp.go b/src/cmd/cli/command/mcp.go index 76c63da14..7d43c487a 100644 --- a/src/cmd/cli/command/mcp.go +++ b/src/cmd/cli/command/mcp.go @@ -81,7 +81,6 @@ var mcpSetupCmd = &cobra.Command{ client, _ := cmd.Flags().GetString("client") if client != "" { - // Aliases mapping switch client { case "code": diff --git a/src/pkg/mcp/setup.go b/src/pkg/mcp/setup.go index 44c9952ee..b1750eff5 100644 --- a/src/pkg/mcp/setup.go +++ b/src/pkg/mcp/setup.go @@ -411,7 +411,7 @@ func SetupClient(clientStr string) error { } } - term.Infof("Restart %s for the changes to take effect.\n", client) + term.Infof("Ensure that %s is upgraded to the latest version and restarted so the changes can take effect.\n", client) return nil }