Skip to main content
Glama
by ttpears

GitLab MCP Server

A Model Context Protocol (MCP) server for GitLab that leverages GraphQL with automatic schema discovery and supports self-hosted GitLab instances. Perfect for LLM-powered GitLab exploration and analysis.

🚀 Recent Updates (2025-10-22)

Major refactor for LibreChat compatibility:

  • Streamable HTTP transport (MCP spec 2025-03-26) - Removed deprecated SSE

  • Per-session credential isolation - Fixed credential bleeding between users

  • Proper session management - Added HTTP 404/400 handling and DELETE support

  • Accept header validation - Full compliance with MCP specification

  • Connection resilience - Improved error handling and reconnection logic

  • Consolidated endpoints - Removed duplicate code, cleaner architecture

These changes resolve LibreChat disconnection issues and improve overall stability.

Key Features for LLMs

  • 🔍 Comprehensive Search: Global search across projects, issues, merge requests, users, and groups

  • 📂 Code Exploration: Browse repository structure and read file contents

  • 🤝 Dual Authentication: Shared read-only access + per-user authentication for write operations

  • 🧠 LLM-Optimized: Tools designed specifically for AI analysis and exploration

  • 🔄 GraphQL Discovery: Automatic schema introspection for dynamic capabilities

  • 🔒 Session Isolation: Per-session credential management prevents cross-user data leaks

Features

  • Search & Discovery: Global search, project search, issue/MR search, code browsing

  • GraphQL-first approach with automatic schema introspection

  • Self-hosted GitLab support with configurable base URLs

  • Comprehensive GitLab operations (projects, issues, merge requests)

  • Custom query execution for advanced use cases

  • Docker & LibreChat integration ready

  • Smithery install support for easy deployment

Installation

📁 File Structure Note

  • Dockerfile - Standard Dockerfile (copy as Dockerfile.mcp-gitlab for LibreChat integration)

  • smithery.yaml - Smithery.ai configuration with both stdio and Docker integration options

Docker (Recommended for LibreChat)

The Dockerfile automatically clones and builds the GitLab MCP server from this repository, so you don't need to copy any source files - just the Dockerfile itself.

  1. Copy Dockerfile to your LibreChat directory:

# Copy the Dockerfile for LibreChat integration cp Dockerfile /path/to/librechat/Dockerfile.mcp-gitlab

Note: The Dockerfile uses git clone to fetch the source code, so it won't accidentally copy LibreChat files. You can specify which version to build using the GITLAB_MCP_VERSION build arg (defaults to main).

  1. Add GitLab environment variables to your LibreChat

# GitLab MCP Configuration GITLAB_URL=https://gitlab.com GITLAB_AUTH_MODE=hybrid GITLAB_SHARED_ACCESS_TOKEN=your-optional-shared-token GITLAB_MAX_PAGE_SIZE=50 GITLAB_TIMEOUT=30000 GITLAB_MCP_PORT=8008 MCP_TRANSPORT=http
  1. Add service to your LibreChat

services: gitlab-mcp: build: context: . dockerfile: Dockerfile.mcp-gitlab env_file: - .env ports: - "8008:8008" networks: - librechat restart: unless-stopped
  1. Configure in your LibreChat

mcpServers: gitlab: type: streamable-http url: "http://localhost:8008/" headers: Authorization: "Bearer {{GITLAB_PAT}}" X-GitLab-Url: "{{GITLAB_URL_OVERRIDE}}" customUserVars: GITLAB_PAT: title: "GitLab Personal Access Token" description: "PAT with api scope" GITLAB_URL_OVERRIDE: title: "GitLab URL (optional)" description: "e.g., https://gitlab.yourdomain.com"
  1. Restart LibreChat:

docker compose down && docker compose -f docker-compose.yml -f docker-compose.override.yml up -d

Smithery.ai (Recommended for Easy Installation)

  1. Visit

  2. Search for "gitlab-mcp-server"

  3. Select the server from search results

  4. Navigate to the "Auto" tab and select "LibreChat"

  5. Copy and run the generated installation command:

    # Example command (actual command from Smithery) npx @smithery/cli install gitlab-mcp-server
  6. Configure in your (Smithery will provide the exact configuration):

    mcpServers: gitlab: command: npx args: ["gitlab-mcp-server"] type: stdio env: GITLAB_URL: "https://gitlab.com" GITLAB_AUTH_MODE: "hybrid" GITLAB_SHARED_ACCESS_TOKEN: "${GITLAB_SHARED_ACCESS_TOKEN:-}" customUserVars: GITLAB_ACCESS_TOKEN: title: "GitLab Personal Access Token" description: "Your GitLab PAT with 'api' or 'read_api' scope" type: password required: false
  7. Restart LibreChat to initialize the server connection

Manual Installation

  1. Clone and build:

git clone <repository-url> cd gitlab-mcp npm install npm run build
  1. Run the server:

GITLAB_URL=https://your-gitlab.com GITLAB_ACCESS_TOKEN=your-token npm start

Configuration

Authentication Modes

The server supports three authentication modes:

1. Hybrid Mode (Recommended)

  • Shared token: Optional read-only token for public operations

  • Per-user auth: Users provide their own tokens for private data and write operations

  • Best for: LibreChat deployments where you want to provide basic GitLab access but allow users to authenticate for full functionality

2. Per-User Only Mode

  • All operations require user authentication

  • Best for: High-security environments where no shared credentials are allowed

3. Shared Only Mode

  • Uses only the shared token for all operations

  • No per-user authentication supported

  • Best for: Single-user or trusted environments

Environment Variables

Variable

Description

Default

Auth Mode

GITLAB_URL

GitLab instance URL

https://gitlab.com

All

GITLAB_AUTH_MODE

Authentication mode

hybrid

All

GITLAB_SHARED_ACCESS_TOKEN

Shared token for read operations

-

Shared/Hybrid

GITLAB_MAX_PAGE_SIZE

Maximum items per page (1-100)

50

All

GITLAB_TIMEOUT

Request timeout in milliseconds

30000

All

GitLab Access Token Setup

For Shared/System Tokens

  1. Go to your GitLab instance → User SettingsAccess Tokens

  2. Create a new token with read_api scope (read-only access)

  3. Set as GITLAB_SHARED_ACCESS_TOKEN

For User Tokens (LibreChat Integration)

Users will be prompted to provide their own tokens with:

  • api scope (full access for write operations)

  • read_api scope (read-only access)

LibreChat will handle user credential collection and management automatically.

Available Tools

🔍 Search & Discovery Tools (Perfect for LLMs)

Comprehensive search capabilities across your GitLab instance:

  • search_gitlab - Global search across projects, issues, and merge requests

  • search_projects - Find repositories by name or description

  • search_issues - Search issues globally or within specific projects

  • search_merge_requests - Find merge requests and code changes

  • search_users - Locate team members and contributors

  • search_groups - Discover groups and organizations

  • browse_repository - Explore codebase structure and files

  • get_file_content - Read specific files for code analysis

🔓 Read-Only Operations (Optional Authentication)

Can use shared token if available, or user credentials for private data:

  • get_project - Get detailed project information

  • get_issues - List project issues with pagination

  • get_merge_requests - List project merge requests with pagination

  • execute_custom_query - Run custom GraphQL queries

  • get_available_queries - Discover available GraphQL operations

🔒 User Authentication Required

Always require user-provided credentials:

  • get_current_user - Get authenticated user information

  • get_projects - List accessible projects (includes private projects)

✏️ Write Operations (User Authentication Required)

Always require user credentials with write permissions:

  • create_issue - Create new issues

  • create_merge_request - Create new merge requests

  • update_issue - Update issue title/description/assignees/labels/due date (schema-aware)

  • update_merge_request - Update MR title/description/assignees/reviewers/labels (schema-aware)

Authentication Behavior by Mode

Tool

Shared Mode

Per-User Mode

Hybrid Mode

Read-only tools

Uses shared token

Requires user auth

Uses shared token, falls back to user auth

User auth tools

Uses shared token

Requires user auth

Requires user auth

Write tools

Uses shared token

Requires user auth

Requires user auth

Usage Examples

🔍 Search & Discovery (Perfect for LLMs)

// Global search across everything - ideal for LLM exploration await callTool('search_gitlab', { searchTerm: 'authentication bug' // Searches projects, issues, and merge requests simultaneously }) // Search for specific projects await callTool('search_projects', { searchTerm: 'api gateway', first: 10 }) // Find issues related to a topic (globally or in specific project) await callTool('search_issues', { searchTerm: 'login error', state: 'opened', projectPath: 'backend/auth-service' // Optional: limit to specific project }) // Search merge requests for code changes await callTool('search_merge_requests', { searchTerm: 'database migration', state: 'merged', first: 20 }) // Find team members await callTool('search_users', { searchTerm: 'john smith' }) // Explore codebase structure await callTool('browse_repository', { projectPath: 'frontend/web-app', path: 'src/components', // Browse specific directory ref: 'main' }) // Get file content for analysis await callTool('get_file_content', { projectPath: 'backend/api', filePath: 'src/auth/login.js', ref: 'develop' })

Basic Project Information

// Get public project info (uses shared token if available) await callTool('get_project', { fullPath: 'group/project' }) // Get project with user authentication (for private projects) await callTool('get_project', { fullPath: 'group/private-project', userCredentials: { accessToken: 'your-personal-access-token' } }) // Get current user (always requires user auth) await callTool('get_current_user', { userCredentials: { accessToken: 'your-personal-access-token' } })

Issues and Merge Requests

// List issues (uses shared token if available) await callTool('get_issues', { projectPath: 'group/project', first: 20 }) // Create an issue (requires user authentication) await callTool('create_issue', { projectPath: 'group/project', title: 'New feature request', description: 'Detailed description...', userCredentials: { accessToken: 'your-personal-access-token' } })

🤖 LLM Use Cases & Examples

Perfect for AI-powered GitLab analysis and automation:

// "Find all recent authentication-related issues" await callTool('search_issues', { searchTerm: 'auth login password', state: 'opened' }) // "Show me the structure of the payment processing service" await callTool('browse_repository', { projectPath: 'backend/payment-service', path: 'src' }) // "What's in the main configuration file?" await callTool('get_file_content', { projectPath: 'infrastructure/config', filePath: 'production.yml' }) // "Find all projects related to machine learning" await callTool('search_projects', { searchTerm: 'ml machine learning AI' }) // "Who worked on the database migration?" await callTool('search_merge_requests', { searchTerm: 'database migration', state: 'merged' })

LibreChat Integration

When using with LibreChat, users will be prompted for their credentials automatically:

// LibreChat stores PAT in creds UI; server reads Authorization header await callTool('create_merge_request', { projectPath: 'group/project', title: 'Feature: Add new functionality', sourceBranch: 'feature-branch', targetBranch: 'main', description: 'Implementation details...' }) // Schema-aware issue update (IDs resolved automatically) await callTool('update_issue', { projectPath: 'group/project', iid: '123', title: 'Updated title', assigneeUsernames: ['alice'], labelNames: ['High Priority'], dueDate: '2025-12-31' }) // Schema-aware MR update (reviewers apply to MRs, not issues) await callTool('update_merge_request', { projectPath: 'group/project', iid: '45', title: 'Refined MR title', reviewerUsernames: ['bob'], assigneeUsernames: ['alice'], labelNames: ['Backend'] })

Advanced GraphQL Queries

// Discover available operations await callTool('get_available_queries', {}) // Execute custom query await callTool('execute_custom_query', { query: ` query GetProjectStatistics($path: ID!) { project(fullPath: $path) { statistics { commitCount storageSize repositorySize } } } `, variables: { path: 'group/project' } })

LibreChat Integration

The GitLab MCP server uses Streamable HTTP transport (MCP spec 2025-03-26) for optimal compatibility with LibreChat and modern MCP clients.

Docker Integration (Recommended)

  1. Copy the Dockerfile to your LibreChat root directory

  2. Add GitLab environment variables to your LibreChat .env

  3. Add the service to your docker-compose.override.yml

  4. Configure the MCP server in your librechat.yml

  5. Restart LibreChat with the override file

Environment Variables

Add these to your LibreChat .env file:

# GitLab MCP Server Configuration GITLAB_URL=https://your-gitlab.com # Your GitLab instance GITLAB_AUTH_MODE=hybrid # Authentication mode GITLAB_SHARED_ACCESS_TOKEN= # Optional shared token GITLAB_MCP_PORT=8008 # Server port (do NOT set PORT in LibreChat) MCP_TRANSPORT=http # Use HTTP transport

LibreChat Configuration

The server uses Streamable HTTP transport on port 8008:

mcpServers: gitlab: type: streamable-http url: "http://gitlab-mcp:8008/" headers: Authorization: "Bearer {{GITLAB_PAT}}" X-GitLab-Url: "{{GITLAB_URL_OVERRIDE}}" customUserVars: GITLAB_PAT: title: "GitLab Personal Access Token" description: "PAT with api scope" GITLAB_URL_OVERRIDE: title: "GitLab URL (optional)" description: "e.g., https://gitlab.yourdomain.com"

Transport Features

  • Streamable HTTP (MCP spec 2025-03-26)

  • Session management with per-session credential isolation

  • Connection resilience with proper error handling

  • Accept header validation per MCP specification

  • DELETE support for explicit session termination

  • Bidirectional communication with streaming support

User Authentication Flow

  • Read operations: Use shared token (if configured) or prompt for user token

  • Write operations: Always prompt for user Personal Access Token

  • Private data: Requires user authentication for access

  • LibreChat handles: Automatic credential prompts and management

  • Session isolation: Each user's credentials are stored per-session (never shared between users)

GraphQL Schema Discovery

The server automatically introspects the GitLab GraphQL schema on startup, enabling:

  • Dynamic query discovery - Find available operations

  • Schema-aware querying - Leverage full GitLab API capabilities

  • Future-proof design - Automatically supports new GitLab features

Self-Hosted GitLab Support

Works with any GitLab instance:

  • GitLab.com (default)

  • GitLab CE/EE self-hosted instances

  • GitLab SaaS custom domains

Simply set GITLAB_URL to your instance URL.

Error Handling

The server includes comprehensive error handling:

  • Authentication errors - Clear token validation messages

  • Rate limiting - Respects GitLab API limits

  • Network issues - Timeout and retry logic

  • GraphQL errors - Detailed query error reporting

Security Considerations

Authentication Security

  • Per-user tokens are never stored or logged by the server

  • Shared tokens are only used for read-only operations when configured

  • Credential isolation - Each user's credentials are handled separately

  • Scope separation - Shared tokens should only have read_api scope

Token Management

  • Shared Token:

    • Should have minimal read_api scope only

    • Used for public/read-only operations

    • Stored as environment variable on server

  • User Tokens:

    • Can have api scope for full functionality

    • Provided by users through LibreChat interface

    • Never persisted by the MCP server

    • Automatically handled by LibreChat's authentication system

Deployment Security

  • Container security - Runs as non-root user

  • Network isolation - Docker network segmentation supported

  • Environment variables - Use Docker secrets or secure environment management

  • HTTPS required - Always use HTTPS for GitLab connections

Recommended Security Practices

  1. Use hybrid mode for LibreChat deployments

  2. Limit shared token scope to read_api only

  3. Enable user authentication for all write operations

  4. Use Docker secrets for shared token storage

  5. Monitor token usage through GitLab audit logs

  6. Rotate tokens regularly according to your security policy

Troubleshooting

Common Issues

  1. LibreChat Connection Drops / Reconnecting

    • Fixed in v1.0.0+: Updated to Streamable HTTP transport

    • Check that LibreChat config uses type: streamable-http

    • Verify URL points to http://gitlab-mcp:8008/ (not /sse)

    • Check Docker logs: docker logs librechat and docker logs gitlab-mcp

    • Ensure both containers are on the same network

  2. Authentication Failed

    • Verify GITLAB_ACCESS_TOKEN is correct

    • Ensure token has read_api or api scope

    • Check token hasn't expired

    • For LibreChat: Verify user provided valid PAT in credentials UI

  3. Session Not Found / 404 Errors

    • This is normal behavior when sessions expire

    • LibreChat will automatically reinitialize

    • Check activeSessions in health endpoint: curl http://localhost:8008/health

  4. Connection Issues

    • Verify GITLAB_URL is accessible from container

    • Check firewall/proxy settings

    • Confirm SSL certificates are valid

    • Test connectivity: docker exec gitlab-mcp curl -I https://gitlab.com

  5. Schema Introspection Failed

    • Ensure GitLab instance supports GraphQL

    • Verify API endpoint is /api/graphql

    • Check GitLab version compatibility (GitLab 12.0+)

Debug Logging

Set NODE_ENV=development for detailed logging:

NODE_ENV=development GITLAB_URL=https://your-gitlab.com npm start

Health Check

Test server health and active sessions:

curl http://localhost:8008/health

Expected response:

{ "status": "healthy", "timestamp": "2025-10-22T12:00:00.000Z", "activeSessions": 2, "transport": "streamable-http", "protocol": "2025-03-26" }

Contributing

  1. Fork the repository

  2. Create a feature branch

  3. Add tests for new functionality

  4. Submit a pull request

License

MIT License - see LICENSE file for details.

-
security - not tested
A
license - permissive license
-
quality - not tested

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ttpears/gitlab-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server