Skip to content

Commit b16b6f4

Browse files
committed
Merge branch 'remove-edit' into develop
2 parents b67d29f + 1e06529 commit b16b6f4

16 files changed

+1128
-748
lines changed

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ ENV/
3535
*.swo
3636

3737
# Testing
38+
*.cover
39+
*,cover
3840
.coverage
3941
.coverage.*
4042
.pytest_cache/

src/mcp_text_editor/handlers/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from .append_text_file_contents import AppendTextFileContentsHandler
44
from .create_text_file import CreateTextFileHandler
55
from .delete_text_file_contents import DeleteTextFileContentsHandler
6-
from .edit_text_file_contents import EditTextFileContentsHandler
76
from .get_text_file_contents import GetTextFileContentsHandler
87
from .insert_text_file_contents import InsertTextFileContentsHandler
98
from .patch_text_file_contents import PatchTextFileContentsHandler
@@ -12,7 +11,6 @@
1211
"AppendTextFileContentsHandler",
1312
"CreateTextFileHandler",
1413
"DeleteTextFileContentsHandler",
15-
"EditTextFileContentsHandler",
1614
"GetTextFileContentsHandler",
1715
"InsertTextFileContentsHandler",
1816
"PatchTextFileContentsHandler",

src/mcp_text_editor/handlers/base.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,9 @@ class BaseHandler:
1313
name: str = ""
1414
description: str = ""
1515

16-
def __init__(self):
16+
def __init__(self, editor: TextEditor | None = None):
1717
"""Initialize the handler."""
18-
self.editor = TextEditor()
18+
self.editor = editor if editor is not None else TextEditor()
1919

2020
def get_tool_description(self) -> Tool:
2121
"""Get the tool description."""

src/mcp_text_editor/handlers/edit_text_file_contents.py

Lines changed: 0 additions & 166 deletions
This file was deleted.

src/mcp_text_editor/handlers/insert_text_file_contents.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,17 @@ async def run_tool(self, arguments: Dict[str, Any]) -> Sequence[TextContent]:
8585
is_before = "before" in arguments
8686
encoding = arguments.get("encoding", "utf-8")
8787

88+
# Get result from editor
8889
result = await self.editor.insert_text_file_contents(
8990
file_path=file_path,
9091
file_hash=arguments["file_hash"],
9192
contents=arguments["contents"],
92-
before=is_before,
93-
line_number=line_number,
93+
before=line_number if is_before else None,
94+
after=None if is_before else line_number,
9495
encoding=encoding,
9596
)
97+
# Wrap result with file_path key
98+
result = {file_path: result}
9699
return [TextContent(type="text", text=json.dumps(result, indent=2))]
97100

98101
except Exception as e:

src/mcp_text_editor/handlers/patch_text_file_contents.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ class PatchTextFileContentsHandler(BaseHandler):
1717
"""Handler for patching a text file."""
1818

1919
name = "patch_text_file_contents"
20-
description = "Apply patches to text files with hash-based validation for concurrency control."
20+
description = "Apply patches to text files with hash-based validation for concurrency control.you need to use get_text_file_contents tool to get the file hash and range hash every time before using this tool. you can use append_text_file_contents tool to append text contents to the file without range hash, start and end. you can use insert_text_file_contents tool to insert text contents to the file without range hash, start and end."
2121

2222
def get_tool_description(self) -> Tool:
2323
"""Get the tool description."""
@@ -43,19 +43,19 @@ def get_tool_description(self) -> Tool:
4343
"properties": {
4444
"start": {
4545
"type": "integer",
46-
"description": "Starting line number (1-based)",
46+
"description": "Starting line number (1-based).it should match the range hash.",
4747
},
4848
"end": {
4949
"type": ["integer", "null"],
50-
"description": "Ending line number (null for end of file)",
50+
"description": "Ending line number (null for end of file).it should match the range hash.",
5151
},
5252
"contents": {
5353
"type": "string",
5454
"description": "New content to replace the range with",
5555
},
5656
"range_hash": {
5757
"type": "string",
58-
"description": "Hash of the content being replaced",
58+
"description": "Hash of the content being replaced. it should get from get_text_file_contents tool with the same start and end.",
5959
},
6060
},
6161
"required": ["start", "contents", "range_hash"],

src/mcp_text_editor/models.py

Lines changed: 34 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -111,6 +111,9 @@ class FileRange(BaseModel):
111111
end: Optional[int] = Field(
112112
None, description="Ending line number (null for end of file)"
113113
)
114+
range_hash: Optional[str] = Field(
115+
None, description="Hash of the content to be deleted"
116+
)
114117

115118

116119
class FileRanges(BaseModel):
@@ -149,6 +152,9 @@ class InsertTextFileContentsRequest(BaseModel):
149152
before: Optional[int] = Field(
150153
None, description="Line number before which to insert content"
151154
)
155+
encoding: Optional[str] = Field(
156+
"utf-8", description="Text encoding (default: 'utf-8')"
157+
)
152158
contents: str = Field(..., description="Content to insert")
153159

154160
@model_validator(mode="after")
@@ -170,10 +176,9 @@ def validate_line_number(cls, v) -> Optional[int]:
170176

171177
class DeleteTextFileContentsRequest(BaseModel):
172178
"""Request model for deleting text from a file.
173-
174179
Example:
175180
{
176-
"path": "/path/to/file",
181+
"file_path": "/path/to/file",
177182
"file_hash": "abc123...",
178183
"ranges": [
179184
{
@@ -185,15 +190,34 @@ class DeleteTextFileContentsRequest(BaseModel):
185190
}
186191
"""
187192

188-
path: str = Field(..., description="Path to the text file")
193+
file_path: str = Field(..., description="Path to the text file")
189194
file_hash: str = Field(..., description="Hash of original contents")
190195
ranges: List[FileRange] = Field(..., description="List of ranges to delete")
196+
encoding: Optional[str] = Field(
197+
"utf-8", description="Text encoding (default: 'utf-8')"
198+
)
191199

192-
@field_validator("range_hash")
193-
def validate_range_hash(cls, v: str) -> str:
194-
"""Validate that range_hash is not empty."""
195-
if not v:
196-
raise ValueError("range_hash cannot be empty")
197-
return v
198200

199-
range_hash: str = Field(..., description="Hash of the content to be deleted")
201+
class PatchTextFileContentsRequest(BaseModel):
202+
"""Request model for patching text in a file.
203+
Example:
204+
{
205+
"file_path": "/path/to/file",
206+
"file_hash": "abc123...",
207+
"patches": [
208+
{
209+
"start": 5,
210+
"end": 10,
211+
"contents": "new content",
212+
"range_hash": "def456..."
213+
}
214+
]
215+
}
216+
"""
217+
218+
file_path: str = Field(..., description="Path to the text file")
219+
file_hash: str = Field(..., description="Hash of original contents")
220+
patches: List[EditPatch] = Field(..., description="List of patches to apply")
221+
encoding: Optional[str] = Field(
222+
"utf-8", description="Text encoding (default: 'utf-8')"
223+
)

src/mcp_text_editor/server.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
AppendTextFileContentsHandler,
1313
CreateTextFileHandler,
1414
DeleteTextFileContentsHandler,
15-
EditTextFileContentsHandler,
1615
GetTextFileContentsHandler,
1716
InsertTextFileContentsHandler,
1817
PatchTextFileContentsHandler,
@@ -27,7 +26,6 @@
2726

2827
# Initialize tool handlers
2928
get_contents_handler = GetTextFileContentsHandler()
30-
edit_contents_handler = EditTextFileContentsHandler()
3129
patch_file_handler = PatchTextFileContentsHandler()
3230
create_file_handler = CreateTextFileHandler()
3331
append_file_handler = AppendTextFileContentsHandler()
@@ -40,7 +38,6 @@ async def list_tools() -> List[Tool]:
4038
"""List available tools."""
4139
return [
4240
get_contents_handler.get_tool_description(),
43-
edit_contents_handler.get_tool_description(),
4441
create_file_handler.get_tool_description(),
4542
append_file_handler.get_tool_description(),
4643
delete_contents_handler.get_tool_description(),
@@ -56,8 +53,6 @@ async def call_tool(name: str, arguments: Any) -> Sequence[TextContent]:
5653
try:
5754
if name == get_contents_handler.name:
5855
return await get_contents_handler.run_tool(arguments)
59-
elif name == edit_contents_handler.name:
60-
return await edit_contents_handler.run_tool(arguments)
6156
elif name == create_file_handler.name:
6257
return await create_file_handler.run_tool(arguments)
6358
elif name == append_file_handler.name:

0 commit comments

Comments
 (0)