Skip to main content
Glama

Edit File Lines MCP Server

by oakenai

MCP 서버 파일 줄 편집

허용된 디렉터리 내에서 텍스트 파일에 대한 정확한 줄 기반 편집을 위한 도구를 제공하는 TypeScript 기반 MCP 서버입니다.

특징

주요 편집 도구

edit_file_lines

문자열 또는 정규식 패턴 매칭을 사용하여 파일을 줄 단위로 편집할 수 있습니다. 각 편집은 다음을 수행할 수 있습니다.

  • 전체 줄 바꾸기

  • 줄 서식을 유지하면서 특정 텍스트 일치 항목 바꾸기

  • 복잡한 일치에 정규식 패턴 사용

  • 여러 줄과 여러 편집을 처리합니다

  • 드라이런 모드로 변경 사항 미리 보기

예제 파일( src/components/App.tsx ):

지엑스피1

예시 사용 사례

  1. 간단한 문자열 교체

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

산출:

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: fcbf740a 이 ID를 approve_edit과 함께 사용하여 변경 사항을 적용합니다.

  1. 구조가 보존된 다중 줄 콘텐츠

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

산출:

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: f2ce973f 이 ID를 approve_edit과 함께 사용하여 변경 사항을 적용합니다.

  1. 복잡한 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 }

산출:

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: f1f1d27b 이 ID를 approve_edit과 함께 사용하여 변경 사항을 적용합니다.

  1. 공백 보존을 통한 구성 업데이트

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

산출:

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: 20e93c34 이 ID를 approve_edit과 함께 사용하여 변경 사항을 적용합니다.

  1. 유연한 공백 매칭

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

산출:

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

추가 도구

approve_edit

edit_file_lines 의 이전 연습 실행에서 변경 사항을 적용합니다. 이 도구는 안전을 위해 2단계 편집 프로세스를 제공합니다. 다음은 워크플로 예시입니다.

  1. 먼저, 테스트 편집을 해보세요.

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

산출:

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: fcbf740a 이 ID를 approve_edit과 함께 사용하여 변경 사항을 적용합니다.

  1. 그런 다음, 상태 ID를 사용하여 변경 사항을 승인합니다.

{ "stateId": "fcbf740a" }

산출:

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. 변경 사항을 확인하세요.

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

산출:

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

보안을 위해 주 ID는 일정 시간 후에 만료됩니다. 만료되었거나 유효하지 않은 주 ID를 사용하려고 하면 오류가 발생합니다.

{ "stateId": "invalid123" }

산출:

Error: Invalid or expired state ID

get_file_lines

파일에서 특정 줄을 검사하고, 선택적으로 컨텍스트 줄을 추가할 수 있습니다. 이 도구는 편집하기 전에 줄 내용을 확인하는 데 유용합니다.

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

산출:

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

파일에서 텍스트 패턴이나 정규 표현식을 검색하여 특정 줄 번호와 그 주변 맥락을 찾습니다. 이 도구는 edit_file_lines 사용하여 편집하려는 정확한 줄을 찾는 데 특히 유용합니다.

특징:

  • 대소문자 구분 옵션을 적용한 간단한 텍스트 검색

  • 정규 표현식 지원

  • 전체 단어 일치

  • 구성 가능한 컨텍스트 줄

  • 줄 번호, 콘텐츠 및 줄 번호와 함께 주변 컨텍스트를 반환합니다.

인수:

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

예시 사용 사례:

  1. 간단한 텍스트 검색:

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

산출:

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. 대소문자를 구분하여 전체 단어 검색:

{ "path": "src/components/App.tsx", "pattern": "props", "caseSensitive": true, "wholeWord": true, "contextLines": 1 }

산출:

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. JSX 구성 요소 찾기:

{ "path": "src/components/App.tsx", "pattern": "<[A-Z]\\w+\\s", "type": "regex", "contextLines": 1 }

산출:

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>

일반적인 워크플로:

  1. 찾아서 편집하세요:

// 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. 모든 사용법을 찾아보세요:

{ "path": "src/components/App.tsx", "pattern": "\\buseMemo\\b", "type": "regex", "contextLines": 2, "maxMatches": 50 }
  1. 특정 소품 패턴 찾기:

{ "path": "src/components/App.tsx", "pattern": "className=['\"]([^'\"]+)['\"]", "type": "regex", "contextLines": 1 }

중요 참고 사항

  1. 공백 처리

    • 이 도구는 문자열과 정규식 일치 모두에서 공백을 지능적으로 처리합니다.

    • 교체 시 원래 들여쓰기가 보존됩니다.

    • 토큰 사이의 여러 공백은 일치를 위해 정규화됩니다.

  2. 패턴 매칭

    • 문자열 일치( strMatch )는 공백으로 정규화됩니다.

    • 정규식 패턴( regexMatch )은 미리 보기와 뒤돌아보기를 지원합니다.

    • 동일한 편집에서 strMatchregexMatch 모두 사용할 수 없습니다.

    • 중복되는 정규식 패턴이 감지되어 방지됩니다.

  3. 모범 사례

    • 변경 사항을 확인하려면 항상 먼저 연습을 실행하세요.

    • 변경 사항을 승인하기 전에 diff 출력을 검토하세요.

    • 편집 작업을 집중적이고 원자적으로 유지하세요

    • 사용 사례에 적합한 패턴 매칭을 사용하세요

Related MCP server: MCP Server

개발

종속성 설치:

npm install

서버를 빌드하세요:

npm run build

자동 재빌드를 사용한 개발의 경우:

npm run watch

테스트

테스트 모음을 실행합니다.

npm run test

추가 테스트 유틸리티:

테스트 도구 스크립트

샘플 파일에 대해 MCP 도구를 직접 테스트해 보세요.

npm run test:tools

이 스크립트:

  • 테스트 고정물을 알려진 상태로 재설정합니다.

  • MCP 서버에 연결합니다

  • 각 도구를 순서대로 테스트합니다.

    • get_file_lines

    • edit_file_lines (드라이런)

    • approve_edit

  • 각 작업의 출력을 보여줍니다

  • 변경 사항이 올바르게 적용되었는지 확인합니다.

경기 일정 재설정 스크립트

테스트 픽스처를 원래 상태로 재설정합니다.

npm run reset:fixtures

이 스크립트를 사용하여 다음을 수행할 수 있습니다.

  • 테스트하기 전에 테스트 파일을 알려진 상태로 재설정합니다.

  • 테스트 실패 후 정리

  • 일관된 테스트 환경 보장

  • 누락된 고정 장치 디렉토리 만들기

용법

서버를 시작할 때 하나 이상의 허용된 디렉토리를 지정해야 합니다.

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

보안을 위해 모든 파일 작업은 이러한 디렉토리로 제한됩니다.

환경 변수

  • MCP_EDIT_STATE_TTL : 편집 상태의 TTL(밀리초)입니다(기본값: 60000). 이 기간이 지나면 편집 상태가 만료되므로 다시 만들어야 합니다.

설치

Claude Desktop과 함께 사용하려면 서버 구성을 추가하세요.

MacOS의 경우: ~/Library/Application Support/Claude/claude_desktop_config.json 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) } } } }

오류 처리

이 도구는 일반적인 문제에 대한 명확한 오류 메시지를 제공합니다.

  1. 일치하는 항목을 찾을 수 없습니다

Error: No string match found for "oldValue" on line 5
  1. 잘못된 정규식

Error: Invalid regex pattern "([": Unterminated group
  1. 같은 줄에 여러 번 편집

Error: Line 5 is affected by multiple edits

보안 고려 사항

  • 모든 파일 작업은 명시적으로 허용된 디렉토리로 제한됩니다.

  • 허용된 디렉토리를 이스케이프하지 못하도록 심볼릭 링크가 검증됩니다.

  • 상위 디렉토리 탐색이 방지됩니다.

  • 일관된 보안 검사를 위해 경로 정규화가 수행됩니다.

  • 잘못된 줄 번호와 문자 위치는 거부됩니다.

  • 줄 끝 정규화는 플랫폼 전반에 걸쳐 일관된 동작을 보장합니다.

  • 보안을 위해 편집 상태는 60초 후에 만료됩니다.

  • 편집 승인에는 파일 경로와 편집 내용이 정확히 일치해야 합니다.

디버깅

테스트 도구 스크립트를 사용하여 샘플 파일에서 MCP 도구를 직접 테스트해 보세요. MCP 검사기가 도움이 될 수도 있지만, 현재 문자열 값이 아닌 입력은 처리할 수 없습니다.

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

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/oakenai/mcp-edit-file-lines'

If you have feedback or need assistance with the MCP directory API, please join our Discord server