summaryrefslogtreecommitdiff
path: root/servers/gitlab_python/src
diff options
context:
space:
mode:
authorDawid Rycerz <dawid@rycerz.xyz>2025-07-15 17:36:46 +0300
committerDawid Rycerz <dawid@rycerz.xyz>2025-07-15 17:36:46 +0300
commitea094d5731ae36db599b9a9803c41db303fc685a (patch)
tree873145a3bc4cc3f5140a5ca12d9d84bf180a1b54 /servers/gitlab_python/src
parent0d3b300943d44ad69f803f2e196bc643b937ef37 (diff)
feat: Add updates issues and epics functinoality
Diffstat (limited to 'servers/gitlab_python/src')
-rw-r--r--servers/gitlab_python/src/mcp_server_gitlab_python/server.py127
1 files changed, 127 insertions, 0 deletions
diff --git a/servers/gitlab_python/src/mcp_server_gitlab_python/server.py b/servers/gitlab_python/src/mcp_server_gitlab_python/server.py
index 05e84c5..c176832 100644
--- a/servers/gitlab_python/src/mcp_server_gitlab_python/server.py
+++ b/servers/gitlab_python/src/mcp_server_gitlab_python/server.py
@@ -152,6 +152,33 @@ class GitLabPythonServer:
except Exception as e:
return {"error": str(e)}
+ def update_issue(
+ self,
+ project: str,
+ issue_iid: int,
+ **kwargs: object,
+ ) -> dict[str, Any]:
+ """Update an existing GitLab issue.
+
+ Args:
+ project (str): The project full path or ID.
+ issue_iid (int): The internal ID of the issue.
+ **kwargs: Fields to update (e.g., title, description, labels, etc.).
+
+ Returns:
+ dict[str, Any]: Dictionary with the issue URL or error message.
+ """
+ try:
+ proj = self.gl.projects.get(project)
+ issue = proj.issues.get(issue_iid)
+ for k, v in kwargs.items():
+ setattr(issue, k, v)
+ issue.save()
+ return {"url": issue.web_url}
+ except Exception as e:
+ logger.error(f"Failed to update issue {project}#{issue_iid}: {e}")
+ return {"error": str(e)}
+
def get_mr_diff(
self,
project: str,
@@ -335,6 +362,33 @@ class GitLabPythonServer:
except Exception as e:
return {"error": str(e)}
+ def update_epic(
+ self,
+ group: str,
+ epic_iid: int,
+ **kwargs: object,
+ ) -> dict[str, Any]:
+ """Update an existing GitLab epic.
+
+ Args:
+ group (str): The group full path or ID.
+ epic_iid (int): The internal ID of the epic.
+ **kwargs: Fields to update (e.g., title, description, labels, etc.).
+
+ Returns:
+ dict[str, Any]: Dictionary with the epic URL or error message.
+ """
+ try:
+ grp = self.gl.groups.get(group)
+ epic = grp.epics.get(epic_iid)
+ for k, v in kwargs.items():
+ setattr(epic, k, v)
+ epic.save()
+ return {"url": epic.web_url}
+ except Exception as e:
+ logger.error(f"Failed to update epic {group}#{epic_iid}: {e}")
+ return {"error": str(e)}
+
def create_server(host: str = "127.0.0.1", port: int = 8080) -> FastMCP:
mcp = FastMCP("GitLab Python", host=host, port=port)
@@ -391,6 +445,37 @@ def create_server(host: str = "127.0.0.1", port: int = 8080) -> FastMCP:
return server.create_issue(project, title, description, **data)
@mcp.tool()
+ def update_issue(
+ project: str,
+ issue_iid: int,
+ working_directory: str,
+ title: str | None = None,
+ description: str | None = None,
+ state_event: str | None = None,
+ labels: list[str] | None = None,
+ assignee_ids: list[int] | None = None,
+ milestone_id: int | None = None,
+ **kwargs: object
+ ) -> dict[str, Any]:
+ """Update an existing GitLab issue."""
+ server = GitLabPythonServer(working_directory)
+ data = {}
+ if title is not None:
+ data["title"] = title
+ if description is not None:
+ data["description"] = description
+ if state_event is not None:
+ data["state_event"] = state_event
+ if labels is not None:
+ data["labels"] = labels
+ if assignee_ids is not None:
+ data["assignee_ids"] = assignee_ids
+ if milestone_id is not None:
+ data["milestone_id"] = milestone_id
+ data.update(kwargs)
+ return server.update_issue(project, issue_iid, **data)
+
+ @mcp.tool()
def get_mr_diff(
project: str,
mr_iid: int,
@@ -489,6 +574,48 @@ def create_server(host: str = "127.0.0.1", port: int = 8080) -> FastMCP:
data.update(kwargs)
return server.create_epic(group, title, description, **data)
+ @mcp.tool()
+ def update_epic(
+ group: str,
+ epic_iid: int,
+ working_directory: str,
+ title: str | None = None,
+ description: str | None = None,
+ state_event: str | None = None,
+ labels: list[str] | None = None,
+ parent_id: int | None = None,
+ color: str | None = None,
+ confidential: bool | None = None,
+ start_date_fixed: str | None = None,
+ due_date_fixed: str | None = None,
+ **kwargs: object
+ ) -> dict[str, Any]:
+ """Update an existing GitLab epic."""
+ server = GitLabPythonServer(working_directory)
+ data = {}
+ if title is not None:
+ data["title"] = title
+ if description is not None:
+ data["description"] = description
+ if state_event is not None:
+ data["state_event"] = state_event
+ if labels is not None:
+ data["labels"] = labels
+ if parent_id is not None:
+ data["parent_id"] = parent_id
+ if color is not None:
+ data["color"] = color
+ if confidential is not None:
+ data["confidential"] = confidential
+ if start_date_fixed is not None:
+ data["start_date_fixed"] = start_date_fixed
+ data["start_date_is_fixed"] = True
+ if due_date_fixed is not None:
+ data["due_date_fixed"] = due_date_fixed
+ data["due_date_is_fixed"] = True
+ data.update(kwargs)
+ return server.update_epic(group, epic_iid, **data)
+
return mcp
async def main(transport_type: str, host: str, port: int) -> None: