mcp-server-code-assist 0.1.1__py3-none-any.whl → 0.1.3__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|