A Model Context Protocol (MCP) server that provides GitLab API integration with per-user authentication, enabling AI models to seamlessly interact with GitLab repositories, merge requests, issues, and project data.
Model Context Protocol (MCP) is an open protocol developed by Anthropic that enables AI applications to securely access external data sources and tools. MCP acts as a bridge between AI models and various services, allowing models to:
- Access External Data: Read files, fetch information from APIs, query databases
- Execute Tools: Perform actions like creating tickets, running scripts, or modifying data
- Maintain Context: Keep relevant information available during conversations
- Ensure Security: Provide controlled, authenticated access to resources
- Servers: Applications that provide resources and tools (like this GitLab server)
- Clients: AI applications that consume MCP servers (Claude, ChatGPT, etc.)
- Tools: Functions that can be called to perform specific actions
- Resources: Data sources that can be read or subscribed to
- Transports: Communication methods (HTTP, WebSocket, stdio)
GitLab is a comprehensive DevOps platform that provides Git repository management, CI/CD pipelines, issue tracking, and project management. The GitLab API is a RESTful API that allows programmatic access to:
- Repositories: Source code, files, branches, commits, tags
- Merge Requests: Code reviews, approvals, discussions, changes
- Issues: Bug tracking, feature requests, project planning
- Projects: Metadata, settings, members, permissions
- CI/CD: Pipelines, jobs, artifacts, deployments
- Wiki & Documentation: Project documentation and knowledge base
- Comprehensive: Access to all GitLab features programmatically
- RESTful Design: Standard HTTP methods and status codes
- Authentication: Personal access tokens, OAuth2, JWT
- Rate Limiting: Built-in protection against abuse
- Webhooks: Real-time notifications for events
This server bridges MCP and GitLab API to enable powerful AI-assisted development workflows:
- Code Understanding: Read and analyze source code from repositories
- Context Awareness: Access project structure, commit history, and documentation
- Code Reviews: Analyze merge requests, suggest improvements, check compliance
- Issue Intelligence: Understand project issues, bugs, and feature requests
- Project Insights: Gather metrics, track progress, analyze development patterns
- AI-Powered Code Review: Get intelligent feedback on merge requests
- Automated Documentation: Generate docs from code and project structure
- Smart Issue Triage: Classify and prioritize issues with AI assistance
- Code Quality Analysis: AI-driven code quality assessments
- Project Planning: AI insights for sprint planning and resource allocation
- Development Intelligence: AI analysis of development patterns and bottlenecks
- Compliance Checking: Automated verification of coding standards and policies
- Knowledge Management: AI-powered search and discovery across projects
- Security Analysis: AI-assisted security review and vulnerability detection
- Multi-Instance Support: Seamless access to multiple GitLab instances (public, self-hosted, different teams)
- 🔐 Per-User Authentication: Each user provides their own GitLab token
- 🌐 Multi-Instance Support: Optional per-request GitLab base URL parameter for multiple GitLab instances
- 📖 Code Reading: Read file contents from GitLab repositories
- 🗂️ Repository Browsing: List files and directories with recursive support
- 🔄 Merge Request Management: Get detailed MR information and file changes
- 🎯 Issue Tracking: List and view detailed issue information
- 📊 Project Information: Access comprehensive project metadata
- 🌿 Branch Management: List and search repository branches
- 💾 Commit Analysis: Get commit information with optional diff viewing
- 🔍 Project Search: Search across accessible GitLab projects
- ✅ MCP 2024-11-05: Latest MCP protocol specification
- 🔌 Multiple Transports: HTTP POST and WebSocket connections
- 🛠️ Rich Tools: 10 different GitLab tools with comprehensive schemas
- 📋 Tool Discovery: Dynamic tool listing with parameter schemas
- ⚡ Real-time: WebSocket support for real-time interactions
- 🛡️ Secure Authentication: Multiple auth methods with token validation
- 👥 Multi-user Support: Concurrent users with isolated permissions
- 🔒 No Token Storage: Tokens never stored or logged server-side
- 🎭 Permission Isolation: Each user operates within their GitLab permissions
- 🚀 Scalable: Handles multiple concurrent requests safely
- 🌍 Multi-Instance: Support for multiple GitLab instances per user/request
- Build the server:
go build -o gitlab-mcp-server- Start the server:
# Basic environment variables
export GITLAB_BASE_URL="https://gitlab.com" # Default GitLab instance
export PORT="8080" # Server port
export GITLAB_TOKEN="your-optional-token" # Optional server token
# SSL Configuration (for self-signed certificates)
export VERIFY_SSL="false" # Disable SSL verification
# Start server
./gitlab-mcp-server- Use with your GitLab token:
HTTP Example:
curl -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer your-gitlab-token" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'WebSocket Example:
# Connect to WebSocket with token
ws://localhost:8080/ws?token=your-gitlab-token🔐 All API endpoints require authentication - users must provide their GitLab personal access token with each request.
Authorization: Bearer <your-gitlab-token>X-GitLab-Token: <your-gitlab-token>
- Query parameter:
ws://localhost:8080/ws?token=<your-gitlab-token> - Subprotocol:
Sec-WebSocket-Protocol: gitlab-token-<your-gitlab-token>
Your GitLab personal access token needs these scopes:
read_api- Access the authenticated user's APIread_repository- Read repository files and metadataread_user- Read user information
Optional configuration via environment variables or YAML:
server:
port: "8080"
gitlab:
base_url: "https://gitlab.com" # Default base URL used when not specified per-request
# token: "optional-server-token-for-testing"GITLAB_BASE_URL: Default GitLab base URL (default: https://gitlab.com)PORT: Server port (default: 8080)GITLAB_TOKEN: Optional server token for testing connection
The server supports multiple GitLab instances through two approaches:
- Server Default: Configure a default GitLab base URL that applies to all requests
- Per-Request Override: Specify
gitlab_base_urlparameter in individual tool calls
Each tool call can optionally include a gitlab_base_url parameter to override the server default:
{
"name": "read_file",
"arguments": {
"project_id": "group/project",
"file_path": "README.md",
"gitlab_base_url": "https://gitlab.example.com"
}
}This allows users to:
- Access multiple GitLab instances from the same server
- Switch between gitlab.com and self-hosted instances
- Use different instances for different projects or teams
- Maintain separate authentication tokens for each instance
Each tool follows MCP protocol specifications with detailed parameter schemas:
All tools support these common parameters:
gitlab_base_url(optional) - The GitLab base URL (e.g., 'https://gitlab.com' or 'https://gitlab.example.com'). If not provided, uses the server default.
read_file- Read file contents from repositories with branch/tag supportlist_files- Browse repository structure with recursive listing options
get_merge_request- Get detailed MR info with optional file changeslist_merge_requests- List project MRs with state filtering
list_issues- List project issues with state and limit optionsget_issue- Get detailed issue information with descriptions
get_project_info- Access comprehensive project metadatasearch_projects- Search across accessible projectslist_branches- List repository branches with search capability
get_commit- Get commit details with optional diff inclusion
{
"initialize": "Establish connection and exchange capabilities",
"tools/list": "Discover available GitLab tools",
"tools/call": "Execute specific GitLab operations",
"ping": "Health check and connectivity test"
}{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": {
"project_id": "group/project",
"file_path": "src/main.py",
"ref": "develop"
}
}
}{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "read_file",
"arguments": {
"project_id": "group/project",
"file_path": "src/main.py",
"ref": "develop",
"gitlab_base_url": "https://gitlab.example.com"
}
}
}{
"jsonrpc": "2.0",
"id": 1,
"result": {
"content": [
{
"type": "text",
"text": "File: src/main.py (ref: develop)\n\n#!/usr/bin/env python3\n..."
}
]
}
}- WebSocket:
ws://localhost:8080/ws?token=<your-gitlab-token> - HTTP:
http://localhost:8080/mcp(with Authorization header) - Health:
http://localhost:8080/health(no auth required) - Info:
http://localhost:8080/(no auth required)
# Get merge request with changes for AI analysis
curl -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer your-gitlab-token" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"tools/call",
"params":{
"name":"get_merge_request",
"arguments":{
"project_id":"mygroup/myproject",
"merge_request_iid":42,
"include_changes":true
}
}
}'# Access a self-hosted GitLab instance
curl -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer your-enterprise-gitlab-token" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"tools/call",
"params":{
"name":"read_file",
"arguments":{
"project_id":"enterprise/internal-project",
"file_path":"config/production.yaml",
"gitlab_base_url":"https://gitlab.company.com"
}
}
}'# List project structure for documentation
curl -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer your-gitlab-token" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"tools/call",
"params":{
"name":"list_files",
"arguments":{
"project_id":"mygroup/myproject",
"recursive":true,
"ref":"main"
}
}
}'# Get issues for AI-powered analysis
curl -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer your-gitlab-token" \
-H "Content-Type: application/json" \
-d '{
"jsonrpc":"2.0",
"id":1,
"method":"tools/call",
"params":{
"name":"list_issues",
"arguments":{
"project_id":"mygroup/myproject",
"state":"opened",
"limit":50
}
}
}'make build # Build binary
make run # Run development server
make test # Run tests
make config # Generate config file
make help # Show all commands# Test the authentication system
./test/test_auth.sh
# Test with real GitLab token
export GITLAB_TOKEN='your-real-gitlab-token'
./test/test_auth.sh real- ✅ Per-request authentication - no tokens stored server-side
- ✅ Token validation - GitLab tokens validated on each request
- ✅ User isolation - each user uses their own GitLab permissions
- ✅ Secure transport - supports HTTPS and WSS
- ✅ No token persistence - tokens are not logged or stored
- ✅ Rate limiting ready - can be integrated with reverse proxies
- ✅ Audit trail - request logging without sensitive data
- Runtime: Go 1.21+
- Authentication: GitLab personal access token with required scopes
- Network: Access to your GitLab instance (gitlab.com or self-hosted)
- MCP Client: Compatible AI application or MCP client
The server supports multiple users simultaneously, each with their own GitLab token:
- No shared state between users
- Permission isolation - each user sees only their accessible projects
- GitLab API enforcement - user permissions enforced by GitLab
- Concurrent requests handled safely with per-user authentication
- Scalable architecture - can handle many simultaneous connections
Authentication Failed
- Verify your GitLab token is valid and has required scopes
- Check if token has access to the specified project
- Ensure GitLab base URL is correct for your instance
- For custom instances, verify the
gitlab_base_urlparameter is properly formatted
Connection Issues
- Verify network connectivity to GitLab instance
- Check firewall settings for outbound HTTPS connections
- Confirm GitLab instance is accessible from server
- For self-hosted instances, ensure the URL is reachable and uses HTTPS
- For SSL certificate issues with self-signed certificates, set
VERIFY_SSL=false
SSL Certificate Errors
- If you see "certificate verify failed" errors with self-hosted GitLab instances
Recommended Solution - Import CA Certificate:
Step 1: Extract Certificate from GitLab Instance:
# Extract certificate from your GitLab instance
echo | openssl s_client -connect gitlab.company.com:443 -servername gitlab.company.com 2>/dev/null | openssl x509 -outform PEM > gitlab-ca.crt
# Verify the certificate was extracted correctly
openssl x509 -in gitlab-ca.crt -text -noout | grep "Subject:"
# Check certificate details
openssl x509 -in gitlab-ca.crt -text -noout | head -20Step 2: Install Certificate (Choose your OS):
macOS:
# Method 1: Using Keychain Access GUI
# 1. Download your GitLab instance's CA certificate (.crt or .pem file)
# 2. Double-click the certificate file to open Keychain Access
# 3. Select "System" keychain and click "Add"
# 4. Find the certificate, double-click it, expand "Trust"
# 5. Set "Secure Sockets Layer (SSL)" to "Always Trust"
# Method 2: Using command line
# Download the CA certificate first
curl -k https://gitlab.company.com/path/to/ca-cert.crt -o gitlab-ca.crt
# Import to system keychain
sudo security add-trusted-cert -d -r trustRoot -k /Library/Keychains/System.keychain gitlab-ca.crt
# Or import to user keychain
security add-trusted-cert -d -r trustRoot -k ~/Library/Keychains/login.keychain gitlab-ca.crtUbuntu/Linux:
# Download the CA certificate
curl -k https://gitlab.company.com/path/to/ca-cert.crt -o gitlab-ca.crt
# Copy to system CA directory
sudo cp gitlab-ca.crt /usr/local/share/ca-certificates/gitlab-ca.crt
# Update CA certificates
sudo update-ca-certificates
# Verify the certificate was added
ls /etc/ssl/certs/ | grep gitlabStep 3: Use Certificate with GitLab MCP Server:
# Option 1: Use extracted certificate directly
export CA_CERT_FILE="./gitlab-ca.crt"
./gitlab-mcp-server
# Option 2: Use in configuration file
cat > config.yaml <<EOF
gitlab:
base_url: "https://gitlab.company.com"
verify_ssl: true
ca_cert_file: "./gitlab-ca.crt"
EOF
./gitlab-mcp-server -config config.yaml
# Option 3: Use system certificate store (after installing above)
# No additional configuration needed - will use system certificates
./gitlab-mcp-serverAlternative - Custom CA Bundle (Recommended):
# Set custom CA bundle path
export SSL_CERT_FILE="/path/to/your/ca-bundle.pem"
export SSL_CERT_DIR="/path/to/your/ca-certificates/"
export CA_BUNDLE="/path/to/your/ca-bundle.pem"
./gitlab-mcp-serverLast Resort - Disable SSL Verification:
- Set
VERIFY_SSL=falsein environment variables or configuration file - Example:
export VERIFY_SSL=falseor addverify_ssl: falseto config.yaml ⚠️ Warning: This disables SSL certificate verification entirely and should only be used in development
Permission Denied
- Ensure your GitLab token has access to the requested project
- Check project visibility settings (private/internal/public)
- Verify token scopes include necessary permissions
- For multi-instance setups, confirm the token is valid for the specified GitLab instance
Multi-Instance Issues
- Verify the
gitlab_base_urlparameter uses the correct format (e.g., https://gitlab.example.com) - Ensure the GitLab token has access to the specified instance
- Check that the custom GitLab instance is accessible from the server
- Confirm API compatibility with the GitLab instance version
# Enable debug logging
GITLAB_DEBUG=true ./gitlab-mcp-serverWe welcome contributions! Please see our contributing guide for:
- Code style guidelines
- Testing requirements
- Pull request process
- Issue reporting
This project is licensed under the MIT License - see LICENSE file for details.
A comprehensive Python client is available in the python-client/ directory that integrates with DeepSeek API for AI-powered code reviews:
- 🤖 AI Code Reviews: Powered by DeepSeek's advanced language models
- 📊 Multiple Review Types: Security, performance, best practices, bug detection
- 🔄 Comprehensive Coverage: Review files, merge requests, commits, and entire projects
- 🌐 Multi-Instance Support: Works with multiple GitLab instances
- 📋 Flexible Output: Markdown, JSON, and text formats
# Setup
cd python-client
pip install -r requirements.txt
# Configure using .env file (recommended)
cp env.example .env
# Edit .env with your GitLab token and LLM API key
# Start web app (recommended)
python run_web_app.py
# Open http://localhost:3000
# Or use examples
./run_examples.sh setup
./run_examples.sh merge-requestSee python-client/README.md for detailed documentation.
- Model Context Protocol - Official MCP specification
- GitLab API Documentation - Complete GitLab API reference
- go-gitlab - Go GitLab API client library
- MCP Servers - Official MCP server implementations
- DeepSeek API - DeepSeek AI API for code analysis
For support and questions:
- 📖 Documentation: Check this README and inline code documentation
- 🐛 Issues: Report bugs and request features via GitHub Issues
- 💬 Discussions: Ask questions in GitHub Discussions
- 🔧 Testing: Use
./test/test_auth.shto verify your setup
Made with ❤️ for the AI and DevOps communities