From ea094d5731ae36db599b9a9803c41db303fc685a Mon Sep 17 00:00:00 2001 From: Dawid Rycerz Date: Tue, 15 Jul 2025 17:36:46 +0300 Subject: feat: Add updates issues and epics functinoality --- .../src/mcp_server_gitlab_python/server.py | 127 +++++++++++++++++++++ 1 file changed, 127 insertions(+) (limited to 'servers/gitlab_python/src/mcp_server_gitlab_python') 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) @@ -390,6 +444,37 @@ def create_server(host: str = "127.0.0.1", port: int = 8080) -> FastMCP: data.update(kwargs) 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, @@ -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: -- cgit v1.2.3