Skip to main content
Glama
hashline-mcp

hashline-mcp

by ck0i

hashline-mcp

an MCP server for precise, hash-referenced file editing. instead of reproducing exact content or relying on fragile line numbers, models reference lines by short content hashes — making edits atomic, verifiable, and resistant to state drift.

the problem

current LLM edit tools are broken in predictable ways:

  • patch format fails catastrophically on most models (50%+ failure rates outside fine-tuned environments)

  • string replacement requires perfect reproduction of content including whitespace — the "string not found" error is practically a meme at this point

  • full file rewrites work but waste tokens and fall apart on large files

all of these approaches force models to recall exact file content they've already seen, which is fundamentally the wrong abstraction.

Related MCP server: Obsidian Native MCP

the idea

tag each line with a short content hash. models reference lines by line:hash instead of reproducing content:

12:a3|function hello() {
13:f1|  return "world";
14:0e|}

to edit line 13, a model just says "replace 13:f1 with return "hello";" — no need to perfectly recall the original string, no whitespace sensitivity, no ambiguity about which occurrence to match.

if the file changed since the model last read it, the hash won't match and the edit fails cleanly. re-read, retry. simple.

tools

hashline_read

reads a file and returns every line tagged as lineNumber:hash|content, where the hash is the first 2 hex characters of SHA-256 of the line content.

{
  "path": "src/index.ts",
  "range": { "start": 1, "end": 50 }
}

hashline_edit

applies one or more operations using line:hash references. all hashes are validated upfront — if any mismatch, the entire edit is rejected (atomic all-or-nothing). operations are applied bottom-to-top to preserve line numbers.

supported operations:

operation

description

replace

replace a single line or range with new content

insert_after

insert content after a referenced line

insert_before

insert content before a referenced line

delete

delete a single line or range

{
  "path": "src/index.ts",
  "operations": [
    { "type": "replace", "target": "12:a3", "content": "function greet() {" },
    { "type": "delete", "target": "20:b7", "end_target": "25:c1" },
    { "type": "insert_after", "target": "30:d4", "content": "// new section\nconst x = 1;" }
  ]
}

after a successful edit, the response includes a context window (±5 lines around each edit) with updated hashes so the model can continue editing without a full re-read.

setup

requires node 18+.

npm install
npm run build

claude code integration

add to your MCP config (~/.claude/settings.json or project-level):

{
  "mcpServers": {
    "hashline": {
      "command": "node",
      "args": ["path/to/hashline-mcp/dist/index.js"]
    }
  }
}

development

npm run dev   # runs with tsx, no build step needed

design decisions

  • 2-char hashes: short enough to not bloat context, long enough to catch stale state. collisions are theoretically possible but practically irrelevant — the goal is detecting file changes, not cryptographic uniqueness

  • bottom-to-top application: when multiple operations target different lines, applying from the bottom up means earlier operations don't shift line numbers for later ones

  • overlap rejection: overlapping ranges in a single edit call are rejected — forces explicit separation and prevents ambiguous intent

  • all-or-nothing validation: one bad hash fails the entire edit. no partial mutations, no corrupted state

tech stack

  • TypeScript + Node.js

  • @modelcontextprotocol/sdk for MCP server/transport

  • zod for schema validation

  • stdio transport (works with any MCP client)

inspiration

the hashline concept was inspired by Can Bölük's article The Harness Problem, which argues that the tooling mediating between LLMs and code changes — not the models themselves — is the real bottleneck in AI-assisted development. the article demonstrates that line-hash referencing dramatically improves edit success rates across models while reducing token usage.

license

MIT

Available Tools

2 tools
hashline_editA

Edit a file using hashline references from hashline_read. Reference lines by "line:hash" (e.g. "12:a3") — if the hash doesn't match the current file, the edit is rejected (re-read and retry). Supports: replace (single line or range), insert_after, insert_before, delete (single line or range). Multiple operations are applied bottom-to-top to preserve line numbers. Returns a context window around edited lines with updated hashes.

Inputs: path (required), operations (required).

hashline_readA

Read a file with hashline-tagged lines. Each line is returned as "lineNumber:hash|content" where hash is a short content fingerprint. Use these line:hash references in hashline_edit to make precise edits without reproducing existing content. Always read (or re-read) a file before editing to get current hashes.

Inputs: path (required), range.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.6/5.0

    Scored across 2 tools

    Disambiguation5/5

    hashline_read only inspects and returns content with hashes, while hashline_edit exclusively mutates files via line:hash references. Their responsibilities are complementary, so there is no realistic ambiguity about which tool to choose.

    Naming Consistency5/5

    Both tools use the exact hashline_<verb> pattern, with a stable domain prefix and an action verb. This makes the API naming predictable and easy to extend.

    Tool Count4/5

    Two tools is on the low end, but it fits the server's narrow read-then-edit workflow without padding. The count is slightly minimal but reasonable for the stated purpose.

    Completeness5/5

    The read/edit pair covers the entire intended workflow: obtain hashes, make verified edits, and receive updated context. No obvious missing operation exists within the documented hashline scope.

    Maintenance

    ActivityInactive
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers