Skip to content

feat: add filesystem MCP server with paginated reads#214

Closed
sheeki03 wants to merge 1 commit intoGitHubSecurityLab:mainfrom
sheeki03:feat/filesystem-paginated-reads
Closed

feat: add filesystem MCP server with paginated reads#214
sheeki03 wants to merge 1 commit intoGitHubSecurityLab:mainfrom
sheeki03:feat/filesystem-paginated-reads

Conversation

@sheeki03
Copy link
Copy Markdown

Problem

The filesystem MCP server's read_file tool has no offset parameter, no line numbers, and a hard 500-line cap with no way to page through the rest. Large files force multiple blind reads with no way to know which section was returned. The list_directory tool uses os.path.normpath for path containment which is vulnerable to sibling-prefix escapes (e.g. ../repo2/secret passes when BASE_DIR=/tmp/repo).

Changes

src/seclab_taskflow_agent/mcp_servers/filesystem/filesystem.py (new)

  • read_file: Adds start_line (1-indexed offset), line_numbers (prefix each line with its number), and include_summary (footer with total line count and displayed range). Default behavior (max_lines=500, no offset) is backward-compatible with existing callers.
  • list_directory: Lists files/directories relative to the repo root.
  • Path traversal protection: Both tools use os.path.realpath to resolve symlinks, then check target.startswith(base + os.sep) to prevent sibling-prefix escapes. This blocks ../, symlink escapes, and paths like ../repo2/file where the prefix overlaps with BASE_DIR.

tests/test_filesystem_mcp.py (new, 16 tests)

  • TestReadFile: default 500-line cap, start_line offset, past-EOF returns empty, line number formatting, summary footer, backward compatibility
  • TestPathTraversal: ../ blocked, sibling-prefix escape blocked, symlink escape blocked (skipped on platforms without symlink support), valid subdirectory allowed, list_directory traversal blocked

…al protection

Introduces read_file with start_line offset, line_numbers, and include_summary
parameters for paginated large-file reads. Both read_file and list_directory
use os.path.realpath to prevent path traversal including symlink escapes.
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