Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 8 additions & 4 deletions cmd/thv/app/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ Valid clients:
- cursor: Cursor editor
- goose: Goose AI agent
- lm-studio: LM Studio application
- opencode: OpenCode editor
- roo-code: Roo Code extension for VS Code
- trae: Trae IDE
- vscode: Visual Studio Code
Expand Down Expand Up @@ -84,6 +85,7 @@ Valid clients:
- cursor: Cursor editor
- goose: Goose AI agent
- lm-studio: LM Studio application
- opencode: OpenCode editor
- roo-code: Roo Code extension for VS Code
- trae: Trae IDE
- vscode: Visual Studio Code
Expand Down Expand Up @@ -191,13 +193,14 @@ func clientRegisterCmdFunc(cmd *cobra.Command, args []string) error {
// Validate the client type
switch clientType {
case "roo-code", "cline", "cursor", "claude-code", "vscode-insider", "vscode", "windsurf", "windsurf-jetbrains",
"amp-cli", "amp-vscode", "amp-vscode-insider", "amp-cursor", "amp-windsurf", "lm-studio", "goose", "trae", "continue":
"amp-cli", "amp-vscode", "amp-vscode-insider", "amp-cursor", "amp-windsurf", "lm-studio", "goose", "trae",
"continue", "opencode":
// Valid client type
default:
return fmt.Errorf(
"invalid client type: %s (valid types: roo-code, cline, cursor, claude-code, vscode, vscode-insider, "+
"windsurf, windsurf-jetbrains, amp-cli, amp-vscode, amp-vscode-insider, amp-cursor, amp-windsurf, lm-studio, "+
"goose, trae, continue)",
"goose, trae, continue, opencode)",
clientType)
}

Expand All @@ -210,13 +213,14 @@ func clientRemoveCmdFunc(cmd *cobra.Command, args []string) error {
// Validate the client type
switch clientType {
case "roo-code", "cline", "cursor", "claude-code", "vscode-insider", "vscode", "windsurf", "windsurf-jetbrains",
"amp-cli", "amp-vscode", "amp-vscode-insider", "amp-cursor", "amp-windsurf", "lm-studio", "goose", "trae", "continue":
"amp-cli", "amp-vscode", "amp-vscode-insider", "amp-cursor", "amp-windsurf", "lm-studio", "goose", "trae",
"continue", "opencode":
// Valid client type
default:
return fmt.Errorf(
"invalid client type: %s (valid types: roo-code, cline, cursor, claude-code, vscode, vscode-insider, "+
"windsurf, windsurf-jetbrains, amp-cli, amp-vscode, amp-vscode-insider, amp-cursor, amp-windsurf, lm-studio, "+
"goose, trae, continue)",
"goose, trae, continue, opencode)",
clientType)
}

Expand Down
1 change: 1 addition & 0 deletions docs/cli/thv_client_register.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions docs/cli/thv_client_remove.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion docs/server/docs.go

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/server/swagger.json

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions docs/server/swagger.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

17 changes: 17 additions & 0 deletions pkg/client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,8 @@ const (
Trae MCPClient = "trae"
// Continue represents the Continue.dev IDE plugins.
Continue MCPClient = "continue"
// OpenCode represents the OpenCode editor.
OpenCode MCPClient = "opencode"
)

// Extension is extension of the client config file.
Expand Down Expand Up @@ -429,6 +431,21 @@ var supportedClientIntegrations = []mcpClientConfig{
YAMLStorageType: YAMLStorageTypeArray,
YAMLIdentifierField: "name",
},
{
ClientType: OpenCode,
Description: "OpenCode editor",
SettingsFile: "opencode.json",
MCPServersPathPrefix: "/mcp",
RelPath: []string{".config", "opencode"},
Extension: JSON,
SupportedTransportTypesMap: map[types.TransportType]string{
types.TransportTypeStdio: "remote", // OpenCode requires "type": "remote" for URL-based servers
types.TransportTypeSSE: "remote",
types.TransportTypeStreamableHTTP: "remote",
},
IsTransportTypeFieldSupported: true, // OpenCode requires "type": "remote" for URL-based servers
MCPServersUrlLabel: "url",
},
}

// ConfigFile represents a client configuration file
Expand Down
5 changes: 4 additions & 1 deletion pkg/client/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ func TestSuccessfulClientConfigOperations(t *testing.T) {
case LMStudio, Trae:
assert.Contains(t, string(content), `"mcpServers":`,
"LMStudio config should contain mcpServers key")
case OpenCode:
assert.Contains(t, string(content), `"mcpServers":`,
"OpenCode config should contain mcpServers key")
case Goose:
// YAML files are created empty and initialized on first use
// Just verify the file exists and is readable
Expand Down Expand Up @@ -464,7 +467,7 @@ func TestSuccessfulClientConfigOperations(t *testing.T) {
assert.Contains(t, string(content), testURL,
"VSCode config should contain the server URL")
case Cursor, RooCode, ClaudeCode, Cline, Windsurf, WindsurfJetBrains, AmpCli,
AmpVSCode, AmpCursor, AmpVSCodeInsider, AmpWindsurf, LMStudio, Goose, Trae, Continue:
AmpVSCode, AmpCursor, AmpVSCodeInsider, AmpWindsurf, LMStudio, Goose, Trae, Continue, OpenCode:
assert.Contains(t, string(content), testURL,
"Config should contain the server URL")
}
Expand Down
Loading