File-system boundary
Hash, read, write, patch, rename, change attributes, and delete without losing current-state guarantees.
File operations are batch-oriented and explicit about state. Mutation tools declare a files object whose keys are paths, avoiding dictionary-only top-level schemas that some hosts cannot encode.
file_hash
Streams up to 50 complete files into SHA-256 without returning their contents. Use it immediately before guarded changes, including AST-capable files.
file_capabilities and file_read
file_capabilities({ filePaths }) reports file kind, language, parse health, configuration generation, intrinsic AST/text/Aider support, and effective methods after configuration filtering.
file_read accepts mode: "auto" | "ast" | "text". AST mode returns a source map/requested symbols or RFC 6901-selected JSON, JSONC, TOML, or YAML values through selectors; text mode returns bounded exact content; auto prefers AST when available. Text requests use range: { start, end }, while the numeric zero-based, end-exclusive lines: [start, end] tuple remains a permanent compatibility alias. Results include the whole-file hash, size, resolved mode, and capabilities.
file_write
Accepts file_write({ files: { "<path>": { content, ... } } }) and creates new files atomically. Replacing an existing non-structurally-rewritable file requires a fresh expectedSha256 by default. Setting safety.require_hash = false makes the hash optional, but any supplied hash is still verified. The complete batch policy preflight runs before filesystem preparation. For a new nested target, in-place formatter staging may transiently create, revalidate, and remove missing parents before the guarded commit recreates them; the live target is not written before commit.
file_patch
The normal mutation API accepts file_patch({ files: { ... } }). The declared files property contains the path-keyed batch, and each file receives one fresh hash and ordered operations under one deterministic lock:
patchStrategy: "ast"withastRulesfor structural changespatchStrategy: "aider_block"withaiderBlocksfor exact text changes
The agent selects either strategy when file_capabilities reports it as effective; parseable source commonly supports both. Configuration can narrow strategies but does not auto-select one.
Set preview: true to execute the strategy dry-run without formatting or committing and receive an opaque one-use previewReceipt. Preview diffs show only the AST or Aider change. Commit with that receipt to reuse the reviewed unformatted candidate after policy, approval, generation, and hash checks; formatting runs only at commit, including previewReceipt commit, so the committed SHA-256 is the formatted file hash. AST and Aider failures include per-operation evidence and a recovery suggestion. A fresh hash is required by default; safety.require_hash = false permits omission while retaining internal compare-and-swap protection and verification of any supplied hash. Formatting follows version 2 inheritance: the first enabled matching formatter wins, stdout consumes candidate stdin, in_place edits an adjacent staged file, and unmatched files use explicit preserve, dprint, or reject fallback.
file_rename
Accepts file_rename({ files: { ... } }) and preflights multiple regular files as one operation. Every source requires delete policy and every destination requires write; one denied or unapproved endpoint prevents all renames. Destinations must not already exist, and every endpoint is locked for cooperating ast-mcp processes. Source hashes are required by default and optional only when safety.require_hash = false; supplied hashes are always enforced. Ordinary failures are rolled back when possible; the operation is no-replace but not crash-atomic, and external actors can race pathname checks.
file_chattr and file_delete
file_chattr({ files: { ... } }) applies bounded chmod and same-owner chown changes under write policy. file_delete({ files: { ... } }) requires delete policy and a fresh hash by default, checks AST import references before deletion, and removes only newly empty authorized ancestors. safety.require_hash = false permits omission, while supplied hashes remain enforced. Version 2 grants no implicit OS temporary-directory or unrestricted access; express required scope through narrow top-level [[paths]] rules. Deleting AST-capable files when a bounded reference scan cannot be proven requires forceReferences: true, and the result reports referenceVerificationBypassed: true separately from known forced importers.