Hmbown/CodeWhale · error

McpLoginServerNotFound

McpLoginServerNotFound

Error message

MCP server '{server}' not found

What it means

Thrown when an MCP OAuth login is requested for a server name that does not exist in the loaded MCP configuration. The code loads the MCP config from disk (with workspace and plugin context) and looks up the requested server name in `cfg.servers`; a missing key aborts the login with a localized message naming the server. This guards the OAuth flow against acting on a name that was deleted, renamed, or never defined.

Solutions

  1. Run /mcp to list currently configured servers and use an exact name from that list
  2. Check the MCP config file at the workspace path and add the server entry before logging in
  3. If the server comes from a plugin, ensure the plugin registry is loaded (check plugin enablement)

Example fix

// before
codew mcp login myserver
// after
# first list names
codew mcp list
# then use an existing name
codew mcp login my-server
Defensive patterns

Strategy: validation

Validate before calling

let cfg = codewhale_mcp::load_config(&path)?;
if !cfg.servers.contains_key(&name) { return Err(anyhow!("MCP server '{name}' not found")); }

Type guard

fn server_exists(cfg: &McpConfig, name: &str) -> bool { cfg.servers.contains_key(name) }

Prevention

When it happens

Trigger: Calling start_mcp_login (via handle_mcp_ui_action) with a server name not present in the mcp config file; a stale UI entry referencing a removed server; a typo in the server key.

Common situations: User edited ~/.codewhale or workspace mcp config and removed a server while the TUI still shows its entry; plugin-contributed servers not loaded (registry mismatch); user typed a server name in a slash command with different casing or spelling.

Understand the failure class

Background: "Not found" and "does not exist" errors: why "Task not found", "No such folder", and "Can't find" fire when a lookup comes back empty — this error's family across 14 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@433685b202 (2026-09-15). Data as JSON: /api/errors/5693d028ea111ddd. Report an issue: GitHub.

Appendix: source

Thrown at crates/tui/src/tui/ui/handlers.rs:520

    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 433685b202)