Hmbown/CodeWhale · error

MCP config exceeds the 1 MiB limit

Error message

MCP config {} exceeds the 1 MiB limit

What it means

The MCP config file is read with a hard cap of MAX_MCP_CONFIG_BYTES (1 MiB); anything larger is rejected before parsing. This bounds memory use and protects against pathological or hostile config files.

Solutions

  1. Trim the config: remove unused servers, disabled tools, and duplicated entries
  2. Move large blobs (certs, data) out of the config into referenced files
  3. Verify the path points at the intended MCP config, not a log or dump file

Example fix

// before
{ "mcpServers": { ...1200 entries incl. inline certs... } } // 1.4 MiB
// after
{ "mcpServers": { ...only active servers... } } // < 1 MiB; certs moved to files
Defensive patterns

Strategy: validation

Validate before calling

let size = std::fs::metadata(path)?.len();
if size > 1024 * 1024 {
    return Err(format!("{path:?} exceeds the 1 MiB MCP config limit"));
}

Try / catch

match load_mcp_config(path) {
    Err(e) if e.to_string().contains("1 MiB limit") => {
        eprintln!("trim {path:?} to under 1 MiB before loading");
    }
    other => other?,
}

Prevention

When it happens

Trigger: Calling the MCP config loader with a file whose contents.len() > 1 MiB (read via file.take(MAX + 1) to detect oversize).

Common situations: An MCP config that accumulated hundreds of server entries or embedded credentials/blobs; a merge tool duplicating entries; accidentally pointing the loader at a large log or data file.

Understand the failure class

Background: "File too large" / "file size exceeds limit" errors: why libraries cap file sizes and how to fix them — this error's family across 46 libraries.

Related errors


AI-assisted analysis of Hmbown/CodeWhale@73e0f67d83 (2026-09-22). Data as JSON: /api/errors/33635152ffa7268f. Report an issue: GitHub.

Appendix: source

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

        Err(err) if err.kind() == std::io::ErrorKind::NotFound => return Ok(None),
        Err(err) => {
            return Err(err)
                .with_context(|| format!("Failed to inspect MCP config {}", path.display()));
        }
    };
    let file_type = metadata.file_type();
    if file_type.is_symlink() || !file_type.is_file() {
        anyhow::bail!("MCP config path must be a regular file: {}", path.display());
    }

    let file = open_mcp_config_file(path)
        .with_context(|| format!("Failed to read MCP config {}", path.display()))?;
    let mut contents = String::new();
    file.take(MAX_MCP_CONFIG_BYTES + 1)
        .read_to_string(&mut contents)
        .with_context(|| format!("Failed to read MCP config {}", path.display()))?;
    if contents.len() as u64 > MAX_MCP_CONFIG_BYTES {
        anyhow::bail!("MCP config {} exceeds the 1 MiB limit", path.display());
    }
    Ok(Some(contents))
}

#[cfg(unix)]
fn open_mcp_config_file(path: &Path) -> std::io::Result<fs::File> {
    use std::os::unix::fs::OpenOptionsExt;

    fs::OpenOptions::new()
        .read(true)
        .custom_flags(libc::O_NOFOLLOW)
        .open(path)
}

#[cfg(not(unix))]
fn open_mcp_config_file(path: &Path) -> std::io::Result<fs::File> {
    fs::File::open(path)
}

View on GitHub (pinned to 73e0f67d83)