MCP Setup Guide

Patchloom includes an MCP (Model Context Protocol) server for structured tool calls. MCP-capable AI agents can call Patchloom tools directly with JSON parameters, with no shell command construction, no quoting issues, and no --apply flag needed.

Verify MCP support

The MCP server is included by default in all pre-built binaries, Homebrew, and crates.io installs. Verify it works:

patchloom mcp-server --help

Configure your agent

Grok (config.toml)

Add to ~/.grok/config.toml:

[mcp_servers.patchloom]
command = "/path/to/patchloom"
args = ["mcp-server"]
# Add "--allow-shell" to args to enable format/validate lifecycle steps:
# args = ["mcp-server", "--allow-shell"]

Claude Desktop (JSON)

Add to ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "patchloom": {
      "command": "/path/to/patchloom",
      "args": ["mcp-server"]
    }
  }
}

VS Code (.vscode/mcp.json)

Create .vscode/mcp.json in your workspace root:

{
  "servers": {
    "patchloom": {
      "command": "/path/to/patchloom",
      "args": ["mcp-server"]
    }
  }
}

Cursor (.cursor/mcp.json)

Create .cursor/mcp.json in your workspace root:

{
  "servers": {
    "patchloom": {
      "command": "/path/to/patchloom",
      "args": ["mcp-server"]
    }
  }
}

Or use the Patchloom VS Code extension to configure MCP automatically via the Patchloom: Configure MCP command.

Generic stdio MCP

Any MCP client that supports stdio transport can connect by spawning patchloom mcp-server as a subprocess. The server communicates via JSON-RPC over stdin/stdout.

Available tools

ToolDescription
doc_setSet a value by selector in a JSON, YAML, or TOML file
doc_deleteDelete a value by selector from a structured file
doc_mergeDeep-merge an object into a document
doc_appendAppend a value to an array
doc_prependPrepend a value to an array
doc_ensureSet a value only if the selector path does not exist
doc_delete_whereDelete array elements matching a predicate
doc_updateUpdate array elements matching a predicate
doc_moveMove a value from one selector path to another
doc_getRead a value by selector (read-only)
doc_queryQuery a structured file: has, keys, len, select, or flatten (read-only)
doc_diffCompare two structured files (read-only)
search_filesSearch text files for a pattern, including literal, case-insensitive, count, file-only, multiline, invert-match, and assert-count modes. Binary and invalid UTF-8 files are skipped (read-only)
git_statusShow uncommitted file changes vs git HEAD (read-only)
read_fileRead file contents with optional line range
replace_textReplace text in a text file (literal or regex). Binary and invalid UTF-8 files are skipped
md_upsert_bulletAdd a bullet under a markdown heading
md_table_appendAppend a row to a markdown table
md_replace_sectionReplace a markdown section by heading
md_insert_after_headingInsert content after a markdown heading
md_insert_before_headingInsert content before a markdown heading
md_lintLint an AGENTS.md file for common issues
fix_whitespaceFix whitespace and line endings in a text file. Binary and invalid UTF-8 files are skipped
create_fileCreate a new file with content
delete_fileDelete a file
move_fileMove or rename a file (binary-safe)
apply_patchApply a unified diff
batch_replaceReplace the same text across multiple files atomically
batch_tidyFix whitespace in multiple files atomically

How MCP mode differs from CLI mode

AspectCLI modeMCP mode
Apply behaviorRequires --apply flagAuto-applies (writes are the default)
Input formatShell argumentsStructured JSON parameters
Path securityNo restrictionPaths must stay within working directory
Error formatstderr textMCP error response with structured content
DiscoveryAgent reads AGENTS.mdAgent discovers tools via MCP protocol

Debugging and logging

The MCP server can log every tool call to a JSONL file for debugging and performance analysis. Each line records the tool name, duration, and success/failure status.

Enable logging with the --log flag:

patchloom mcp-server --log /tmp/patchloom-mcp.log

Or set the PATCHLOOM_MCP_LOG environment variable (the --log flag takes precedence):

export PATCHLOOM_MCP_LOG=/tmp/patchloom-mcp.log
patchloom mcp-server

Each line is a JSON object:

{"ts":1749123456789,"tool":"replace_text","duration_ms":3,"ok":true}
{"ts":1749123456800,"tool":"doc_set","duration_ms":5,"ok":false,"error":"file not found"}
FieldTypeDescription
tsnumberUnix timestamp in milliseconds
toolstringTool name that was called
duration_msnumberExecution time in milliseconds
okbooleanWhether the call succeeded
errorstringError message (only present on failure)

Configuring logging in your MCP client

Grok (config.toml) -- pass the env var to the MCP server subprocess:

[mcp_servers.patchloom]
command = "/path/to/patchloom"
args = ["mcp-server"]
env = { PATCHLOOM_MCP_LOG = "/tmp/patchloom-mcp.log" }

Or use --log in the args:

[mcp_servers.patchloom]
command = "/path/to/patchloom"
args = ["mcp-server", "--log", "/tmp/patchloom-mcp.log"]

Claude Desktop / VS Code / Cursor (JSON) -- use --log in the args:

{
  "mcpServers": {
    "patchloom": {
      "command": "/path/to/patchloom",
      "args": ["mcp-server", "--log", "/tmp/patchloom-mcp.log"]
    }
  }
}

Or pass the env var (Claude Desktop supports env in server config):

{
  "mcpServers": {
    "patchloom": {
      "command": "/path/to/patchloom",
      "args": ["mcp-server"],
      "env": { "PATCHLOOM_MCP_LOG": "/tmp/patchloom-mcp.log" }
    }
  }
}

Security model

The MCP server enforces path containment: all file paths must resolve within the working directory where patchloom mcp-server was started. Absolute paths, ../ traversal, and symlinks escaping the working directory are rejected. This prevents an agent from accidentally (or maliciously) editing files outside the project.

Each individual tool validates every path before execution.

Example tool call

An MCP-capable agent sends:

{
  "method": "tools/call",
  "params": {
    "name": "doc_set",
    "arguments": {
      "path": "config.yaml",
      "selector": "database.port",
      "value": 5432
    }
  }
}

Patchloom parses the YAML, changes database.port to 5432, preserves all comments and formatting, and writes the file. The agent receives a success response with no further action needed.