Skip to content

fix(mcp): add size-based log rotation to prevent unbounded MCP log growth#9308

Open
OthmanAdi wants to merge 2 commits intowarpdotdev:masterfrom
OthmanAdi:othmanadi/fix-mcp-log-rotation
Open

fix(mcp): add size-based log rotation to prevent unbounded MCP log growth#9308
OthmanAdi wants to merge 2 commits intowarpdotdev:masterfrom
OthmanAdi:othmanadi/fix-mcp-log-rotation

Conversation

@OthmanAdi
Copy link
Copy Markdown

@OthmanAdi OthmanAdi commented Apr 28, 2026

Description

Fixes #8993

MCP server log files grow without any size limit or rotation. A single log file was reported at 16.4 GB, with total MCP log storage consuming 18.3 GB across 1,423 files on Windows. The only cleanup mechanism is a full directory purge on application startup, meaning logs accumulate unbounded during a single session.

Root cause: SimpleLogger (in crates/simple_logger/) opens log files with truncate on creation and writes every line via an unbounded async channel to a background task. There is zero size checking, zero rotation, and zero max file size logic. The main Warp application log (in crates/warp_logging/) already has rotation (up to 5 files for GUI, 10 for CLI), but this was never implemented for SimpleLogger.

Fix: Add size-based log rotation to SimpleLogger's async writer task. When the current log file exceeds 50 MB, the writer:

  1. Flushes and drops the async file handle
  2. Deletes the oldest rotated file (.old.4)
  3. Shifts existing rotated files up (.old.3 -> .old.4, .old.2 -> .old.3, etc.)
  4. Renames the current file to .old.0
  5. Opens a fresh empty log file
  6. Continues logging

This mirrors the rotation pattern in crates/warp_logging/src/native.rs (lines 132-184).

Bounds

Parameter Value Rationale
MAX_LOG_FILE_SIZE 50 MB Large enough to capture extended sessions, small enough to prevent disk abuse
MAX_ROTATED_FILES 5 Matches the GUI rotation count for the main Warp log
Total storage per server ~300 MB 50 MB active + 5 x 50 MB rotated
Rotation trigger Before write that would exceed limit Never exceeds 50 MB + one line

What this changes

Before After
Log files grow to 16+ GB Capped at 50 MB per file
No rotation at all Up to 5 rotated copies preserved
Disk usage unbounded Bounded at ~300 MB per MCP server
No user-configurable limits Constants can be tuned (future: settings)

Testing

  • cargo check -p simple_logger -p warp passes clean
  • The rotation logic follows the same pattern as warp_logging/src/native.rs::rotate_files (lines 154-184), which is already in production
  • std::fs::rename and std::fs::remove_file are synchronous, which is correct here: rotation is rare (once per 50 MB) and must complete atomically before the new file is opened
  • Byte counter tracks writes in-memory rather than calling metadata() per line, avoiding unnecessary syscalls on every log write

Server API dependencies

  • N/A

Agent Mode

  • Warp Agent Mode

Changelog Entries for Stable

CHANGELOG-BUG-FIX: MCP server log files now rotate at 50 MB with a maximum of 5 rotated files per server, preventing unbounded disk usage on Windows and all platforms.

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Apr 28, 2026

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @OthmanAdi on file. In order for us to review and merge your code, each contributor must visit https://cla.warp.dev to read and agree to our CLA. Once you have done so, please comment @cla-bot check to trigger another check.

@oz-for-oss
Copy link
Copy Markdown

oz-for-oss Bot commented Apr 28, 2026

@OthmanAdi

I'm starting a first review of this pull request.

You can follow along in the session on Warp.

I requested changes on this pull request and posted feedback.

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Copy link
Copy Markdown

@oz-for-oss oz-for-oss Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Overview

This PR adds size-based rotation to SimpleLogger so MCP log files are rotated after roughly 50 MB and older files are retained with .old.N suffixes.

Concerns

  • A single oversized MCP log message can still exceed the intended per-file cap because rotation is skipped when the active file is empty; this leaves disk usage unbounded by message size.
  • Untouched-code concern: app/src/ai/mcp/templatable_manager/native.rs appends stderr into the same String with read_line(&mut buf) without clearing it, so each stderr line can re-log all prior stderr and create the oversized messages that bypass this cap.

Security

  • Untrusted MCP server output can still drive unbounded disk growth with a single large log message; chunk or truncate log messages before writing.

Verdict

Found: 0 critical, 1 important, 0 suggestions

Request changes

Comment /oz-review on this pull request to retrigger a review (up to 3 times on the same pull request).

Powered by Oz

Comment thread crates/simple_logger/src/lib.rs Outdated
log_line
);
let line_bytes = line.len() as u64;
if bytes_written > 0 && bytes_written + line_bytes > MAX_LOG_FILE_SIZE {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ [IMPORTANT] [SECURITY] A single oversized MCP log message still bypasses the cap when the new file is empty (bytes_written == 0), so untrusted server output can write an arbitrarily large active/rotated file; truncate or chunk messages before writing.

@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Apr 29, 2026

Thank you for your pull request and welcome to our community. We require contributors to sign our Contributor License Agreement, and we don't seem to have the users @OthmanAdi on file. In order for us to review and merge your code, each contributor must visit https://cla.warp.dev to read and agree to our CLA. Once you have done so, please comment @cla-bot check to trigger another check.

@OthmanAdi
Copy link
Copy Markdown
Author

Updated to address the security concern:

  1. Removed the bytes_written > 0 guard so rotation triggers even on a fresh/empty file. The empty file still gets rotated (renamed to .old.0) and a new one is opened, so the total rotated set still caps at ~300 MB.

  2. Added a per-line truncation limit of 1 MB (MAX_LOG_LINE_BYTES). Any single log message exceeding this gets its first 1 MB written followed by ... [truncated]. This bounds the worst case for any individual write, regardless of what the MCP server sends.

The stderr accumulation bug in templatable_manager/native.rs (where read_line appends to an uncleared buffer) is a pre-existing issue separate from log rotation. Happy to file a follow-up issue for that if it would be helpful.

@OthmanAdi
Copy link
Copy Markdown
Author

@cla-bot check

@cla-bot cla-bot Bot added the cla-signed label Apr 29, 2026
@cla-bot
Copy link
Copy Markdown

cla-bot Bot commented Apr 29, 2026

The cla-bot has been summoned, and re-checked this pull request!

…owth

MCP server log files in the SimpleLogger grew without any size limit or
rotation. A single log file could reach 16+ GB, with total MCP log
directories consuming 18+ GB of disk space on Windows.

The main Warp application log already has rotation logic in
warp_logging, but SimpleLogger (used for MCP server logs) had none.

Add size-based rotation to SimpleLogger's async writer: when a log file
exceeds 50 MB, it is renamed to .old.0 and older rotated files are
shifted (.old.0 -> .old.1, etc.), up to a maximum of 5 rotated files.
The oldest file beyond the limit is deleted. A new empty log file is
created to continue logging.

Rotation is synchronous (std::fs::rename/remove_file) since it happens
once per 50 MB and must complete atomically before the new file is
opened. The async file handle is dropped first to release the lock.

The constants MAX_LOG_FILE_SIZE (50 MB) and MAX_ROTATED_FILES (5) keep
total MCP log storage bounded at approximately 300 MB per server.

Closes warpdotdev#8993
…ty file

Oz review found that a single oversized MCP log message bypasses the
per-file cap when bytes_written is 0 (fresh file after rotation or
startup), because the guard checked bytes_written > 0 before triggering
rotation. A malicious MCP server could emit a single multi-GB log line
that gets written without any size check.

Two fixes:

1. Remove the bytes_written > 0 guard. Rotation now triggers even when
   the active file is empty if the incoming line would exceed the cap.
   The empty file gets rotated immediately and a fresh one opened.

2. Truncate individual log lines at 1 MB (MAX_LOG_LINE_BYTES). Any
   line exceeding the limit is written with its first 1 MB of content
   followed by ... [truncated]. This bounds the maximum size of any
   single write regardless of what the MCP server sends.
@OthmanAdi OthmanAdi force-pushed the othmanadi/fix-mcp-log-rotation branch from f410f84 to ae011cb Compare April 29, 2026 06:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Windows] MCP server log files grow unbounded, consuming 18+ GB of disk space

1 participant