edit_file_linesLABSCO SUMMARY
The dry run is not optional theatre — the state ID is what makes it a real gate.
Because applying an edit needs the exact state ID and an exact match of path and edits, an assistant cannot quietly widen a change between the preview you read and the write that lands. The expiry is short by default, which is a security property rather than an annoyance: if you walked away, the approval is gone and the edit has to be re-proposed.
What it is
A TypeScript MCP server for making exact, line-based edits to text files. An edit names a line range and either a literal string or a regex to match within it, so replacements preserve the surrounding formatting and indentation rather than rewriting whole lines. Every edit can run as a dry run that returns a unified diff and a state ID; nothing touches the file until that state ID is approved.
What you get
- Line-based edits by literal match or regex, across single or multiple lines, several edits at once, previewable before they apply —
edit_file_lines - A two-step commit: the dry run returns a diff plus a state ID, and applying requires that ID and an exact match of file path and edits —
approve_edit - Specific lines read back with surrounding context, to verify content before and after an edit —
get_file_lines - Search that hands you the line numbers to edit: text or regex, case sensitivity, whole-word matching, configurable context, with defaults of 2 context lines, 100 maximum matches and a 10-line context cap —
search_file - Whitespace handled deliberately: literal matches are whitespace-normalised, original indentation is preserved in replacements, and
strMatchandregexMatchcannot be combined in one edit - Guardrails that fail loudly: overlapping regex patterns are rejected, and so is a line affected by multiple edits
Requirements
No account and no key. Build from a clone with npm install and npm run build. The server must be started with one or more allowed directories — node build/index.js <allowed-directory> [additional-directories...] — and every file operation is restricted to them, with symlink escapes and parent-directory traversal rejected. MCP_EDIT_STATE_TTL sets how long an edit state stays approvable, in milliseconds, defaulting to 60000; an expired or unknown state ID returns an error rather than applying anything. The package is edit-file-lines 0.1.0.
Setup effort
Build from source
USE CASES
Changing one value without rewriting the file
Search for the line, run the edit as a dry run against that line number, read the diff, then approve it with the returned state ID.
Letting an assistant edit code you have to sign off on
Every write arrives as a diff plus a state ID first, so nothing lands until you have read what it would do.
Restructuring a block that spans several lines
Match it with a regex across the line range and replace it as one operation, keeping the surrounding indentation intact.
Keeping an agent inside one project
Start the server with only that project's directory allowed; traversal and symlink escapes out of it are rejected rather than silently followed.
4 tools
Listed in project docs. Your client may show a different list.
approve_editget_file_linessearch_fileBEFORE YOU INSTALL
What to know first
Tools you get
4 tools named in the project's documentation.
Where it runs
The documented client runs the server on your machine.
INSTALLATION
Connect your client
You clone and build this one yourself.
Server setup
git clone https://github.com/oakenai/mcp-edit-file-lines
cd mcp-edit-file-lines
npm install
npm run build
node build/index.js <YOUR_ALLOWED_DIRECTORY> [<YOUR_ADDITIONAL_DIRECTORIES>]MCP Clients
Claude Desktop
{
"mcpServers": {
"edit-file-lines": {
"command": "node",
"args": [
"<YOUR_PATH_TO_EDIT_FILE_LINES>/build/index.js",
"<YOUR_ALLOWED_DIRECTORY>"
],
"env": {
"MCP_EDIT_STATE_TTL": "300000"
}
}
}
}