Hmbown/CodeWhale · error · anyhow::Error
No external MCP candidate named '{name}'. Run /mcp import to
Error message
No external MCP candidate named '{name}'. Run /mcp import to list sources with provenance. What it means
MCP import resolves the requested name (case-insensitive equality) against external MCP sources discovered from the home dir, the workspace, and the marketplace file (~/.codewhale/mcp-marketplace.json via codewhale_home). A miss bails with this message pointing to /mcp import, which lists candidates with provenance. Note this is a discovery miss - a discovered-but-hard-blocked candidate is found and then refused by a separate check.
Source
Thrown at crates/tui/src/tui/ui/provider_routes.rs:742
) -> anyhow::Result<String> {
use crate::mcp::external_import::{
ImportDecision, apply_approved, discover_external_sources, load_consent_store,
merge_approved_into_config, record_decisions, save_consent_store,
};
use std::collections::HashMap;
use std::time::{SystemTime, UNIX_EPOCH};
let home = crate::config::effective_home_dir().unwrap_or_else(|| PathBuf::from("."));
let market_path = codewhale_config::codewhale_home()
.ok()
.map(|h| h.join("mcp-marketplace.json"));
let markets: Vec<PathBuf> = market_path.into_iter().collect();
let all = discover_external_sources(&home, workspace, &markets);
let candidate = all
.iter()
.find(|c| c.name.eq_ignore_ascii_case(name))
.ok_or_else(|| {
anyhow::anyhow!(
"No external MCP candidate named '{name}'. Run /mcp import to list sources with provenance."
)
})?;
if approve && candidate.hard_blocked {
anyhow::bail!(
"Refusing to import '{}': {} (enabled=false is a hard block)",
candidate.name,
candidate.block_reason.as_deref().unwrap_or("hard blocked")
);
}
let mut decisions = HashMap::new();
decisions.insert(
candidate.name.clone(),
if approve {
ImportDecision::Approve
} else {View on GitHub (pinned to 0c42157ee5)
Solutions
- Run /mcp import with no argument to list candidates with provenance, then copy the exact name
- Add or refresh the source: place it in a discovered location or update mcp-marketplace.json
- Check spelling - matching is case-insensitive but exact, not fuzzy
Defensive patterns
Strategy: validation
Validate before calling
// Rust - list discovered candidates and exact-match before import
let home = crate::config::effective_home_dir().unwrap_or_else(|| PathBuf::from("."));
let all = discover_external_sources(&home, workspace, &markets);
if !all.iter().any(|c| c.name.eq_ignore_ascii_case(name)) {
return list_candidates_with_provenance(&all); // show what IS importable instead of erroring blind
} Try / catch
match all.iter().find(|c| c.name.eq_ignore_ascii_case(name)) {
Some(candidate) => import_candidate(candidate),
None => show_hint("run /mcp import to list sources with provenance"),
} Prevention
- Run /mcp import without arguments first to see exact candidate names
- Keep mcp-marketplace.json synced and workspace sources in discovered locations
- Remember matching is case-insensitive but exact - no fuzzy or prefix matching
When it happens
Trigger: Importing a name that matches no discovered candidate: typo, the source file or mcp-marketplace.json absent/empty, discovery paths not covering where the source lives, or the entry renamed upstream.
Common situations: Name copied from stale docs; marketplace JSON not synced; workspace-level source moved; case differences beyond exact-ignore-case (no fuzzy or prefix matching).
Related errors
- MCP server '{name}' not found
- MCP server '{name}' not found
- app-server auth token cannot be empty
- {} has no supported external CLI credential source
- MCP server '{}' collides with already-registered server '{ex
AI-assisted analysis of Hmbown/CodeWhale@0c42157ee5 (2026-08-20).
Data as JSON: /api/errors/cef4c4eba828acec.
Report an issue: GitHub.