{"record":{"id":"e8654cf8f06948ec","repo":"Hmbown/CodeWhale","slug":"mcp-http-destination-requires-network-approval","errorCode":null,"errorMessage":"MCP HTTP destination requires network approval","messagePattern":"MCP HTTP destination requires network approval","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"crates/tui/src/mcp/http_client.rs","lineNumber":227,"sourceCode":"            .context(\"building guarded MCP HTTP client\")?;\n        let mut clients = self\n            .clients\n            .lock()\n            .unwrap_or_else(std::sync::PoisonError::into_inner);\n        if !proxied && clients.len() < 32 {\n            clients.insert(key, client.clone());\n        }\n        Ok(client)\n    }\n}\n\nfn validate_network_policy(url: &Url, network_policy: Option<&NetworkPolicyDecider>) -> Result<()> {\n    let host = url.host_str().context(\"MCP URL has no host\")?;\n    if let Some(policy) = network_policy {\n        match policy.evaluate(host, \"mcp\") {\n            Decision::Allow => {}\n            Decision::Deny => bail!(\"MCP HTTP destination blocked by network policy\"),\n            Decision::Prompt => bail!(\"MCP HTTP destination requires network approval\"),\n        }\n    }\n    Ok(())\n}\n\nfn validate_url(url: &Url) -> Result<()> {\n    if !matches!(url.scheme(), \"http\" | \"https\") || url.host_str().is_none() {\n        bail!(\"MCP HTTP requires an http:// or https:// URL with a host\");\n    }\n    Ok(())\n}\n\nfn url_has_credentials(url: &Url) -> bool {\n    !url.username().is_empty() || url.password().is_some()\n}\n\nimpl McpHttpClient {\n    async fn public_dns_pin(&self, url: &Url) -> Result<Option<(String, SocketAddr)>> {","sourceCodeStart":209,"sourceCodeEnd":245,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/73e0f67d83c59909b571efdfc88c4bc28c309cb1/crates/tui/src/mcp/http_client.rs#L209-L245","documentation":"Network policy evaluation can return Decision::Prompt, meaning the destination requires interactive user approval before connecting. In this synchronous validation path no prompt can be shown, so validate_network_policy throws this error to indicate approval must be obtained beforehand.","triggerScenarios":"validate_network_policy gets Decision::Prompt from policy.evaluate(host, \"mcp\") — the host is neither allow-listed nor denied, so policy demands user consent, from either new (initial URL) or client_for_target (redirect target).","commonSituations":"First-time connection to a new MCP host under an approval-based policy; a redirect to a host the user has not yet approved; running headless/automated where the approval UI never runs.","solutions":["Pre-approve the host in the network policy (add to allowlist) so evaluate returns Allow","Trigger the approval flow for this host in the UI, then retry the connection","Use a decider implementation that auto-allows known-good hosts for automated environments"],"exampleFix":"// before\n// policy.evaluate(\"new-host.example.com\", \"mcp\") == Prompt -> error\n// after\npolicy.approve_host(\"new-host.example.com\", \"mcp\"); // user consented earlier\n// evaluate now returns Allow and the request proceeds","handlingStrategy":"fallback","validationCode":"let host = Url::parse(endpoint)?.host_str().unwrap_or_default().to_string();\nif let Decision::Prompt = policy.evaluate(&host, \"mcp\") {\n    // trigger interactive approval flow before constructing the client\n    approval_ui.request_host_approval(&host, \"mcp\").await?;\n}","typeGuard":null,"tryCatchPattern":"match connect(...).await {\n    Err(e) if e.to_string().contains(\"requires network approval\") => {\n        // surface approval prompt to user, then retry after consent\n        approval_ui.request_host_approval(&host, \"mcp\").await?;\n        connect(...).await?\n    }\n    other => other?,\n}","preventionTips":["Pre-approve known MCP hosts so evaluate() never returns Prompt in automation","Run headless workloads with an explicit allowlist policy, not a prompt policy","Catch Decision::Prompt before constructing the HTTP client"],"tags":["mcp","http","network-policy","approval"],"backgroundTag":"permission-denied","analyzedSha":"73e0f67d83c59909b571efdfc88c4bc28c309cb1","analyzedAt":"2026-09-22T01:30:00.501Z","contentChangedAt":"2026-09-22T01:30:00.501Z","schemaVersion":2},"datasetVersion":"2026-09-22T21:17:16.096Z"}