Hmbown/CodeWhale · error
MCP server ' ' was not found.
Error message
MCP server '{server}' was not found. What it means
Thrown by start_mcp_login when the MCP server name given for an OAuth login does not exist in the loaded MCP configuration. The config is loaded via load_config_with_workspace_and_plugins (including plugin-registered servers) and `cfg.servers.get(&name)` returns None. The message is produced from the localized McpLoginServerNotFound template with `{server}` substituted.
Solutions
- Verify the server name matches a `servers` entry in your MCP config (check spelling/case).
- Confirm the TUI is loading the config file you edited (workspace path / plugin registry).
- Re-run discovery or reload MCP config so the server list is fresh, then retry login.
- If the server comes from a plugin, enable that plugin so its servers appear in the merged config.
Example fix
// before
begin_oauth_login_for_server_tool(&name, ...)?;
// after: validate first
if !cfg.servers.contains_key(&name) {
eprintln!("server '{name}' not in config; available: {:?}",
cfg.servers.keys().collect::<Vec<_>>());
return Ok(());
}
begin_oauth_login_for_server_tool(&name, ...)?; Defensive patterns
Strategy: validation
Validate before calling
let cfg = crate::mcp::load_config_with_workspace_and_plugins(&path, &workspace, plugin_registry.as_ref())?;
if !cfg.servers.contains_key(&name) {
eprintln!("unknown server '{name}'; known: {:?}", cfg.servers.keys().collect::<Vec<_>>());
return Ok(());
} Try / catch
match start_mcp_login(app, &name).await {
Ok(()) => {},
Err(e) if e.to_string().contains("was not found") => {
status(format!("Server '{name}' not in config — reload the server list"));
}
Err(e) => status(format!("MCP login failed: {e:#}")),
} Prevention
- Always derive server names from the loaded config's `servers` keys, never from memory.
- Refresh the TUI's MCP snapshot after editing the config file or toggling plugins.
- Enable the plugin that registers the server before attempting login.
- Match names exactly — the lookup is case-sensitive map access.
When it happens
Trigger: Calling the MCP UI login action (handle_mcp_ui_action -> start_mcp_login) with a server name that is absent from the mcp config file at `path` and from any plugin registry servers — e.g. a typo'd name, a server removed from config, or the wrong config path being loaded.
Common situations: Renaming or deleting a server in the MCP config while the TUI still shows a stale snapshot; passing a name from a different config file than the one loaded; plugin providing the server not enabled so the merged config lacks it.
Understand the failure class
Background: Record Not Found Errors: "not found", RecordNotFound, and "was not found" — what they mean and how to fix them — this error's family across 28 libraries.
Related errors
- invalid MCP OAuth callback port 0
- MCP server ' ' already has bearer/static Authorization…
- MCP server ' ' not found
- MCP server ' ' not found
- MCP server ' ' not found
AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22).
Data as JSON: /api/errors/89acad8a9491e255.
Report an issue: GitHub.
Appendix: source
Thrown at crates/tui/src/tui/ui/handlers.rs:555
let progress = Arc::clone(&pending.progress);
app.mcp_login = Some(pending);
report_mcp_login(
app,
app.tr(MessageId::McpLoginStarting)
.replace("{server}", &name)
.replace("{cancel_key}", "Esc"),
StatusToastLevel::Info,
);
tokio::spawn(async move {
let handshake = async {
let cfg = crate::mcp::load_config_with_workspace_and_plugins(
&path,
&workspace,
plugin_registry.as_ref(),
)?;
let server = cfg.servers.get(&name).ok_or_else(|| {
anyhow::anyhow!(
codewhale_localization::tr(locale, MessageId::McpLoginServerNotFound)
.replace("{server}", &name)
)
})?;
crate::mcp::oauth::begin_oauth_login_for_server_tool(
&name,
server,
(!scopes.is_empty()).then_some(scopes),
callback_port,
callback_url.as_deref(),
network_policy.as_ref(),
)
.await
};
let operation = async {
// Bound the whole handshake as well as each guarded HTTP request.
// The timeout is in the background: even an unresponsive issuer
// cannot delay redraw, input or cancellation.View on GitHub (pinned to 73e0f67d83)