BigPizzaV3/CodexPlusPlus · error · anyhow::Error
缺少 command 或 url
Error message
缺少 command 或 url
What it means
json_server_to_toml infers the transport from the url field: empty url means Stdio, which requires a command to launch. If the entry has neither a url nor a non-empty command, no executable transport can be built and the conversion bails; this surfaces either directly or as a per-entry warning ('已跳过 {id}: ...') during JSON import.
Solutions
- Add a 'command' field (with args if needed) for stdio servers.
- Add a 'url' field for HTTP servers instead.
- Rename incorrectly cased keys (command/url must be lowercase, exact).
- Remove placeholder entries that have no launch configuration.
Example fix
// before
{"myserver":{"args":["--port","8080"]}}
// after
{"myserver":{"command":"node","args":["server.js","--port","8080"]}} Defensive patterns
Strategy: validation
Validate before calling
function entryHasTransport(cfg) {
return (typeof cfg.url === 'string' && cfg.url.trim() !== '') ||
(typeof cfg.command === 'string' && cfg.command.trim() !== '');
} Type guard
function isStdioServer(c) { return typeof c.command === 'string' && c.command.trim() !== ''; }
function isHttpServer(c) { return typeof c.url === 'string' && c.url.trim() !== ''; } Try / catch
match json_server_to_toml(&config) {
Ok(body) => /* ... */,
Err(e) if e.to_string().contains("缺少 command 或 url") => warn!("跳过 {id}: {e}"),
Err(e) => return Err(e),
} Prevention
- Require command or url in the server editor form before save
- Map alternate key names (cmd, serverUrl, endpoint) to command/url on import
- Lint pasted JSON against the expected server schema
- Drop or comment out placeholder entries with no transport
When it happens
Trigger: A server object in the JSON lacks both 'command' and 'url' (or both are empty/whitespace), e.g. {"myserver":{"args":[...]}} passed through parse_mcp_servers_json.
Common situations: Copied config from a tool that uses different key names (e.g. 'cmd', 'endpoint', 'serverUrl'); entry describing a disabled placeholder; hand-written JSON missing the launch field.
Understand the failure class
Background: "missing required argument" and "the following required arguments were not provided": what required-argument errors mean and how to fix them — this error's family across 20 libraries.
Related errors
AI-assisted analysis of BigPizzaV3/CodexPlusPlus@b1ed92e5e4 (2026-09-19).
Data as JSON: /api/errors/b185868155ae2495.
Report an issue: GitHub.
Appendix: source
Thrown at crates/codex-plus-core/src/mcp_config.rs:375
json_map(config, "headers")
} else {
Vec::new()
};
if let Some(timeout) = config.get("startup_timeout_sec").and_then(Value::as_f64) {
form.startup_timeout_sec = format_number(timeout);
}
if let Some(enabled) = config.get("enabled").and_then(Value::as_bool) {
form.enabled = enabled;
}
form.transport = if form.url.is_empty() {
McpTransport::Stdio
} else {
McpTransport::Http
};
if form.transport == McpTransport::Stdio && form.command.trim().is_empty() {
anyhow::bail!("缺少 command 或 url");
}
build_mcp_toml_body(&form)
}
fn json_string(config: &Map<String, Value>, key: &str) -> String {
config
.get(key)
.and_then(Value::as_str)
.unwrap_or_default()
.to_string()
}
fn json_map(config: &Map<String, Value>, key: &str) -> Vec<McpKeyValue> {
config
.get(key)
.and_then(Value::as_object)
.map(|map| {View on GitHub (pinned to b1ed92e5e4)