Difference Between fileWriteLineLimit and fileReadLineLimit in DesktopCommanderMCP

fileReadLineLimit controls the maximum lines returned when reading files without an explicit length parameter, while fileWriteLineLimit restricts how many lines can be written in a single operation to prevent accidental massive writes.

DesktopCommanderMCP implements protective boundaries for file operations through two distinct configuration settings. Understanding the difference between fileWriteLineLimit and fileReadLineLimit is essential for managing large file interactions in MCP (Model Context Protocol) environments. These limits are defined in src/config-manager.ts and enforced within the filesystem handlers to balance performance and safety.

What Are MCP File Line Limits?

DesktopCommanderMCP uses configurable line limits to protect both the LLM and the filesystem from performance degradation. The fileReadLineLimit defaults to 1000 lines and controls automatic truncation during read operations, while the fileWriteLineLimit defaults to 50 lines and guards against unintentional bulk writes.

How fileReadLineLimit Controls Read Operations

When executing a read_file request without an explicit length parameter, MCP falls back to the configured read limit.

In src/handlers/filesystem-handlers.ts, the handleReadFile function constructs a ReadOptions object that uses the default limit when no specific length is provided:

// src/handlers/filesystem-handlers.ts (lines 87-94)
const config = await configManager.getConfig();
const defaultLimit = config.fileReadLineLimit ?? 1000;
...
length: parsed.length ?? defaultLimit,

This means a request like read_file { path: "log.txt" } automatically truncates responses to the first 1000 lines (or your configured value). Users can bypass this limit by explicitly specifying a length parameter in the request.

How fileWriteLineLimit Restricts Write Operations

The write limit operates as a safety guard during write_file operations. Unlike the read limit, which truncates, the write limit generates warnings when content exceeds the threshold.

In src/handlers/filesystem-handlers.ts, the handleWriteFile function validates line counts against the configured maximum:

// src/handlers/filesystem-handlers.ts (lines 34-44)
const config = await configManager.getConfig();
const MAX_LINES = config.fileWriteLineLimit ?? 50;
const lines = parsed.content.split('\n');
const lineCount = lines.length;
if (lineCount > MAX_LINES) {
  // currently the code only adds a tip; the write is still performed,
  // but the intention is to warn the caller that the file is unusually large.
}

When content exceeds 50 lines, MCP completes the write but includes a warning tip suggesting the file be split into smaller chunks (≤30 lines for optimal performance).

Configuration Locations and Default Values

Both limits are defined in src/config-manager.ts with different default values reflecting their distinct purposes:

  • fileReadLineLimit: Defined at line 15, defaults to 1000 lines (line 175 in default config)
  • fileWriteLineLimit: Defined at line 14, defaults to 50 lines (line 174 in default config)

Administrators can override these values in the runtime config.json file without modifying source code, allowing deployment-specific tuning of resource constraints.

Why Separate Limits for Reading and Writing?

The divergence in default values (1000 vs 50) reflects different risk profiles:

  • Reading: Large reads primarily risk overwhelming the LLM context window. The generous 1000-line default allows substantial content exploration while preventing accidental massive payloads. Users can request more data explicitly when needed.
  • Writing: Large writes risk permanent data corruption or disk space exhaustion. The strict 50-line default prevents models from accidentally overwriting files with huge generated content, as writes are typically intentional and should be chunked for better performance.

Practical Code Examples

Override the read limit explicitly when you know you need more data:

// Request specific line count exceeding the default
await rpc.call('read_file', {
  path: 'large-log.txt',
  length: 2500  // Explicitly request more than the 1000-line default
});

Stay within write limits to avoid warnings:

// Safe: 40 lines is under the 50-line limit
const safeContent = Array(40).fill('entry').join('\n');
await rpc.call('write_file', {
  path: 'notes.txt',
  content: safeContent
});

Triggering the write limit warning:

// Warning: 120 lines exceeds the 50-line default
const largeContent = Array(120).fill('log-entry').join('\n');
await rpc.call('write_file', {
  path: 'debug.log',
  content: largeContent
});
// Returns with tip suggesting chunked writes

Summary

  • fileReadLineLimit (default: 1000) truncates file reads to prevent LLM context overflow when no explicit length is specified in src/handlers/filesystem-handlers.ts.
  • fileWriteLineLimit (default: 50) warns against large write operations to prevent accidental bulk file modifications, as implemented in handleWriteFile.
  • Both settings are configured in src/config-manager.ts (lines 14-15) and customizable via config.json.
  • Read limits apply automatically; write limits generate warnings while allowing the operation to complete.
  • Explicit length parameters in read requests bypass the read limit entirely.

Frequently Asked Questions

What happens if I exceed fileReadLineLimit when reading a file?

When you read a file without specifying a length parameter and the file exceeds fileReadLineLimit (default 1000 lines), DesktopCommanderMCP automatically truncates the response to the first 1000 lines according to the logic in src/handlers/filesystem-handlers.ts. The LLM receives only the truncated portion. To access more content, you must make additional read requests with explicit offset and length parameters, or adjust the limit in your config.json file.

Does fileWriteLineLimit prevent writes entirely or just warn?

Currently, fileWriteLineLimit generates a warning tip when exceeded but still completes the write operation. According to the implementation in src/handlers/filesystem-handlers.ts, the handleWriteFile function checks the line count against the configured limit and includes a warning if exceeded, though the content is still written. For strict enforcement, you would need to modify the handler to return an error instead of completing the operation.

Where can I change these limits in DesktopCommanderMCP?

Both limits are defined in src/config-manager.ts (lines 14-15) with default values set in the default configuration (lines 174-175). At runtime, DesktopCommanderMCP reads these values from config.json in the application root. You can modify this JSON file to set custom limits without recompiling the source code, allowing per-deployment customization of file operation boundaries.

Why is the default write limit (50) so much lower than the read limit (1000)?

The 50-line default for writes reflects the destructive nature of write operations versus the non-destructive nature of reads. Large writes risk permanent data loss, disk space exhaustion, and performance degradation from generating massive files accidentally. Meanwhile, large reads only risk context window overflow, which is recoverable. Additionally, according to the DesktopCommanderMCP source code, performance is optimized when files are kept under 30 lines, making the 50-line limit a generous upper bound for intentional bulk operations while encouraging file chunking.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →