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. Each batch accepts 1–50 requests, including renames.
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. New operations require an explicit strategy; receipt commits intentionally omit it. AST failure never triggers an implicit Aider fallback.
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; if formatting is enabled, it runs only at commit, including previewReceipt commit. 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 is disabled by default. When enabled, the first enabled matching external formatter runs in stdout or staged in_place mode. Formatter executables must already be available; ast-mcp does not download them. See the optional formatting guide.
Receipts remain reserved during the entire batch, including mutation completion and freshness publication. Confirmed no-change failures and verified rollback release reservations for retry. Success consumes receipts; changed source, expiry, configuration changes, or uncertain recovery require a new preview. Concurrent replay is rejected.
Optional SQL candidate validation
Each file_patch entry may include sql: { policy?, dialect?, version?, variant? }. Validation is optional: no per-operation SQL selection and no required default means no parser call. A configured dialect alone does not request validation. Advisory results never block a safe patch; required validation allows only a valid result. Per-operation policy: "skip" overrides a required default without changing persistent configuration.
The bundled adapter supports PostgreSQL 18 core SQL only. It does not validate procedural DO or function bodies, PL/pgSQL, extensions, catalog state, or execution. Other dialects and unsupported variants remain patchable with advisory policy or an explicit skip. The adapter accepts 512 KiB per source and 2 MiB outstanding; eight total requests include the active request, leaving up to seven waiting. One worker runs at a time. A five-second end-to-end deadline covers queueing, lazy initialization, parsing, and result handling. Bounded worker retirement keeps capacity reserved until termination is confirmed. Generic SQL AST matching through run does not validate a selected database dialect.
A preview receipt binds SQL selection, policy, and validation outcome. Generate a new preview to change them. Read the configuration reference for persistent defaults, selectors, and result details.
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. Authorized missing destination parents are created without marker files. Policy and physical paths are revalidated before side effects. Rollback removes only operation-owned empty directories. 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. It rechecks hashes and file identity after journaling and applies metadata through the verified open handle. 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. File access is restricted by default and can use an explicitly approved unrestricted mode. See the filesystem access guide for its scope, approval, and preserved safeguards. 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.
Reference roots are inventoried and candidate files parsed once per delete batch. Internal batch references do not block a jointly deleted target; external importers still require explicit overrides.
Default cancellation returns the string code aborted. Incomplete rollback failures include bounded cause codes and affected paths. Preserve this recovery information, inspect current state, and obtain fresh hashes before retrying.
Reference verification requires effective AST read access. If [files.read].modes excludes ast, deletion of AST-capable files fails with reference_verification_failed before parsing. Restore AST reads or use a reviewed forceReferences: true override; OS permissions and hash guards remain enforced.