Skip to content

Claude Instructions

MCP Filesystem Ultra — Instructions for AI Agents (v4.5.x)

Section titled “MCP Filesystem Ultra — Instructions for AI Agents (v4.5.x)”

Designed to be included in AI agent system prompts or context. Copy this entire page to your AI’s custom instructions, or call help at runtime to retrieve the same information dynamically.


1. Tool inventory — v4.5.x exposes 20 tools

Section titled “1. Tool inventory — v4.5.x exposes 20 tools”

The server registers 20 tools (17 core + git + minify_js + help). Aliases and the fs super-tool are disabled to save tokens (see tools_core.go:103-105). Call help() to see the live catalog at runtime.

ToolPurpose
read_fileRead with start_line/end_line, head/tail, base64; batch paths
write_fileAtomic write; auto-path-conversion
edit_fileSurgical edit with backup; modes: replace, search_replace, regex, delete_range, replace_range; tolerant_whitespace, diff_format, expected_hash
multi_editMultiple edits in one atomic batch; diff_format, dry_run, expected_hash
list_directoryCached listing; output_format (compact | json | tree); max_depth (tree)
search_filesRegex / literal; include_content (file search vs content); count_only, output_format:json
get_file_infoStat + paths JSON array for batch
move_fileMove/rename with auto-create-dirs
copy_fileCopy with auto-create-dirs
delete_fileSoft by default (v4.5.11+); permanent:true for hard delete; returns SD-ID
create_directoryMkdir -p
batch_operationsAtomic request_json; multi-step pipeline_json; rename_json
project_replaceFind/replace across a tree (one round-trip)
backuplist/info/compare/cleanup/restore/undo_last/undo_chain + list_trash/restore_trash/purge_trash
analyze_operationDry-run file/write/edit/delete/optimize
wslsync (workspace or single file) | status (auto-sync is env-var driven in v4.5.x via MCP_WSL_AUTOSYNC)
server_infohelp (topic filter) | stats | artifact (capture/write/info)
ToolPurpose
git (v4.5.2+, 9 actions since v4.5.25)init/status/diff/log/show/add/commit/restore/branch; paths is a native array, rev replaces commit_range/source
minify_js (v4.5.7+)Pure-Go JS minifier — no Node, no external deps
helpDiscovery — call this first to see all 20 tools and current best practices

1.3 Aliases are disabled (do not call them)

Section titled “1.3 Aliases are disabled (do not call them)”

The following are defined in tools_aliases.go but commented out in registerTools():

  • 6 compatibility aliases: read_text_file, search, edit, write, create_file, directory_tree
  • 7 Claude-Code aliases: View, Edit, Write, Replace, LS, GlobTool, GrepTool
  • 1 super-tool: fs (dispatch via action)

The rationale (see tools_core.go:103-105 and the startup log line Registered 20 tools ... aliases disabled): duplicates inflate the tool list returned by tools/list, hurting both discovery latency and token cost. Use the core names directly.


1. search_files(path, pattern, count_only:true)
→ "found N matches at lines X, Y"
2. read_file(path, start_line, end_line)
→ only the lines you need (token-efficient)
3. edit_file(path, old_text, new_text) // single edit
or
multi_edit(path, edits_json: "[{old_text:..., new_text:...}]") // many
4. (optional) verify with search_files(path, old_text, count_only:true)
→ "0 matches" ← old text gone

For project-wide refactors, replace steps 3 + 4 with one call:

project_replace({path:".", find:"foo", replace:"bar", preview:true})
→ if preview is OK, call again with preview:false

2.2 multi_edit over multiple edit_file calls on the same file

Section titled “2.2 multi_edit over multiple edit_file calls on the same file”

Every successful edit_file invalidates the file cache and the session’s auto-OCC baseline. A second edit_file immediately after a successful one is safe (the engine recorded the post-edit hash as the new baseline) but slow. For 2+ edits on the same file, use multi_edit:

multi_edit({
path: "file.go",
edits_json: "[
{\"old_text\":\"foo()\", \"new_text\":\"bar()\"},
{\"old_text\":\"baz()\", \"new_text\":\"qux()\"}
]"
})

2.3 batch_operations over many small edits across files

Section titled “2.3 batch_operations over many small edits across files”

For edits across many files, prefer batch_operations(request_json) with atomic:true over N individual edit_file calls. One backup, one round-trip, atomic rollback on any failure.

For complex multi-step refactors, use pipeline_json with parallel:true for DAG-scheduled concurrent steps.

2.4 Whole-file rewrites — use write_file

Section titled “2.4 Whole-file rewrites — use write_file”

Never edit_file with old_text = a 15-line header and new_text = a 150-line file body. v4.5.10 added a server-side guard that blocks this anti-pattern (the accidental full-file rewrite) because the model thinks it is rewriting the file but edit_file only swaps the matched block, leaving the old tail concatenated. Heuristic: if len(new_text) > 2 × len(old_text) and there is more than 50% of the file outside the match → use write_file. Override with allow_rewrite:true (creates a safety backup).


Risk is computed from edit magnitude (bytes-touched / file-size) and occurrence count:

LevelBytes touchedOccurrencesDefault action
LOW≤ 20%< 50Proceed with backup
MEDIUM> 20%≥ 50Proceed with backup + warning
HIGH> 75%≥ 100Proceed with backup + warning + VERIFY
CRITICAL≥ 90%Proceed with backup + warning + VERIFY

All operations auto-proceed with backup — never blocked. HIGH and CRITICAL include an explicit VERIFY instruction in the response.

The session remembers the content_hash of every file it last read or last wrote. Before an edit_file without an explicit expected_hash, the engine compares the on-disk hash to that baseline. If the file changed on disk since the session last saw it (i.e. another process modified it), it flags it.

Modes (--auto-occ CLI flag):

  • off — no check
  • warn (default) — non-blocking notice in the response
  • block — rejects the edit with a clear error

Key correctness property: the baseline is updated on the session’s own writes too (using the post-edit content_hash), so consecutive edits never false-positive. Only genuinely external changes do.

To opt in explicitly per call, pass expected_hash:"<hash from previous edit's structured content_hash field>". The chained-edit pattern: read → edit (response contains content_hash in StructuredContent) → edit again with expected_hash: <that hash>.

Three signals, ALL must fire, to block:

  1. len(new_text) > 2 × len(old_text)
  2. File has > 50% content outside the matched block
  3. len(new_text) > 500 bytes AND len(new_text) > 50% of file size

When blocked, the error message recommends write_file. Override with allow_rewrite:true (creates a safety backup and proceeds).


Cause: stale old_text from a prior read, or whitespace mismatch. Fix: re-read_file (range) and copy the exact bytes — tabs vs spaces, CRLF vs LF. As a last resort, try tolerant_whitespace:true.

“stale edit: file content changed since read”

Section titled ““stale edit: file content changed since read””

Cause: the file was modified between your read and your edit (OCC detected a content hash mismatch against your expected_hash). Fix: re-read_file and use the new content_hash from the response.

Cause: the heuristic in §3.3 fired. Fix: use write_file for full-file rewrites; or pass allow_rewrite:true if the rewrite is genuinely intended.

“Tool not found: create_file / recovery_edit / mcp_read / …”

Section titled ““Tool not found: create_file / recovery_edit / mcp_read / …””

Cause: these were v3.x aliases, all disabled in v4.x. Fix: use the core name (write_file, edit_file, read_file).

Cause: should not happen — every tool calls core.NormalizePath before I/O. Fix: if you still see one, file an issue with the exact path that failed.

search_files returns “No matches found” but the text is in the file

Section titled “search_files returns “No matches found” but the text is in the file”

Cause: you asked for filename search, not content search (default). Fix: add include_content:true. Since v4.5.24, the “no-match” message self-explains this. As a shortcut, any of output_format:json, output:content, or context_lines:N also auto-flips include_content:true.


5. Token efficiency — preferred workflow

Section titled “5. Token efficiency — preferred workflow”
Inefficient: read_file(entire_file) → write_file(entire_file)
5,000-line file ≈ 250,000 tokens
Efficient: search_files(file, "function")
read_file(file, start_line, end_line)
edit_file(file, "old", "new")
5,000-line file ≈ 2,500 tokens

For multiple changes in one file:

Inefficient: N × edit_file(path, old_i, new_i)
Efficient: multi_edit(path, edits_json: "[...]") ← 1 call

For project-wide changes:

Efficient: project_replace({path, find, replace, preview:true})
→ preview:false if it looks right

For very large refactors:

Efficient: batch_operations({pipeline_json: "..."}) ← parallel DAG

All tools handle path conversion automatically. Examples:

You provideEngine writes / reads
/home/user/app.go (in WSL)/home/user/app.go
/mnt/c/Users/user/app.go (in WSL)C:\Users\user\app.go
C:\Users\user\app.go (Windows)C:\Users\user\app.go
C:\Users\user\app.go (in WSL)C:\Users\user\app.go

Always copy paths from list_directory or read_file output — never retype them. A documented incident (2026-06-11): a path written from memory with the wrong case (estats.razor vs Estats.razor) resolves correctly on Windows (case-insensitive) but downstream Razor compiles fail three layers down (RZ10011 class estats).



TaskTool
Read a fileread_file
Read specific linesread_file({path, start_line, end_line})
Create / overwrite a filewrite_file
Surgical editedit_file({path, old_text, new_text})
Multiple edits in one filemulti_edit({path, edits_json})
Project-wide find/replaceproject_replace({path, find, replace})
Find where code issearch_files
Count occurrencessearch_files({count_only:true})
List directory (compact)list_directory({path})
List directory (JSON)list_directory({path, output_format:"json"})
Copy / move filescopy_file, move_file
Soft deletedelete_file({path})
Atomic multi-file opsbatch_operations({request_json})
Multi-step pipelinebatch_operations({pipeline_json})
Undo last editbackup({action:"undo_last"})
Restore a soft-deletebackup({action:"restore_trash", sd_id})
Dry-run a deleteanalyze_operation({operation:"delete", path})
Git status / commitgit({action:"status"}) / git({action:"commit"})
Minify JSminify_js({path, dry_run:true})
Help / discoverhelp

Version: v4.5.29 | Last updated: 2026-07-11