3.0 KiB
File Tools
Use file_* tools for all file I/O. Do not substitute shell commands (cat, sed, grep, find, echo >).
All args values must be JSON strings — even numbers. Write "780" not 780.
file_read
Read a file with line numbers. Prefer segments over full reads.
Args: [path] or [path, start, end] or [path, "--head=N"]
start/end: 1-indexed line numbers, inclusive. Must be strings. Max segment: 2000 lines.- No start/end: reads up to 500 lines from line 1.
--head=N: read first N lines.
call_tool: calls=[{tool: "file_read", args: ["/abs/path"]}]
call_tool: calls=[{tool: "file_read", args: ["/abs/path", "100", "200"]}]
call_tool: calls=[{tool: "file_read", args: ["/abs/path", "--head=50"]}]
- BAD:
args: ["/path", 100, 200]— numbers are not strings - BAD:
args: ["/path", "match=foo"]— not a valid argument - GOOD:
args: ["/abs/path", "100", "200"]— string line numbers
Constraints: Absolute paths only.
file_write
Create or overwrite a file. Produces a unified diff.
Args: [path, content]
call_tool: calls=[{tool: "file_write", args: ["/abs/path", "file content here"]}]
Constraints: Absolute paths only. Parent directory must exist.
file_edit
Replace text in a file. Has fuzzy matching (whitespace/indent flexible).
Args: [path, old_string, new_string] or [path, old_string, new_string, "replace_all=true"]
call_tool: calls=[{tool: "file_edit", args: ["/abs/path", "old text", "new text"]}]
call_tool: calls=[{tool: "file_edit", args: ["/abs/path", "old text", "new text", "replace_all=true"]}]
Constraints: Absolute paths only. Errors if old_string matches multiple locations — add surrounding context to disambiguate, or use replace_all=true.
file_glob
Find files by glob pattern, sorted by mtime (newest first).
Args: [pattern] or [pattern, search_dir]
- First arg: glob pattern (e.g.
"*.go","**/*.ts"). - Second arg (optional): absolute search directory. Defaults to cwd.
call_tool: calls=[{tool: "file_glob", args: ["*.go", "/abs/search/dir"]}]
call_tool: calls=[{tool: "file_glob", args: ["**/*.go"]}]
file_grep
Search file contents with ripgrep. Capped at 50 matches by default.
Args: [pattern, ...flags]
- First arg (required): regex search pattern (positional).
- Remaining args: flags only. The search path is a flag, not a positional arg.
call_tool: calls=[{tool: "file_grep", args: ["pattern", "--path=/abs/dir"]}]
call_tool: calls=[{tool: "file_grep", args: ["TODO", "--path=src/", "--glob=*.go", "-i"]}]
call_tool: calls=[{tool: "file_grep", args: ["func main", "--path=/home/user/project"]}]
- BAD:
args: ["pattern", "/path/to/dir"]— path must use--path=flag - GOOD:
args: ["pattern", "--path=/path/to/dir"]
Flags: --path=<dir>, --mode=files_with_matches|content|count, --glob=<pattern>, --type=<type>, -i, -A <n>, -B <n>, -C <n>, --multiline, --head=<n>, --offset=<n>.