Skip to main content
Glama
patchloom
by patchloom

Patchloom

CI Security crates.io Release License

Tests Coverage OpenSSF Best Practices OpenSSF Scorecard FOSSA Status

Docs VS Code Marketplace crates.io downloads

One binary. Every platform. Structured file edits for AI agents.

Patchloom is a single-binary CLI that gives AI coding agents safe, structured file editing on any operating system. It edits JSON, YAML, and TOML by selector (not regex), preserves comments, understands code structure across 20 languages, batches multiple file edits into one tool call, and works identically on Linux, macOS, and Windows.

Not a generic filesystem MCP. Default MCP filesystem servers read/write files as text. Patchloom adds dry-run previews, parser-backed config and markdown edits, AST ops, multi-file batch/tx with undo, and stable error_kind peels for hosts. Full coding agents (Claude Code, Codex, Cursor) own the loop; Patchloom is the tool layer they (or a Rust embedder) call.

Patchloom demo: 6 edits across 4 files in JSON, YAML, and TOML: one command, comments preserved

# Edit a YAML value by selector without breaking comments or formatting
patchloom doc set config.yaml database.port 5432 --apply

# Batch 6 file edits into a single tool call
patchloom batch --apply <<'EOF'
doc.set package.json version "2.0.0"
doc.set config.yaml app.version "2.0.0"
doc.set config.toml project.version "2.0.0"
replace README.md "1.0.0" "2.0.0"
replace CHANGELOG.md "1.0.0" "2.0.0"
file.create VERSION "2.0.0"
EOF

Why Patchloom? | Install | Quick start | Commands | Comparison | When to use what | Architecture | Status


Why Patchloom?

The problem

AI agents edit files through tool calls. Each call is a round-trip back to the LLM. When a task touches config files, that process has three failure modes:

  1. Syntax corruption. The agent uses text replacement on JSON, YAML, or TOML and produces invalid output (mismatched braces, broken indentation, lost comments).

  2. Round-trip tax. Editing 6 files means 6 separate tool calls. Each one waits for the LLM to generate, execute, read the result, and plan the next call.

  3. Platform fragmentation. On Linux the agent uses sed, jq, grep. On Windows, none of those exist. The agent falls back to verbose PowerShell or makes errors with unfamiliar syntax.

How patchloom solves each one

Problem

How patchloom solves it

Syntax corruption

doc commands parse the file, change the value by selector path, and write valid output. Comments and formatting are preserved. No regex needed.

Round-trip tax

batch and tx combine N operations into 1 tool call. Six file edits become one command with atomic rollback on failure.

Platform fragmentation

Single static binary with zero dependencies. Same commands, same flags, same behavior on Linux, macOS, and Windows.

What changes with patchloom

Without patchloom (6 tool calls)

Agent: edit file 1  ─── tool call ───▶  15s
Agent: edit file 2  ─── tool call ───▶  15s
Agent: edit file 3  ─── tool call ───▶  15s
Agent: edit file 4  ─── tool call ───▶  15s
Agent: edit file 5  ─── tool call ───▶  15s
Agent: edit file 6  ─── tool call ───▶  15s
                                    Total: ~90s

With patchloom batch (1 tool call)

Agent: batch with
  all 6 edits     ─── tool call ───▶  25s



                  5 round-trips saved
                                    Total: ~25s

Key capabilities

Capability

What it does

Example

Parser-backed edits

Edit JSON/YAML/TOML by selector, preserving comments and formatting

doc set config.yaml db.port 5432 --apply

Batch N files in 1 call

batch and tx combine operations into one tool call with rollback

batch --apply < ops.txt

Comment preservation

YAML/TOML comments survive all edits, including array resizing

doc append config.yaml tags '"v2"' --apply

Heading-aware markdown

Edit sections, tables, and bullets by heading, not line number

md table-append README.md --heading "API" --row "| new | row |" --apply

AST-aware code ops

List, rename, replace, and analyze symbols across 20 languages

ast rename src/ --old old_name --new new_name --apply

Atomic rollback

strict: true reverts every file if format or validate steps fail

tx plan.json --apply

MCP server

Expose all operations as structured MCP tool calls

patchloom mcp-server

Optional CLI sandbox

Reject ../ / absolute path escapes from --cwd on reads and writes (off by default; MCP always on)

patchloom --cwd <ws> --contain search … / create … --apply

Cross-platform

Identical behavior on Linux, macOS, Windows. No sed, jq, grep required.

Same binary everywhere

When to use patchloom vs native tools

Patchloom is not a replacement for all file operations. Its instructions tell agents exactly when to use it and when native tools are faster:

Task

Use patchloom?

Why

Edit a JSON/YAML/TOML value by selector

Yes

Parser guarantees valid output, preserves comments

Edit 3+ files in one task

Yes

batch/tx eliminates round-trips

Append a row to a markdown table

Yes

Heading-aware, no line number guessing

Read a single file

No

Native read_file is faster

Simple text search

No

Native grep is faster

Single-file text replacement

No

Native search_replace is faster

Correctness over speed

Patchloom is not faster than native tools for simple, single-file edits. Use native tools for those. But native text replacement cannot safely edit structured files: a sed on YAML can corrupt indentation, strip comments, or produce invalid syntax. doc set parses the file, changes the value by selector, and writes valid output. That guarantee is the point.

Where patchloom is faster is multi-file batching. Six file edits via native tools means six round-trips to the LLM. One batch call does the same work in a single round-trip.

Task                    PL-CLI    MCP    Native
──────────────────────  ──────  ──────  ──────
search                   18.5s   12.7s   13.9s  ◀ ~same
replace                  36.1s   26.6s   26.1s  ◀ ~same
doc_set                  30.9s   16.9s   13.7s  ◀ native fastest
md_table                 15.5s   13.5s   15.3s  ◀ MCP fastest
tx_multi_file            41.4s   28.5s   22.9s  ◀ native fastest
batch_6_files            50.6s   46.6s   30.3s  ◀ native fastest
batch_mixed_ops          24.7s   13.6s   20.9s  ◀ MCP fastest
yaml_comment_preserve    18.1s   11.6s   16.1s  ◀ MCP fastest
md_insert                15.0s   11.7s   15.7s  ◀ MCP fastest
file_ops                 26.0s   16.6s   17.2s  ◀ ~same
tidy                     45.0s   30.3s   41.7s  ◀ MCP fastest
──────────────────────  ──────  ──────  ──────
TOTAL                   321.9s  228.5s  233.8s

MCP mode wins overall (228.5s vs 233.8s native) because structured tool calls skip shell syntax construction entirely. MCP wins 5/11 tasks; native wins 3/11; 3 are ties. CLI mode is always slowest due to shell construction overhead.


Related MCP server: mcp-json-yaml-toml

Install

# Homebrew (macOS/Linux)
brew install patchloom/tap/patchloom

# crates.io (requires Rust 1.95+, includes MCP server)
cargo install patchloom
# Scoop (Windows)
scoop bucket add patchloom https://github.com/patchloom/scoop-bucket
scoop install patchloom/patchloom

# winget (Windows; PackageIdentifier Patchloom.Patchloom)
winget install Patchloom.Patchloom

# Chocolatey (Windows; community feed; newer versions may lag moderation)
choco install patchloom
# npm / npx (downloads the platform binary from GitHub Releases)
npx patchloom --version
# or: npm install -g patchloom

Pre-built binaries for Linux, macOS, and Windows are on the Releases page. See Installation for shell installer scripts, source builds, and shell completion setup.

  • MCP Registry name: mcp-name: io.github.patchloom/patchloom

Editor extension

Install the companion extension for VS Code, Cursor, Windsurf, or VSCodium:

The extension auto-discovers the CLI (or installs it for you), generates AGENTS.md, configures MCP servers, and adds Quick Actions to the command palette. See the Editor Extension guide for details.

Quick start

1. Set up your project

patchloom init

This creates AGENTS.md in a new project or appends the rules to an existing agent instructions file, offers shell completions, and detects MCP configuration opportunities. Pass -y to skip confirmation prompts.

If you only want the rules text:

patchloom agent-rules >> AGENTS.md

# Or tailor the output:
patchloom agent-rules --mode mcp >> AGENTS.md            # MCP-only (no CLI examples)
patchloom agent-rules --platform windows >> AGENTS.md    # Windows-only syntax

If .vscode/ or .cursor/ exists, init also prints ready-to-copy .vscode/mcp.json or .cursor/mcp.json snippets.

Your AI agent reads AGENTS.md and learns when to use patchloom vs native tools.

2. Edit a config file safely

# Parser-backed: changes the value, preserves comments and formatting
patchloom doc set config.yaml database.port 5432 --apply

3. Batch multiple edits into one call

patchloom batch --apply <<'EOF'
doc.set config.json version '"2.0.0"'
md.upsert_bullet AGENTS.md "Rules" "- Always test"
replace src/main.rs "v1" "v2"
EOF

Values are JSON-first: unquoted 2.0 becomes a number. Force a string with nested quotes as above (Unix shells).

Or use a JSON plan with format and validate lifecycle:

{
  "version": 1,
  "operations": [
    { "op": "doc.set", "path": "config.json", "selector": "version", "value": "2.0.0" },
    { "op": "md.upsert_bullet", "path": "AGENTS.md", "heading": "Rules", "bullet": "- Always test" },
    { "op": "replace", "path": "src/main.rs", "old": "v1", "new": "v2" }
  ],
  "format": [{ "cmd": "cargo fmt --all" }],
  "validate": [{ "cmd": "cargo test", "required": true }]
}
patchloom tx plan.json --apply

tx plans are trusted input. format and validate run their cmd fields through the host shell (sh -c on Unix, cmd /C on Windows), so only run plans you trust.

4. Or use MCP for structured tool calls (no shell syntax)

After installing with MCP support, start the server:

patchloom mcp-server

MCP-capable agents call patchloom tools directly as structured JSON, with no shell quoting or command construction. The agent sends {"path": "config.json", "selector": "version", "value": "2.0"} instead of building patchloom doc set config.json version '"2.0"' --apply.

Coding agents: set PATCHLOOM_MCP_SURFACE=core for an 11-tool pack (list_files, search/read/replace, doc/md, execute_plan, server_info) so schemas stay small. Product default remains full inventory when the env is unset. Prefer Patchloom MCP alone for list+edit (no second filesystem MCP). See the MCP setup guide for Cursor / Claude / Codex paste configs and the full security model.

Using VS Code, Cursor, or Windsurf? The Patchloom extension handles setup automatically: it installs the binary, runs init, and configures your editor's MCP settings.

As a Rust library

Host teams embedding Patchloom instead of a private edit stack: see the embedder host case study (for_agent, peels, fuzzy refuse, apply_fragment, path-only ops).

Add patchloom as a dependency (omit CLI/MCP/AST with default-features = false):

[dependencies]
patchloom = { version = "0.22", default-features = false }
use patchloom::api::{self, ApplyMode, ReplaceOptions, edit_error_kind, EditErrorKind};
use std::path::Path;

// Replace text (preview only, no disk write)
let result = api::replace_text(
    Path::new("src/config.rs"),
    "old_value", "new_value",
    &ReplaceOptions::default(),
    ApplyMode::Preview,
    None,
)?;
println!("{}", result.diff);

// Agent hosts: shared primary+fallback policy (unique, require_change, fuzzy @ 0.90)
let opts = ReplaceOptions::for_agent();
// Fail closed: zero matches become EditErrorKind::NoMatch
match api::replace_in_content("body", "missing", "x", &opts) {
    Ok(r) => println!("changed={}", r.changed),
    Err(e) => assert_eq!(edit_error_kind(&e), Some(EditErrorKind::NoMatch)),
}
// for_agent auto-refuses over-wide fuzzy; custom options use api::fuzzy_span_suspicious
// Buffer multi-op + host write: api::refuse_batch_if_suspicious_fuzzy after apply_content_edits
// Invalid options and bad regex peel InvalidInput (CLI/tx typed errors included)
match api::replace_in_content("body", "", "x", &ReplaceOptions::default()) {
    Err(e) => assert_eq!(edit_error_kind(&e), Some(EditErrorKind::InvalidInput)),
    Ok(_) => panic!("empty pattern must error"),
}

// Set a value in a JSON file
api::doc_set(
    Path::new("config.json"),
    "version",
    serde_json::json!("2.0"),
    ApplyMode::Apply,
    None,
)?;

// Multi-doc YAML: merge into document 0 (selector None = root only)
api::doc_merge(
    Path::new("stream.yaml"),
    serde_json::json!({"env": "prod"}),
    ApplyMode::Apply,
    None,
    Some("0"),
)?;

// Sole-path text load: binary → EditErrorKind::Binary; invalid UTF-8 → InvalidEncoding
let _text = api::load_text(Path::new("notes.md"))?;

All API types are Send + Sync. Beyond the api module, utility modules are also public: containment (workspace path guarding), exec (shell command execution), files (file-walking, load_text_strict, binary detection), backup (restore_path_from_latest_backup for post-Apply validate/revert), and write (atomic file writes with policy transformations). Library users needing temp dirs (e.g. agents) can use PathGuard::builder(cwd).allow_temp_directory() (handles /tmp on macOS); see the containment and api module rustdocs. Multi-doc bare keys and wrong-root merges peel to EditErrorKind::TypeError via edit_error_kind. Create/rename dest-exists peels to EditErrorKind::AlreadyExists (or api::is_already_exists / api::error_kind_str for CLI-stable "already_exists" strings). Fine-grained kinds also have bool peels (is_not_found, is_conflicts, is_changes_detected, is_type_error, is_format_failed, is_guard_rejected, is_invalid_input, is_no_match, is_ambiguous) matching edit_error_kind.

Replace fail-closed / shell-token options: CLI replace --require-change and --command-position (also plan/MCP fields and ReplaceOptions on the library). Agent hosts: ReplaceOptions::for_agent() on primary and fallback replace paths (auto span refuse); custom options still call api::fuzzy_span_suspicious / FuzzySpanPolicy after fuzzy Apply; buffer multi-op hosts call api::refuse_batch_if_suspicious_fuzzy after apply_content_edits (#2064). Library-only AST mutators: ast_rename / ast_replace_in_symbol / ast_rename_batch (feature ast + files), and FunctionSigEdit::parse_rust. Ordered host onboarding: Embedder host checklist (#2009). Full surface: docs.rs/patchloom.

Getting started

Resource

What you'll learn

Installation

Install options and shell completions

Core concepts

Write modes, transaction plans, exit codes

MCP setup

Configure patchloom as an MCP server for your agent

Editor extension

VS Code, Cursor, Windsurf, and VSCodium integration

Quickstart

5-minute walkthrough

Reference

Every command, operation, and mode

Examples

Transaction plan templates

Commands

Agent-optimized (these are faster or safer than native tools)

Command

What it does

When to use

batch

Line-oriented multi-file edits in 1 call

Editing 3+ files with simple syntax

tx

JSON plan with format/validate lifecycle

Complex multi-file edits with rollback

doc

Parser-backed JSON/YAML/TOML edits

Changing config values without breaking syntax

md

Heading-aware markdown edits

Updating tables, sections, bullets in docs

ast

AST-aware symbol operations (20 languages)

Renaming identifiers, listing symbols, impact analysis

patch

Apply unified diffs with stale detection

Replaying patches safely

tidy

Text-file whitespace and newline normalization

CI checks for text tidiness

mcp-server

MCP protocol server

MCP-capable agents (no shell syntax)

General-purpose (also useful in scripts and CI)

Command

Description

search

Fast literal or regex search across text files (supports --glob/--exclude/--ignore-file for layered custom ignore files, --max-results, -C context, etc.)

replace

Mechanical string replacement across text files with diff preview

apply-fragment

Freeform fragment with required anchors (MorphLLM-style markers stripped; no cloud merge)

append

Append content to an existing file

prepend

Prepend content to an existing file

create

Create a new file with content

delete

Delete a file

rename

Move (rename) a file

read

Read file contents with optional line range

status

Show which files have uncommitted changes

explain

Summarize a tx plan in plain English

undo

Restore files from a backup created by --apply

completions

Generate shell completions (bash, zsh, fish, elvish)

init

Set up patchloom in a project (agent rules, completions, MCP)

schema

Export operation schemas with tier filtering and system prompts

agent-rules

Generate agent instructions for your project

How patchloom compares

Tool

Strength

Where patchloom differs

jq

JSON query/transform

patchloom also handles YAML, TOML, markdown; batches across files; preserves comments

yq

YAML/JSON query/transform

patchloom preserves YAML comments via CST editing; adds markdown, batching, atomic transactions

dasel

Multi-format get/set

patchloom adds batching (N edits in 1 call), atomic rollback, format/validate lifecycle

sd

Regex find/replace

patchloom adds parser-backed structured edits; batching; never produces invalid JSON/YAML

comby

Structural code patterns

patchloom targets config files and agent workflows, not source code pattern matching

The key difference: patchloom is designed for AI agent workflows. One batch or tx call replaces N sequential tool calls, cutting round-trips and eliminating partial-failure states.

vs agent-native editing tools

The table above compares patchloom to human CLI tools. But agents already have built-in editing: Claude Code's edit_file, Cursor's apply, Grok Build's search_replace, Aider's /code blocks. Why add patchloom on top?

Agent-native tools use text matching. They find a block of text and replace it. This works for source code but fails on structured config files:

Agent uses search_replace on YAML

database:
  # Production settings
  host: db.prod.internal
  port: 5432  # PostgreSQL default
  pool_size: 10

The agent replaces port: 5432 with port: 5433. Result depends on implementation. Many agents lose the inline comment, break indentation, or fail to match because of surrounding context changes.

Agent uses patchloom doc set

patchloom doc set config.yaml \
  database.port 5433 --apply

The YAML parser changes the value at the selector path. Comments, indentation, key ordering, and all other formatting are preserved. The output is always valid YAML.

Limitation of agent-native tools

How patchloom addresses it

Comment destruction

CST-level YAML/TOML editing preserves all comments

One file per tool call

batch/tx edit N files in 1 call (6.7x faster in benchmarks)

No rollback

tx with strict: true reverts all files if validation fails

Platform-dependent

Same binary and syntax on Linux, macOS, Windows

Stale context risk

patch apply uses fuzz matching to handle context drift

When to keep using native tools: Single-file reads, simple text search, single-file text replacement where comments don't matter. Patchloom's agent-rules tell agents exactly when to use each approach.

When to use what

Need

Prefer

Prefer something else

JSON/YAML/TOML by path

Patchloom doc

Generic filesystem MCP / blind text replace

Multi-doc YAML stream

Patchloom selectors (0.key)

Bare key on stream root

Structural code pattern search

ast-grep

Text-only grep for shapes

Identifier rename in code

Patchloom ast rename

Fuzzy text replace for symbols

Multi-file atomic apply + undo

Patchloom batch / tx

N sequential shell edits

Freeform snippet with known anchor (after/before/old)

Patchloom apply-fragment (strips Morph-style // ... existing code ... markers)

Whole-file rewrite or guessing placement

Freeform snippet without anchors (cloud model merge)

Morph Fast Apply or similar

Patchloom (anchor-less Morph merge is a non-goal)

Full agent product

Claude Code / Codex / Cursor

Patchloom alone

Longer write-ups: Comparisons · Embedder host checklist · MCP setup

Library hosts: Embedder host checklist: dual-path ReplaceOptions::for_agent() (primary + fallback, includes refuse_suspicious_fuzzy), peels via edit_error_kind / is_* / is_fuzzy_span_suspicious with #[non_exhaustive] _ arm, multi-op ContentEditsResult.op_honesty + refuse_batch_if_suspicious_fuzzy after buffer multi-op (#2064), plan/tx widest matched_text, optional apply_content_edits_to_file_with_span_policy. Custom options still use api::fuzzy_span_suspicious / FuzzySpanPolicy after fuzzy Apply.

Context budget: line-range read, search --count / --files-with-matches, one batch/tx, --jsonl for large streams.

How it works with your AI agent

Two integration modes, same capabilities:

flowchart LR
    subgraph CLI["CLI mode (any agent)"]
        direction TB
        A["patchloom agent-rules >> AGENTS.md"] --> B["Agent reads AGENTS.md"]
        B --> C{"What kind of edit?"}
        C -->|Simple edit| D["Native tool (faster)"]
        C -->|Config edit| E["patchloom doc (safer)"]
        C -->|Markdown edit| F["patchloom md (smarter)"]
        C -->|Multi-file edit| G["patchloom batch (batched)"]
    end

    subgraph MCP["MCP mode (MCP-capable agents)"]
        direction TB
        H["patchloom mcp-server"] --> I["Agent discovers tools via MCP"]
        I --> J["Structured JSON tool calls"]
        J --> K["No shell syntax needed"]
    end

Status

4000+ tests across 24 commands. Tested with Grok 4.3, GPT-5.4, and Claude Opus 4.6.

Component

Status

CLI

Published on crates.io, Homebrew, Scoop, Chocolatey (choco install patchloom), and npm (npx patchloom). winget (winget install Patchloom.Patchloom; community index may lag the latest GitHub Release).

MCP server

Official MCP Registry name io.github.patchloom/patchloom (stdio; crates.io / npm packages; see server.json). Local MCPB for Smithery / desktop hosts: make pack-mcpb (mcpb/). Glama directory prep: root glama.json + manual Add MCP Server (see MCP setup)

Editor extension

Published on VS Code Marketplace and Open VSX

Full command reference

Every command, flag, transaction operation, and exit code is documented in the Command Reference (also available at docs/reference/README.md).

License

Licensed under either of:

at your option.

Contributing

See CONTRIBUTING.md.

For local verification before opening a pull request, run make check. It matches the main Linux CI gate: formatting, clippy, unit tests (including feature-matrix jobs), integration tests, PTY tests, release-notes structure, test hygiene, and generated-doc freshness (check-patchloom-md, check-readme). While iterating locally, make check-fast is the same except it skips only check-patchloom-md (it still runs check-readme so a drifted test-count badge fails before CI).

All commits must be signed off with git commit -s.

Agent integration tests

make agent-test runs 19 pytest scenarios that verify AI agents correctly use patchloom when given instructions. make bench-agent runs 3-way benchmarks (CLI vs MCP vs native) across 11 tasks. Use MODEL=X to switch models and RUNS=N for variance reduction. Requires an LLM API key. Not part of make check. See tests/agent/README.md for details.

Security

For current security reporting guidance, see SECURITY.md.

A
license - permissive license
-
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
1dRelease cycle
34Releases (12mo)
Commit activity
Issues opened vs closed

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Advanced code search and transformation MCP server for AI assistants. Combines ugrep's speed with intelligent replace capabilities, dry-run previews, and language-aware refactoring across 11 tools.
    Last updated
    1
    9
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A robust, language-agnostic Model Context Protocol (MCP) server that provides AI coding agents with the ability to edit files surgically via Abstract Syntax Trees (AST) instead of relying on token-heavy, brittle search-and-replace or diff operations.
    Last updated
    28
    7
    MIT

View all related MCP servers

Related MCP Connectors

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/patchloom/patchloom'

If you have feedback or need assistance with the MCP directory API, please join our Discord server