@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 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.