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 04a866551..b1750eff5 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 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) + } } // 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 @@ -399,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 } diff --git a/src/pkg/mcp/setup_test.go b/src/pkg/mcp/setup_test.go index d35382774..606b5c67a 100644 --- a/src/pkg/mcp/setup_test.go +++ b/src/pkg/mcp/setup_test.go @@ -444,6 +444,24 @@ func TestWriteConfig(t *testing.T) { existingData: `{"servers": "not an object}`, expectedError: true, }, + { + 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", fileExists: false, @@ -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) {