Panniantong/Agent-Reach · error · McporterConfigError
mcporter 配置包含无效的 server name
Error message
mcporter 配置包含无效的 server name
What it means
Raised while iterating a layer's mcpServers entries when a key is not a non-empty string after strip(). JSON object keys are normally strings, but whitespace-only or empty names (possible via programmatic writes or lenient parsers) are rejected because they cannot be valid MCP server names for routing.
Source
Thrown at agent_reach/channels/mcporter.py:60
deliberately not opened because Doctor must not expand its
credential-read boundary.
"""
selected_layers = _select_config_layers(root_dir)
if not selected_layers:
return McporterConfigInspection(frozenset(), None)
names = set()
imports_unchecked = False
sources = []
for config_path, source in selected_layers:
payload = _read_config_object(config_path)
servers = payload.get("mcpServers")
if not isinstance(servers, dict):
raise McporterConfigError("mcporter 配置缺少 mcpServers 对象")
for name, definition in servers.items():
if not isinstance(name, str) or not name.strip():
raise McporterConfigError("mcporter 配置包含无效的 server name")
if not isinstance(definition, dict):
raise McporterConfigError("mcporter server 定义必须是对象")
names.add(name.casefold())
imports = payload.get("imports", _MISSING)
if imports is _MISSING:
# mcporter defaults to importing supported editor configs when the
# key is omitted. Doctor intentionally does not open those files.
imports_unchecked = True
elif not isinstance(imports, list) or not all(
isinstance(item, str) for item in imports
):
raise McporterConfigError("mcporter imports 必须是字符串列表")
elif imports:
imports_unchecked = True
sources.append(source)
return McporterConfigInspection(View on GitHub (pinned to 93ae1d18c3)
Solutions
- Find and remove/rename blank keys: jq 'keys' on each config file
- Regenerate the server entry with a real name matching ^[A-Za-z0-9_-]+$
- If the entry is a leftover placeholder, delete the whole key/value pair
Example fix
// before
{ "mcpServers": { "": { "command": "npx" } } }
// after
{ "mcpServers": { "fetch": { "command": "npx" } } } Defensive patterns
Strategy: validation
Validate before calling
import json
def server_names_ok(path) -> bool:
try:
servers = json.load(open(path, encoding="utf-8")).get("mcpServers", {})
except Exception:
return False
return all(isinstance(k, str) and k.strip() for k in servers) Type guard
def valid_server_entries(servers: dict) -> bool:
return all(isinstance(k, str) and k.strip() and isinstance(v, dict) for k, v in servers.items()) Try / catch
except McporterConfigError as exc:
if "server name" in str(exc):
point_user_at_blank_key(str(exc)) Prevention
- Never emit empty or whitespace server keys from templates
- Lint generated configs with jq before deploying
- Delete placeholder entries instead of blanking their names
When it happens
Trigger: mcpServers contains a key like "", " ", or "\t" in any selected config layer. Keys are then casefolded into the name set used for doctor output, so garbage names are rejected up front.
Common situations: Templating bugs producing '"${name}"': '' style keys; jq scripts inserting empty keys; merge tools leaving blank placeholder entries.
Related errors
- mcporter 配置缺少 mcpServers 对象
- mcporter server 定义必须是对象
- mcporter imports 必须是字符串列表
- mcporter 配置不是有效的 UTF-8 JSON
- mcporter 配置顶层必须是对象
AI-assisted analysis of Panniantong/Agent-Reach@93ae1d18c3 (2026-08-14).
Data as JSON: /api/errors/0d5e6813f7b7e5b7.
Report an issue: GitHub.