Problem
The current dry-run workflow doubles token usage:
patch_file(dry_run=true, search_content=<big>, replace_content=<big>) → diff preview
# model inspects diff, looks good…
patch_file(dry_run=false, search_content=<big>, replace_content=<big>) → apply
# identical payload sent twice ≈ 2× tokens
Proposed Solution — Option C: run_id flow
When dry_run=true, the server caches the computed patched_content in-memory (keyed by a short random run_id) and returns that run_id alongside the diff preview.
A new tool apply_last_dry_run commits the cached result using only the run_id — no payload repetition.
patch_file(dry_run=true, ...) → { diff: "...", run_id: "a1b2c3", expires_in: 300 }
apply_last_dry_run(run_id: "a1b2c3") → { applied: true }
Implementation Scope
New module: src/patchitright_mcp/run_cache.py
- Thread-safe in-memory dict
{ run_id: RunEntry }
- Each
RunEntry stores: target_path, patched_content, original_hash, created_at
- TTL: 300 seconds (hard default, no persistence across restarts)
RunCache.store(target_path, patched_content, original_content) → run_id
RunCache.consume(run_id) → RunEntry | None (pops entry — single-use)
Changes: patch_file() in patch_file.py
- On
dry_run=True: after computing patched_content, store in RunCache and include run_id + expires_in in the response dict.
Changes: batch_patch_files() in patch_file.py
- Same: on
dry_run=True, cache each file's patched result under a single shared run_id, return it.
New tool: apply_last_dry_run in server.py
- Input:
run_id: str
- Looks up entry in
RunCache.consume(run_id)
- Guards: original file hash must match (file unchanged since dry-run)
- Writes patched content to disk
- Returns standard success dict
Schema update: instructions.md + MCP schema JSON
- Document
run_id field in patch_file / batch_patch_files responses
- Document
apply_last_dry_run tool
Acceptance Criteria
Token Savings
For a typical patch call with a 200-token search_content + replace_content, this eliminates the second full payload entirely. For batch_patch_files with N files, savings scale linearly.
Problem
The current dry-run workflow doubles token usage:
Proposed Solution — Option C:
run_idflowWhen
dry_run=true, the server caches the computedpatched_contentin-memory (keyed by a short randomrun_id) and returns thatrun_idalongside the diff preview.A new tool
apply_last_dry_runcommits the cached result using only therun_id— no payload repetition.Implementation Scope
New module:
src/patchitright_mcp/run_cache.py{ run_id: RunEntry }RunEntrystores:target_path,patched_content,original_hash,created_atRunCache.store(target_path, patched_content, original_content) → run_idRunCache.consume(run_id) → RunEntry | None(pops entry — single-use)Changes:
patch_file()inpatch_file.pydry_run=True: after computingpatched_content, store inRunCacheand includerun_id+expires_inin the response dict.Changes:
batch_patch_files()inpatch_file.pydry_run=True, cache each file's patched result under a single sharedrun_id, return it.New tool:
apply_last_dry_runinserver.pyrun_id: strRunCache.consume(run_id)Schema update:
instructions.md+ MCP schema JSONrun_idfield inpatch_file/batch_patch_filesresponsesapply_last_dry_runtoolAcceptance Criteria
patch_file(dry_run=True)returnsrun_idandexpires_inin its responsebatch_patch_files(dry_run=True)returns a singlerun_idcovering all filesapply_last_dry_run(run_id=...)applies the cached patch and returns successapply_last_dry_runfails with a clear error ifrun_idis unknown or expiredapply_last_dry_runfails with a clear error if the file was modified after the dry-runpatch_file/batch_patch_filesbehavior unchanged whendry_run=FalseToken Savings
For a typical patch call with a 200-token
search_content+replace_content, this eliminates the second full payload entirely. Forbatch_patch_fileswith N files, savings scale linearly.