forked from ShouZhengAI/CS146S_CN
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsimple_mcp.py
More file actions
84 lines (77 loc) · 2.46 KB
/
Copy pathsimple_mcp.py
File metadata and controls
84 lines (77 loc) · 2.46 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
from pathlib import Path
from typing import Any, Dict, List
from fastmcp import FastMCP
mcp = FastMCP(name="SimpleMCPTestServer")
def resolve_abs_path(path_str: str) -> Path:
"""
file.py -> /Users/home/mihail/modern-software-dev-lectures/file.py
"""
path = Path(path_str).expanduser()
if not path.is_absolute():
path = (Path.cwd() / path).resolve()
return path
@mcp.tool
def read_file_tool(filename: str) -> Dict[str, Any]:
"""
Gets the full content of a file provided by the user.
:param filename: The name of the file to read.
:return: The full content of the file.
"""
full_path = resolve_abs_path(filename)
print(full_path)
# TODO (mihail): Be more defensive in the file reading here
with open(str(full_path), "r") as f:
content = f.read()
return {
"file_path": str(full_path),
"content": content
}
@mcp.tool
def list_files_tool(path: str) -> Dict[str, Any]:
"""
Lists the files in a directory provided by the user.
:param path: The path to the directory to list files from.
:return: A list of files in the directory.
"""
full_path = resolve_abs_path(path)
all_files = []
for item in full_path.iterdir():
all_files.append({
"filename": item.name,
"type": "file" if item.is_file() else "dir"
})
return {
"path": str(full_path),
"files": all_files
}
@mcp.tool
def edit_file_tool(path: str, old_str: str, new_str: str) -> Dict[str, Any]:
"""
Replaces first occurrence of old_str with new_str in file. If old_str is empty, creates/overwrites file with new_str.
:param path: The path to the file to edit.
:param old_str: The string to replace.
:param new_str: The string to replace with.
:return: A dictionary with the path to the file and the action taken.
"""
full_path = resolve_abs_path(path)
p = Path(full_path)
if old_str == "":
p.write_text(new_str, encoding="utf-8")
return {
"path": str(full_path),
"action": "created_file"
}
original = p.read_text(encoding="utf-8")
if original.find(old_str) == -1:
return {
"path": str(full_path),
"action": "old_str not found"
}
edited = original.replace(old_str, new_str, 1)
p.write_text(edited, encoding="utf-8")
return {
"path": str(full_path),
"action": "edited"
}
if __name__ == "__main__":
mcp.run()