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

  1. Find and remove/rename blank keys: jq 'keys' on each config file
  2. Regenerate the server entry with a real name matching ^[A-Za-z0-9_-]+$
  3. 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

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


AI-assisted analysis of Panniantong/Agent-Reach@93ae1d18c3 (2026-08-14). Data as JSON: /api/errors/0d5e6813f7b7e5b7. Report an issue: GitHub.