Skip to content

Commit 0f7fef7

Browse files
committed
Update project name to 'gitlab-mcp-server' and enhance project metadata in pyproject.toml; refactor merge request services and schemas for improved input handling and validation; add Dockerfile for containerization.
1 parent a9f9d5c commit 0f7fef7

File tree

6 files changed

+102
-206
lines changed

6 files changed

+102
-206
lines changed

Dockerfile

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
FROM python:3.13-slim
2+
3+
# Install uv
4+
COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
5+
6+
# Copy the application into the container
7+
COPY . /app
8+
9+
# Set working directory
10+
WORKDIR /app
11+
12+
# Install dependencies (from lockfile for reproducibility)
13+
RUN uv sync --frozen --no-cache
14+
15+
# Run the MCP server (adjust entrypoint as needed)
16+
CMD ["uv", "run", "server.py"]

pyproject.toml

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[project]
2-
name = "gitlab-mcp"
2+
name = "gitlab-mcp-server"
33
version = "0.2.0"
44
description = "GitLab MCP (Model Context Protocol) server for interacting with GitLab API through AI Clients"
55
readme = "README.md"
@@ -11,6 +11,21 @@ dependencies = [
1111
"pydantic-settings>=2.8.1",
1212
"asyncio>=3.4.3",
1313
]
14+
authors = [{ name = "Adit pal Singh", email = "aditpalsing@gmail.com" }]
15+
license = { file = "LICENSE" }
16+
classifiers = [
17+
"Programming Language :: Python :: 3.13",
18+
"License :: OSI Approved :: MIT License",
19+
"Operating System :: OS Independent",
20+
"Development Status :: 3 - Alpha",
21+
"Intended Audience :: Developers",
22+
"Topic :: Software Development :: Libraries :: Application Frameworks",
23+
]
24+
keywords = ["gitlab", "mcp", "ai", "server"]
25+
26+
[project.urls]
27+
Homepage = "https://github.com/Adit-999/gitlab-mcp"
28+
Documentation = "https://github.com/Adit-999/gitlab-mcp#readme"
1429

1530
[project.optional-dependencies]
1631
dev = [
@@ -20,18 +35,14 @@ dev = [
2035
"pytest>=8.0.0",
2136
"pytest-asyncio>=0.23.5",
2237
]
38+
ruff = ["ruff>=0.11.5"]
2339

2440
[build-system]
2541
requires = ["hatchling"]
2642
build-backend = "hatchling.build"
2743

2844
[tool.hatch.build.targets.wheel]
29-
packages = ["mcp"]
45+
packages = ["src"]
3046

3147
[tool.pytest.ini_options]
3248
asyncio_mode = "auto"
33-
34-
[dependency-groups]
35-
dev = [
36-
"ruff>=0.11.5",
37-
]

server.py

Lines changed: 0 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,8 @@
3535
get_job_logs,
3636
)
3737
from src.services.merge_requests import (
38-
apply_multiple_suggestions,
39-
apply_suggestion,
4038
create_merge_request,
4139
create_merge_request_comment,
42-
create_merge_request_thread,
4340
delete_merge_request,
4441
get_merge_request,
4542
list_merge_requests,
@@ -175,18 +172,6 @@
175172
mcp.tool(
176173
name="create_merge_request_comment", description="Add a comment to a merge request."
177174
)(create_merge_request_comment)
178-
mcp.tool(
179-
name="create_merge_request_thread",
180-
description="Create a new thread on a merge request.",
181-
)(create_merge_request_thread)
182-
mcp.tool(
183-
name="apply_suggestion",
184-
description="Apply a suggestion in a merge request comment.",
185-
)(apply_suggestion)
186-
mcp.tool(
187-
name="apply_multiple_suggestions",
188-
description="Apply multiple suggestions in a merge request.",
189-
)(apply_multiple_suggestions)
190175

191176
# Register job tools
192177

src/schemas/merge_requests.py

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -169,12 +169,54 @@ class CreateMergeRequestCommentInput(BaseModel):
169169

170170

171171
class CreateMergeRequestThreadInput(BaseModel):
172-
"""Input model for creating a thread on a GitLab merge request."""
172+
"""Input model for creating a thread (suggestion) on a GitLab merge request.
173+
174+
Attributes:
175+
project_path: The path of the project (e.g., 'namespace/project').
176+
mr_iid: The internal ID of the merge request.
177+
body: The content of the thread (should include suggestion block for suggestions).
178+
position_type: The type of position (usually 'text').
179+
base_sha: The base commit SHA.
180+
start_sha: The start commit SHA.
181+
head_sha: The head commit SHA.
182+
old_path: The old file path (for changes, required).
183+
new_path: The new file path (for changes, required).
184+
old_line: The line number in the old file (optional).
185+
new_line: The line number in the new file (optional).
186+
"""
173187

174188
project_path: str
175189
mr_iid: int
176190
body: str
177-
position: dict[str, Any]
191+
position_type: str
192+
base_sha: str
193+
start_sha: str
194+
head_sha: str
195+
old_path: str
196+
new_path: str
197+
old_line: int | None = None
198+
new_line: int | None = None
199+
200+
@classmethod
201+
def validate_line(cls, values):
202+
if values.get("old_line") is None and values.get("new_line") is None:
203+
raise ValueError("At least one of old_line or new_line must be provided.")
204+
return values
205+
206+
def to_position(self) -> dict[str, Any]:
207+
position = {
208+
"position_type": self.position_type,
209+
"base_sha": self.base_sha,
210+
"start_sha": self.start_sha,
211+
"head_sha": self.head_sha,
212+
"old_path": self.old_path,
213+
"new_path": self.new_path,
214+
}
215+
if self.old_line is not None:
216+
position["old_line"] = str(self.old_line)
217+
if self.new_line is not None:
218+
position["new_line"] = str(self.new_line)
219+
return position
178220

179221

180222
class ApplySuggestionInput(BaseModel):

0 commit comments

Comments
 (0)