@ttpears/gitlab-mcp-server 1.7.1 → 1.7.3

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.
Files changed (3) hide show
  1. package/README.md +138 -584
  2. package/dist/index.js +0 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,144 +1,94 @@
1
1
  # GitLab MCP Server
2
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.**
3
+ [![npm version](https://img.shields.io/npm/v/@ttpears/gitlab-mcp-server)](https://www.npmjs.com/package/@ttpears/gitlab-mcp-server)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
4
5
 
5
- ## Quick Start (Claude Desktop & Claude Code)
6
+ A community MCP server for GitLab — works with **any GitLab tier** (Free, Premium, Ultimate), no GitLab Duo required.
6
7
 
7
- The fastest way to get started with GitLab MCP:
8
+ ```bash
9
+ npx @ttpears/gitlab-mcp-server
10
+ ```
8
11
 
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`)
12
+ ## How This Differs from GitLab's Official MCP Server
14
13
 
15
- ### 2. Configure Claude Desktop or Claude Code
14
+ GitLab ships an [official MCP server](https://docs.gitlab.com/user/gitlab_duo/model_context_protocol/mcp_server/) (Beta) that requires **Premium/Ultimate** and **GitLab Duo** with beta features enabled. This community server is an alternative for teams that don't have those requirements or need different capabilities.
16
15
 
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
- ```
16
+ | | This server | GitLab official |
17
+ |---|---|---|
18
+ | **GitLab tier** | Free, Premium, Ultimate | Premium / Ultimate only |
19
+ | **GitLab Duo required** | No | Yes |
20
+ | **Auth** | Personal Access Token | OAuth 2.0 Dynamic Client Registration |
21
+ | **Transport** | stdio + streamable HTTP | stdio (via `mcp-remote`) + HTTP |
22
+ | **Multi-client** | Claude Code, LibreChat, any MCP client | Claude Desktop, Claude Code, Cursor, VS Code |
23
+ | **Multi-user auth modes** | hybrid / shared / per-user | OAuth per-user |
24
+ | **GraphQL schema discovery** | Yes — introspect & run custom queries | No |
25
+ | **Repository browsing & file reading** | Yes | No |
26
+ | **User / group search** | Yes | No |
27
+ | **Update issues & MRs** | Yes | No (create only) |
28
+ | **CI/CD pipeline management** | No | Yes |
29
+ | **MR diffs & commits** | No | Yes |
30
+ | **Work item notes** | No | Yes |
31
+ | **Semantic code search** | No | Yes (requires additional setup) |
32
+ | **Label search** | No | Yes |
33
+
34
+ **Choose this server** if you're on GitLab Free/Community Edition, need GraphQL flexibility, want repo browsing, or run LibreChat multi-user deployments.
35
+
36
+ **Choose the official server** if you have GitLab Premium/Ultimate with Duo, need CI/CD pipeline tools, or prefer OAuth over PATs.
37
+
38
+ ---
39
+
40
+ ## Quick Start
41
+
42
+ ### 1. Create a GitLab Token
43
+
44
+ Go to GitLab → **User Settings** → **Access Tokens** → create a token with `read_api` (read-only) or `api` (full access) scope.
45
+
46
+ ### 2. Choose Your Client
47
+
48
+ - [Claude Code](#claude-code) — stdio transport, single-user
49
+ - [LibreChat (Docker)](#librechat-docker) — streamable HTTP, multi-user with per-user auth
50
+
51
+ ---
52
+
53
+ ## Claude Code
54
+
55
+ Add to your Claude Code settings (`.claude/settings.json` or project `.mcp.json`):
33
56
 
34
- **For Claude Code CLI** - Add to `.clauderc`:
35
57
  ```json
36
58
  {
37
59
  "mcpServers": {
38
60
  "gitlab": {
39
61
  "command": "npx",
40
- "args": ["-y", "gitlab-mcp-server"],
62
+ "args": ["-y", "@ttpears/gitlab-mcp-server"],
41
63
  "env": {
42
64
  "GITLAB_URL": "https://gitlab.com",
43
- "GITLAB_SHARED_ACCESS_TOKEN": "glpat-your-token-here",
44
- "GITLAB_AUTH_MODE": "hybrid"
65
+ "GITLAB_SHARED_ACCESS_TOKEN": "glpat-your-token-here"
45
66
  }
46
67
  }
47
68
  }
48
69
  }
49
70
  ```
50
71
 
51
- ### 3. Restart Claude
52
- Restart Claude Desktop or Claude Code to load the GitLab MCP server.
72
+ Restart Claude Code to load the server.
53
73
 
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"
74
+ ---
59
75
 
60
- ### 🔍 Test with MCP Inspector
61
- Test your configuration before using it with Claude:
76
+ ## LibreChat (Docker)
62
77
 
63
- ```bash
64
- # Test with MCP Inspector (interactive UI)
65
- npx @modelcontextprotocol/inspector npx gitlab-mcp-server
66
- ```
78
+ 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.
67
79
 
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
- ```
80
+ ### 1. Add environment variables to your LibreChat `.env`:
126
81
 
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
82
  ```bash
131
- # GitLab MCP Configuration
132
83
  GITLAB_URL=https://gitlab.com
133
84
  GITLAB_AUTH_MODE=hybrid
134
- GITLAB_SHARED_ACCESS_TOKEN=your-optional-shared-token
135
- GITLAB_MAX_PAGE_SIZE=50
136
- GITLAB_TIMEOUT=30000
85
+ GITLAB_SHARED_ACCESS_TOKEN=glpat-your-shared-token
137
86
  GITLAB_MCP_PORT=8008
138
87
  MCP_TRANSPORT=http
139
88
  ```
140
89
 
141
- 3. **Add service to your LibreChat `docker-compose.override.yml`:**
90
+ ### 2. Add the service to `docker-compose.override.yml`:
91
+
142
92
  ```yaml
143
93
  services:
144
94
  gitlab-mcp:
@@ -154,12 +104,15 @@ services:
154
104
  restart: unless-stopped
155
105
  ```
156
106
 
157
- 4. **Configure in your LibreChat `librechat.yml`:**
107
+ 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.
108
+
109
+ ### 3. Configure in `librechat.yml`:
110
+
158
111
  ```yaml
159
112
  mcpServers:
160
113
  gitlab:
161
114
  type: streamable-http
162
- url: "http://localhost:8008/"
115
+ url: "http://gitlab-mcp:8008/"
163
116
  headers:
164
117
  Authorization: "Bearer {{GITLAB_PAT}}"
165
118
  X-GitLab-Url: "{{GITLAB_URL_OVERRIDE}}"
@@ -172,514 +125,115 @@ mcpServers:
172
125
  description: "e.g., https://gitlab.yourdomain.com"
173
126
  ```
174
127
 
175
- 5. **Restart LibreChat:**
128
+ ### 4. Restart LibreChat:
129
+
176
130
  ```bash
177
131
  docker compose down && docker compose -f docker-compose.yml -f docker-compose.override.yml up -d
178
132
  ```
179
133
 
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
- ```
134
+ ---
220
135
 
221
- 2. Run the server:
222
- ```bash
223
- GITLAB_URL=https://your-gitlab.com GITLAB_ACCESS_TOKEN=your-token npm start
224
- ```
136
+ ## Available Tools
137
+
138
+ ### Search & Discovery
139
+ | Tool | Description |
140
+ |------|-------------|
141
+ | `search_gitlab` | Global search across projects, issues, and merge requests |
142
+ | `search_projects` | Find repositories by name or description |
143
+ | `search_issues` | Search issues globally or within a project (filter by assignee, author, labels, state) |
144
+ | `search_merge_requests` | Find merge requests by username or within a project |
145
+ | `search_users` | Find team members and contributors |
146
+ | `search_groups` | Discover groups and organizations |
147
+ | `browse_repository` | Explore directory structure and files |
148
+ | `get_file_content` | Read file contents for code analysis |
149
+
150
+ ### Read Operations
151
+ | Tool | Description |
152
+ |------|-------------|
153
+ | `get_project` | Detailed project information |
154
+ | `get_issues` | List project issues with pagination |
155
+ | `get_merge_requests` | List project merge requests with pagination |
156
+ | `get_user_issues` | Get all issues assigned to a user |
157
+ | `get_user_merge_requests` | Get MRs authored by or assigned to a user |
158
+ | `resolve_path` | Resolve a path to a project or group |
159
+ | `get_available_queries` | Discover available GraphQL operations |
160
+ | `execute_custom_query` | Run custom GraphQL queries |
161
+
162
+ ### Write Operations (requires user authentication)
163
+ | Tool | Description |
164
+ |------|-------------|
165
+ | `create_issue` | Create new issues |
166
+ | `create_merge_request` | Create new merge requests |
167
+ | `update_issue` | Update title, description, assignees, labels, due date |
168
+ | `update_merge_request` | Update title, description, assignees, reviewers, labels |
169
+
170
+ ---
225
171
 
226
172
  ## Configuration
227
173
 
228
174
  ### Authentication Modes
229
175
 
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 |
176
+ | Mode | Description | Use Case |
177
+ |------|-------------|----------|
178
+ | **hybrid** (default) | Shared token for reads + per-user tokens for writes | Multi-user deployments |
179
+ | **shared** | Single token for all operations | Single-user / trusted environments |
180
+ | **per-user** | All operations require user authentication | High-security environments |
253
181
 
254
182
  ### Environment Variables
255
183
 
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
- })
184
+ | Variable | Description | Default |
185
+ |----------|-------------|---------|
186
+ | `GITLAB_URL` | GitLab instance URL | `https://gitlab.com` |
187
+ | `GITLAB_AUTH_MODE` | Authentication mode (`hybrid`, `shared`, `per-user`) | `hybrid` |
188
+ | `GITLAB_SHARED_ACCESS_TOKEN` | Shared token for read operations | |
189
+ | `GITLAB_MAX_PAGE_SIZE` | Maximum items per page (1-100) | `50` |
190
+ | `GITLAB_TIMEOUT` | Request timeout in milliseconds | `30000` |
191
+ | `GITLAB_MCP_PORT` | HTTP server port (LibreChat mode) | `8008` |
192
+ | `MCP_TRANSPORT` | Transport mode (`http` for LibreChat) | stdio |
384
193
 
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
194
+ ---
617
195
 
618
196
  ## Troubleshooting
619
197
 
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`
198
+ **Connection issues with LibreChat:**
199
+ - Verify `type: streamable-http` in `librechat.yml` (not `sse`)
200
+ - URL should be `http://gitlab-mcp:8008/` (the Docker service name, not localhost)
201
+ - Ensure both containers share the same Docker network
202
+ - Check logs: `docker logs gitlab-mcp`
645
203
 
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+)
204
+ **Authentication errors:**
205
+ - Verify token has `read_api` or `api` scope and hasn't expired
206
+ - For LibreChat: check the user provided a valid PAT in the credentials UI
650
207
 
651
- ### Debug Logging
208
+ **Schema introspection failed:**
209
+ - Requires GitLab 12.0+ with GraphQL API enabled
210
+ - Verify `GITLAB_URL` is reachable from the container
652
211
 
653
- Set `NODE_ENV=development` for detailed logging:
212
+ **Debug logging:**
654
213
  ```bash
655
214
  NODE_ENV=development GITLAB_URL=https://your-gitlab.com npm start
656
215
  ```
657
216
 
658
- ### Health Check
659
-
660
- Test server health and active sessions:
217
+ **Health check (HTTP mode):**
661
218
  ```bash
662
219
  curl http://localhost:8008/health
663
220
  ```
664
221
 
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
- }
222
+ ---
223
+
224
+ ## Testing
225
+
226
+ ```bash
227
+ # Test with MCP Inspector
228
+ npx @modelcontextprotocol/inspector npx @ttpears/gitlab-mcp-server
674
229
  ```
675
230
 
676
231
  ## Contributing
677
232
 
678
233
  1. Fork the repository
679
234
  2. Create a feature branch
680
- 3. Add tests for new functionality
681
- 4. Submit a pull request
235
+ 3. Submit a pull request
682
236
 
683
237
  ## License
684
238
 
685
- MIT License - see LICENSE file for details.
239
+ 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.1",
3
+ "version": "1.7.3",
4
4
  "description": "GitLab MCP Server with GraphQL discovery",
5
5
  "main": "dist/index.js",
6
6
  "module": "./src/index.ts",