@ttpears/gitlab-mcp-server 1.7.0
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/LICENSE +21 -0
- package/README.md +685 -0
- package/dist/config.d.ts +35 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +29 -0
- package/dist/config.js.map +1 -0
- package/dist/gitlab-client.d.ts +96 -0
- package/dist/gitlab-client.d.ts.map +1 -0
- package/dist/gitlab-client.js +1036 -0
- package/dist/gitlab-client.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +600 -0
- package/dist/index.js.map +1 -0
- package/dist/tools.d.ts +29 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +777 -0
- package/dist/tools.js.map +1 -0
- package/icon.svg +32 -0
- package/package.json +58 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Tim Pearson
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,685 @@
|
|
|
1
|
+
# GitLab MCP Server
|
|
2
|
+
|
|
3
|
+
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.**
|
|
4
|
+
|
|
5
|
+
## ⚡ Quick Start (Claude Desktop & Claude Code)
|
|
6
|
+
|
|
7
|
+
The fastest way to get started with GitLab MCP:
|
|
8
|
+
|
|
9
|
+
### 1. Get Your GitLab Token
|
|
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`)
|
|
14
|
+
|
|
15
|
+
### 2. Configure Claude Desktop or Claude Code
|
|
16
|
+
|
|
17
|
+
**For Claude Desktop** - Add to `claude_desktop_config.json`:
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"mcpServers": {
|
|
21
|
+
"gitlab": {
|
|
22
|
+
"command": "npx",
|
|
23
|
+
"args": ["-y", "gitlab-mcp-server"],
|
|
24
|
+
"env": {
|
|
25
|
+
"GITLAB_URL": "https://gitlab.com",
|
|
26
|
+
"GITLAB_SHARED_ACCESS_TOKEN": "glpat-your-token-here",
|
|
27
|
+
"GITLAB_AUTH_MODE": "hybrid"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**For Claude Code CLI** - Add to `.clauderc`:
|
|
35
|
+
```json
|
|
36
|
+
{
|
|
37
|
+
"mcpServers": {
|
|
38
|
+
"gitlab": {
|
|
39
|
+
"command": "npx",
|
|
40
|
+
"args": ["-y", "gitlab-mcp-server"],
|
|
41
|
+
"env": {
|
|
42
|
+
"GITLAB_URL": "https://gitlab.com",
|
|
43
|
+
"GITLAB_SHARED_ACCESS_TOKEN": "glpat-your-token-here",
|
|
44
|
+
"GITLAB_AUTH_MODE": "hybrid"
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
### 3. Restart Claude
|
|
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
|
|
110
|
+
|
|
111
|
+
## Installation
|
|
112
|
+
|
|
113
|
+
### 📁 **File Structure Note**
|
|
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
|
|
116
|
+
|
|
117
|
+
### Docker (Recommended for LibreChat)
|
|
118
|
+
|
|
119
|
+
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.
|
|
120
|
+
|
|
121
|
+
1. **Copy Dockerfile to your LibreChat directory:**
|
|
122
|
+
```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
|
+
GITLAB_URL=https://gitlab.com
|
|
133
|
+
GITLAB_AUTH_MODE=hybrid
|
|
134
|
+
GITLAB_SHARED_ACCESS_TOKEN=your-optional-shared-token
|
|
135
|
+
GITLAB_MAX_PAGE_SIZE=50
|
|
136
|
+
GITLAB_TIMEOUT=30000
|
|
137
|
+
GITLAB_MCP_PORT=8008
|
|
138
|
+
MCP_TRANSPORT=http
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
3. **Add service to your LibreChat `docker-compose.override.yml`:**
|
|
142
|
+
```yaml
|
|
143
|
+
services:
|
|
144
|
+
gitlab-mcp:
|
|
145
|
+
build:
|
|
146
|
+
context: .
|
|
147
|
+
dockerfile: Dockerfile.mcp-gitlab
|
|
148
|
+
env_file:
|
|
149
|
+
- .env
|
|
150
|
+
ports:
|
|
151
|
+
- "8008:8008"
|
|
152
|
+
networks:
|
|
153
|
+
- librechat
|
|
154
|
+
restart: unless-stopped
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
4. **Configure in your LibreChat `librechat.yml`:**
|
|
158
|
+
```yaml
|
|
159
|
+
mcpServers:
|
|
160
|
+
gitlab:
|
|
161
|
+
type: streamable-http
|
|
162
|
+
url: "http://localhost:8008/"
|
|
163
|
+
headers:
|
|
164
|
+
Authorization: "Bearer {{GITLAB_PAT}}"
|
|
165
|
+
X-GitLab-Url: "{{GITLAB_URL_OVERRIDE}}"
|
|
166
|
+
customUserVars:
|
|
167
|
+
GITLAB_PAT:
|
|
168
|
+
title: "GitLab Personal Access Token"
|
|
169
|
+
description: "PAT with api scope"
|
|
170
|
+
GITLAB_URL_OVERRIDE:
|
|
171
|
+
title: "GitLab URL (optional)"
|
|
172
|
+
description: "e.g., https://gitlab.yourdomain.com"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
5. **Restart LibreChat:**
|
|
176
|
+
```bash
|
|
177
|
+
docker compose down && docker compose -f docker-compose.yml -f docker-compose.override.yml up -d
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Smithery.ai (Recommended for Easy Installation)
|
|
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
|
+
```
|
|
220
|
+
|
|
221
|
+
2. Run the server:
|
|
222
|
+
```bash
|
|
223
|
+
GITLAB_URL=https://your-gitlab.com GITLAB_ACCESS_TOKEN=your-token npm start
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Configuration
|
|
227
|
+
|
|
228
|
+
### Authentication Modes
|
|
229
|
+
|
|
230
|
+
The server supports three authentication modes:
|
|
231
|
+
|
|
232
|
+
#### 1. **Hybrid Mode (Recommended)**
|
|
233
|
+
- **Shared token**: Optional read-only token for public operations
|
|
234
|
+
- **Per-user auth**: Users provide their own tokens for private data and write operations
|
|
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 |
|
|
253
|
+
|
|
254
|
+
### Environment Variables
|
|
255
|
+
|
|
256
|
+
| Variable | Description | Default | Auth Mode |
|
|
257
|
+
|----------|-------------|---------|-----------|
|
|
258
|
+
| `GITLAB_URL` | GitLab instance URL | `https://gitlab.com` | All |
|
|
259
|
+
| `GITLAB_AUTH_MODE` | Authentication mode | `hybrid` | All |
|
|
260
|
+
| `GITLAB_SHARED_ACCESS_TOKEN` | Shared token for read operations | - | Shared/Hybrid |
|
|
261
|
+
| `GITLAB_MAX_PAGE_SIZE` | Maximum items per page (1-100) | `50` | All |
|
|
262
|
+
| `GITLAB_TIMEOUT` | Request timeout in milliseconds | `30000` | All |
|
|
263
|
+
|
|
264
|
+
### GitLab Access Token Setup
|
|
265
|
+
|
|
266
|
+
#### For Shared/System Tokens
|
|
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
|
|
617
|
+
|
|
618
|
+
## Troubleshooting
|
|
619
|
+
|
|
620
|
+
### Common Issues
|
|
621
|
+
|
|
622
|
+
1. **LibreChat Connection Drops / Reconnecting**
|
|
623
|
+
- ✅ **Fixed in v1.0.0+**: Updated to Streamable HTTP transport
|
|
624
|
+
- Check that LibreChat config uses `type: streamable-http`
|
|
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`
|
|
645
|
+
|
|
646
|
+
5. **Schema Introspection Failed**
|
|
647
|
+
- Ensure GitLab instance supports GraphQL
|
|
648
|
+
- Verify API endpoint is `/api/graphql`
|
|
649
|
+
- Check GitLab version compatibility (GitLab 12.0+)
|
|
650
|
+
|
|
651
|
+
### Debug Logging
|
|
652
|
+
|
|
653
|
+
Set `NODE_ENV=development` for detailed logging:
|
|
654
|
+
```bash
|
|
655
|
+
NODE_ENV=development GITLAB_URL=https://your-gitlab.com npm start
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
### Health Check
|
|
659
|
+
|
|
660
|
+
Test server health and active sessions:
|
|
661
|
+
```bash
|
|
662
|
+
curl http://localhost:8008/health
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
Expected response:
|
|
666
|
+
```json
|
|
667
|
+
{
|
|
668
|
+
"status": "healthy",
|
|
669
|
+
"timestamp": "2025-10-22T12:00:00.000Z",
|
|
670
|
+
"activeSessions": 2,
|
|
671
|
+
"transport": "streamable-http",
|
|
672
|
+
"protocol": "2025-03-26"
|
|
673
|
+
}
|
|
674
|
+
```
|
|
675
|
+
|
|
676
|
+
## Contributing
|
|
677
|
+
|
|
678
|
+
1. Fork the repository
|
|
679
|
+
2. Create a feature branch
|
|
680
|
+
3. Add tests for new functionality
|
|
681
|
+
4. Submit a pull request
|
|
682
|
+
|
|
683
|
+
## License
|
|
684
|
+
|
|
685
|
+
MIT License - see LICENSE file for details.
|