Hmbown/CodeWhale · error · anyhow::Error

Reviewed plugin MCP server returned an error in '{method}' (

Error message

Reviewed plugin MCP server returned an error in '{method}' (server details suppressed to protect environment-backed credentials)

What it means

response_result inspects every JSON-RPC response for an `error` member during initialize and catalogue discovery (tools/list, resources/list, resources/templates/list, prompts/list). When the server belongs to a reviewed plugin, the error body is dropped and replaced with this generic message (crates/tui/src/mcp.rs:1225-1230), because a reviewed plugin may hold environment-backed credentials whose values could be echoed in server error text. The method name is kept; the payload is not.

Source

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

impl McpServerCapabilities {
    fn from_initialize_response(response: &serde_json::Value) -> Option<Self> {
        let capabilities = response.get("result")?.get("capabilities")?.as_object()?;
        Some(Self {
            tools: capabilities.contains_key("tools"),
            resources: capabilities.contains_key("resources"),
            prompts: capabilities.contains_key("prompts"),
        })
    }
}

fn response_result<'a>(
    response: &'a serde_json::Value,
    method: &str,
    suppress_server_details: bool,
) -> Result<Option<&'a serde_json::Value>> {
    if let Some(error) = response.get("error") {
        if suppress_server_details {
            anyhow::bail!(
                "Reviewed plugin MCP server returned an error in '{method}' (server details suppressed to protect environment-backed credentials)"
            );
        }
        anyhow::bail!("MCP error in '{method}': {error}");
    }
    Ok(response.get("result"))
}

async fn run_optional_discovery<F>(server: &str, method: &str, timeout: Duration, discovery: F)
where
    F: Future<Output = Result<()>>,
{
    match tokio::time::timeout(timeout, discovery).await {
        Ok(Ok(())) => {}
        Ok(Err(error)) => {
            tracing::warn!(
                target: "mcp",
                server,

View on GitHub (pinned to 8880682c63)

Solutions

  1. Check the plugin MCP server's own logs - the suppressed detail exists only there.
  2. Temporarily register the same endpoint as a plain (non-reviewed) MCP server to see the full `MCP error in '...'` body, then remove it.
  3. Verify the endpoint and credentials out-of-band (curl the MCP endpoint) and fix the server.
  4. After fixing server-side state, retry; re-trust only if the plugin's own bytes changed.
Defensive patterns

Strategy: try-catch

Try / catch

if let Err(err) = initialize_and_discover(&mut conn).await {
    if err.to_string().starts_with("Reviewed plugin MCP server returned an error") {
        // Detail is intentionally suppressed; the answer lives in the plugin
        // server's own logs, not in this error chain.
        tracing::warn!(server = %name, "reviewed plugin server error; check server-side logs");
    }
    return Err(err);
}

Prevention

When it happens

Trigger: The reviewed plugin's remote MCP server returns a JSON-RPC error for initialize or one of the */list discovery calls: bad path, expired or insufficient token, a 4xx/5xx mapped to a protocol error, or an unimplemented method.

Common situations: Provider endpoint rotated or credentials expired after the plugin was trusted; server version drift; scopes missing for catalogue methods.

Related errors


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