# GitLab CLI MCP Server This MCP server provides integration with GitLab through the GitLab CLI (`glab`) tool. It allows LLM agents to interact with GitLab repositories and resources using the GitLab API. ## Features - Check if the GitLab CLI is available and accessible - Find GitLab projects by name and retrieve their IDs - Search for GitLab issues with various filters - Create new GitLab issues - Get merge request diffs with automatic handling of large diffs - Run CI/CD pipelines with support for variables and web mode - More features to be added in the future ## Prerequisites - Python 3.11 or higher - GitLab CLI (`glab`) installed and accessible in the system PATH - GitLab account with proper authentication set up via `glab auth login` ## Installation ```bash # Clone the repository git clone https://codeberg.org/knightdave/dawids-mcp-servers.git cd dawids-mcp-servers ``` ## Usage ### Running from repository root (recommended) ```bash # Run with stdio transport (for MCP client integration) uv --directory /path-to-repo/dawids-mcp-servers/servers/gitlab_glab run mcp-gitlab-glab --transport stdio # Run with remote transport uv --directory /path-to-repo/dawids-mcp-servers/servers/gitlab_glab run mcp-gitlab-glab --transport remote --host 0.0.0.0 --port 8080 ``` Replace `/path-to-repo` with the actual path to where you cloned this repository. ### Alternative: Running from server directory ```bash cd servers/gitlab_glab # Run with stdio transport uv run mcp-gitlab-glab --transport stdio # Run with remote transport uv run mcp-gitlab-glab --transport remote --host 0.0.0.0 --port 8080 ``` ## Available Tools ### check_glab_availability Checks if the GitLab CLI tool is installed and accessible. ```python result = use_mcp_tool( server_name="gitlab_glab", tool_name="check_glab_availability", arguments={ "working_directory": "/path/to/current/directory" } ) ``` ### find_project Finds GitLab projects by name and returns their details. ```python result = use_mcp_tool( server_name="gitlab_glab", tool_name="find_project", arguments={ "project_name": "my-project", "working_directory": "/path/to/current/directory" } ) ``` The function returns a list of matching projects, each containing the following fields: - `id`: The project ID - `name`: The project name - `path_with_namespace`: The project path with namespace - `web_url`: The project web URL - `description`: The project description ### search_issues Search for GitLab issues with various filters. ```python result = use_mcp_tool( server_name="gitlab_glab", tool_name="search_issues", arguments={ "working_directory": "/path/to/current/directory", # Optional filters "author": "username", # Filter by author "assignee": "username", # Filter by assignee "closed": True, # Get only closed issues "confidential": True, # Filter by confidential issues "group": "group-name", # Select a group or subgroup "issue_type": "issue", # Filter by type: issue, incident, test_case "iteration": 123, # Filter by iteration ID "label": ["bug", "critical"], # Filter by labels "milestone": "v1.0", # Filter by milestone "not_assignee": "username", # Filter by not being assigned to "not_author": "username", # Filter by not being authored by "not_label": ["wontfix"], # Filter by lack of labels "page": 1, # Page number (default: 1) "per_page": 30, # Items per page (default: 30) "project": "group/project" # Project path with namespace } ) ``` The function returns a dictionary containing: - `issues`: A list of issues, each with: - `id`: The issue ID - `iid`: The internal issue ID - `title`: The issue title - `web_url`: The issue URL - `state`: The issue state (opened/closed) - `created_at`: Creation timestamp - `updated_at`: Last update timestamp - `error`: Error message if the operation failed ### create_issue Creates a new GitLab issue and returns its URL. ```python result = use_mcp_tool( server_name="gitlab_glab", tool_name="create_issue", arguments={ "title": "Issue title", "description": "Issue description", "working_directory": "/path/to/current/directory", # Optional parameters "labels": ["bug", "critical"], # List of labels "assignee": ["username1", "username2"], # List of usernames "milestone": "v1.0", # Milestone title or ID "epic_id": 123, # Epic ID "project": "group/project" # Project path with namespace } ) ``` The function returns a dictionary containing: - `url`: The URL of the created issue - `error`: Error message if the operation failed ### get_mr_diff Get the diff for a merge request using `glab mr diff` with optional content filtering. ```python result = use_mcp_tool( server_name="gitlab_glab", tool_name="get_mr_diff", arguments={ "working_directory": "/path/to/current/directory", # Optional parameters "mr_id": "123", # MR ID or branch name (if None, uses current branch) "color": "never", # Use color in diff output: always, never, auto (default: never) "raw": True, # Use raw diff format (default: False) "repo": "group/project", # Project path with namespace "max_size_kb": 100, # Maximum size in KB before saving to temp file (default: 100) "filter_extensions": [".lock", ".log"] # File extensions to exclude from diff (default: [".lock", ".log"]) } ) ``` The function returns a dictionary containing: - `diff`: The diff content (if small enough) - `size_kb`: The size of the diff in KB - `temp_file_path`: Path to temporary file if diff is too large (None otherwise) - `diff_too_large`: Boolean indicating if diff was saved to temp file - `max_size_kb`: The configured maximum size threshold - `message`: Human-readable message about temp file creation (if applicable) - `error`: Error message if the operation failed **Content Filtering**: By default, this tool filters out changes to files with `.lock` and `.log` extensions to reduce noise in diffs. This includes: - Lock files: `package-lock.json`, `yarn.lock`, `composer.lock`, etc. - Log files: `debug.log`, `error.log`, `application.log`, etc. You can customize the filtering by providing a `filter_extensions` list, or disable filtering entirely by passing an empty list `[]`. **Note on Large Diffs**: To prevent overwhelming LLMs with extremely large diffs, this tool automatically saves diffs larger than `max_size_kb` (default: 100KB) to a temporary file and returns the file path instead of the content. This allows you to process large merge request diffs without hitting token limits. ### run_ci_pipeline Run a CI/CD pipeline on GitLab using `glab ci run`. ```python result = use_mcp_tool( server_name="gitlab_glab", tool_name="run_ci_pipeline", arguments={ "working_directory": "/path/to/current/directory", # Optional parameters "branch": "main", # Branch/ref to run pipeline on (if None, uses current branch) "variables": ["VAR1:value1", "VAR2:value2"], # Variables in key:value format "variables_env": ["ENV1:envval1"], # Environment variables in key:value format "variables_file": ["FILE1:file1.txt"], # File variables in key:filename format "variables_from": "/path/to/vars.json", # JSON file containing variables "web_mode": True, # Enable web mode (sets CI_PIPELINE_SOURCE=web) "repo": "group/project" # Project path with namespace } ) ``` The function returns a dictionary containing: - `success`: Boolean indicating if the pipeline was created successfully - `output`: The full command output from glab - `branch`: The branch the pipeline was created on - `web_mode`: Boolean indicating if web mode was used - `pipeline_url`: The URL of the created pipeline (if found in output) - `error`: Error message if the operation failed **Branch Detection**: If no `branch` is specified, the tool will automatically detect the current git branch using `git branch --show-current`. If branch detection fails, the pipeline will be created without specifying a branch (uses GitLab's default behavior). **Web Mode**: When `web_mode` is set to `True`, the tool adds `CI_PIPELINE_SOURCE:web` as an environment variable, which allows the pipeline to run with web-triggered behavior and access to manual pipeline features. ## Working Directory Context All tools require a `working_directory` parameter that specifies the directory context in which the GitLab CLI commands should be executed. This ensures that commands are run in the same directory as the agent, maintaining proper context for repository operations. The working directory should be the absolute path to the directory where you want the GitLab CLI commands to be executed. For example, if you're working with a GitLab repository cloned to `/home/user/projects/my-repo`, you would pass that path as the `working_directory` parameter. ## Development ### Running tests ```bash cd servers/gitlab_glab uv run pytest ``` ### Running tests with coverage ```bash cd servers/gitlab_glab uv run pytest --cov=mcp_server_gitlab_glab ``` ## License This project is licensed under the MIT License - see the LICENSE file for details.