Edit File Lines MCP Server

local-only server

The server can only run on the client’s local machine because it depends on local resources.

Integrations

  • Offers tools specifically designed for editing TypeScript files with specialized pattern matching and regex support for handling TypeScript syntax, components, and configurations.

Editar líneas de archivo del servidor MCP

Un servidor MCP basado en TypeScript que proporciona herramientas para realizar ediciones precisas en líneas de archivos de texto dentro de directorios permitidos.

Características

Herramienta de edición principal

edit_file_lines

Realice ediciones lineales en un archivo mediante la coincidencia de patrones de cadenas o expresiones regulares. Cada edición puede:

  • Reemplazar líneas enteras
  • Reemplazar coincidencias de texto específicas conservando el formato de línea
  • Utilice patrones de expresiones regulares para coincidencias complejas
  • Manejar múltiples líneas y múltiples ediciones
  • Vista previa de los cambios con el modo de ejecución en seco

Archivo de ejemplo ( src/components/App.tsx ):

// Basic component with props const Button = ({ color = "blue", size = "md" }) => { return <button className={`btn-${color} size-${size}`}>Click me</button>; }; // 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 ( <div className={cardClass}> <h2>{title}</h2> <p>{subtitle}</p> </div> ); }; // 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, };

Ejemplos de casos de uso

  1. Reemplazo de cuerda simple
{ "p": "src/components/App.tsx", "e": [{ "startLine": 2, "endLine": 2, "content": "primary", "strMatch": "blue" }], "dryRun": true }

Producción:

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

ID de estado: fcbf740a Utilice este ID con approved_edit para aplicar los cambios.

  1. Contenido de varias líneas con estructura preservada
{ "p": "src/components/App.tsx", "e": [{ "startLine": 16, "endLine": 19, "content": " <div className={cardClass}>\n <h2 className=\"title\">{title}</h2>\n <p className=\"subtitle\">{subtitle}</p>\n </div>", "regexMatch": "<div[^>]*>[\\s\\S]*?</div>" }], "dryRun": true }

Producción:

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 ( <div className={cardClass}> - <h2>{title}</h2> - <p>{subtitle}</p> + <h2 className="title">{title}</h2> + <p className="subtitle">{subtitle}</p> </div> ); };

ID de estado: f2ce973f Utilice este ID con approved_edit para aplicar los cambios.

  1. Modificación compleja de la estructura JSX
{ "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 }

Producción:

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 (

ID de estado: f1f1d27b Utilice este ID con approved_edit para aplicar los cambios.

  1. Actualización de la configuración con conservación de espacios en blanco
{ "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 }

Producción:

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 };

ID de estado: 20e93c34 Utilice este ID con approved_edit para aplicar los cambios.

  1. Coincidencia flexible de espacios en blanco
{ "p": "src/components/App.tsx", "e": [{ "startLine": 9, "endLine": 9, "content": "description", "strMatch": "subtitle = \"Default subtitle\"" // Extra spaces are handled }], "dryRun": true }

Producción:

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}`;

Herramientas adicionales

approve_edit

Aplique los cambios de un simulacro previo de edit_file_lines . Esta herramienta ofrece un proceso de edición de dos pasos para mayor seguridad. A continuación, se muestra un ejemplo de flujo de trabajo:

  1. Primero, haz una edición en seco:
{ "p": "src/components/App.tsx", "e": [{ "startLine": 2, "endLine": 2, "content": "primary", "strMatch": "blue" }], "dryRun": true }

Producción:

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 <button className={`btn-${color} size-${size}`}>Click me</button>; };

ID de estado: fcbf740a Utilice este ID con approved_edit para aplicar los cambios.

  1. Luego, aprueba los cambios utilizando el ID del estado:
{ "stateId": "fcbf740a" }

Producción:

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 <button className={`btn-${color} size-${size}`}>Click me</button>; };
  1. Verificar los cambios:
{ "path": "src/components/App.tsx", "lineNumbers": [2], "context": 1 }

Producción:

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

Tenga en cuenta que, por razones de seguridad, las identificaciones estatales caducan poco después. Intentar usar una identificación estatal caducada o no válida generará un error:

{ "stateId": "invalid123" }

Producción:

Error: Invalid or expired state ID

get_file_lines

Inspeccione líneas específicas de un archivo con líneas de contexto opcionales. Esta herramienta es útil para verificar el contenido de las líneas antes de realizar modificaciones.

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

Producción:

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

Busque patrones de texto o expresiones regulares en un archivo para encontrar números de línea específicos y su contexto. Esta herramienta es especialmente útil para localizar las líneas exactas que desea editar con edit_file_lines .

Características:

  • Búsqueda de texto simple con distinción entre mayúsculas y minúsculas opcional
  • Compatibilidad con expresiones regulares
  • Coincidencia de palabras completas
  • Líneas de contexto configurables
  • Devuelve números de línea, contenido y contexto circundante con números de línea

Argumentos:

{ 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) }

Ejemplos de casos de uso:

  1. Búsqueda de texto simple:
{ "path": "src/components/App.tsx", "pattern": "const", "contextLines": 2 }

Producción:

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 <button className={`btn-${color} size-${size}`}>Click me</button>; 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. Búsqueda de palabras completas que distingue entre mayúsculas y minúsculas:
{ "path": "src/components/App.tsx", "pattern": "props", "caseSensitive": true, "wholeWord": true, "contextLines": 1 }

Producción:

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. Encontrar componentes JSX:
{ "path": "src/components/App.tsx", "pattern": "<[A-Z]\\w+\\s", "type": "regex", "contextLines": 1 }

Producción:

Found 2 matches in 0.6ms: File size: 0.7KB Match 1: Line 3, Column 10 ---------------------------------------- 2 | const Button = ({ color = "blue", size = "md" }) => { > 3 | return <button className={`btn-${color} size-${size}`}>Click me</button>; 4 | }; Match 2: Line 16, Column 5 ---------------------------------------- 15 | return ( > 16 | <div className={cardClass}> 17 | <h2>{title}</h2>

Flujos de trabajo comunes:

  1. Buscar y luego editar:
// First, search for the line { "path": "src/config.ts", "pattern": "API_URL", "wholeWord": true } // Then use the returned line number in edit_file_lines { "p": "src/config.ts", "e": [{ "startLine": 23, // Line number from search result "endLine": 23, "content": "export const API_URL = 'https://new-api.example.com';" }] }
  1. Encuentra todos los usos:
{ "path": "src/components/App.tsx", "pattern": "\\buseMemo\\b", "type": "regex", "contextLines": 2, "maxMatches": 50 }
  1. Encuentre patrones de accesorios específicos:
{ "path": "src/components/App.tsx", "pattern": "className=['\"]([^'\"]+)['\"]", "type": "regex", "contextLines": 1 }

Notas importantes

  1. Manejo de espacios en blanco
    • La herramienta maneja de forma inteligente los espacios en blanco tanto en coincidencias de cadenas como de expresiones regulares.
    • La sangría original se conserva en los reemplazos.
    • Los espacios múltiples entre tokens se normalizan para que coincidan
  2. Coincidencia de patrones
    • Las coincidencias de cadenas ( strMatch ) se normalizan con espacios en blanco
    • Los patrones de expresiones regulares ( regexMatch ) admiten la mirada hacia adelante y hacia atrás
    • No se pueden usar strMatch y regexMatch en la misma edición
    • Se detectan y evitan los patrones de expresiones regulares superpuestos
  3. Mejores prácticas
    • Utilice siempre primero la ejecución en seco para verificar los cambios
    • Revise la salida diff antes de aprobar los cambios
    • Mantenga las operaciones de edición enfocadas y atómicas
    • Utilice la coincidencia de patrones adecuada para su caso de uso

Desarrollo

Instalar dependencias:

npm install

Construir el servidor:

npm run build

Para desarrollo con reconstrucción automática:

npm run watch

Pruebas

Ejecute el conjunto de pruebas:

npm run test

Utilidades de prueba adicionales:

Script de herramientas de prueba

Pruebe las herramientas MCP directamente con archivos de muestra:

npm run test:tools

Este guión:

  • Restablece los accesorios de prueba a un estado conocido
  • Se conecta al servidor MCP
  • Prueba cada herramienta en secuencia:
    • get_file_lines
    • edit_file_lines (ejecución en seco)
    • approve_edit
  • Muestra la salida de cada operación.
  • Verifica que los cambios se aplicaron correctamente

Script de reinicio de accesorios

Restablecer los accesorios de prueba a su estado original:

npm run reset:fixtures

Utilice este script para:

  • Restablecer los archivos de prueba a un estado conocido antes de realizar la prueba
  • Limpiar después de pruebas fallidas
  • Garantizar un entorno de prueba consistente
  • Crear directorios de accesorios faltantes

Uso

El servidor requiere que se especifiquen uno o más directorios permitidos al iniciarse:

node build/index.js <allowed-directory> [additional-directories...]

Todas las operaciones con archivos estarán restringidas a estos directorios por seguridad.

Variables de entorno

  • MCP_EDIT_STATE_TTL : Tiempo de vida en milisegundos para los estados de edición (valor predeterminado: 60000). Los estados de edición expirarán después de este tiempo y deberán volver a crearse.

Instalación

Para utilizar con Claude Desktop, agregue la configuración del servidor:

En MacOS: ~/Library/Application Support/Claude/claude_desktop_config.json En Windows: %APPDATA%/Claude/claude_desktop_config.json

{ "mcpServers": { "edit-file-lines": { "command": "node", "args": [ "/path/to/edit-file-lines/build/index.js", "<allowed-directory>" ], "env": { "MCP_EDIT_STATE_TTL": "300000" // Optional: Set custom TTL (in milliseconds) } } } }

Manejo de errores

La herramienta proporciona mensajes de error claros para problemas comunes:

  1. Coincidencia no encontrada
Error: No string match found for "oldValue" on line 5
  1. Expresión regular no válida
Error: Invalid regex pattern "([": Unterminated group
  1. Varias ediciones en la misma línea
Error: Line 5 is affected by multiple edits

Consideraciones de seguridad

  • Todas las operaciones con archivos están restringidas a directorios explícitamente permitidos
  • Los enlaces simbólicos se validan para evitar escapar de directorios permitidos
  • Se evita el recorrido del directorio principal
  • La normalización de rutas se realiza para realizar comprobaciones de seguridad consistentes
  • Se rechazan los números de línea y las posiciones de caracteres no válidos.
  • La normalización del final de línea garantiza un comportamiento consistente en todas las plataformas
  • Los estados de edición expiran después de 60 segundos por seguridad.
  • Las aprobaciones de edición requieren una coincidencia exacta de la ruta del archivo y las ediciones

Depuración

Utilice el script Herramientas de prueba para probar las herramientas MCP directamente con archivos de ejemplo. El Inspector MCP podría ser útil, pero actualmente no admite el procesamiento de entradas que no sean valores de cadena.

-
security - not tested
A
license - permissive license
-
quality - not tested

Un servidor MCP basado en TypeScript que proporciona herramientas para realizar ediciones precisas basadas en líneas en archivos de texto dentro de directorios permitidos.

  1. Features
    1. Main Editing Tool
    2. Example Use Cases
    3. Additional Tools
    4. Important Notes
  2. Development
    1. Testing
  3. Usage
    1. Environment Variables
  4. Installation
    1. Error Handling
    2. Security Considerations
    3. Debugging
ID: 2apib1zht1