BigPizzaV3/CodexPlusPlus · error · anyhow::Error

JSON 里没有可导入的 MCP 服务器

Error message

JSON 里没有可导入的 MCP 服务器

What it means

parse_mcp_servers_json converts each server entry to a TOML body via json_server_to_toml; entries that fail conversion are skipped and recorded as warnings. If every entry was skipped (import.entries is empty), the function bails because a no-op import is meaningless. Note the per-entry warnings still explain why each entry failed.

Solutions

  1. Read the returned warnings via the error chain/warnings to see why each entry was skipped (commonly '缺少 command 或 url').
  2. Add a command (stdio) or url (http) field to each server entry.
  3. Import a subset: fix or remove broken entries so at least one valid server remains.
  4. Validate one entry manually with json_server_to_toml before batch import.

Example fix

// before
{"mcpServers":{"a":{"enabled":false}}}
// after
{"mcpServers":{"a":{"command":"npx","args":["-y","server"]}}}
Defensive patterns

Strategy: validation

Validate before calling

function allEntriesConvertible(root) {
  const map = root.mcpServers ?? root.servers ?? root;
  return Object.values(map).every(c => typeof c.command === 'string' || typeof c.url === 'string');
}

Try / catch

match parse_mcp_servers_json(&text) {
    Ok(import) => apply(import),
    Err(e) if e.to_string().contains("没有可导入") => ui.show_warnings(collected_warnings),
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: All entries in the JSON failed json_server_to_toml (e.g. each missing command/url, or malformed nested fields), so zero entries survive the loop.

Common situations: Importing a config whose servers all use unsupported/invalid fields; every entry has neither command nor url; an exporter produced entries incompatible with this tool's schema.

Understand the failure class

Background: EmptyResultError / "no results found": when an API or scraper succeeds but returns zero rows — this error's family across 9 libraries.

Related errors


AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19). Data as JSON: /api/errors/86dd8bb6dab8b577. Report an issue: GitHub.

Appendix: source

Thrown at crates/codex-plus-core/src/mcp_config.rs:298

    if servers.is_empty() {
        anyhow::bail!("JSON 里没有找到任何 MCP 服务器");
    }

    let mut import = McpJsonImport::default();
    for (id, config) in servers {
        let Value::Object(config) = config else {
            import.warnings.push(format!("已跳过 {id}:配置不是对象"));
            continue;
        };
        match json_server_to_toml(&id, &config, &mut import.warnings) {
            Ok(toml_body) => import.entries.push(McpJsonEntry { id, toml_body }),
            Err(error) => import.warnings.push(format!("已跳过 {id}:{error}")),
        }
    }

    if import.entries.is_empty() {
        anyhow::bail!("JSON 里没有可导入的 MCP 服务器");
    }
    Ok(import)
}

/// 只有 command 或 url、且没有嵌套的 server 对象,就当成单个 server。
fn looks_like_single_server(root: &Map<String, Value>) -> bool {
    (root.contains_key("command") || root.contains_key("url"))
        && !root.values().any(|value| {
            value
                .as_object()
                .map(|obj| obj.contains_key("command") || obj.contains_key("url"))
                .unwrap_or(false)
        })
}

fn json_server_to_toml(
    id: &str,
    config: &Map<String, Value>,

View on GitHub (pinned to b1ed92e5e4)