T

mcp-edit-file-lines

Created Oct 19, 2025 by oakenai

Language:

TypeScript

Stars:

19

Forks:

2

README

Edit File Lines MCP Server

A TypeScript-based MCP server that provides tools for making precise line-based edits to text files within allowed directories.

Features

Main Editing Tool

edit_file_lines

Make line-based edits to a file using string or regex pattern matching. Each edit can:

  • Replace entire lines
  • Replace specific text matches while preserving line formatting
  • Use regex patterns for complex matches
  • Handle multiple lines and multiple edits
  • Preview changes with dry run mode

Example file (src/components/App.tsx):

// Basic component with props
const Button = ({ color = "blue", size = "md" }) => {
  return Click me;
};

// Component with multiple props and nested structure
export const Card = ({
  title,
  subtitle = "Default subtitle",
  theme = "light",
  size = "lg",
}) => {
  const cardClass = `card-${theme} size-${size}`;

  return (

      {title}
      {subtitle}

  );
};

// Constants and configurations
const THEME = {
  light: { bg: "#ffffff", text: "#000000" },
  dark: { bg: "#000000", text: "#ffffff" },
};

const CONFIG = {
  apiUrl: "https://api.example.com",
  timeout: 5000,
  retries: 3,
};

Example Use Cases

  1. Simple String Replacement
    {
    "p": "src/components/App.tsx",
    "e": [{
     "startLine": 2,
     "endLine": 2,
     "content": "primary",
     "strMatch": "blue"
    }],
    "dryRun": true
    }

Output:

Index: src/components/App.tsx
===================================================================
--- src/components/App.tsx        original
+++ src/components/App.tsx        modified
@@ -1,6 +1,6 @@
 // Basic component with props
-const Button = ({ color = "blue", size = "md" }) => {
+const Button = ({ color = "primary", size = "md" }) => {
   return Click me;
 };

 // Component with multiple props and nested structure

State ID: fcbf740a Use this ID with approve_edit to apply the changes.

  1. Multi-line Content with Preserved Structure
    {
    "p": "src/components/App.tsx",
    "e": [{
     "startLine": 16,
     "endLine": 19,
     "content": "    \n      {title}\n      {subtitle}\n    ",
     "regexMatch": "]*>[\\s\\S]*?"
    }],
    "dryRun": true
    }

Output:

Index: src/components/App.tsx
===================================================================
--- src/components/App.tsx        original
+++ src/components/App.tsx        modified
@@ -13,10 +13,10 @@
   const cardClass = `card-${theme} size-${size}`;

   return (

-      {title}
-      {subtitle}
+      {title}
+      {subtitle}

   );
 };

State ID: f2ce973f Use this ID with approve_edit to apply the changes.

  1. Complex JSX Structure Modification
    {
    "p": "src/components/App.tsx",
    "e": [{
     "startLine": 7,
     "endLine": 12,
     "content": "export const Card = ({\n  title,\n  subtitle = \"New default\",\n  theme = \"modern\",\n  size = \"responsive\"\n}) => {",
     "regexMatch": "export const Card[\\s\\S]*?\\) => \\{"
    }],
    "dryRun": true
    }

Output:

Index: src/components/App.tsx
===================================================================
--- src/components/App.tsx        original
+++ src/components/App.tsx        modified
@@ -5,11 +5,11 @@
 // Component with multiple props and nested structure
 export const Card = ({
   title,
-  subtitle = "Default subtitle",
-  theme = "light",
-  size = "lg",
+  subtitle = "New default",
+  theme = "modern",
+  size = "responsive"
 }) => {
   const cardClass = `card-${theme} size-${size}`;

   return (

State ID: f1f1d27b Use this ID with approve_edit to apply the changes.

  1. Configuration Update with Whitespace Preservation
    {
    "p": "src/components/App.tsx",
    "e": [{
     "startLine": 29,
     "endLine": 32,
     "content": "const CONFIG = {\n  baseUrl: \"https://api.newexample.com\",\n  timeout: 10000,\n  maxRetries: 5",
     "regexMatch": "const CONFIG[\\s\\S]*?retries: \\d+"
    }],
    "dryRun": true
    }

Output:

Index: src/components/App.tsx
===================================================================
--- src/components/App.tsx        original
+++ src/components/App.tsx        modified
@@ -26,8 +26,8 @@
   dark: { bg: "#000000", text: "#ffffff" },
 };

 const CONFIG = {
-  apiUrl: "https://api.example.com",
-  timeout: 5000,
-  retries: 3,
+  baseUrl: "https://api.newexample.com",
+  timeout: 10000,
+  maxRetries: 5
 };

State ID: 20e93c34 Use this ID with approve_edit to apply the changes.

  1. Flexible Whitespace Matching
    {
    "p": "src/components/App.tsx",
    "e": [{
     "startLine": 9,
     "endLine": 9,
     "content": "description",
     "strMatch": "subtitle   =   \"Default subtitle\""  // Extra spaces are handled
    }],
    "dryRun": true
    }

Output:

Index: src/components/App.tsx
===================================================================
--- src/components/App.tsx        original
+++ src/components/App.tsx        modified
@@ -5,9 +5,9 @@
 // Component with multiple props and nested structure
 export const Card = ({
   title,
-  subtitle = "Default subtitle",
+  description
   theme = "light",
   size = "lg",
 }) => {
   const cardClass = `card-${theme} size-${size}`;

Additional Tools

approve_edit

Apply changes from a previous dry run of edit_file_lines. This tool provides a two-step editing process for safety. Here is an example workflow:

  1. First, make a dry run edit:
    {
    "p": "src/components/App.tsx",
    "e": [{
     "startLine": 2,
     "endLine": 2,
     "content": "primary",
     "strMatch": "blue"
    }],
    "dryRun": true
    }

Output:

Index: src/components/App.tsx
===================================================================
--- src/components/App.tsx        original
+++ src/components/App.tsx        modified
@@ -1,6 +1,6 @@
 // Basic component with props
-const Button = ({ color = "blue", size = "md" }) => {
+const Button = ({ color = "primary", size = "md" }) => {
   return Click me;
 };

State ID: fcbf740a Use this ID with approve_edit to apply the changes.

  1. Then, approve the changes using the state ID:
    {
    "stateId": "fcbf740a"
    }

Output:

Index: src/components/App.tsx
===================================================================
--- src/components/App.tsx        original
+++ src/components/App.tsx        modified
@@ -1,6 +1,6 @@
 // Basic component with props
-const Button = ({ color = "blue", size = "md" }) => {
+const Button = ({ color = "primary", size = "md" }) => {
   return Click me;
 };
  1. Verify the changes:
    {
    "path": "src/components/App.tsx",
    "lineNumbers": [2],
    "context": 1
    }

Output:

Line 2:
  1: // Basic component with props
> 2: const Button = ({ color = "primary", size = "md" }) => {
  3:   return Click me;

Note that state IDs expire after a short time for security. Attempting to use an expired or invalid state ID will result in an error:

{
  "stateId": "invalid123"
}

Output:

Error: Invalid or expired state ID

get_file_lines

Inspect specific lines in a file with optional context lines. This tool is useful for verifying line content before making edits.

{
  "path": "src/components/App.tsx",
  "lineNumbers": [1, 2, 3],
  "context": 1
}

Output:

Line 1:
> 1: // Basic component with props
  2: const Button = ({ color = "blue", size = "md" }) => {

Line 2:
  1: // Basic component with props
> 2: const Button = ({ color = "blue", size = "md" }) => {
  3:   return Click me;

Line 3:
  2: const Button = ({ color = "blue", size = "md" }) => {
> 3:   return Click me;
  4: };

search_file

Search a file for text patterns or regular expressions to find specific line numbers and their surrounding context. This tool is particularly useful for locating the exact lines you want to edit with edit_file_lines.

Features:

  • Simple text search with optional case sensitivity
  • Regular expression support
  • Whole word matching
  • Configurable context lines
  • Returns line numbers, content, and surrounding context with line numbers

Arguments:

{
  path: string;          // Path to the file to search
  pattern: string;       // Search pattern (text or regex)
  type?: "text" | "regex"; // Type of search (default: "text")
  caseSensitive?: boolean; // Case-sensitive search (default: false)
  contextLines?: number;   // Number of context lines (default: 2, max: 10)
  maxMatches?: number;     // Maximum matches to return (default: 100)
  wholeWord?: boolean;     // Match whole words only (default: false)
  multiline?: boolean;     // Enable multiline regex mode (default: false)
}

Example use cases:

  1. Simple text search:
    {
    "path": "src/components/App.tsx",
    "pattern": "const",
    "contextLines": 2
    }

Output:

Found 6 matches in 0.9ms:
File size: 0.7KB

Match 1: Line 2, Column 1
----------------------------------------
     1 | // Basic component with props
>    2 | const Button = ({ color = "blue", size = "md" }) => {
     3 |   return Click me;
     4 | };

Match 2: Line 7, Column 8
----------------------------------------
     5 | 
     6 | // Component with multiple props and nested structure
>    7 | export const Card = ({
     8 |   title,
     9 |   subtitle = "Default subtitle",

Match 3: Line 13, Column 3
----------------------------------------
    11 |   size = "lg",
    12 | }) => {
>   13 |   const cardClass = `card-${theme} size-${size}`;
    14 |   
    15 |   return (

Match 4: Line 23, Column 4
----------------------------------------
    21 | };
    22 | 
>   23 | // Constants and configurations
    24 | const THEME = {
    25 |   light: { bg: "#ffffff", text: "#000000" },

Match 5: Line 24, Column 1
----------------------------------------
    22 | 
    23 | // Constants and configurations
>   24 | const THEME = {
    25 |   light: { bg: "#ffffff", text: "#000000" },
    26 |   dark: { bg: "#000000", text: "#ffffff" },

Match 6: Line 29, Column 1
----------------------------------------
    27 | };
    28 | 
>   29 | const CONFIG = {
    30 |   apiUrl: "https://api.example.com",
    31 |   timeout: 5000,
  1. Case-sensitive whole word search:
    {
    "path": "src/components/App.tsx",
    "pattern": "props",
    "caseSensitive": true,
    "wholeWord": true,
    "contextLines": 1
    }

Output:

Found 2 matches in 0.7ms:
File size: 0.7KB

Match 1: Line 1, Column 25
----------------------------------------
>    1 | // Basic component with props
     2 | const Button = ({ color = "blue", size = "md" }) => {

Match 2: Line 6, Column 28
----------------------------------------
     5 | 
>    6 | // Component with multiple props and nested structure
     7 | export const Card = ({
  1. Finding JSX components:
    
    {
    "path": "src/components/App.tsx",
    "pattern": "
Last updated: Oct 19, 2025

Publisher info

oakenai's avatar

oakenai

1
followers
0
following
8
repos

More MCP servers built with TypeScript

Vue.js

This is the repo for Vue 2. For Vue 3, go to https://github.com/vuejs/core

By vuejs 209.9K
Excalidraw

Virtual whiteboard for sketching hand-drawn like diagrams

By excalidraw 114.9K
Angular

Deliver web apps with confidence 🚀

By angular 99.7K