summaryrefslogtreecommitdiff
path: root/servers/gitlab_glab/src/mcp_server_gitlab_glab
diff options
context:
space:
mode:
Diffstat (limited to 'servers/gitlab_glab/src/mcp_server_gitlab_glab')
-rw-r--r--servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py126
1 files changed, 126 insertions, 0 deletions
diff --git a/servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py b/servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py
index d3fd074..881228f 100644
--- a/servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py
+++ b/servers/gitlab_glab/src/mcp_server_gitlab_glab/server.py
@@ -11,6 +11,7 @@ import os
import re
import subprocess
import sys
+import tempfile
from typing import Any
from mcp.server.fastmcp import FastMCP
@@ -309,6 +310,98 @@ class GitLabServer:
logger.error(f"Failed to extract issue URL from output: {result}")
return {"error": "Failed to extract issue URL from command output"}
+ def get_mr_diff(
+ self,
+ working_directory: str,
+ mr_id: str | None = None,
+ color: str = "never",
+ raw: bool = False,
+ repo: str | None = None,
+ max_size_kb: int = 100,
+ ) -> dict[str, Any]:
+ """Get the diff for a merge request.
+
+ Args:
+ working_directory: The directory to execute the command in.
+ mr_id: The merge request ID or branch name. If None, uses current branch.
+ color: Use color in diff output: always, never, auto (default: never).
+ raw: Use raw diff format that can be piped to commands.
+ repo: Select another repository (OWNER/REPO or GROUP/NAMESPACE/REPO format).
+ max_size_kb: Maximum size in KB before saving to temporary file
+ (default: 100).
+
+ Returns:
+ A dictionary containing the diff content or a path to temporary file
+ if too large.
+ """
+ # Build command arguments
+ args = ["mr", "diff"]
+
+ # Add MR ID or branch if specified
+ if mr_id:
+ args.append(mr_id)
+
+ # Add color option
+ if color in ["always", "never", "auto"]:
+ args.extend(["--color", color])
+
+ # Add raw option
+ if raw:
+ args.append("--raw")
+
+ # Add repo option
+ if repo:
+ args.extend(["-R", repo])
+
+ # Execute the command
+ success, result = self.execute_glab_command(args, working_directory)
+
+ if not success:
+ return result
+
+ # Check if the diff is too large
+ diff_content = result
+ diff_size_kb = len(diff_content.encode('utf-8')) / 1024
+
+ if diff_size_kb > max_size_kb:
+ try:
+ # Create a temporary file to store the large diff
+ with tempfile.NamedTemporaryFile(
+ mode='w',
+ suffix='.diff',
+ prefix='mr_diff_',
+ delete=False,
+ encoding='utf-8'
+ ) as temp_file:
+ temp_file.write(diff_content)
+ temp_path = temp_file.name
+
+ return {
+ "diff_too_large": True,
+ "size_kb": round(diff_size_kb, 2),
+ "max_size_kb": max_size_kb,
+ "temp_file_path": temp_path,
+ "message": (
+ f"Diff is too large ({diff_size_kb:.2f} KB > "
+ f"{max_size_kb} KB). Content saved to temporary file: "
+ f"{temp_path}"
+ )
+ }
+ except Exception as e:
+ logger.error(f"Failed to create temporary file: {str(e)}")
+ return {
+ "error": (
+ f"Diff is too large ({diff_size_kb:.2f} KB) and failed to "
+ f"create temporary file: {str(e)}"
+ )
+ }
+
+ return {
+ "diff": diff_content,
+ "size_kb": round(diff_size_kb, 2),
+ "temp_file_path": None
+ }
+
def create_server(host: str = "127.0.0.1", port: int = 8080) -> FastMCP:
"""Create and configure the FastMCP server.
@@ -455,6 +548,39 @@ def create_server(host: str = "127.0.0.1", port: int = 8080) -> FastMCP:
project=project,
)
+ @mcp.tool()
+ def get_mr_diff(
+ working_directory: str,
+ mr_id: str | None = None,
+ color: str = "never",
+ raw: bool = False,
+ repo: str | None = None,
+ max_size_kb: int = 100,
+ ) -> dict[str, Any]:
+ """Get the diff for a merge request.
+
+ Args:
+ working_directory: The directory to execute the command in.
+ mr_id: The merge request ID or branch name. If None, uses current branch.
+ color: Use color in diff output: always, never, auto (default: never).
+ raw: Use raw diff format that can be piped to commands.
+ repo: Select another repository (OWNER/REPO or GROUP/NAMESPACE/REPO format).
+ max_size_kb: Maximum size in KB before saving to temporary file
+ (default: 100).
+
+ Returns:
+ A dictionary containing the diff content or a path to temporary file
+ if too large.
+ """
+ return gitlab.get_mr_diff(
+ working_directory=working_directory,
+ mr_id=mr_id,
+ color=color,
+ raw=raw,
+ repo=repo,
+ max_size_kb=max_size_kb,
+ )
+
return mcp