mcp-server-code-assist 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl
Sign up to get free protection for your applications and to get access to all the features.
- mcp_server_code_assist/server.py +27 -2
- mcp_server_code_assist/tools/file_tools.py +44 -5
- mcp_server_code_assist/tools/models.py +8 -0
- {mcp_server_code_assist-0.1.1.dist-info → mcp_server_code_assist-0.1.3.dist-info}/METADATA +4 -1
- {mcp_server_code_assist-0.1.1.dist-info → mcp_server_code_assist-0.1.3.dist-info}/RECORD +7 -7
- {mcp_server_code_assist-0.1.1.dist-info → mcp_server_code_assist-0.1.3.dist-info}/WHEEL +0 -0
- {mcp_server_code_assist-0.1.1.dist-info → mcp_server_code_assist-0.1.3.dist-info}/entry_points.txt +0 -0
mcp_server_code_assist/server.py
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
import logging
|
2
2
|
import os
|
3
|
+
import json
|
3
4
|
from pathlib import Path
|
4
5
|
from typing import Any
|
5
6
|
from enum import Enum
|
@@ -9,18 +10,20 @@ from mcp.server.stdio import stdio_server
|
|
9
10
|
from mcp.types import ClientCapabilities, TextContent, Tool, ListRootsResult, RootsCapability
|
10
11
|
import git
|
11
12
|
from mcp_server_code_assist.tools.models import (
|
12
|
-
FileCreate, FileDelete, FileModify, FileRewrite,
|
13
|
+
FileCreate, FileDelete, FileModify, FileRewrite, FileRead,
|
13
14
|
GitBase, GitAdd, GitCommit, GitDiff, GitCreateBranch,
|
14
|
-
GitCheckout, GitShow, GitLog
|
15
|
+
GitCheckout, GitShow, GitLog, ListDirectory
|
15
16
|
)
|
16
17
|
from mcp_server_code_assist.tools.file_tools import FileTools
|
17
18
|
from mcp_server_code_assist.tools.git_functions import git_status, git_diff_unstaged, git_diff_staged, git_diff, git_log, git_show
|
18
19
|
|
19
20
|
class CodeAssistTools(str, Enum):
|
21
|
+
LIST_DIRECTORY = "list_directory"
|
20
22
|
FILE_CREATE = "file_create"
|
21
23
|
FILE_DELETE = "file_delete"
|
22
24
|
FILE_MODIFY = "file_modify"
|
23
25
|
FILE_REWRITE = "file_rewrite"
|
26
|
+
FILE_READ = "file_read"
|
24
27
|
GIT_STATUS = "git_status"
|
25
28
|
GIT_DIFF_UNSTAGED = "git_diff_unstaged"
|
26
29
|
GIT_DIFF_STAGED = "git_diff_staged"
|
@@ -81,6 +84,11 @@ async def serve(working_dir: Path | None) -> None:
|
|
81
84
|
@server.list_tools()
|
82
85
|
async def list_tools() -> list[Tool]:
|
83
86
|
return [
|
87
|
+
Tool(
|
88
|
+
name=CodeAssistTools.LIST_DIRECTORY,
|
89
|
+
description="Lists contents of a directory",
|
90
|
+
inputSchema=ListDirectory.schema(),
|
91
|
+
),
|
84
92
|
Tool(
|
85
93
|
name=CodeAssistTools.FILE_CREATE,
|
86
94
|
description="Creates a new file with content",
|
@@ -101,6 +109,11 @@ async def serve(working_dir: Path | None) -> None:
|
|
101
109
|
description="Rewrites entire file content",
|
102
110
|
inputSchema=FileRewrite.schema(),
|
103
111
|
),
|
112
|
+
Tool(
|
113
|
+
name=CodeAssistTools.FILE_READ,
|
114
|
+
description="Reads contents of a file",
|
115
|
+
inputSchema=FileRead.schema(),
|
116
|
+
),
|
104
117
|
Tool(
|
105
118
|
name=CodeAssistTools.GIT_STATUS,
|
106
119
|
description="Shows the working tree status",
|
@@ -161,6 +174,14 @@ async def serve(working_dir: Path | None) -> None:
|
|
161
174
|
@server.call_tool()
|
162
175
|
async def call_tool(name: str, arguments: dict) -> list[TextContent]:
|
163
176
|
match name:
|
177
|
+
case CodeAssistTools.LIST_DIRECTORY:
|
178
|
+
result = await FileTools.list_directory(
|
179
|
+
arguments["path"],
|
180
|
+
arguments.get("recursive", False),
|
181
|
+
arguments.get("include_hidden", False)
|
182
|
+
)
|
183
|
+
return [TextContent(type="text", text=json.dumps(result, indent=2))]
|
184
|
+
|
164
185
|
case CodeAssistTools.FILE_CREATE:
|
165
186
|
result = await FileTools.create_file(arguments["path"], arguments.get("content", ""))
|
166
187
|
return [TextContent(type="text", text=result)]
|
@@ -177,6 +198,10 @@ async def serve(working_dir: Path | None) -> None:
|
|
177
198
|
result = await FileTools.rewrite_file(arguments["path"], arguments["content"])
|
178
199
|
return [TextContent(type="text", text=result)]
|
179
200
|
|
201
|
+
case CodeAssistTools.FILE_READ:
|
202
|
+
content = await FileTools.read_file(arguments["path"])
|
203
|
+
return [TextContent(type="text", text=content)]
|
204
|
+
|
180
205
|
case CodeAssistTools.GIT_STATUS:
|
181
206
|
repo = git.Repo(arguments["repo_path"])
|
182
207
|
status = git_status(repo)
|
@@ -90,12 +90,51 @@ class FileTools:
|
|
90
90
|
return ''.join(diff)
|
91
91
|
|
92
92
|
@classmethod
|
93
|
-
async def list_directory(cls, path: str) -> list[
|
93
|
+
async def list_directory(cls, path: str, recursive: bool = False, include_hidden: bool = False) -> list[dict]:
|
94
|
+
"""List contents of a directory.
|
95
|
+
|
96
|
+
Args:
|
97
|
+
path: Directory path to list
|
98
|
+
recursive: Whether to list subdirectories recursively
|
99
|
+
include_hidden: Whether to include hidden files/directories
|
100
|
+
|
101
|
+
Returns:
|
102
|
+
List of dicts with file/directory info:
|
103
|
+
{
|
104
|
+
"name": str,
|
105
|
+
"path": str,
|
106
|
+
"type": "file"|"directory",
|
107
|
+
"size": int, # for files only
|
108
|
+
"children": list # for directories when recursive=True
|
109
|
+
}
|
110
|
+
"""
|
94
111
|
path = await cls.validate_path(path)
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
112
|
+
if not os.path.isdir(path):
|
113
|
+
raise ValueError(f"Path {path} is not a directory")
|
114
|
+
|
115
|
+
result = []
|
116
|
+
for entry in os.scandir(path):
|
117
|
+
if not include_hidden and entry.name.startswith('.'):
|
118
|
+
continue
|
119
|
+
|
120
|
+
info = {
|
121
|
+
"name": entry.name,
|
122
|
+
"path": str(Path(entry.path).relative_to(path)),
|
123
|
+
"type": "directory" if entry.is_dir() else "file",
|
124
|
+
}
|
125
|
+
|
126
|
+
if entry.is_file():
|
127
|
+
info["size"] = entry.stat().st_size
|
128
|
+
elif recursive and entry.is_dir():
|
129
|
+
info["children"] = await cls.list_directory(
|
130
|
+
entry.path,
|
131
|
+
recursive=True,
|
132
|
+
include_hidden=include_hidden
|
133
|
+
)
|
134
|
+
|
135
|
+
result.append(info)
|
136
|
+
|
137
|
+
return result
|
99
138
|
|
100
139
|
@classmethod
|
101
140
|
async def create_directory(cls, path: str) -> None:
|
@@ -13,6 +13,9 @@ class FileModify(BaseModel):
|
|
13
13
|
path: Union[str, Path]
|
14
14
|
replacements: dict[str, str]
|
15
15
|
|
16
|
+
class FileRead(BaseModel):
|
17
|
+
path: Union[str, Path]
|
18
|
+
|
16
19
|
class FileRewrite(BaseModel):
|
17
20
|
path: Union[str, Path]
|
18
21
|
content: str
|
@@ -42,6 +45,11 @@ class GitShow(GitBase):
|
|
42
45
|
class GitLog(GitBase):
|
43
46
|
max_count: int = 10
|
44
47
|
|
48
|
+
class ListDirectory(BaseModel):
|
49
|
+
path: Union[str, Path]
|
50
|
+
recursive: bool = False
|
51
|
+
include_hidden: bool = False
|
52
|
+
|
45
53
|
class RepositoryOperation(BaseModel):
|
46
54
|
path: str
|
47
55
|
content: Optional[str] = None
|
@@ -1,11 +1,14 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: mcp-server-code-assist
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: MCP Code Assist Server
|
5
5
|
Requires-Python: >=3.11
|
6
6
|
Requires-Dist: aiofiles>=24.0.0
|
7
|
+
Requires-Dist: click>=8.1.7
|
7
8
|
Requires-Dist: gitpython>=3.1.40
|
9
|
+
Requires-Dist: mcp>=1.2.0
|
8
10
|
Requires-Dist: pydantic>=2.0.0
|
11
|
+
Requires-Dist: xmlschema>=3.4.3
|
9
12
|
Provides-Extra: test
|
10
13
|
Requires-Dist: pytest-asyncio>=0.25.0; extra == 'test'
|
11
14
|
Requires-Dist: pytest>=8.0.0; extra == 'test'
|
@@ -1,15 +1,15 @@
|
|
1
1
|
mcp_server_code_assist/__init__.py,sha256=Aai1h9YUGDDWQn9rsHq5gCZXO7QCQs2pJtyGC9mYV0o,661
|
2
2
|
mcp_server_code_assist/__main__.py,sha256=lbLwix6a0gDF7YKoqbXF88oTdmr8KQGKWchLKEIn5SU,47
|
3
3
|
mcp_server_code_assist/schema.xsd,sha256=vtfQQDzCHvbILT78zF_53N-68GrJRbELg1Xgq3Uu9DE,1235
|
4
|
-
mcp_server_code_assist/server.py,sha256=
|
4
|
+
mcp_server_code_assist/server.py,sha256=X5TkxoDTWNNqVV_d9xjVoUolAUPPus5UqcOwCcQiHjQ,11041
|
5
5
|
mcp_server_code_assist/xml_parser.py,sha256=FMmcAk7PbnTNidBGUynq6ZbUs1O9OHHI298REAQEMqw,1827
|
6
6
|
mcp_server_code_assist/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
7
|
-
mcp_server_code_assist/tools/file_tools.py,sha256=
|
7
|
+
mcp_server_code_assist/tools/file_tools.py,sha256=SZwZjN763D31zCZ4yz8IBJtaf8R5A4bRd9DwwY_exuA,9404
|
8
8
|
mcp_server_code_assist/tools/git_functions.py,sha256=iGIhi8i7BxIrAL8JytWjfcZP7xgla0uVweazSKUNtB4,882
|
9
9
|
mcp_server_code_assist/tools/invoke.py,sha256=lYIu5bJYBaKDDVYz6HRqodpLBMnfVpcvgAref10LO2s,313
|
10
|
-
mcp_server_code_assist/tools/models.py,sha256=
|
10
|
+
mcp_server_code_assist/tools/models.py,sha256=fNCjX0klqa8awTHJH4wx0Z50HmRXDf0_AA8YHV90PwE,1113
|
11
11
|
mcp_server_code_assist/tools/repository_tools.py,sha256=5OG4ecmqXVEeuX9U5jdegbQ2So4lxKkIjG3M3e5rgFI,2700
|
12
|
-
mcp_server_code_assist-0.1.
|
13
|
-
mcp_server_code_assist-0.1.
|
14
|
-
mcp_server_code_assist-0.1.
|
15
|
-
mcp_server_code_assist-0.1.
|
12
|
+
mcp_server_code_assist-0.1.3.dist-info/METADATA,sha256=PhuoTxw1z1lRmkLe5GsfdkGi0Hy1FNtqTXCna8uPINU,426
|
13
|
+
mcp_server_code_assist-0.1.3.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
14
|
+
mcp_server_code_assist-0.1.3.dist-info/entry_points.txt,sha256=n1CONsVBue7ckhZetmRyyoIIUpyD_gmHHNf7SlWQUCM,80
|
15
|
+
mcp_server_code_assist-0.1.3.dist-info/RECORD,,
|
File without changes
|
{mcp_server_code_assist-0.1.1.dist-info → mcp_server_code_assist-0.1.3.dist-info}/entry_points.txt
RENAMED
File without changes
|