{"record":{"id":"6dc87dcb2c78c96c","repo":"Hmbown/CodeWhale","slug":"refusing-mcp-server-server-name-its-remote-en","errorCode":null,"errorMessage":"Refusing MCP server '{server_name}': its remote endpoint no longer matches the reviewed plugin origin","messagePattern":"Refusing MCP server '(.+?)': its remote endpoint no longer matches the reviewed plugin origin","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/tui/src/mcp.rs","lineNumber":741,"sourceCode":"        );\n        crate::plugins::registry::verify_plugin_component_authority(\n            &self.authority,\n            self.required_capability(),\n        )\n        .map_err(|reason| {\n            anyhow::anyhow!(\n                \"Refusing to {operation} MCP server '{server_name}' from plugin bundle `{}`: {reason}. {remediation}\",\n                self.authority.plugin_name\n            )\n        })\n    }\n\n    fn validate_remote_endpoint(&self, server_name: &str, endpoint: &str) -> Result<()> {\n        let (endpoint, origin) = reviewed_remote_endpoint_identity(endpoint)?;\n        if self.approved_remote_endpoint.as_deref() != Some(endpoint.as_str())\n            || self.approved_remote_origin.as_deref() != Some(origin.as_str())\n        {\n            anyhow::bail!(\n                \"Refusing MCP server '{server_name}': its remote endpoint no longer matches the reviewed plugin origin\"\n            );\n        }\n        Ok(())\n    }\n\n    fn catalog_is_current(&self) -> bool {\n        // Catalog exposure is an authority boundary too: stale tool, prompt,\n        // or resource descriptions can steer the model even when the later\n        // operation would be denied. Revalidate both the mutable reviewed\n        // source and the Codewhale-owned stage before publishing any entry.\n        crate::plugins::registry::verify_plugin_component_authority(\n            &self.authority,\n            self.required_capability(),\n        )\n        .is_ok()\n    }\n}","sourceCodeStart":723,"sourceCodeEnd":759,"githubUrl":"https://github.com/Hmbown/CodeWhale/blob/8880682c63083a91624de936797efa3ce9e498fd/crates/tui/src/mcp.rs#L723-L759","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","solutions":["Restore the endpoint to the exact reviewed URL, matching scheme, host, port, and path character-for-character","If the change is intentional: /plugin reload, redo the trust flow so the new endpoint and origin are recorded, then /plugin enable","Remember the comparison is on exact strings: trailing slashes and case differences count as drift"],"exampleFix":"# before: endpoint drifted from the reviewed origin\n\"url\": \"https://api.example.com/v2/mcp\"   # reviewed: /v1/mcp\n# after (intentional change): re-review the new endpoint\n/plugin reload && /plugin show p\n# repeat the displayed trust command + /plugin enable p","handlingStrategy":"validation","validationCode":"// Compare the configured endpoint against the approved record before connecting\nfn endpoint_approved(configured: &str, approved_endpoint: &str, approved_origin: &str) -> bool {\n    let (endpoint, origin) = reviewed_remote_endpoint_identity(configured)?;\n    endpoint == approved_endpoint && origin == approved_origin\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Pin remote MCP endpoints to exact reviewed URLs; avoid trailing-slash variants","Re-run the trust flow after any endpoint change, however small","Follow provider migration guides so endpoint URLs stay canonical","Treat unexpected endpoint drift as a possible config swap; verify before re-approving"],"tags":["plugin","mcp","security","endpoint","origin"],"backgroundTag":null,"analyzedSha":"8880682c63083a91624de936797efa3ce9e498fd","analyzedAt":"2026-08-16T11:31:27.956Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}