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
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.

6 changes: 4 additions & 2 deletions docs/server/docs.go

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

6 changes: 4 additions & 2 deletions docs/server/swagger.json

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

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

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

21 changes: 21 additions & 0 deletions pkg/client/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ const (
KimiCli ClientApp = "kimi-cli"
// Factory represents the Factory.ai Droid CLI.
Factory ClientApp = "factory"
// CopilotCli represents the GitHub Copilot CLI.
CopilotCli ClientApp = "copilot-cli"
)

const (
Expand Down Expand Up @@ -1003,6 +1005,25 @@ var supportedClientIntegrations = []clientAppConfig{
SkillsGlobalPath: []string{".factory", skillsDirName},
SkillsProjectPath: []string{".factory", skillsDirName},
},
{
ClientType: CopilotCli,
Description: "GitHub Copilot CLI",
SettingsFile: "mcp-config.json",
MCPServersPathPrefix: "/mcpServers",
RelPath: []string{".copilot"},
Extension: JSON,
SupportedTransportTypesMap: map[types.TransportType]string{
types.TransportTypeStdio: httpTransportLabel,
types.TransportTypeSSE: "sse",
types.TransportTypeStreamableHTTP: httpTransportLabel,
},
IsTransportTypeFieldSupported: true,
MCPServersUrlLabelMap: map[types.TransportType]string{
types.TransportTypeStdio: defaultURLFieldName,
types.TransportTypeSSE: defaultURLFieldName,
types.TransportTypeStreamableHTTP: defaultURLFieldName,
},
},
{
// Xcode does not support MCP; it is an LLM-gateway-only entry.
// Cast LLMClientApp → ClientApp for internal config storage; the type
Expand Down
12 changes: 6 additions & 6 deletions pkg/client/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -504,7 +504,7 @@ func TestSuccessfulClientConfigOperations(t *testing.T) {
case AmpWindsurf:
assert.Contains(t, string(content), `"mcpServers":`,
"AmpWindsurf config should contain mcpServers key")
case LMStudio, Trae, Kiro, Antigravity, GeminiCli, KimiCli, Factory:
case LMStudio, Trae, Kiro, Antigravity, GeminiCli, KimiCli, Factory, CopilotCli:
assert.Contains(t, string(content), `"mcpServers":`,
"Config should contain mcpServers key")
case VSCodeServer:
Expand Down Expand Up @@ -563,7 +563,7 @@ func TestSuccessfulClientConfigOperations(t *testing.T) {
"VSCode config should contain the server URL")
case Cursor, RooCode, ClaudeCode, Cline, Windsurf, WindsurfJetBrains, AmpCli,
AmpVSCode, AmpCursor, AmpVSCodeInsider, AmpWindsurf, LMStudio, Goose, Trae, Continue, OpenCode, Kiro, Antigravity, Zed, GeminiCli, VSCodeServer,
MistralVibe, Codex, KimiCli, Factory:
MistralVibe, Codex, KimiCli, Factory, CopilotCli:
assert.Contains(t, string(content), testURL,
"Config should contain the server URL")
}
Expand Down Expand Up @@ -1292,8 +1292,8 @@ func TestGetAllClients(t *testing.T) {

clients := GetAllClients()

// Should return all 27 supported clients
assert.Len(t, clients, 27, "Expected 27 supported clients")
// Should return all 28 supported clients
assert.Len(t, clients, 28, "Expected 28 supported clients")

// Verify the list is sorted alphabetically
for i := 1; i < len(clients); i++ {
Expand Down Expand Up @@ -1507,7 +1507,7 @@ func TestGetClientListCSV(t *testing.T) {
clientNames[i-1], clientNames[i])
}

// Count the number of clients (should be 25)
// Count the number of clients (should be 28)
clients := strings.Split(csv, ", ")
assert.Len(t, clients, 27, "Expected 27 clients in CSV list")
assert.Len(t, clients, 28, "Expected 28 clients in CSV list")
}
Loading