npx skills add ...
npx skills add mathews-tom/armory --skill filesystem
File and directory operations via Claude Code built-in tools, replacing the Filesystem MCP server. Triggers on: "read this file", "write to file", "edit file", "find files matching", "search for text in files", "list directory", "show directory tree", "rename file".
npx skills add mathews-tom/armory --skill filesystem
All file and directory operations use Claude Code's built-in tools. No MCP server needed — native tools are faster, more capable, and cost zero context tokens when idle.
| Filesystem MCP Tool | Replacement | Notes |
|---|---|---|
read_file(path) | Read tool | Supports line offset and limit |
read_multiple_files(paths) | Multiple parallel Read calls | Faster than sequential MCP calls |
write_file(path, content) | Write tool | Overwrites entire file |
edit_file(path, edits) | Edit tool | Exact string replacement; surgical edits |
list_directory(path) | Glob or Bash ls | Glob for patterns, ls for simple listing |
directory_tree(path) | Bash fd or Glob **/* | fd is fastest; Glob for pattern filtering |
search_files(pattern, path) | Grep tool | Full regex, file type filters, context lines |
create_directory(path) | Bash mkdir -p | -p creates intermediate directories |
move_file(src, dst) | Bash mv | Also handles renames |
get_file_info(path) | Bash stat or Bash ls -la | Size, permissions, timestamps |
list_allowed_directories | N/A | Claude Code operates in the working directory; no sandbox restrictions |
Use the Read tool with an absolute path:
For large files, use offset and limit to read specific sections:
This reads 50 lines starting from line 100. Use this for files with thousands of lines to avoid flooding context.
Issue multiple Read calls in a single response. Claude Code executes them concurrently:
Parallel reads are faster than the MCP's read_multiple_files which serialized internally.
The Read tool handles binary formats:
pages: "1-5" for large documents (max 20 pages per call)Use the Write tool to create a file or overwrite an existing one:
The Write tool requires reading the file first if it already exists. For new files,
write directly.
Use the Edit tool for surgical modifications — replace exact string matches:
The Edit tool fails if old_string is not unique in the file. Provide enough
surrounding context to make the match unique, or use replace_all: true for
find-and-replace across the entire file.
Prefer Edit over Write for existing files. Edit preserves everything outside the changed region and shows a clear diff. Write replaces the entire file.
Results are sorted by modification time (most recent first).
| Grep Parameter | Purpose |
|---|---|
pattern | Regex pattern to match |
type | File type filter (py, js, ts, rust, go, etc.) |
glob | Glob pattern filter (*.tsx, src/**/*.py) |
output_mode | files_with_matches (default), content, count |
-C, -A, -B | Context lines: around, after, before matches |
-i | Case-insensitive search |
Simple listing:
Recursive tree with fd:
Tree with depth limit:
Filter by extension:
The -p flag creates all intermediate directories. Always verify the parent path
exists first with ls.
Rename a file (same directory):
Move a directory:
Always confirm with the user before deleting files or directories.
| Command | Returns |
|---|---|
stat | Size, permissions, timestamps, inode |
ls -la | Permissions, owner, size, modification date |
wc -l | Line count |
file | MIME type detection |
fd . --type f --max-depth 2Read: package.json or Read: pyproject.tomlGrep: pattern="def main|if __name__" type="py"| Error | Cause | Resolution |
|---|---|---|
| Read: file not found | Path incorrect or file deleted | Verify with ls or Glob |
| Edit: old_string not unique | Multiple matches in the file | Add more surrounding context to make it unique |
| Edit: old_string not found | Content changed since last read | Re-read the file, then retry with current content |
| Write: file not read first | Attempting to overwrite without reading | Read the file first, then Write |
| Permission denied | Insufficient OS permissions | Check with ls -la; use chmod if appropriate |
| Glob: no files found | Pattern too restrictive | Broaden the pattern; check path spelling |
Bash ls or fd to list directories.fd or find for queries Glob cannot express (size filters, date filters).grep or rg via Bash.Glob: **/*.py → all Python files recursively
Glob: src/**/*.ts → TypeScript files under src/
Glob: *.md → Markdown files in current directory
Glob: **/test_*.py → test files anywhere in the treeGrep: pattern="def process_data" type="py"
Grep: pattern="TODO|FIXME" glob="*.py"
Grep: pattern="class.*Controller" output_mode="content" -C=2ls -la /path/to/directoryfd . /path/to/directory --type ffd . /path/to/directory --type f --max-depth 2fd -e py /path/to/directorymkdir -p /path/to/new/directorymv /path/to/source.py /path/to/destination.pymv /path/to/old-name.py /path/to/new-name.pymv /path/to/source-dir /path/to/destination-dircp /path/to/source.py /path/to/destination.py
cp -r /path/to/source-dir /path/to/destination-dirrm /path/to/file.py
rm -r /path/to/directorystat /path/to/file.py
ls -la /path/to/file.py
wc -l /path/to/file.py# Find all files containing the old string
Grep: pattern="old_function_name" type="py" output_mode="files_with_matches"
# Then Edit each file
Edit: /path/to/file1.py (old_string → new_string, replace_all: true)
Edit: /path/to/file2.py (old_string → new_string, replace_all: true)fd --type f --exec stat -f '%z %N' {} \; | sort -rn | head -20