Skip to main content
Glama
README.md
# GitLab MCP Server

![CI](https://github.com/SynclyAI/gitlab-mcp/actions/workflows/ci.yml/badge.svg)
[![codecov](https://codecov.io/gh/SynclyAI/gitlab-mcp/graph/badge.svg)](https://codecov.io/gh/SynclyAI/gitlab-mcp)

MCP (Model Context Protocol) server for AI-assisted code review with GitLab on-premise instances.

## Features

### Merge Request Tools
- List, get, create, update merge requests
- Set MR draft status
- List changed files, get one file's diff or all MR changes
- Get MR commits and pipelines
- Get notes and discussions, add notes, start discussions on the MR or on a diff line
- Reply to, resolve, edit and delete comments
- Approve, unapprove, merge MRs

### Repository Tools
- List projects
- Browse repository tree
- Get file content, whole or by line range, and blame
- Search code
- List branches and commits

## Security Model

Uses OAuth with intersection-based access control:
- User authenticates via GitLab OAuth
- AI access limited to repos both user AND service account can access
- All API calls made with service account token for audit trail

## Prerequisites

- Python 3.11+
- GitLab instance with OAuth application configured
- SSL certificate for HTTPS

## Setup

### 1. GitLab OAuth Application

Create in GitLab Admin > Applications:
- **Redirect URI:** `https://<server-host>:<port>/oauth/callback`
- **Scopes:** `read_user`, `read_api`, `read_repository`, `api` (for write operations)
- **Confidential:** Yes

### 2. Secrets File

Create a JSON file with credentials:

```json
{
  "oauth_client_id": "<gitlab-oauth-app-id>",
  "oauth_client_secret": "<gitlab-oauth-app-secret>",
  "service_token": "<service-account-personal-access-token>"
}
```

### 3. Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| `GITLAB_URL` | yes | GitLab instance URL |
| `GITLAB_SECRETS_PATH` | yes | Path to secrets JSON file |
| `MCP_SERVER_BIND_URL` | yes | Bind URL with protocol and port (e.g., `https://0.0.0.0:8443` or `http://0.0.0.0:8080`) |
| `MCP_SERVER_ADVERTISED_URL` | yes | Client-facing URL (e.g., `https://mcp.example.com:8443`) |
| `MCP_SSL_CERT_PATH` | when bind uses https | Path to SSL certificate |
| `MCP_SSL_KEY_PATH` | when bind uses https | Path to SSL private key |
| `SSL_CERT_FILE` | no | CA certificate for GitLab (self-signed certs) |

### 4. Install

```bash
pip install .
```

## Running

```bash
gitlab-mcp
```

## Docker

Each release is published to the GitHub Container Registry:

```bash
docker pull ghcr.io/synclyai/gitlab-mcp:1.1.1
docker pull ghcr.io/synclyai/gitlab-mcp:latest
```

To build locally instead, the image installs a pre-built wheel and `dist/` is the build context:

```bash
make image
```

Equivalent to building the wheel into an emptied `dist/` and running
`docker build -f Dockerfile -t ghcr.io/synclyai/gitlab-mcp:<version> dist/`, so a local build
carries the same name as the published image. The wheel is built
with `venv/bin/python`, so the `dev` extra must be installed.

## Development

```bash
pip install -e ".[dev]"
pytest
```