Edit File Lines MCP Server
一个基于 TypeScript 的 MCP 服务器,提供工具以对允许目录内的文本文件进行精确的、基于行的编辑。
README
Edit File Lines MCP 服务器
一个基于 TypeScript 的 MCP 服务器,提供用于对允许目录中的文本文件进行精确的基于行的编辑的工具。
功能
主要编辑工具
edit_file_lines
使用字符串或正则表达式模式匹配对文件进行基于行的编辑。每个编辑可以:
- 替换整行
- 替换特定的文本匹配项,同时保留行格式
- 使用正则表达式模式进行复杂的匹配
- 处理多行和多个编辑
- 使用 dry run 模式预览更改
示例文件 (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,
};
示例用例
- 简单字符串替换
{
"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
State ID: fcbf740a 使用此 ID 与 approve_edit 一起应用更改。
- 具有保留结构的多行内容
{
"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>
- </div>
+ <div className={cardClass}>
+ <h2 className="title">{title}</h2>
+ <p className="subtitle">{subtitle}</p>
+ </div>
);
};
State ID: f2ce973f 使用此 ID 与 approve_edit 一起应用更改。
- 复杂的 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 (
State ID: f1f1d27b 使用此 ID 与 approve_edit 一起应用更改。
- 使用空格保留进行配置更新
{
"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
};
State ID: 20e93c34 使用此 ID 与 approve_edit 一起应用更改。
- 灵活的空格匹配
{
"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
先前 dry run 的更改。此工具提供了一个两步编辑过程以确保安全。这是一个示例工作流程:
- 首先,进行 dry run 编辑:
{
"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>;
};
State ID: fcbf740a 使用此 ID 与 approve_edit 一起应用更改。
- 然后,使用状态 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>;
};
- 验证更改:
{
"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; // 要搜索的文件的路径
pattern: string; // 搜索模式(文本或正则表达式)
type?: "text" | "regex"; // 搜索类型(默认值:"text")
caseSensitive?: boolean; // 大小写敏感搜索(默认值:false)
contextLines?: number; // 上下文行数(默认值:2,最大值:10)
maxMatches?: number; // 要返回的最大匹配数(默认值:100)
wholeWord?: boolean; // 仅匹配整个单词(默认值:false)
multiline?: boolean; // 启用多行正则表达式模式(默认值:false)
}
示例用例:
- 简单文本搜索:
{
"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,
- 大小写敏感的全字搜索:
{
"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 = ({
- 查找 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>
常用工作流程:
- 查找然后编辑:
// 首先,搜索该行
{
"path": "src/config.ts",
"pattern": "API_URL",
"wholeWord": true
}
// 然后在 edit_file_lines 中使用返回的行号
{
"p": "src/config.ts",
"e": [{
"startLine": 23, // 来自搜索结果的行号
"endLine": 23,
"content": "export const API_URL = 'https://new-api.example.com';"
}]
}
- 查找所有用法:
{
"path": "src/components/App.tsx",
"pattern": "\\buseMemo\\b",
"type": "regex",
"contextLines": 2,
"maxMatches": 50
}
- 查找特定的 prop 模式:
{
"path": "src/components/App.tsx",
"pattern": "className=['\"]([^'\"]+)['\"]",
"type": "regex",
"contextLines": 1
}
重要说明
-
空格处理
- 该工具智能地处理字符串和正则表达式匹配中的空格
- 原始缩进在替换中保留
- 令牌之间的多个空格被标准化以进行匹配
-
模式匹配
- 字符串匹配 (
strMatch
) 是空格标准化的 - 正则表达式模式 (
regexMatch
) 支持前瞻和后顾 - 不能在同一个编辑中同时使用
strMatch
和regexMatch
- 检测并阻止重叠的正则表达式模式
- 字符串匹配 (
-
最佳实践
- 始终首先使用 dry run 来验证更改
- 在批准更改之前查看 diff 输出
- 保持编辑操作集中且原子化
- 为您的用例使用适当的模式匹配
开发
安装依赖项:
npm install
构建服务器:
npm run build
对于具有自动重建功能的开发:
npm run watch
测试
运行测试套件:
npm run test
其他测试实用程序:
测试工具脚本
直接针对示例文件测试 MCP 工具:
npm run test:tools
此脚本:
- 将测试装置重置为已知状态
- 连接到 MCP 服务器
- 按顺序测试每个工具:
get_file_lines
edit_file_lines
(dry run)approve_edit
- 显示每个操作的输出
- 验证更改是否已正确应用
重置装置脚本
将测试装置重置为其原始状态:
npm run reset:fixtures
使用此脚本来:
- 在测试之前将测试文件重置为已知状态
- 清理失败的测试后
- 确保一致的测试环境
- 创建缺少的装置目录
用法
服务器需要在启动时指定一个或多个允许的目录:
node build/index.js <allowed-directory> [additional-directories...]
所有文件操作都将限制在这些目录中以确保安全。
环境变量
MCP_EDIT_STATE_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" // 可选:设置自定义 TTL(以毫秒为单位)
}
}
}
}
错误处理
该工具为常见问题提供清晰的错误消息:
- 未找到匹配项
Error: No string match found for "oldValue" on line 5
- 无效的正则表达式
Error: Invalid regex pattern "([": Unterminated group
- 同一行上的多个编辑
Error: Line 5 is affected by multiple edits
安全注意事项
- 所有文件操作都限制在显式允许的目录中
- 验证符号链接以防止转义允许的目录
- 防止父目录遍历
- 执行路径规范化以进行一致的安全检查
- 拒绝无效的行号和字符位置
- 行尾规范化确保跨平台的一致行为
- 编辑状态在 60 秒后过期以确保安全
- 编辑批准需要文件路径和编辑的完全匹配
调试
使用测试工具脚本直接针对示例文件测试 MCP 工具。MCP Inspector 可能会有所帮助,但它目前不支持处理非字符串值的输入。
推荐服务器
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Excel MCP Server
一个模型上下文协议服务器,使 AI 助手能够读取和写入 Microsoft Excel 文件,支持诸如 xlsx、xlsm、xltx 和 xltm 等格式。
MCP Package Docs Server
促进大型语言模型高效访问和获取 Go、Python 和 NPM 包的结构化文档,通过多语言支持和性能优化来增强软件开发。
Claude Code MCP
一个实现了 Claude Code 作为模型上下文协议(Model Context Protocol, MCP)服务器的方案,它可以通过标准化的 MCP 接口来使用 Claude 的软件工程能力(代码生成、编辑、审查和文件操作)。
@kazuph/mcp-taskmanager
用于任务管理的模型上下文协议服务器。它允许 Claude Desktop(或任何 MCP 客户端)在基于队列的系统中管理和执行任务。
Gitingest-MCP
一个用于 gitingest 的 MCP 服务器。它允许像 Claude Desktop、Cursor、Cline 等 MCP 客户端快速提取关于 Github 仓库的信息,包括仓库摘要、项目目录结构、文件内容等。
mermaid-mcp-server
一个模型上下文协议 (MCP) 服务器,用于将 Mermaid 图表转换为 PNG 图像。
Jira-Context-MCP
MCP 服务器向 AI 编码助手(如 Cursor)提供 Jira 工单信息。

Linear MCP Server
一个模型上下文协议(Model Context Protocol)服务器,它与 Linear 的问题跟踪系统集成,允许大型语言模型(LLM)通过自然语言交互来创建、更新、搜索和评论 Linear 问题。