Skip to content

Commit 6e08da1

Browse files
authored
Merge pull request #17 from zhujian0805/main
fix: Continue MCP config format
2 parents d90b1e3 + cc998db commit 6e08da1

File tree

2 files changed

+90
-13
lines changed

2 files changed

+90
-13
lines changed

code_assistant_manager/mcp/continue_mcp.py

Lines changed: 76 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,33 @@ def _convert_server_config_to_client_format(self, server_config) -> dict:
3434
# Continue uses the standard MCP "mcpServers" format (stdio/http)
3535
return super()._convert_server_config_to_client_format(server_config)
3636

37+
def _normalize_mcp_servers(self, servers):
38+
"""Normalize Continue's mcpServers to the list-of-objects format.
39+
40+
Continue's newer format:
41+
mcpServers:
42+
- name: foo
43+
command: ...
44+
45+
We also accept the legacy dict format:
46+
mcpServers:
47+
foo: {command: ...}
48+
"""
49+
if isinstance(servers, list):
50+
return [s for s in servers if isinstance(s, dict)]
51+
52+
if isinstance(servers, dict):
53+
normalized = []
54+
for name, cfg in servers.items():
55+
if not isinstance(cfg, dict):
56+
continue
57+
item = {"name": name}
58+
item.update(cfg)
59+
normalized.append(item)
60+
return normalized
61+
62+
return []
63+
3764
def _add_server_config_to_file(
3865
self, config_path, server_name: str, client_config: dict
3966
) -> bool:
@@ -46,12 +73,22 @@ def _add_server_config_to_file(
4673
if isinstance(loaded, dict):
4774
config = loaded
4875

49-
if "mcpServers" not in config or not isinstance(
50-
config.get("mcpServers"), dict
51-
):
52-
config["mcpServers"] = {}
76+
servers = self._normalize_mcp_servers(config.get("mcpServers"))
77+
78+
new_entry = {"name": server_name}
79+
new_entry.update(client_config)
5380

54-
config["mcpServers"][server_name] = client_config
81+
updated = False
82+
for i, item in enumerate(servers):
83+
if item.get("name") == server_name:
84+
servers[i] = new_entry
85+
updated = True
86+
break
87+
88+
if not updated:
89+
servers.append(new_entry)
90+
91+
config["mcpServers"] = servers
5592

5693
config_path.parent.mkdir(parents=True, exist_ok=True)
5794
with open(config_path, "w", encoding="utf-8") as f:
@@ -103,9 +140,25 @@ def remove_server(self, server_name: str, scope: str = "user") -> bool:
103140
if not isinstance(config, dict):
104141
continue
105142

106-
if "mcpServers" in config and isinstance(config["mcpServers"], dict):
107-
if server_name in config["mcpServers"]:
108-
del config["mcpServers"][server_name]
143+
servers = config.get("mcpServers")
144+
145+
if isinstance(servers, dict):
146+
if server_name in servers:
147+
del servers[server_name]
148+
config["mcpServers"] = servers
149+
with open(config_path, "w", encoding="utf-8") as f:
150+
yaml.safe_dump(config, f, sort_keys=False)
151+
removed_any = True
152+
break
153+
154+
if isinstance(servers, list):
155+
new_servers = [
156+
s
157+
for s in servers
158+
if not (isinstance(s, dict) and s.get("name") == server_name)
159+
]
160+
if len(new_servers) != len(servers):
161+
config["mcpServers"] = new_servers
109162
with open(config_path, "w", encoding="utf-8") as f:
110163
yaml.safe_dump(config, f, sort_keys=False)
111164
removed_any = True
@@ -142,13 +195,25 @@ def list_servers(self, scope: str = "all") -> bool:
142195
if not isinstance(config, dict):
143196
continue
144197
servers = config.get("mcpServers")
145-
if not isinstance(servers, dict):
198+
199+
parsed = {}
200+
if isinstance(servers, dict):
201+
parsed = servers
202+
elif isinstance(servers, list):
203+
for item in servers:
204+
if not isinstance(item, dict):
205+
continue
206+
name = item.get("name")
207+
if not name:
208+
continue
209+
parsed[name] = {k: v for k, v in item.items() if k != "name"}
210+
else:
146211
continue
147212

148213
if config_path == home / ".continue" / "config.yaml":
149-
user_servers.update(servers)
214+
user_servers.update(parsed)
150215
elif config_path == cwd / ".continue" / "config.yaml":
151-
project_servers.update(servers)
216+
project_servers.update(parsed)
152217
except Exception:
153218
continue
154219

code_assistant_manager/tools/continue_tool.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,20 @@ def _write_continue_config(self, selected_models: List[tuple]) -> Path:
117117
if config_file.exists():
118118
try:
119119
existing = yaml.safe_load(config_file.read_text(encoding="utf-8")) or {}
120-
if isinstance(existing, dict) and isinstance(existing.get("mcpServers"), dict):
121-
continue_config["mcpServers"] = existing["mcpServers"]
120+
if isinstance(existing, dict) and "mcpServers" in existing:
121+
existing_servers = existing.get("mcpServers")
122+
if isinstance(existing_servers, dict):
123+
# Convert legacy dict format to Continue's list-of-objects format
124+
converted = []
125+
for name, cfg in existing_servers.items():
126+
if not isinstance(cfg, dict):
127+
continue
128+
item = {"name": name}
129+
item.update(cfg)
130+
converted.append(item)
131+
continue_config["mcpServers"] = converted
132+
elif isinstance(existing_servers, list):
133+
continue_config["mcpServers"] = existing_servers
122134
except Exception:
123135
pass
124136

0 commit comments

Comments
 (0)