- Overview
- Prerequisites
- Installation
- Configuration
- Usage with Claude Code
- Common Workflows
- Advanced Examples
- Troubleshooting
- Security Best Practices
The GitLab MCP (Model Context Protocol) Server enables Claude Code to interact directly with your GitLab repositories. This integration allows you to perform code reviews, manage branches, push code, and execute other GitLab operations directly from your conversation with Claude.
Key capabilities:
- Review merge requests and provide feedback
- Create and manage branches
- Push code changes to remote repositories
- Query repository information
- Manage issues and merge requests
- Interact with GitLab CI/CD pipelines
Before installing the GitLab MCP server, ensure you have:
-
Node.js and npm (version 14 or higher)
node --version # Should be v14.0.0 or higher npm --version # Should be 6.0.0 or higher
-
GitLab Account with access to the repositories you want to work with
-
GitLab Personal Access Token with appropriate scopes:
api- Full API accessread_repository- Read repository datawrite_repository- Write repository dataread_user- Read user information
-
Claude Code CLI installed and configured
The GitLab MCP server is installed automatically when Claude Code starts, using npx to run the latest version. No manual installation is required.
The configuration in .mcp.json tells Claude Code to:
- Use
npxto download and run the latest version of@luiscusihuaman/gitlab-mcp-server - Pass environment variables for authentication
- Establish a connection between Claude and your GitLab instance
To verify the server is working, you can ask Claude:
"List my GitLab projects"
If configured correctly, Claude will return a list of your accessible GitLab repositories.
- Log in to your GitLab instance
- Navigate to User Settings > Access Tokens
- Click Add new token
- Configure the token:
- Token name:
Claude Code MCP - Expiration date: Set according to your security policy
- Scopes: Select the following:
apiread_repositorywrite_repositoryread_user
- Token name:
- Click Create personal access token
- Important: Copy the token immediately - you won't be able to see it again
Create or update your .env file in the workspace root:
# GitLab Configuration
GITLAB_URL=https://gitlab.com
GITLAB_PERSONAL_ACCESS_TOKEN=your-personal-access-token-hereFor self-hosted GitLab instances, replace the URL:
GITLAB_URL=https://gitlab.yourcompany.com
GITLAB_PERSONAL_ACCESS_TOKEN=your-personal-access-token-hereThe .mcp.json file should contain the following configuration:
{
"mcpServers": {
"gitlab": {
"command": "npx",
"args": ["-y", "@luiscusihuaman/gitlab-mcp-server"],
"env": {
"GITLAB_URL": "${GITLAB_URL}",
"GITLAB_PERSONAL_ACCESS_TOKEN": "${GITLAB_PERSONAL_ACCESS_TOKEN}"
}
}
}
}Configuration breakdown:
command: Usesnpxto run the package without global installationargs:-y: Automatically accepts prompts@luiscusihuaman/gitlab-mcp-server: The npm package to run
env: Environment variables passed to the server${GITLAB_URL}: Replaced with value from your.envfile${GITLAB_PERSONAL_ACCESS_TOKEN}: Replaced with your token from.env
After configuration, restart Claude Code to load the new environment variables:
# Exit current session and restart
claudeOnce configured, Claude can interact with GitLab through natural language commands. The MCP server translates your requests into GitLab API calls.
- Ask Claude to perform a GitLab operation
- Claude analyzes your request and determines the appropriate GitLab API calls
- Claude executes the operation via the MCP server
- Claude reports the results back to you
You: "Show me all open merge requests in the project 'myapp'"
You: "Create a new branch called 'feature/user-authentication' from main"
You: "Review the merge request #42 in the 'backend-api' project"
You: "Push my local changes to the remote branch 'feature/payment-integration'"
Code review is one of the most powerful use cases for the GitLab MCP integration. Claude can analyze merge requests, provide feedback, and suggest improvements.
You: "Review merge request #23 in the 'frontend-app' project"
What Claude does:
- Fetches the merge request details
- Retrieves the diff/changes
- Analyzes the code for:
- Code quality issues
- Potential bugs
- Security vulnerabilities
- Best practice violations
- Documentation needs
- Provides structured feedback
Example output:
I've reviewed merge request #23 "Add user authentication". Here's my analysis:
Strengths:
- Well-structured authentication flow
- Good error handling in login component
- Comprehensive test coverage
Concerns:
1. Security: Password stored in plain text in component state (line 45)
Recommendation: Use a secure state management solution
2. Performance: Multiple unnecessary re-renders in AuthContext
Recommendation: Memoize the context value
3. Code Quality: Magic numbers in token expiration (line 78)
Recommendation: Extract to configuration constant
Would you like me to provide code snippets for these fixes?
You: "Review all open merge requests in my current project and prioritize them by importance"
What Claude does:
- Lists all open merge requests
- Analyzes each for complexity and impact
- Provides a prioritized summary
You: "Add a comment to merge request #23 suggesting that we extract the authentication logic into a custom hook"
What Claude does:
- Locates the merge request
- Posts your comment with proper formatting
- Confirms the action
You: "Create a new branch called 'feature/dark-mode' from the main branch in project 'frontend-app'"
What Claude does:
- Verifies the source branch exists
- Creates the new branch
- Confirms creation with branch details
Best practice example:
You: "I'm about to work on adding a dark mode feature. Create an appropriate branch following our naming conventions"
Claude will:
- Analyze your repository's branching patterns
- Suggest a branch name following your conventions (e.g.,
feature/dark-mode) - Create the branch from the appropriate base
- Provide next steps for local checkout
You: "Show me all branches in the 'backend-api' project"
Example output:
Active branches in 'backend-api':
Main branches:
- main (protected)
- develop (protected)
Feature branches:
- feature/payment-gateway (last updated 2 days ago)
- feature/user-roles (last updated 1 week ago)
Bugfix branches:
- bugfix/memory-leak (last updated 3 days ago)
Stale branches (no updates in 30+ days):
- feature/old-experiment (90 days ago)
Would you like me to suggest branches for cleanup?
You: "Delete the branch 'feature/old-experiment' as it's no longer needed"
What Claude does:
- Checks if the branch has been merged
- Warns if the branch hasn't been merged
- Deletes the branch after confirmation
- Confirms deletion
You: "Push my current branch to GitLab"
What Claude does:
- Detects your current branch name
- Checks for uncommitted changes
- Pushes to the remote repository
- Provides the branch URL for creating a merge request
Important note: Claude needs to work with your local Git repository. Ensure your current working directory is a Git repository.
You: "Push my changes to GitLab and create a merge request to main"
What Claude does:
- Pushes the current branch
- Creates a merge request with:
- Appropriate title (based on branch name or recent commits)
- Description (summarizing changes)
- Target branch set to main
- Proper labels and assignees (if configured)
- Provides the merge request URL
Example interaction:
You: "I've finished implementing the dark mode feature. Push the code and create a merge request."
Claude: "I'll help you push your changes and create a merge request. Let me analyze your commits first."
[Claude analyzes commits]
Claude: "I found 8 commits related to dark mode implementation:
- Add dark mode toggle component
- Implement theme context
- Update color scheme variables
- Add dark mode styles to main components
- Add tests for theme switching
- Update documentation
- Fix contrast issues
- Add user preference persistence
Pushing to remote branch 'feature/dark-mode'...
✓ Branch pushed successfully
Creating merge request...
✓ Merge request #45 created: 'Add dark mode feature'
Title: Add dark mode feature
Target: main
URL: https://gitlab.com/yourorg/frontend-app/-/merge_requests/45
I've included:
- Summary of all 8 commits
- Screenshots from your recent work
- Testing checklist
- Closes #123 (dark mode issue)
Would you like me to assign reviewers?"
You: "I rebased my feature branch on main. Force push to update the remote branch."
What Claude does:
- Warns about force pushing and its implications
- Confirms this is what you want to do
- Executes force push with lease (safer than regular force push)
- Confirms completion
Claude's warning:
⚠️ Force pushing will overwrite remote history. This affects:
- Any team members working on this branch
- Open merge requests pointing to this branch
I recommend force push with lease (--force-with-lease) which is safer.
Proceed? (yes/no)
You: "Before merging MR #42, perform a comprehensive review including code quality, security, performance, and test coverage"
What Claude does:
- Fetches the complete merge request
- Analyzes code changes across multiple dimensions:
- Security: Scans for vulnerabilities, injection risks, authentication issues
- Performance: Identifies inefficient patterns, N+1 queries, memory leaks
- Code Quality: Checks formatting, naming conventions, code complexity
- Test Coverage: Analyzes test files and coverage
- Documentation: Verifies comments, README updates, API docs
- Provides a detailed report with severity levels
- Suggests specific improvements with code examples
You: "Identify all stale branches (no updates in 60+ days) that have been merged and create a cleanup plan"
What Claude does:
- Lists all branches with last commit dates
- Filters for branches older than 60 days
- Checks merge status for each branch
- Provides a categorized list:
- Safe to delete (merged)
- Review needed (not merged but old)
- Keep (protected or recent activity)
- Offers to delete safe branches after confirmation
You: "Create a merge request for my current branch using our standard template with all sections filled out based on my commits"
What Claude does:
- Analyzes your commits and code changes
- Loads your merge request template
- Intelligently fills in:
- Title from branch name or primary commit
- Description summarizing changes
- Type of change (feature/bugfix/refactor)
- Breaking changes (if any)
- Testing checklist
- Related issues
- Screenshots (if UI changes detected)
- Creates the merge request with complete information
You: "Check the pipeline status for merge request #38 and explain any failures"
What Claude does:
- Fetches pipeline information for the merge request
- Analyzes job statuses
- For failed jobs:
- Retrieves error logs
- Explains the failure in plain language
- Suggests fixes
- Provides a summary with actionable next steps
Symptoms:
- Claude says it can't connect to GitLab
- GitLab commands time out
Solutions:
-
Verify environment variables:
# Check if variables are set echo $GITLAB_URL echo $GITLAB_PERSONAL_ACCESS_TOKEN
-
Restart Claude Code:
# Exit and restart exit claude
-
Test token validity:
# Test with curl curl --header "PRIVATE-TOKEN: your-token" "https://gitlab.com/api/v4/projects"
-
Check network connectivity:
# Ping GitLab instance ping gitlab.com
Symptoms:
- Claude reports insufficient permissions
- Operations fail with 403 errors
Solutions:
-
Verify token scopes:
- Go to GitLab → User Settings → Access Tokens
- Ensure the token has all required scopes:
apiread_repositorywrite_repositoryread_user
-
Check project access:
- Verify you have the appropriate role in the project (Developer or Maintainer)
- For protected branches, ensure you have permission to push
-
Regenerate token:
- Create a new token with correct scopes
- Update
.envfile with new token - Restart Claude Code
Symptoms:
- Claude can't find your project
- Project list is empty
Solutions:
-
Use full project path:
Instead of: "Review MR #42" Use: "Review MR #42 in project 'myorg/myapp'" -
Verify project visibility:
- Check if the project is private and you have access
- Ensure your token has access to the project's group
-
Use project ID instead of name:
You: "Show me merge requests in project ID 12345"
Symptoms:
- Operations slow down after many requests
- "Rate limit exceeded" errors
Solutions:
-
Wait and retry:
- GitLab API has rate limits (typically 600 requests per minute)
- Wait a minute before retrying
-
Batch operations:
Instead of: Multiple separate requests Use: "Review all open merge requests in one analysis" -
For self-hosted GitLab:
- Contact your administrator to adjust rate limits if needed
DO:
- Store tokens in
.envfiles that are in.gitignore - Use tokens with minimal required scopes
- Set expiration dates on tokens
- Rotate tokens regularly (every 90 days recommended)
- Use different tokens for different purposes
DON'T:
- Commit tokens to version control
- Share tokens between team members
- Use tokens with
sudoscope unless absolutely necessary - Store tokens in configuration files that are tracked by Git
Principle of Least Privilege:
For read-only operations: Use a token with only `read_repository` scope
For code reviews: Add `read_api` scope
For pushing code: Add `write_repository` scope only when needed
Development vs. Production:
Development .env:
GITLAB_URL=https://gitlab.dev.company.com
GITLAB_PERSONAL_ACCESS_TOKEN=dev-token-hereProduction .env:
GITLAB_URL=https://gitlab.company.com
GITLAB_PERSONAL_ACCESS_TOKEN=prod-token-hereKeep these files separate and never use production tokens in development.
Regularly review:
- Active tokens in GitLab settings
- Recent API activity in audit logs
- Unusual access patterns
If a token is compromised:
- Immediately revoke the token in GitLab
- Review recent activity for unauthorized access
- Generate a new token with appropriate scopes
- Update the
.envfile - Restart Claude Code
- Document the incident
- GitLab API Documentation
- GitLab Personal Access Tokens Guide
- MCP Server Documentation
- Claude Code Documentation
If you encounter issues not covered in this documentation:
- Check the GitLab MCP Server GitHub Issues
- Review GitLab API status page for service interruptions
- Consult your organization's internal documentation for self-hosted instances
Last Updated: January 2025 Version: 1.0 Maintainer: Documentation Team