Skip to content

Conversation

@abderraouf-belalia
Copy link

@abderraouf-belalia abderraouf-belalia commented Oct 29, 2025

Summary

Implements #60 - Adds an optional with_line_numbers parameter to the read_text_file tool to support line-numbered output for AI agents.

Changes

  • Added with_line_numbers optional boolean parameter to ReadTextFile struct
  • Updated read_text_file service method to format output with line numbers when enabled
  • Line numbers are right-aligned (6 digits) with pipe separator format: 1 | content
  • Uses 1-based indexing for line numbers (matching standard text editor conventions)
  • Maintains full backward compatibility (defaults to false)
  • Added comprehensive unit tests covering various edge cases
  • Updated CHANGELOG.md with feature description
  • Updated capabilities.md documentation using mcp-discovery

Motivation

Modern AI agents (like Codex and others) rely on line numbers to inject targeted patches to code. This feature allows agents to obtain all necessary context in a single tool invocation rather than making multiple calls, significantly improving efficiency for code modification tasks.

Example Output

Without line numbers (default):

fn main() {
    println!("Hello");
}

With line numbers (with_line_numbers: true):

     1 | fn main() {
     2 |     println!("Hello");
     3 | }

Test Plan

  • All existing tests pass
  • New tests added for line numbering feature:
    • Line numbers enabled
    • Line numbers disabled (backward compatibility)
    • Empty files
    • Single line files
    • Files without trailing newlines
    • Large files (1000+ lines)

Testing

Run tests with:

cargo test --test test_fs_service test_read_text_file

All 6 new tests pass successfully.

Validation

All project checks pass:

cargo make check
  • Formatting check: Passed
  • Clippy linting: Passed
  • All 123 tests: Passed
  • Cargo check: Passed

[agent pull request]

Copy link
Member

@hashemix hashemix left a comment

Choose a reason for hiding this comment

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

Hey @abderraouf-belalia , thanks for the contribution. this is a good enhancement.

I requested some small changes, I will review it after those are addressed.

CHANGELOG.md Outdated
Comment on lines 3 to 12
## [Unreleased]

### 🚀 Features

* Add optional line numbering to read_text_file tool ([#60](https://github.com/rust-mcp-stack/rust-mcp-filesystem/issues/60))
- Added `with_line_numbers` optional parameter to `read_text_file` tool
- When enabled, prefixes each line with right-aligned line numbers and pipe separator
- Useful for AI agents that need to target specific lines for code patches
- Maintains backward compatibility with existing usage

Copy link
Member

Choose a reason for hiding this comment

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

Updating the CHANGELOG.md is not necesarry :) , it will be auto-generated at release time.

<code><b>read_text_file</b></code>
</td>
<td>Read the complete contents of a text file from the file system as text. Handles various text encodings and provides detailed error messages if the file cannot be read. Use this tool when you need to examine the contents of a single file. Only works within allowed directories.</td>
<td>Read the complete contents of a text file from the file system as text. Handles various text encodings and provides detailed error messages if the file cannot be read. Use this tool when you need to examine the contents of a single file. Optionally include line numbers for precise code targeting. Only works within allowed directories.</td>
Copy link
Member

Choose a reason for hiding this comment

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

This file will be automatically generated using mcp-discovery

Comment on lines 27 to 28
/// When enabled, each line is prefixed with its line number (1-based).
/// Useful for AI agents that need to target specific lines for code patches.
Copy link
Member

Choose a reason for hiding this comment

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

This makes it easier for AI systems to understand the format , more concise, precise, and clear.

Suggested change
/// When enabled, each line is prefixed with its line number (1-based).
/// Useful for AI agents that need to target specific lines for code patches.
/// When enabled, each line is prefixed with a right-aligned, 1-based line number
/// Followed by a space, a vertical bar (`|`), and another space in the format: ` 123 | <original line content>`

let file_path = create_temp_file(
temp_dir.join("dir1").as_path(),
"test.txt",
"line1\nline2\nline3",
Copy link
Member

Choose a reason for hiding this comment

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

Would you mind adding similar test case that uses \r\n instead of just \n? to test the windows line ending?

#[tokio::test]
async fn test_read_text_file_with_line_numbers_empty_file() {
let (temp_dir, service, _allowed_dirs) = setup_service(vec!["dir1".to_string()]);
let file_path = create_temp_file(temp_dir.join("dir1").as_path(), "empty.txt", "");
Copy link
Member

Choose a reason for hiding this comment

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

Can you please add two more tests for some edge cases?
one test for a file with only one \n in the content , and another one with a \r\n content
both should read:

     1 |
     2 |

Copy link
Author

Choose a reason for hiding this comment

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

Hey!

Regarding the tests with a file with only one \n or \r\n, it wouldn't generate 2 empty lines per my understanding and some playground confirmations but a single empty due to how .lines() works as it splits the file using \n as a separator and "\n" is seen as "[EMPTY STRING]\n" rather than "[EMPTY STRING]\n[EMPTY STRING]". The only way to get,

     1 |
     2 |

is to write the tests with \n\n (similar logic for windows).

abderraouf-belalia pushed a commit to abderraouf-belalia/rust-mcp-filesystem that referenced this pull request Nov 3, 2025
- Remove manual CHANGELOG.md entry (auto-generated at release)
- Revert docs/capabilities.md changes (auto-generated via mcp-discovery)
- Improve documentation clarity for with_line_numbers parameter format
- Add test for Windows line endings (\r\n)
- Add edge case tests for newline-only content

Addresses review comments on PR rust-mcp-stack#61

[agent commit]
Abderraouf Belalia added 4 commits November 3, 2025 14:13
Implements rust-mcp-stack#60 - Add line numbering flag for read_text_file

Changes:
- Added `with_line_numbers` optional parameter to ReadTextFile struct
- Updated read_text_file service method to format output with line numbers
- Line numbers are right-aligned (6 digits) with pipe separator format
- Uses 1-based indexing for line numbers
- Maintains backward compatibility (defaults to false)
- Added comprehensive unit tests for various scenarios
- Updated CHANGELOG.md with feature description

This feature enables AI agents to obtain file content with line numbers
in a single tool invocation, improving efficiency for code modification
tasks that require precise line-based targeting.

[agent commit]
- Remove manual CHANGELOG.md entry (auto-generated at release)
- Revert docs/capabilities.md changes (auto-generated via mcp-discovery)
- Improve documentation clarity for with_line_numbers parameter format
- Add test for Windows line endings (\r\n)
- Add edge case tests for newline-only content

Addresses review comments on PR rust-mcp-stack#61

[agent commit]
@abderraouf-belalia abderraouf-belalia force-pushed the feature/read-text-file-line-numbers branch from ffbc6e5 to 7300ee3 Compare November 3, 2025 13:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants