Skip to content

Commit ef6dc24

Browse files
mauriciocoderMauricio Bonettidmjb
authored
feature/1155/add-windsurf - Enhance client configuration to support Windsurf IDE and IntelliJ plugin (#1156)
Solves issue: #1155 Co-authored-by: Mauricio Bonetti <[email protected]> Co-authored-by: Don Browne <[email protected]>
1 parent 99e963d commit ef6dc24

File tree

7 files changed

+76
-9
lines changed

7 files changed

+76
-9
lines changed

cmd/thv/app/client.go

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,11 +148,12 @@ func clientRegisterCmdFunc(cmd *cobra.Command, args []string) error {
148148

149149
// Validate the client type
150150
switch clientType {
151-
case "roo-code", "cline", "cursor", "claude-code", "vscode-insider", "vscode":
151+
case "roo-code", "cline", "cursor", "claude-code", "vscode-insider", "vscode", "windsurf", "windsurf-intellij":
152152
// Valid client type
153153
default:
154154
return fmt.Errorf(
155-
"invalid client type: %s (valid types: roo-code, cline, cursor, claude-code, vscode, vscode-insider)",
155+
"invalid client type: %s (valid types: roo-code, cline, cursor, claude-code, vscode, "+
156+
"vscode-insider, windsurf, windsurf-intellij)",
156157
clientType)
157158
}
158159

@@ -178,11 +179,12 @@ func clientRemoveCmdFunc(cmd *cobra.Command, args []string) error {
178179

179180
// Validate the client type
180181
switch clientType {
181-
case "roo-code", "cline", "cursor", "claude-code", "vscode-insider", "vscode":
182+
case "roo-code", "cline", "cursor", "claude-code", "vscode-insider", "vscode", "windsurf", "windsurf-intellij":
182183
// Valid client type
183184
default:
184185
return fmt.Errorf(
185-
"invalid client type: %s (valid types: roo-code, cline, cursor, claude-code, vscode, vscode-insider)",
186+
"invalid client type: %s (valid types: roo-code, cline, cursor, claude-code, vscode, "+
187+
"vscode-insider, windsurf, windsurf-intellij)",
186188
clientType)
187189
}
188190

docs/server/docs.go

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/server/swagger.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

docs/server/swagger.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/client/config.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,10 @@ const (
3838
VSCode MCPClient = "vscode"
3939
// ClaudeCode represents the Claude Code CLI.
4040
ClaudeCode MCPClient = "claude-code"
41+
// Windsurf represents the Windsurf IDE.
42+
Windsurf MCPClient = "windsurf"
43+
// WindsurfIntelliJ represents the Windsurf plugin for IntelliJ.
44+
WindsurfIntelliJ MCPClient = "windsurf-intellij"
4145
)
4246

4347
// Extension is extension of the client config file.
@@ -59,6 +63,7 @@ type mcpClientConfig struct {
5963
Extension Extension
6064
SupportedTransportTypesMap map[types.TransportType]string // stdio should be mapped to sse
6165
IsTransportTypeFieldSupported bool
66+
MCPServersUrlLabel string
6267
}
6368

6469
var (
@@ -87,6 +92,7 @@ var supportedClientIntegrations = []mcpClientConfig{
8792
types.TransportTypeStreamableHTTP: "streamable-http",
8893
},
8994
IsTransportTypeFieldSupported: true,
95+
MCPServersUrlLabel: "url",
9096
},
9197
{
9298
ClientType: Cline,
@@ -107,6 +113,7 @@ var supportedClientIntegrations = []mcpClientConfig{
107113
types.TransportTypeStdio: "sse",
108114
},
109115
IsTransportTypeFieldSupported: false,
116+
MCPServersUrlLabel: "url",
110117
},
111118
{
112119
ClientType: VSCodeInsider,
@@ -128,6 +135,7 @@ var supportedClientIntegrations = []mcpClientConfig{
128135
types.TransportTypeStreamableHTTP: "http",
129136
},
130137
IsTransportTypeFieldSupported: true,
138+
MCPServersUrlLabel: "url",
131139
},
132140
{
133141
ClientType: VSCode,
@@ -149,6 +157,7 @@ var supportedClientIntegrations = []mcpClientConfig{
149157
types.TransportTypeStreamableHTTP: "http",
150158
},
151159
IsTransportTypeFieldSupported: true,
160+
MCPServersUrlLabel: "url",
152161
},
153162
{
154163
ClientType: Cursor,
@@ -165,6 +174,7 @@ var supportedClientIntegrations = []mcpClientConfig{
165174
// Adding type field is not explicitly required though, Cursor auto-detects and is able to
166175
// connect to both sse and streamable-http types
167176
IsTransportTypeFieldSupported: true,
177+
MCPServersUrlLabel: "url",
168178
},
169179
{
170180
ClientType: ClaudeCode,
@@ -179,6 +189,37 @@ var supportedClientIntegrations = []mcpClientConfig{
179189
types.TransportTypeStreamableHTTP: "http",
180190
},
181191
IsTransportTypeFieldSupported: true,
192+
MCPServersUrlLabel: "url",
193+
},
194+
{
195+
ClientType: Windsurf,
196+
Description: "Windsurf IDE",
197+
SettingsFile: "mcp_config.json",
198+
MCPServersPathPrefix: "/mcpServers",
199+
RelPath: []string{".codeium", "windsurf"},
200+
Extension: JSON,
201+
SupportedTransportTypesMap: map[types.TransportType]string{
202+
types.TransportTypeStdio: "sse",
203+
types.TransportTypeSSE: "sse",
204+
types.TransportTypeStreamableHTTP: "http",
205+
},
206+
IsTransportTypeFieldSupported: true,
207+
MCPServersUrlLabel: "serverUrl",
208+
},
209+
{
210+
ClientType: WindsurfIntelliJ,
211+
Description: "Windsurf plugin for IntelliJ",
212+
SettingsFile: "mcp_config.json",
213+
MCPServersPathPrefix: "/mcpServers",
214+
RelPath: []string{".codeium"},
215+
Extension: JSON,
216+
SupportedTransportTypesMap: map[types.TransportType]string{
217+
types.TransportTypeStdio: "sse",
218+
types.TransportTypeSSE: "sse",
219+
types.TransportTypeStreamableHTTP: "http",
220+
},
221+
IsTransportTypeFieldSupported: true,
222+
MCPServersUrlLabel: "serverUrl",
182223
},
183224
}
184225

@@ -323,10 +364,17 @@ func Upsert(cf ConfigFile, name string, url string, transportType string) error
323364
if cf.ClientType != supportedClientIntegrations[i].ClientType {
324365
continue
325366
}
367+
isServerUrl := supportedClientIntegrations[i].MCPServersUrlLabel == "serverUrl"
326368
mappedTransportType, ok := supportedClientIntegrations[i].SupportedTransportTypesMap[types.TransportType(transportType)]
327369
if supportedClientIntegrations[i].IsTransportTypeFieldSupported && ok {
370+
if isServerUrl {
371+
return cf.ConfigUpdater.Upsert(name, MCPServer{ServerUrl: url, Type: mappedTransportType})
372+
}
328373
return cf.ConfigUpdater.Upsert(name, MCPServer{Url: url, Type: mappedTransportType})
329374
}
375+
if isServerUrl {
376+
return cf.ConfigUpdater.Upsert(name, MCPServer{ServerUrl: url})
377+
}
330378
return cf.ConfigUpdater.Upsert(name, MCPServer{Url: url})
331379
}
332380
return nil

pkg/client/config_editor.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,9 @@ type ConfigUpdater interface {
2323

2424
// MCPServer represents an MCP server in a MCP client config file
2525
type MCPServer struct {
26-
Url string `json:"url,omitempty"`
27-
Type string `json:"type,omitempty"`
26+
Url string `json:"url,omitempty"`
27+
ServerUrl string `json:"serverUrl,omitempty"`
28+
Type string `json:"type,omitempty"`
2829
}
2930

3031
// JSONConfigUpdater is a ConfigUpdater that is responsible for updating

pkg/client/config_test.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,6 +312,12 @@ func TestSuccessfulClientConfigOperations(t *testing.T) {
312312
case Cline:
313313
assert.Contains(t, string(content), `"mcpServers":`,
314314
"Cline config should contain mcpServers key")
315+
case Windsurf:
316+
assert.Contains(t, string(content), `"mcpServers":`,
317+
"Windsurf config should contain mcpServers key")
318+
case WindsurfIntelliJ:
319+
assert.Contains(t, string(content), `"mcpServers":`,
320+
"WindsurfIntelliJ config should contain mcpServers key")
315321
}
316322
}
317323
})
@@ -337,7 +343,7 @@ func TestSuccessfulClientConfigOperations(t *testing.T) {
337343
case VSCode, VSCodeInsider:
338344
assert.Contains(t, string(content), testURL,
339345
"VSCode config should contain the server URL")
340-
case Cursor, RooCode, ClaudeCode, Cline:
346+
case Cursor, RooCode, ClaudeCode, Cline, Windsurf, WindsurfIntelliJ:
341347
assert.Contains(t, string(content), testURL,
342348
"Config should contain the server URL")
343349
}

0 commit comments

Comments
 (0)