Hmbown/CodeWhale · error

Refusing MCP server '{server_name}': its remote endpoint no

Error message

Refusing MCP server '{server_name}': its remote endpoint no longer matches the reviewed plugin origin

What it means

A plugin-contributed remote MCP server may only connect to the endpoint and origin recorded at review time. validate_remote_endpoint re-derives the endpoint identity and compares both the endpoint and origin strings against the approved ones; any drift refuses the connection because the approval covers exactly one remote destination.

Source

Thrown at crates/tui/src/mcp.rs:741

        );
        crate::plugins::registry::verify_plugin_component_authority(
            &self.authority,
            self.required_capability(),
        )
        .map_err(|reason| {
            anyhow::anyhow!(
                "Refusing to {operation} MCP server '{server_name}' from plugin bundle `{}`: {reason}. {remediation}",
                self.authority.plugin_name
            )
        })
    }

    fn validate_remote_endpoint(&self, server_name: &str, endpoint: &str) -> Result<()> {
        let (endpoint, origin) = reviewed_remote_endpoint_identity(endpoint)?;
        if self.approved_remote_endpoint.as_deref() != Some(endpoint.as_str())
            || self.approved_remote_origin.as_deref() != Some(origin.as_str())
        {
            anyhow::bail!(
                "Refusing MCP server '{server_name}': its remote endpoint no longer matches the reviewed plugin origin"
            );
        }
        Ok(())
    }

    fn catalog_is_current(&self) -> bool {
        // Catalog exposure is an authority boundary too: stale tool, prompt,
        // or resource descriptions can steer the model even when the later
        // operation would be denied. Revalidate both the mutable reviewed
        // source and the Codewhale-owned stage before publishing any entry.
        crate::plugins::registry::verify_plugin_component_authority(
            &self.authority,
            self.required_capability(),
        )
        .is_ok()
    }
}

View on GitHub (pinned to 8880682c63)

Solutions

  1. Restore the endpoint to the exact reviewed URL, matching scheme, host, port, and path character-for-character
  2. If the change is intentional: /plugin reload, redo the trust flow so the new endpoint and origin are recorded, then /plugin enable
  3. Remember the comparison is on exact strings: trailing slashes and case differences count as drift

Example fix

# before: endpoint drifted from the reviewed origin
"url": "https://api.example.com/v2/mcp"   # reviewed: /v1/mcp
# after (intentional change): re-review the new endpoint
/plugin reload && /plugin show p
# repeat the displayed trust command + /plugin enable p
Defensive patterns

Strategy: validation

Validate before calling

// Compare the configured endpoint against the approved record before connecting
fn endpoint_approved(configured: &str, approved_endpoint: &str, approved_origin: &str) -> bool {
    let (endpoint, origin) = reviewed_remote_endpoint_identity(configured)?;
    endpoint == approved_endpoint && origin == approved_origin
}

Prevention

When it happens

Trigger: Editing the remote URL after approval (different host, scheme, port, or path), normalization differences such as trailing slashes or case, providers moving routes (/sse to /mcp), or a swapped config pointing at a different host.

Common situations: Domain migrations by MCP providers, fixing a typo in the URL post-review, staging-to-production URL changes, copied configs pointing at a different environment.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@8880682c63 (2026-08-16). Data as JSON: /api/errors/6dc87dcb2c78c96c. Report an issue: GitHub.