Skip to content

Commit 96cca06

Browse files
authored
Added a client picker for MCP setup command (#1446)
1 parent f465397 commit 96cca06

File tree

4 files changed

+56
-38
lines changed

4 files changed

+56
-38
lines changed

src/cmd/cli/command/commands.go

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -300,7 +300,6 @@ func SetupCommands(ctx context.Context, version string) {
300300
mcpCmd.AddCommand(mcpServerCmd)
301301
mcpSetupCmd.Flags().String("client", "", fmt.Sprintf("MCP setup client %v", mcp.ValidClients))
302302
mcpServerCmd.Flags().Int("auth-server", 0, "auth server port")
303-
mcpSetupCmd.MarkFlagRequired("client")
304303
RootCmd.AddCommand(mcpCmd)
305304

306305
// Send Command

src/cmd/cli/command/mcp.go

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,9 +79,36 @@ var mcpSetupCmd = &cobra.Command{
7979
RunE: func(cmd *cobra.Command, args []string) error {
8080
term.Debug("Setting up MCP client")
8181
client, _ := cmd.Flags().GetString("client")
82-
term.Debugf("MCP Client: %q", client)
83-
if err := mcp.SetupClient(client); err != nil {
84-
return err
82+
83+
if client != "" {
84+
85+
// Aliases mapping
86+
switch client {
87+
case "code":
88+
client = string(mcp.MCPClientVSCode)
89+
case "code-insiders":
90+
client = string(mcp.MCPClientVSCodeInsiders)
91+
case "cascade", "codeium":
92+
client = string(mcp.MCPClientWindsurf)
93+
}
94+
95+
term.Debugf("Using MCP client flag: %q", client)
96+
if err := mcp.SetupClient(client); err != nil {
97+
return err
98+
}
99+
} else {
100+
term.Debugf("Using MCP client picker: %q", client)
101+
clients, err := mcp.SelectMCPclients()
102+
if err != nil {
103+
return err
104+
}
105+
for _, client := range clients {
106+
term.Debugf("Selected MCP client using picker: %q", client)
107+
108+
if err := mcp.SetupClient(client); err != nil {
109+
return err
110+
}
111+
}
85112
}
86113

87114
return nil

src/pkg/mcp/setup.go

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@ import (
1010
"slices"
1111
"strings"
1212

13+
"github.com/AlecAivazis/survey/v2"
14+
1315
"github.com/DefangLabs/defang/src/pkg/term"
1416
"github.com/DefangLabs/defang/src/pkg/track"
1517
)
@@ -53,24 +55,18 @@ type MCPClient string
5355

5456
const (
5557
MCPClientVSCode MCPClient = "vscode"
56-
MCPClientCode MCPClient = "code"
5758
MCPClientVSCodeInsiders MCPClient = "vscode-insiders"
58-
MCPClientInsiders MCPClient = "code-insiders"
5959
MCPClientClaudeDesktop MCPClient = "claude-desktop"
6060
MCPClientClaudeCode MCPClient = "claude-code"
6161
MCPClientWindsurf MCPClient = "windsurf"
62-
MCPClientCascade MCPClient = "cascade"
63-
MCPClientCodeium MCPClient = "codeium"
6462
MCPClientCursor MCPClient = "cursor"
6563
MCPClientKiro MCPClient = "kiro"
6664
)
6765

6866
// ValidVSCodeClients is a list of supported VSCode MCP clients with shorthand names
6967
var ValidVSCodeClients = []MCPClient{
7068
MCPClientVSCode,
71-
MCPClientCode,
7269
MCPClientVSCodeInsiders,
73-
MCPClientInsiders,
7470
}
7571

7672
// ValidClients is a list of supported MCP clients
@@ -79,14 +75,13 @@ var ValidClients = append(
7975
MCPClientClaudeDesktop,
8076
MCPClientClaudeCode,
8177
MCPClientWindsurf,
82-
MCPClientCascade,
83-
MCPClientCodeium,
8478
MCPClientCursor,
8579
MCPClientKiro,
8680
},
8781
ValidVSCodeClients...,
8882
)
8983

84+
// ParseMCPClient parses and validates the MCP client string
9085
func ParseMCPClient(clientStr string) (MCPClient, error) {
9186
clientStr = strings.ToLower(clientStr)
9287
client := MCPClient(clientStr)
@@ -96,6 +91,29 @@ func ParseMCPClient(clientStr string) (MCPClient, error) {
9691
return client, nil
9792
}
9893

94+
// ValidClientStrings converts ValidClients to []string for survey options
95+
func ValidClientStrings() []string {
96+
strings := make([]string, len(ValidClients))
97+
for i, client := range ValidClients {
98+
strings[i] = string(client)
99+
}
100+
return strings
101+
}
102+
103+
// SelectMCPclients prompts the user to select one or more MCP clients
104+
func SelectMCPclients() ([]string, error) {
105+
var clients []string
106+
err := survey.AskOne(&survey.MultiSelect{
107+
Message: "Choose a client(s):",
108+
Options: ValidClientStrings(),
109+
}, &clients)
110+
if err != nil {
111+
return nil, fmt.Errorf("failed to select MCP client(s): %w", err)
112+
}
113+
114+
return clients, nil
115+
}
116+
99117
// ClientInfo defines where each client stores its MCP configuration
100118
type ClientInfo struct {
101119
configFile string // Configuration file name
@@ -140,12 +158,8 @@ var kiroConfig = ClientInfo{
140158
// clientRegistry maps client names to their configuration details
141159
var clientRegistry = map[MCPClient]ClientInfo{
142160
MCPClientWindsurf: windsurfConfig,
143-
MCPClientCascade: windsurfConfig,
144-
MCPClientCodeium: windsurfConfig,
145161
MCPClientVSCode: vscodeConfig,
146-
MCPClientCode: vscodeConfig,
147162
MCPClientVSCodeInsiders: codeInsidersConfig,
148-
MCPClientInsiders: codeInsidersConfig,
149163
MCPClientClaudeDesktop: claudeDesktopConfig,
150164
MCPClientClaudeCode: claudeCodeConfig,
151165
MCPClientCursor: cursorConfig,

src/pkg/mcp/setup_test.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -30,16 +30,6 @@ func TestGetClientConfigPath(t *testing.T) {
3030
client: MCPClientWindsurf,
3131
expectedPath: filepath.Join(homeDir, ".codeium", "windsurf", "mcp_config.json"),
3232
},
33-
{
34-
name: "cascade",
35-
client: MCPClientCascade,
36-
expectedPath: filepath.Join(homeDir, ".codeium", "windsurf", "mcp_config.json"),
37-
},
38-
{
39-
name: "codeium",
40-
client: MCPClientCodeium,
41-
expectedPath: filepath.Join(homeDir, ".codeium", "windsurf", "mcp_config.json"),
42-
},
4333

4434
// Claude Desktop tests - Darwin
4535
{
@@ -159,12 +149,6 @@ func TestGetClientConfigPath(t *testing.T) {
159149
goos: "darwin",
160150
expectedPath: filepath.Join(homeDir, "Library", "Application Support", "Code", "User", "mcp.json"),
161151
},
162-
{
163-
name: "code_darwin",
164-
client: MCPClientCode,
165-
goos: "darwin",
166-
expectedPath: filepath.Join(homeDir, "Library", "Application Support", "Code", "User", "mcp.json"),
167-
},
168152

169153
// VSCode tests - Windows with APPDATA
170154
{
@@ -209,12 +193,6 @@ func TestGetClientConfigPath(t *testing.T) {
209193
goos: "darwin",
210194
expectedPath: filepath.Join(homeDir, "Library", "Application Support", "Code - Insiders", "User", "mcp.json"),
211195
},
212-
{
213-
name: "insiders_darwin",
214-
client: MCPClientInsiders,
215-
goos: "darwin",
216-
expectedPath: filepath.Join(homeDir, "Library", "Application Support", "Code - Insiders", "User", "mcp.json"),
217-
},
218196

219197
// VSCode Insiders tests - Windows with APPDATA
220198
{

0 commit comments

Comments
 (0)