Hmbown/CodeWhale · warning · anyhow::Error
MCP server '{name}' connection to '{host}' requires approval
Error message
MCP server '{name}' connection to '{host}' requires approval; re-run after `/network allow {host}` or set network.default = "allow" in config What it means
The same network-policy gate as the Deny case, but the decider returned Prompt: the host is neither allowed nor denied and the default posture requires interactive approval before this host may be contacted (crates/tui/src/mcp.rs:1499-1504). Because connect_with_policy does not prompt interactively, it fails immediately with the remediation embedded in the message.
Source
Thrown at crates/tui/src/mcp.rs:1500
Arc::clone(&authority_revocation_reason),
)
});
let transport: Box<dyn McpTransport> = if let Some(url) = &config.url {
// Per-domain network policy gate (#135). Only the HTTP/SSE transport
// is gated; STDIO MCP servers run as local subprocesses and never
// touch the network from this code path.
if let Some(decider) = network_policy
&& let Some(host) = host_from_url(url)
{
match decider.evaluate(&host, "mcp") {
Decision::Allow => {}
Decision::Deny => {
anyhow::bail!(
"MCP server '{name}' connection to '{host}' blocked by network policy"
);
}
Decision::Prompt => {
anyhow::bail!(
"MCP server '{name}' connection to '{host}' requires approval; \
re-run after `/network allow {host}` or set network.default = \"allow\" in config"
);
}
}
}
// Honor the standard `HTTP_PROXY` / `HTTPS_PROXY` (and their
// lowercase equivalents) plus `NO_PROXY` env vars when
// reaching MCP HTTP servers (#1408). Reqwest 0.13 does not
// auto-detect these by default, so users behind corporate
// proxies, on China-mainland connections routing through a
// local Clash / Shadowsocks tunnel, etc. previously had MCP
// HTTP traffic bypass the proxy entirely while every other
// tool on the box (curl, npm, …) used it.
// `connect_timeout` bounds only the connect phase; the total request
// timeout is the read timeout (a sane backstop) so per-call
// execute_timeout can actually govern request duration. Previously
// this set reqwest's TOTAL `.timeout()` from connect_timeout (10s),View on GitHub (pinned to 8880682c63)
Solutions
- Run /network allow <host> in the session, then retry the operation.
- Or set [network] default = "allow" in ~/.codewhale/config.toml to stop prompting globally (a weaker posture - prefer per-host allows).
- For scripts/CI, pre-allowlist the exact MCP hosts before starting the run.
Example fix
# before: connect fails # MCP server 'linear' connection to 'mcp.linear.app' requires approval # after (session-scoped): run in the TUI, then retry # /network allow mcp.linear.app # after (config, ~/.codewhale/config.toml): # [network] # default = "allow"
Defensive patterns
Strategy: validation
Validate before calling
// Before connecting under a prompt-default posture, confirm the host is
// already allowlisted for this session (via /network allow <host>).
use crate::network_policy::{host_from_url, Decision};
fn host_preapproved(policy: &NetworkPolicyDecider, url: &str) -> bool {
match host_from_url(url) {
Some(host) => !matches!(policy.evaluate(&host, "mcp"), Decision::Prompt | Decision::Deny),
None => false,
}
} Prevention
- Pre-allowlist remote MCP hosts with /network allow <host> before first use.
- In CI/scripts, allowlist hosts in setup rather than weakening the default.
- Prefer per-host allows over setting network.default = "allow" globally.
When it happens
Trigger: First connection to a new remote MCP host under the default prompt posture; the host has not been added to the session allow list.
Common situations: Fresh installs; newly added servers in config; scripted or CI contexts where nobody can answer an interactive prompt.
Related errors
- MCP server '{name}' connection to '{host}' blocked by networ
- Timed out waiting for MCP JSON-RPC response from server '{}'
- GET timeout
- MCP SSE connect cancelled before the request completed
- Could not inspect GitHub Release ${tag}: ${detail}
AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16).
Data as JSON: /api/errors/6d7e30e61adb8942.
Report an issue: GitHub.