@ttpears/gitlab-mcp-server 1.7.0 → 1.7.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -584
- package/dist/index.js +0 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,144 +1,66 @@
|
|
|
1
1
|
# GitLab MCP Server
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@ttpears/gitlab-mcp-server)
|
|
4
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
5
|
|
|
5
|
-
|
|
6
|
+
A Model Context Protocol (MCP) server for GitLab with GraphQL schema discovery, self-hosted instance support, and multi-client compatibility.
|
|
6
7
|
|
|
7
|
-
|
|
8
|
+
```bash
|
|
9
|
+
npx @ttpears/gitlab-mcp-server
|
|
10
|
+
```
|
|
8
11
|
|
|
9
|
-
|
|
10
|
-
Create a GitLab Personal Access Token with `read_api` or `api` scope:
|
|
11
|
-
- Go to GitLab → **User Settings** → **Access Tokens**
|
|
12
|
-
- Create token with appropriate scope
|
|
13
|
-
- Copy the token (e.g., `glpat-xxxxxxxxxxxx`)
|
|
12
|
+
## Quick Start
|
|
14
13
|
|
|
15
|
-
###
|
|
14
|
+
### 1. Create a GitLab Token
|
|
16
15
|
|
|
17
|
-
**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
```
|
|
16
|
+
Go to GitLab → **User Settings** → **Access Tokens** → create a token with `read_api` (read-only) or `api` (full access) scope.
|
|
17
|
+
|
|
18
|
+
### 2. Choose Your Client
|
|
19
|
+
|
|
20
|
+
- [Claude Code](#claude-code) — stdio transport, single-user
|
|
21
|
+
- [LibreChat (Docker)](#librechat-docker) — streamable HTTP, multi-user with per-user auth
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## Claude Code
|
|
26
|
+
|
|
27
|
+
Add to your Claude Code settings (`.claude/settings.json` or project `.mcp.json`):
|
|
33
28
|
|
|
34
|
-
**For Claude Code CLI** - Add to `.clauderc`:
|
|
35
29
|
```json
|
|
36
30
|
{
|
|
37
31
|
"mcpServers": {
|
|
38
32
|
"gitlab": {
|
|
39
33
|
"command": "npx",
|
|
40
|
-
"args": ["-y", "gitlab-mcp-server"],
|
|
34
|
+
"args": ["-y", "@ttpears/gitlab-mcp-server"],
|
|
41
35
|
"env": {
|
|
42
36
|
"GITLAB_URL": "https://gitlab.com",
|
|
43
|
-
"GITLAB_SHARED_ACCESS_TOKEN": "glpat-your-token-here"
|
|
44
|
-
"GITLAB_AUTH_MODE": "hybrid"
|
|
37
|
+
"GITLAB_SHARED_ACCESS_TOKEN": "glpat-your-token-here"
|
|
45
38
|
}
|
|
46
39
|
}
|
|
47
40
|
}
|
|
48
41
|
}
|
|
49
42
|
```
|
|
50
43
|
|
|
51
|
-
|
|
52
|
-
Restart Claude Desktop or Claude Code to load the GitLab MCP server.
|
|
53
|
-
|
|
54
|
-
### 4. Test It
|
|
55
|
-
Try asking Claude:
|
|
56
|
-
- "Search for issues in project X"
|
|
57
|
-
- "Show me recent merge requests"
|
|
58
|
-
- "Browse the repository structure of project Y"
|
|
59
|
-
|
|
60
|
-
### 🔍 Test with MCP Inspector
|
|
61
|
-
Test your configuration before using it with Claude:
|
|
62
|
-
|
|
63
|
-
```bash
|
|
64
|
-
# Test with MCP Inspector (interactive UI)
|
|
65
|
-
npx @modelcontextprotocol/inspector npx gitlab-mcp-server
|
|
66
|
-
```
|
|
67
|
-
|
|
68
|
-
Set environment variables when prompted or create `mcp-inspector.example.json`:
|
|
69
|
-
```json
|
|
70
|
-
{
|
|
71
|
-
"command": "npx",
|
|
72
|
-
"args": ["-y", "gitlab-mcp-server"],
|
|
73
|
-
"env": {
|
|
74
|
-
"GITLAB_URL": "https://gitlab.com",
|
|
75
|
-
"GITLAB_SHARED_ACCESS_TOKEN": "glpat-your-test-token"
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
## 🚀 **Recent Updates (2026-01-26)**
|
|
81
|
-
|
|
82
|
-
**Major modernization for universal MCP support:**
|
|
83
|
-
- ✅ **Claude Desktop & Claude Code support** - Easy npx installation with stdio transport
|
|
84
|
-
- ✅ **Removed deprecated SSE transport** - Clean Streamable HTTP only for LibreChat
|
|
85
|
-
- ✅ **Enhanced logging** - Clear transport mode detection and configuration display
|
|
86
|
-
- ✅ **Quick start documentation** - Copy-paste configs for all MCP clients
|
|
87
|
-
- ✅ **MCP Inspector support** - Easy testing and debugging
|
|
88
|
-
- ✅ **Single codebase** - Auto-detects stdio vs HTTP mode based on environment
|
|
89
|
-
|
|
90
|
-
**These changes make GitLab MCP work seamlessly across all MCP clients while simplifying deployment.**
|
|
91
|
-
|
|
92
|
-
## ✨ **Key Features for LLMs**
|
|
93
|
-
|
|
94
|
-
- 🔍 **Comprehensive Search**: Global search across projects, issues, merge requests, users, and groups
|
|
95
|
-
- 📂 **Code Exploration**: Browse repository structure and read file contents
|
|
96
|
-
- 🤝 **Dual Authentication**: Shared read-only access + per-user authentication for write operations
|
|
97
|
-
- 🧠 **LLM-Optimized**: Tools designed specifically for AI analysis and exploration
|
|
98
|
-
- 🔄 **GraphQL Discovery**: Automatic schema introspection for dynamic capabilities
|
|
99
|
-
- 🔒 **Session Isolation**: Per-session credential management prevents cross-user data leaks
|
|
100
|
-
|
|
101
|
-
## Features
|
|
102
|
-
|
|
103
|
-
- **Search & Discovery**: Global search, project search, issue/MR search, code browsing
|
|
104
|
-
- **GraphQL-first approach** with automatic schema introspection
|
|
105
|
-
- **Self-hosted GitLab support** with configurable base URLs
|
|
106
|
-
- **Comprehensive GitLab operations** (projects, issues, merge requests)
|
|
107
|
-
- **Custom query execution** for advanced use cases
|
|
108
|
-
- **Docker & LibreChat integration** ready
|
|
109
|
-
- **Smithery install support** for easy deployment
|
|
44
|
+
Restart Claude Code to load the server.
|
|
110
45
|
|
|
111
|
-
|
|
46
|
+
---
|
|
112
47
|
|
|
113
|
-
|
|
114
|
-
- **`Dockerfile`** - Standard Dockerfile (copy as `Dockerfile.mcp-gitlab` for LibreChat integration)
|
|
115
|
-
- **`smithery.yaml`** - Smithery.ai configuration with both stdio and Docker integration options
|
|
48
|
+
## LibreChat (Docker)
|
|
116
49
|
|
|
117
|
-
|
|
50
|
+
Runs as a sidecar container using [streamable HTTP transport](https://www.librechat.ai/docs/features/mcp) for multi-user deployments with per-user credential isolation.
|
|
118
51
|
|
|
119
|
-
|
|
52
|
+
### 1. Add environment variables to your LibreChat `.env`:
|
|
120
53
|
|
|
121
|
-
1. **Copy Dockerfile to your LibreChat directory:**
|
|
122
54
|
```bash
|
|
123
|
-
# Copy the Dockerfile for LibreChat integration
|
|
124
|
-
cp Dockerfile /path/to/librechat/Dockerfile.mcp-gitlab
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
**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`).
|
|
128
|
-
|
|
129
|
-
2. **Add GitLab environment variables to your LibreChat `.env` file:**
|
|
130
|
-
```bash
|
|
131
|
-
# GitLab MCP Configuration
|
|
132
55
|
GITLAB_URL=https://gitlab.com
|
|
133
56
|
GITLAB_AUTH_MODE=hybrid
|
|
134
|
-
GITLAB_SHARED_ACCESS_TOKEN=your-
|
|
135
|
-
GITLAB_MAX_PAGE_SIZE=50
|
|
136
|
-
GITLAB_TIMEOUT=30000
|
|
57
|
+
GITLAB_SHARED_ACCESS_TOKEN=glpat-your-shared-token
|
|
137
58
|
GITLAB_MCP_PORT=8008
|
|
138
59
|
MCP_TRANSPORT=http
|
|
139
60
|
```
|
|
140
61
|
|
|
141
|
-
|
|
62
|
+
### 2. Add the service to `docker-compose.override.yml`:
|
|
63
|
+
|
|
142
64
|
```yaml
|
|
143
65
|
services:
|
|
144
66
|
gitlab-mcp:
|
|
@@ -154,12 +76,15 @@ services:
|
|
|
154
76
|
restart: unless-stopped
|
|
155
77
|
```
|
|
156
78
|
|
|
157
|
-
|
|
79
|
+
Copy the Dockerfile from this repo into your LibreChat directory as `Dockerfile.mcp-gitlab`. It clones and builds from this repository automatically — no source files needed.
|
|
80
|
+
|
|
81
|
+
### 3. Configure in `librechat.yml`:
|
|
82
|
+
|
|
158
83
|
```yaml
|
|
159
84
|
mcpServers:
|
|
160
85
|
gitlab:
|
|
161
86
|
type: streamable-http
|
|
162
|
-
url: "http://
|
|
87
|
+
url: "http://gitlab-mcp:8008/"
|
|
163
88
|
headers:
|
|
164
89
|
Authorization: "Bearer {{GITLAB_PAT}}"
|
|
165
90
|
X-GitLab-Url: "{{GITLAB_URL_OVERRIDE}}"
|
|
@@ -172,514 +97,115 @@ mcpServers:
|
|
|
172
97
|
description: "e.g., https://gitlab.yourdomain.com"
|
|
173
98
|
```
|
|
174
99
|
|
|
175
|
-
|
|
100
|
+
### 4. Restart LibreChat:
|
|
101
|
+
|
|
176
102
|
```bash
|
|
177
103
|
docker compose down && docker compose -f docker-compose.yml -f docker-compose.override.yml up -d
|
|
178
104
|
```
|
|
179
105
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
1. **Visit [smithery.ai](https://smithery.ai)**
|
|
183
|
-
2. **Search for "gitlab-mcp-server"**
|
|
184
|
-
3. **Select the server** from search results
|
|
185
|
-
4. **Navigate to the "Auto" tab** and select "LibreChat"
|
|
186
|
-
5. **Copy and run** the generated installation command:
|
|
187
|
-
```bash
|
|
188
|
-
# Example command (actual command from Smithery)
|
|
189
|
-
npx @smithery/cli install gitlab-mcp-server
|
|
190
|
-
```
|
|
191
|
-
6. **Configure in your `librechat.yml`** (Smithery will provide the exact configuration):
|
|
192
|
-
```yaml
|
|
193
|
-
mcpServers:
|
|
194
|
-
gitlab:
|
|
195
|
-
command: npx
|
|
196
|
-
args: ["gitlab-mcp-server"]
|
|
197
|
-
type: stdio
|
|
198
|
-
env:
|
|
199
|
-
GITLAB_URL: "https://gitlab.com"
|
|
200
|
-
GITLAB_AUTH_MODE: "hybrid"
|
|
201
|
-
GITLAB_SHARED_ACCESS_TOKEN: "${GITLAB_SHARED_ACCESS_TOKEN:-}"
|
|
202
|
-
customUserVars:
|
|
203
|
-
GITLAB_ACCESS_TOKEN:
|
|
204
|
-
title: "GitLab Personal Access Token"
|
|
205
|
-
description: "Your GitLab PAT with 'api' or 'read_api' scope"
|
|
206
|
-
type: password
|
|
207
|
-
required: false
|
|
208
|
-
```
|
|
209
|
-
7. **Restart LibreChat** to initialize the server connection
|
|
210
|
-
|
|
211
|
-
### Manual Installation
|
|
212
|
-
|
|
213
|
-
1. Clone and build:
|
|
214
|
-
```bash
|
|
215
|
-
git clone <repository-url>
|
|
216
|
-
cd gitlab-mcp
|
|
217
|
-
npm install
|
|
218
|
-
npm run build
|
|
219
|
-
```
|
|
106
|
+
---
|
|
220
107
|
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
108
|
+
## Available Tools
|
|
109
|
+
|
|
110
|
+
### Search & Discovery
|
|
111
|
+
| Tool | Description |
|
|
112
|
+
|------|-------------|
|
|
113
|
+
| `search_gitlab` | Global search across projects, issues, and merge requests |
|
|
114
|
+
| `search_projects` | Find repositories by name or description |
|
|
115
|
+
| `search_issues` | Search issues globally or within a project (filter by assignee, author, labels, state) |
|
|
116
|
+
| `search_merge_requests` | Find merge requests by username or within a project |
|
|
117
|
+
| `search_users` | Find team members and contributors |
|
|
118
|
+
| `search_groups` | Discover groups and organizations |
|
|
119
|
+
| `browse_repository` | Explore directory structure and files |
|
|
120
|
+
| `get_file_content` | Read file contents for code analysis |
|
|
121
|
+
|
|
122
|
+
### Read Operations
|
|
123
|
+
| Tool | Description |
|
|
124
|
+
|------|-------------|
|
|
125
|
+
| `get_project` | Detailed project information |
|
|
126
|
+
| `get_issues` | List project issues with pagination |
|
|
127
|
+
| `get_merge_requests` | List project merge requests with pagination |
|
|
128
|
+
| `get_user_issues` | Get all issues assigned to a user |
|
|
129
|
+
| `get_user_merge_requests` | Get MRs authored by or assigned to a user |
|
|
130
|
+
| `resolve_path` | Resolve a path to a project or group |
|
|
131
|
+
| `get_available_queries` | Discover available GraphQL operations |
|
|
132
|
+
| `execute_custom_query` | Run custom GraphQL queries |
|
|
133
|
+
|
|
134
|
+
### Write Operations (requires user authentication)
|
|
135
|
+
| Tool | Description |
|
|
136
|
+
|------|-------------|
|
|
137
|
+
| `create_issue` | Create new issues |
|
|
138
|
+
| `create_merge_request` | Create new merge requests |
|
|
139
|
+
| `update_issue` | Update title, description, assignees, labels, due date |
|
|
140
|
+
| `update_merge_request` | Update title, description, assignees, reviewers, labels |
|
|
141
|
+
|
|
142
|
+
---
|
|
225
143
|
|
|
226
144
|
## Configuration
|
|
227
145
|
|
|
228
146
|
### Authentication Modes
|
|
229
147
|
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
- **Best for**: LibreChat deployments where you want to provide basic GitLab access but allow users to authenticate for full functionality
|
|
236
|
-
|
|
237
|
-
#### 2. **Per-User Only Mode**
|
|
238
|
-
- All operations require user authentication
|
|
239
|
-
- **Best for**: High-security environments where no shared credentials are allowed
|
|
240
|
-
|
|
241
|
-
#### 3. **Shared Only Mode**
|
|
242
|
-
- Uses only the shared token for all operations
|
|
243
|
-
- No per-user authentication supported
|
|
244
|
-
- **Best for**: Single-user or trusted environments
|
|
245
|
-
|
|
246
|
-
#### Authentication Mode Comparison
|
|
247
|
-
|
|
248
|
-
| Mode | stdio (Claude Desktop/Code) | HTTP (LibreChat) | Use Case |
|
|
249
|
-
|------|----------------------------|------------------|----------|
|
|
250
|
-
| **hybrid** (default) | Uses `GITLAB_SHARED_ACCESS_TOKEN` from env + optional per-user PAT | Session headers + user credentials | Recommended for most deployments |
|
|
251
|
-
| **shared** | Uses only `GITLAB_SHARED_ACCESS_TOKEN` from env | Uses only shared token | Single-user environments |
|
|
252
|
-
| **per-user** | Requires PAT in env or tool args | Requires user PAT in session | Maximum security, multi-user |
|
|
148
|
+
| Mode | Description | Use Case |
|
|
149
|
+
|------|-------------|----------|
|
|
150
|
+
| **hybrid** (default) | Shared token for reads + per-user tokens for writes | Multi-user deployments |
|
|
151
|
+
| **shared** | Single token for all operations | Single-user / trusted environments |
|
|
152
|
+
| **per-user** | All operations require user authentication | High-security environments |
|
|
253
153
|
|
|
254
154
|
### Environment Variables
|
|
255
155
|
|
|
256
|
-
| Variable | Description | Default |
|
|
257
|
-
|
|
258
|
-
| `GITLAB_URL` | GitLab instance URL | `https://gitlab.com` |
|
|
259
|
-
| `GITLAB_AUTH_MODE` | Authentication mode
|
|
260
|
-
| `GITLAB_SHARED_ACCESS_TOKEN` | Shared token for read operations |
|
|
261
|
-
| `GITLAB_MAX_PAGE_SIZE` | Maximum items per page (1-100) | `50` |
|
|
262
|
-
| `GITLAB_TIMEOUT` | Request timeout in milliseconds | `30000` |
|
|
263
|
-
|
|
264
|
-
|
|
156
|
+
| Variable | Description | Default |
|
|
157
|
+
|----------|-------------|---------|
|
|
158
|
+
| `GITLAB_URL` | GitLab instance URL | `https://gitlab.com` |
|
|
159
|
+
| `GITLAB_AUTH_MODE` | Authentication mode (`hybrid`, `shared`, `per-user`) | `hybrid` |
|
|
160
|
+
| `GITLAB_SHARED_ACCESS_TOKEN` | Shared token for read operations | — |
|
|
161
|
+
| `GITLAB_MAX_PAGE_SIZE` | Maximum items per page (1-100) | `50` |
|
|
162
|
+
| `GITLAB_TIMEOUT` | Request timeout in milliseconds | `30000` |
|
|
163
|
+
| `GITLAB_MCP_PORT` | HTTP server port (LibreChat mode) | `8008` |
|
|
164
|
+
| `MCP_TRANSPORT` | Transport mode (`http` for LibreChat) | stdio |
|
|
265
165
|
|
|
266
|
-
|
|
267
|
-
1. Go to your GitLab instance → **User Settings** → **Access Tokens**
|
|
268
|
-
2. Create a new token with **read_api** scope (read-only access)
|
|
269
|
-
3. Set as `GITLAB_SHARED_ACCESS_TOKEN`
|
|
270
|
-
|
|
271
|
-
#### For User Tokens (LibreChat Integration)
|
|
272
|
-
Users will be prompted to provide their own tokens with:
|
|
273
|
-
- **api** scope (full access for write operations)
|
|
274
|
-
- **read_api** scope (read-only access)
|
|
275
|
-
|
|
276
|
-
LibreChat will handle user credential collection and management automatically.
|
|
277
|
-
|
|
278
|
-
## Available Tools
|
|
279
|
-
|
|
280
|
-
### 🔍 **Search & Discovery Tools (Perfect for LLMs)**
|
|
281
|
-
Comprehensive search capabilities across your GitLab instance:
|
|
282
|
-
- `search_gitlab` - Global search across projects, issues, and merge requests
|
|
283
|
-
- `search_projects` - Find repositories by name or description
|
|
284
|
-
- `search_issues` - Search issues globally or within specific projects
|
|
285
|
-
- `search_merge_requests` - Find merge requests and code changes
|
|
286
|
-
- `search_users` - Locate team members and contributors
|
|
287
|
-
- `search_groups` - Discover groups and organizations
|
|
288
|
-
- `browse_repository` - Explore codebase structure and files
|
|
289
|
-
- `get_file_content` - Read specific files for code analysis
|
|
290
|
-
|
|
291
|
-
### 🔓 Read-Only Operations (Optional Authentication)
|
|
292
|
-
Can use shared token if available, or user credentials for private data:
|
|
293
|
-
- `get_project` - Get detailed project information
|
|
294
|
-
- `get_issues` - List project issues with pagination
|
|
295
|
-
- `get_merge_requests` - List project merge requests with pagination
|
|
296
|
-
- `execute_custom_query` - Run custom GraphQL queries
|
|
297
|
-
- `get_available_queries` - Discover available GraphQL operations
|
|
298
|
-
|
|
299
|
-
### 🔒 User Authentication Required
|
|
300
|
-
Always require user-provided credentials:
|
|
301
|
-
- `get_current_user` - Get authenticated user information
|
|
302
|
-
- `get_projects` - List accessible projects (includes private projects)
|
|
303
|
-
|
|
304
|
-
### ✏️ Write Operations (User Authentication Required)
|
|
305
|
-
Always require user credentials with write permissions:
|
|
306
|
-
- `create_issue` - Create new issues
|
|
307
|
-
- `create_merge_request` - Create new merge requests
|
|
308
|
-
- `update_issue` - Update issue title/description/assignees/labels/due date (schema-aware)
|
|
309
|
-
- `update_merge_request` - Update MR title/description/assignees/reviewers/labels (schema-aware)
|
|
310
|
-
|
|
311
|
-
### Authentication Behavior by Mode
|
|
312
|
-
|
|
313
|
-
| Tool | Shared Mode | Per-User Mode | Hybrid Mode |
|
|
314
|
-
|------|-------------|---------------|-------------|
|
|
315
|
-
| Read-only tools | Uses shared token | Requires user auth | Uses shared token, falls back to user auth |
|
|
316
|
-
| User auth tools | Uses shared token | Requires user auth | Requires user auth |
|
|
317
|
-
| Write tools | Uses shared token | Requires user auth | Requires user auth |
|
|
318
|
-
|
|
319
|
-
## Usage Examples
|
|
320
|
-
|
|
321
|
-
### 🔍 **Search & Discovery (Perfect for LLMs)**
|
|
322
|
-
|
|
323
|
-
```typescript
|
|
324
|
-
// Global search across everything - ideal for LLM exploration
|
|
325
|
-
await callTool('search_gitlab', {
|
|
326
|
-
searchTerm: 'authentication bug'
|
|
327
|
-
// Searches projects, issues, and merge requests simultaneously
|
|
328
|
-
})
|
|
329
|
-
|
|
330
|
-
// Search for specific projects
|
|
331
|
-
await callTool('search_projects', {
|
|
332
|
-
searchTerm: 'api gateway',
|
|
333
|
-
first: 10
|
|
334
|
-
})
|
|
335
|
-
|
|
336
|
-
// Find issues related to a topic (globally or in specific project)
|
|
337
|
-
await callTool('search_issues', {
|
|
338
|
-
searchTerm: 'login error',
|
|
339
|
-
state: 'opened',
|
|
340
|
-
projectPath: 'backend/auth-service' // Optional: limit to specific project
|
|
341
|
-
})
|
|
342
|
-
|
|
343
|
-
// Search merge requests for code changes
|
|
344
|
-
await callTool('search_merge_requests', {
|
|
345
|
-
searchTerm: 'database migration',
|
|
346
|
-
state: 'merged',
|
|
347
|
-
first: 20
|
|
348
|
-
})
|
|
349
|
-
|
|
350
|
-
// Find team members
|
|
351
|
-
await callTool('search_users', {
|
|
352
|
-
searchTerm: 'john smith'
|
|
353
|
-
})
|
|
354
|
-
|
|
355
|
-
// Explore codebase structure
|
|
356
|
-
await callTool('browse_repository', {
|
|
357
|
-
projectPath: 'frontend/web-app',
|
|
358
|
-
path: 'src/components', // Browse specific directory
|
|
359
|
-
ref: 'main'
|
|
360
|
-
})
|
|
361
|
-
|
|
362
|
-
// Get file content for analysis
|
|
363
|
-
await callTool('get_file_content', {
|
|
364
|
-
projectPath: 'backend/api',
|
|
365
|
-
filePath: 'src/auth/login.js',
|
|
366
|
-
ref: 'develop'
|
|
367
|
-
})
|
|
368
|
-
```
|
|
369
|
-
|
|
370
|
-
### Basic Project Information
|
|
371
|
-
```typescript
|
|
372
|
-
// Get public project info (uses shared token if available)
|
|
373
|
-
await callTool('get_project', {
|
|
374
|
-
fullPath: 'group/project'
|
|
375
|
-
})
|
|
376
|
-
|
|
377
|
-
// Get project with user authentication (for private projects)
|
|
378
|
-
await callTool('get_project', {
|
|
379
|
-
fullPath: 'group/private-project',
|
|
380
|
-
userCredentials: {
|
|
381
|
-
accessToken: 'your-personal-access-token'
|
|
382
|
-
}
|
|
383
|
-
})
|
|
384
|
-
|
|
385
|
-
// Get current user (always requires user auth)
|
|
386
|
-
await callTool('get_current_user', {
|
|
387
|
-
userCredentials: {
|
|
388
|
-
accessToken: 'your-personal-access-token'
|
|
389
|
-
}
|
|
390
|
-
})
|
|
391
|
-
```
|
|
392
|
-
|
|
393
|
-
### Issues and Merge Requests
|
|
394
|
-
```typescript
|
|
395
|
-
// List issues (uses shared token if available)
|
|
396
|
-
await callTool('get_issues', {
|
|
397
|
-
projectPath: 'group/project',
|
|
398
|
-
first: 20
|
|
399
|
-
})
|
|
400
|
-
|
|
401
|
-
// Create an issue (requires user authentication)
|
|
402
|
-
await callTool('create_issue', {
|
|
403
|
-
projectPath: 'group/project',
|
|
404
|
-
title: 'New feature request',
|
|
405
|
-
description: 'Detailed description...',
|
|
406
|
-
userCredentials: {
|
|
407
|
-
accessToken: 'your-personal-access-token'
|
|
408
|
-
}
|
|
409
|
-
})
|
|
410
|
-
```
|
|
411
|
-
|
|
412
|
-
### 🤖 **LLM Use Cases & Examples**
|
|
413
|
-
|
|
414
|
-
Perfect for AI-powered GitLab analysis and automation:
|
|
415
|
-
|
|
416
|
-
```typescript
|
|
417
|
-
// "Find all recent authentication-related issues"
|
|
418
|
-
await callTool('search_issues', {
|
|
419
|
-
searchTerm: 'auth login password',
|
|
420
|
-
state: 'opened'
|
|
421
|
-
})
|
|
422
|
-
|
|
423
|
-
// "Show me the structure of the payment processing service"
|
|
424
|
-
await callTool('browse_repository', {
|
|
425
|
-
projectPath: 'backend/payment-service',
|
|
426
|
-
path: 'src'
|
|
427
|
-
})
|
|
428
|
-
|
|
429
|
-
// "What's in the main configuration file?"
|
|
430
|
-
await callTool('get_file_content', {
|
|
431
|
-
projectPath: 'infrastructure/config',
|
|
432
|
-
filePath: 'production.yml'
|
|
433
|
-
})
|
|
434
|
-
|
|
435
|
-
// "Find all projects related to machine learning"
|
|
436
|
-
await callTool('search_projects', {
|
|
437
|
-
searchTerm: 'ml machine learning AI'
|
|
438
|
-
})
|
|
439
|
-
|
|
440
|
-
// "Who worked on the database migration?"
|
|
441
|
-
await callTool('search_merge_requests', {
|
|
442
|
-
searchTerm: 'database migration',
|
|
443
|
-
state: 'merged'
|
|
444
|
-
})
|
|
445
|
-
```
|
|
446
|
-
|
|
447
|
-
### LibreChat Integration
|
|
448
|
-
When using with LibreChat, users will be prompted for their credentials automatically:
|
|
449
|
-
|
|
450
|
-
```typescript
|
|
451
|
-
// LibreChat stores PAT in creds UI; server reads Authorization header
|
|
452
|
-
await callTool('create_merge_request', {
|
|
453
|
-
projectPath: 'group/project',
|
|
454
|
-
title: 'Feature: Add new functionality',
|
|
455
|
-
sourceBranch: 'feature-branch',
|
|
456
|
-
targetBranch: 'main',
|
|
457
|
-
description: 'Implementation details...'
|
|
458
|
-
})
|
|
459
|
-
|
|
460
|
-
// Schema-aware issue update (IDs resolved automatically)
|
|
461
|
-
await callTool('update_issue', {
|
|
462
|
-
projectPath: 'group/project',
|
|
463
|
-
iid: '123',
|
|
464
|
-
title: 'Updated title',
|
|
465
|
-
assigneeUsernames: ['alice'],
|
|
466
|
-
labelNames: ['High Priority'],
|
|
467
|
-
dueDate: '2025-12-31'
|
|
468
|
-
})
|
|
469
|
-
|
|
470
|
-
// Schema-aware MR update (reviewers apply to MRs, not issues)
|
|
471
|
-
await callTool('update_merge_request', {
|
|
472
|
-
projectPath: 'group/project',
|
|
473
|
-
iid: '45',
|
|
474
|
-
title: 'Refined MR title',
|
|
475
|
-
reviewerUsernames: ['bob'],
|
|
476
|
-
assigneeUsernames: ['alice'],
|
|
477
|
-
labelNames: ['Backend']
|
|
478
|
-
})
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
### Advanced GraphQL Queries
|
|
482
|
-
```typescript
|
|
483
|
-
// Discover available operations
|
|
484
|
-
await callTool('get_available_queries', {})
|
|
485
|
-
|
|
486
|
-
// Execute custom query
|
|
487
|
-
await callTool('execute_custom_query', {
|
|
488
|
-
query: `
|
|
489
|
-
query GetProjectStatistics($path: ID!) {
|
|
490
|
-
project(fullPath: $path) {
|
|
491
|
-
statistics {
|
|
492
|
-
commitCount
|
|
493
|
-
storageSize
|
|
494
|
-
repositorySize
|
|
495
|
-
}
|
|
496
|
-
}
|
|
497
|
-
}
|
|
498
|
-
`,
|
|
499
|
-
variables: { path: 'group/project' }
|
|
500
|
-
})
|
|
501
|
-
```
|
|
502
|
-
|
|
503
|
-
## LibreChat Integration
|
|
504
|
-
|
|
505
|
-
The GitLab MCP server uses **Streamable HTTP** transport (MCP spec 2025-03-26) for optimal compatibility with LibreChat and modern MCP clients.
|
|
506
|
-
|
|
507
|
-
### **Docker Integration (Recommended)**
|
|
508
|
-
|
|
509
|
-
1. **Copy the Dockerfile** to your LibreChat root directory
|
|
510
|
-
2. **Add GitLab environment variables** to your LibreChat `.env`
|
|
511
|
-
3. **Add the service** to your `docker-compose.override.yml`
|
|
512
|
-
4. **Configure the MCP server** in your `librechat.yml`
|
|
513
|
-
5. **Restart LibreChat** with the override file
|
|
514
|
-
|
|
515
|
-
### **Environment Variables**
|
|
516
|
-
Add these to your LibreChat `.env` file:
|
|
517
|
-
```bash
|
|
518
|
-
# GitLab MCP Server Configuration
|
|
519
|
-
GITLAB_URL=https://your-gitlab.com # Your GitLab instance
|
|
520
|
-
GITLAB_AUTH_MODE=hybrid # Authentication mode
|
|
521
|
-
GITLAB_SHARED_ACCESS_TOKEN= # Optional shared token
|
|
522
|
-
GITLAB_MCP_PORT=8008 # Server port (do NOT set PORT in LibreChat)
|
|
523
|
-
MCP_TRANSPORT=http # Use HTTP transport
|
|
524
|
-
```
|
|
525
|
-
|
|
526
|
-
### **LibreChat Configuration**
|
|
527
|
-
The server uses **Streamable HTTP** transport on port 8008:
|
|
528
|
-
```yaml
|
|
529
|
-
mcpServers:
|
|
530
|
-
gitlab:
|
|
531
|
-
type: streamable-http
|
|
532
|
-
url: "http://gitlab-mcp:8008/"
|
|
533
|
-
headers:
|
|
534
|
-
Authorization: "Bearer {{GITLAB_PAT}}"
|
|
535
|
-
X-GitLab-Url: "{{GITLAB_URL_OVERRIDE}}"
|
|
536
|
-
customUserVars:
|
|
537
|
-
GITLAB_PAT:
|
|
538
|
-
title: "GitLab Personal Access Token"
|
|
539
|
-
description: "PAT with api scope"
|
|
540
|
-
GITLAB_URL_OVERRIDE:
|
|
541
|
-
title: "GitLab URL (optional)"
|
|
542
|
-
description: "e.g., https://gitlab.yourdomain.com"
|
|
543
|
-
```
|
|
544
|
-
|
|
545
|
-
### **Transport Features**
|
|
546
|
-
- ✅ **Streamable HTTP** (MCP spec 2025-03-26)
|
|
547
|
-
- ✅ **Session management** with per-session credential isolation
|
|
548
|
-
- ✅ **Connection resilience** with proper error handling
|
|
549
|
-
- ✅ **Accept header validation** per MCP specification
|
|
550
|
-
- ✅ **DELETE support** for explicit session termination
|
|
551
|
-
- ✅ **Bidirectional communication** with streaming support
|
|
552
|
-
|
|
553
|
-
### **User Authentication Flow**
|
|
554
|
-
- **Read operations**: Use shared token (if configured) or prompt for user token
|
|
555
|
-
- **Write operations**: Always prompt for user Personal Access Token
|
|
556
|
-
- **Private data**: Requires user authentication for access
|
|
557
|
-
- **LibreChat handles**: Automatic credential prompts and management
|
|
558
|
-
- **Session isolation**: Each user's credentials are stored per-session (never shared between users)
|
|
559
|
-
|
|
560
|
-
## GraphQL Schema Discovery
|
|
561
|
-
|
|
562
|
-
The server automatically introspects the GitLab GraphQL schema on startup, enabling:
|
|
563
|
-
|
|
564
|
-
- **Dynamic query discovery** - Find available operations
|
|
565
|
-
- **Schema-aware querying** - Leverage full GitLab API capabilities
|
|
566
|
-
- **Future-proof design** - Automatically supports new GitLab features
|
|
567
|
-
|
|
568
|
-
## Self-Hosted GitLab Support
|
|
569
|
-
|
|
570
|
-
Works with any GitLab instance:
|
|
571
|
-
- **GitLab.com** (default)
|
|
572
|
-
- **GitLab CE/EE** self-hosted instances
|
|
573
|
-
- **GitLab SaaS** custom domains
|
|
574
|
-
|
|
575
|
-
Simply set `GITLAB_URL` to your instance URL.
|
|
576
|
-
|
|
577
|
-
## Error Handling
|
|
578
|
-
|
|
579
|
-
The server includes comprehensive error handling:
|
|
580
|
-
- **Authentication errors** - Clear token validation messages
|
|
581
|
-
- **Rate limiting** - Respects GitLab API limits
|
|
582
|
-
- **Network issues** - Timeout and retry logic
|
|
583
|
-
- **GraphQL errors** - Detailed query error reporting
|
|
584
|
-
|
|
585
|
-
## Security Considerations
|
|
586
|
-
|
|
587
|
-
### Authentication Security
|
|
588
|
-
- **Per-user tokens** are never stored or logged by the server
|
|
589
|
-
- **Shared tokens** are only used for read-only operations when configured
|
|
590
|
-
- **Credential isolation** - Each user's credentials are handled separately
|
|
591
|
-
- **Scope separation** - Shared tokens should only have `read_api` scope
|
|
592
|
-
|
|
593
|
-
### Token Management
|
|
594
|
-
- **Shared Token**:
|
|
595
|
-
- Should have minimal `read_api` scope only
|
|
596
|
-
- Used for public/read-only operations
|
|
597
|
-
- Stored as environment variable on server
|
|
598
|
-
- **User Tokens**:
|
|
599
|
-
- Can have `api` scope for full functionality
|
|
600
|
-
- Provided by users through LibreChat interface
|
|
601
|
-
- Never persisted by the MCP server
|
|
602
|
-
- Automatically handled by LibreChat's authentication system
|
|
603
|
-
|
|
604
|
-
### Deployment Security
|
|
605
|
-
- **Container security** - Runs as non-root user
|
|
606
|
-
- **Network isolation** - Docker network segmentation supported
|
|
607
|
-
- **Environment variables** - Use Docker secrets or secure environment management
|
|
608
|
-
- **HTTPS required** - Always use HTTPS for GitLab connections
|
|
609
|
-
|
|
610
|
-
### Recommended Security Practices
|
|
611
|
-
1. **Use hybrid mode** for LibreChat deployments
|
|
612
|
-
2. **Limit shared token scope** to `read_api` only
|
|
613
|
-
3. **Enable user authentication** for all write operations
|
|
614
|
-
4. **Use Docker secrets** for shared token storage
|
|
615
|
-
5. **Monitor token usage** through GitLab audit logs
|
|
616
|
-
6. **Rotate tokens regularly** according to your security policy
|
|
166
|
+
---
|
|
617
167
|
|
|
618
168
|
## Troubleshooting
|
|
619
169
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
- Verify URL points to `http://gitlab-mcp:8008/` (not `/sse`)
|
|
626
|
-
- Check Docker logs: `docker logs librechat` and `docker logs gitlab-mcp`
|
|
627
|
-
- Ensure both containers are on the same network
|
|
628
|
-
|
|
629
|
-
2. **Authentication Failed**
|
|
630
|
-
- Verify `GITLAB_ACCESS_TOKEN` is correct
|
|
631
|
-
- Ensure token has `read_api` or `api` scope
|
|
632
|
-
- Check token hasn't expired
|
|
633
|
-
- For LibreChat: Verify user provided valid PAT in credentials UI
|
|
634
|
-
|
|
635
|
-
3. **Session Not Found / 404 Errors**
|
|
636
|
-
- This is normal behavior when sessions expire
|
|
637
|
-
- LibreChat will automatically reinitialize
|
|
638
|
-
- Check `activeSessions` in health endpoint: `curl http://localhost:8008/health`
|
|
639
|
-
|
|
640
|
-
4. **Connection Issues**
|
|
641
|
-
- Verify `GITLAB_URL` is accessible from container
|
|
642
|
-
- Check firewall/proxy settings
|
|
643
|
-
- Confirm SSL certificates are valid
|
|
644
|
-
- Test connectivity: `docker exec gitlab-mcp curl -I https://gitlab.com`
|
|
170
|
+
**Connection issues with LibreChat:**
|
|
171
|
+
- Verify `type: streamable-http` in `librechat.yml` (not `sse`)
|
|
172
|
+
- URL should be `http://gitlab-mcp:8008/` (the Docker service name, not localhost)
|
|
173
|
+
- Ensure both containers share the same Docker network
|
|
174
|
+
- Check logs: `docker logs gitlab-mcp`
|
|
645
175
|
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
- Check GitLab version compatibility (GitLab 12.0+)
|
|
176
|
+
**Authentication errors:**
|
|
177
|
+
- Verify token has `read_api` or `api` scope and hasn't expired
|
|
178
|
+
- For LibreChat: check the user provided a valid PAT in the credentials UI
|
|
650
179
|
|
|
651
|
-
|
|
180
|
+
**Schema introspection failed:**
|
|
181
|
+
- Requires GitLab 12.0+ with GraphQL API enabled
|
|
182
|
+
- Verify `GITLAB_URL` is reachable from the container
|
|
652
183
|
|
|
653
|
-
|
|
184
|
+
**Debug logging:**
|
|
654
185
|
```bash
|
|
655
186
|
NODE_ENV=development GITLAB_URL=https://your-gitlab.com npm start
|
|
656
187
|
```
|
|
657
188
|
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
Test server health and active sessions:
|
|
189
|
+
**Health check (HTTP mode):**
|
|
661
190
|
```bash
|
|
662
191
|
curl http://localhost:8008/health
|
|
663
192
|
```
|
|
664
193
|
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
"protocol": "2025-03-26"
|
|
673
|
-
}
|
|
194
|
+
---
|
|
195
|
+
|
|
196
|
+
## Testing
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
# Test with MCP Inspector
|
|
200
|
+
npx @modelcontextprotocol/inspector npx @ttpears/gitlab-mcp-server
|
|
674
201
|
```
|
|
675
202
|
|
|
676
203
|
## Contributing
|
|
677
204
|
|
|
678
205
|
1. Fork the repository
|
|
679
206
|
2. Create a feature branch
|
|
680
|
-
3.
|
|
681
|
-
4. Submit a pull request
|
|
207
|
+
3. Submit a pull request
|
|
682
208
|
|
|
683
209
|
## License
|
|
684
210
|
|
|
685
|
-
MIT
|
|
211
|
+
MIT
|
package/dist/index.js
CHANGED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ttpears/gitlab-mcp-server",
|
|
3
|
-
"version": "1.7.
|
|
3
|
+
"version": "1.7.2",
|
|
4
4
|
"description": "GitLab MCP Server with GraphQL discovery",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "./src/index.ts",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"homepage": "https://github.com/ttpears/gitlab-mcp#readme",
|
|
28
28
|
"repository": {
|
|
29
29
|
"type": "git",
|
|
30
|
-
"url": "https://github.com/ttpears/gitlab-mcp.git"
|
|
30
|
+
"url": "git+https://github.com/ttpears/gitlab-mcp.git"
|
|
31
31
|
},
|
|
32
32
|
"bugs": {
|
|
33
33
|
"url": "https://github.com/ttpears/gitlab-mcp/issues"
|