@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/dist/index.js
ADDED
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
|
+
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
|
+
import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
|
|
5
|
+
import { randomUUID } from 'node:crypto';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import express from 'express';
|
|
8
|
+
import { zodToJsonSchema } from 'zod-to-json-schema';
|
|
9
|
+
import { z } from 'zod';
|
|
10
|
+
// Helper to break type inference chain and avoid "Type instantiation is excessively deep" errors
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
const toJsonSchema = (schema) => zodToJsonSchema(schema, { target: 'jsonSchema7' });
|
|
13
|
+
import { ListToolsRequestSchema, CallToolRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, ErrorCode, McpError, } from '@modelcontextprotocol/sdk/types.js';
|
|
14
|
+
import { loadConfig } from './config.js';
|
|
15
|
+
import { GitLabGraphQLClient } from './gitlab-client.js';
|
|
16
|
+
import { tools } from './tools.js';
|
|
17
|
+
class GitLabMCPServer {
|
|
18
|
+
server = null; // Used only for stdio mode
|
|
19
|
+
gitlabClient;
|
|
20
|
+
httpSessions = new Map();
|
|
21
|
+
sessionCleanupInterval;
|
|
22
|
+
constructor() {
|
|
23
|
+
// Initialize GitLab client using environment configuration
|
|
24
|
+
const config = loadConfig();
|
|
25
|
+
this.gitlabClient = new GitLabGraphQLClient(config);
|
|
26
|
+
// Log configuration on startup (for debugging)
|
|
27
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
28
|
+
console.error('[MCP] Configuration loaded:');
|
|
29
|
+
console.error(` GitLab URL: ${config.gitlabUrl}`);
|
|
30
|
+
console.error(` Auth mode: ${config.authMode}`);
|
|
31
|
+
console.error(` Shared token: ${config.sharedAccessToken ? '✓ configured' : '✗ not set'}`);
|
|
32
|
+
console.error(` Max page size: ${config.maxPageSize}`);
|
|
33
|
+
console.error(` Timeout: ${config.defaultTimeout}ms`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Create a new MCP Server instance with all handlers configured
|
|
38
|
+
*/
|
|
39
|
+
createServer() {
|
|
40
|
+
const server = new Server({
|
|
41
|
+
name: 'gitlab-mcp-server',
|
|
42
|
+
version: '1.7.0',
|
|
43
|
+
}, {
|
|
44
|
+
capabilities: {
|
|
45
|
+
tools: {},
|
|
46
|
+
prompts: {},
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
this.setupToolHandlers(server);
|
|
50
|
+
this.setupPromptHandlers(server);
|
|
51
|
+
server.onerror = (error) => {
|
|
52
|
+
console.error('[MCP Error]', error);
|
|
53
|
+
};
|
|
54
|
+
return server;
|
|
55
|
+
}
|
|
56
|
+
setupToolHandlers(server) {
|
|
57
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
58
|
+
return {
|
|
59
|
+
tools: tools.map(tool => ({
|
|
60
|
+
name: tool.name,
|
|
61
|
+
...(tool.title && { title: tool.title }),
|
|
62
|
+
description: tool.description,
|
|
63
|
+
inputSchema: toJsonSchema(tool.inputSchema),
|
|
64
|
+
...(tool.outputSchema && { outputSchema: toJsonSchema(tool.outputSchema) }),
|
|
65
|
+
...(tool.annotations && { annotations: tool.annotations }),
|
|
66
|
+
...(tool.icon && { icon: tool.icon }),
|
|
67
|
+
})),
|
|
68
|
+
};
|
|
69
|
+
});
|
|
70
|
+
server.setRequestHandler(CallToolRequestSchema, async (request, extra) => {
|
|
71
|
+
const { name, arguments: args } = request.params;
|
|
72
|
+
const tool = tools.find(t => t.name === name);
|
|
73
|
+
if (!tool) {
|
|
74
|
+
throw new McpError(ErrorCode.MethodNotFound, `Tool ${name} not found`);
|
|
75
|
+
}
|
|
76
|
+
try {
|
|
77
|
+
const validatedInput = tool.inputSchema.parse(args || {});
|
|
78
|
+
// Extract user credentials: prioritize args, fallback to session-specific config
|
|
79
|
+
let userConfig = validatedInput.userCredentials;
|
|
80
|
+
// If no credentials in args, try to get from session context
|
|
81
|
+
if (!userConfig && extra?._meta?.sessionId) {
|
|
82
|
+
const sessionData = this.httpSessions.get(extra._meta.sessionId);
|
|
83
|
+
if (sessionData?.userConfig) {
|
|
84
|
+
userConfig = sessionData.userConfig;
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
delete validatedInput.userCredentials; // Remove from input to avoid passing to handler
|
|
88
|
+
const result = await tool.handler(validatedInput, this.gitlabClient, userConfig);
|
|
89
|
+
return {
|
|
90
|
+
content: [
|
|
91
|
+
{
|
|
92
|
+
type: 'text',
|
|
93
|
+
text: JSON.stringify(result, null, 2),
|
|
94
|
+
},
|
|
95
|
+
],
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
catch (error) {
|
|
99
|
+
if (error instanceof Error) {
|
|
100
|
+
throw new McpError(ErrorCode.InternalError, error.message);
|
|
101
|
+
}
|
|
102
|
+
throw new McpError(ErrorCode.InternalError, 'Unknown error occurred');
|
|
103
|
+
}
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
setupPromptHandlers(server) {
|
|
107
|
+
// Define helpful prompts for common GitLab workflows
|
|
108
|
+
const prompts = [
|
|
109
|
+
{
|
|
110
|
+
name: 'explore-project',
|
|
111
|
+
title: 'Explore Project',
|
|
112
|
+
description: 'Explore a GitLab project structure and recent activity',
|
|
113
|
+
arguments: [
|
|
114
|
+
{
|
|
115
|
+
name: 'projectPath',
|
|
116
|
+
description: 'Full path of the project (e.g., "group/project-name")',
|
|
117
|
+
required: true,
|
|
118
|
+
},
|
|
119
|
+
],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
name: 'find-my-work',
|
|
123
|
+
title: 'Find My Work',
|
|
124
|
+
description: 'Find issues and merge requests assigned to you',
|
|
125
|
+
arguments: [],
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
name: 'review-merge-request',
|
|
129
|
+
title: 'Review Merge Request',
|
|
130
|
+
description: 'Review a specific merge request with code changes',
|
|
131
|
+
arguments: [
|
|
132
|
+
{
|
|
133
|
+
name: 'projectPath',
|
|
134
|
+
description: 'Full path of the project (e.g., "group/project-name")',
|
|
135
|
+
required: true,
|
|
136
|
+
},
|
|
137
|
+
{
|
|
138
|
+
name: 'mrIid',
|
|
139
|
+
description: 'Merge request IID number',
|
|
140
|
+
required: true,
|
|
141
|
+
},
|
|
142
|
+
],
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
server.setRequestHandler(ListPromptsRequestSchema, async () => {
|
|
146
|
+
return { prompts };
|
|
147
|
+
});
|
|
148
|
+
server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
149
|
+
const { name, arguments: args } = request.params;
|
|
150
|
+
if (name === 'explore-project') {
|
|
151
|
+
const projectPath = args?.projectPath;
|
|
152
|
+
return {
|
|
153
|
+
messages: [
|
|
154
|
+
{
|
|
155
|
+
role: 'user',
|
|
156
|
+
content: {
|
|
157
|
+
type: 'text',
|
|
158
|
+
text: `Please explore the GitLab project "${projectPath}". Show me:
|
|
159
|
+
1. Project overview and description
|
|
160
|
+
2. Recent issues (last 10)
|
|
161
|
+
3. Recent merge requests (last 10)
|
|
162
|
+
4. Repository structure (browse the root directory)
|
|
163
|
+
|
|
164
|
+
Provide direct links to all resources you find.`,
|
|
165
|
+
},
|
|
166
|
+
},
|
|
167
|
+
],
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
if (name === 'find-my-work') {
|
|
171
|
+
return {
|
|
172
|
+
messages: [
|
|
173
|
+
{
|
|
174
|
+
role: 'user',
|
|
175
|
+
content: {
|
|
176
|
+
type: 'text',
|
|
177
|
+
text: `Please find all issues and merge requests assigned to me. Search for:
|
|
178
|
+
1. Open issues assigned to me
|
|
179
|
+
2. Open merge requests where I'm assigned or a reviewer
|
|
180
|
+
3. Recently closed items from the last week
|
|
181
|
+
|
|
182
|
+
Provide direct links to each item and summarize the current state.`,
|
|
183
|
+
},
|
|
184
|
+
},
|
|
185
|
+
],
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
if (name === 'review-merge-request') {
|
|
189
|
+
const projectPath = args?.projectPath;
|
|
190
|
+
const mrIid = args?.mrIid;
|
|
191
|
+
return {
|
|
192
|
+
messages: [
|
|
193
|
+
{
|
|
194
|
+
role: 'user',
|
|
195
|
+
content: {
|
|
196
|
+
type: 'text',
|
|
197
|
+
text: `Please review merge request !${mrIid} in project "${projectPath}". Show me:
|
|
198
|
+
1. MR title, description, and status
|
|
199
|
+
2. Source and target branches
|
|
200
|
+
3. Changed files (browse the repository at both refs if needed)
|
|
201
|
+
4. Related issues
|
|
202
|
+
5. Review comments and approvals
|
|
203
|
+
|
|
204
|
+
Provide the direct link to the MR and suggest any concerns or next steps.`,
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
],
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
throw new McpError(ErrorCode.InvalidRequest, `Unknown prompt: ${name}`);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
setupProcessHandlers() {
|
|
214
|
+
process.on('SIGINT', async () => {
|
|
215
|
+
if (this.sessionCleanupInterval) {
|
|
216
|
+
clearInterval(this.sessionCleanupInterval);
|
|
217
|
+
}
|
|
218
|
+
// Close all HTTP sessions
|
|
219
|
+
for (const [sessionId, data] of this.httpSessions.entries()) {
|
|
220
|
+
try {
|
|
221
|
+
await data.server.close();
|
|
222
|
+
}
|
|
223
|
+
catch (e) {
|
|
224
|
+
// Ignore errors during shutdown
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
this.httpSessions.clear();
|
|
228
|
+
// Close stdio server if running
|
|
229
|
+
if (this.server) {
|
|
230
|
+
await this.server.close();
|
|
231
|
+
}
|
|
232
|
+
process.exit(0);
|
|
233
|
+
});
|
|
234
|
+
}
|
|
235
|
+
/**
|
|
236
|
+
* Start periodic cleanup of inactive sessions
|
|
237
|
+
*/
|
|
238
|
+
startSessionCleanup() {
|
|
239
|
+
const SESSION_TIMEOUT = 10 * 60 * 1000; // 10 minutes (reduced from 30)
|
|
240
|
+
const CLEANUP_INTERVAL = 2 * 60 * 1000; // Check every 2 minutes (reduced from 5)
|
|
241
|
+
this.sessionCleanupInterval = setInterval(() => {
|
|
242
|
+
const now = Date.now();
|
|
243
|
+
const expiredSessions = [];
|
|
244
|
+
for (const [sessionId, data] of this.httpSessions.entries()) {
|
|
245
|
+
if (now - data.lastActivity > SESSION_TIMEOUT) {
|
|
246
|
+
expiredSessions.push(sessionId);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
for (const sessionId of expiredSessions) {
|
|
250
|
+
const data = this.httpSessions.get(sessionId);
|
|
251
|
+
if (data) {
|
|
252
|
+
console.error(`[MCP] Session ${sessionId} expired due to inactivity`);
|
|
253
|
+
data.server.close().catch(() => { });
|
|
254
|
+
data.transport.close().catch(() => { });
|
|
255
|
+
this.httpSessions.delete(sessionId);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
if (expiredSessions.length > 0) {
|
|
259
|
+
console.error(`[MCP] Cleaned up ${expiredSessions.length} expired session(s). Active sessions: ${this.httpSessions.size}`);
|
|
260
|
+
}
|
|
261
|
+
}, CLEANUP_INTERVAL);
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Extract and validate user credentials from request headers
|
|
265
|
+
*/
|
|
266
|
+
extractUserCredentials(req) {
|
|
267
|
+
const authHeader = req.headers['authorization'] || '';
|
|
268
|
+
const gitlabUrlHeader = req.headers['x-gitlab-url'] || undefined;
|
|
269
|
+
if (!authHeader) {
|
|
270
|
+
return undefined;
|
|
271
|
+
}
|
|
272
|
+
const token = authHeader.startsWith('Bearer ')
|
|
273
|
+
? authHeader.slice('Bearer '.length).trim()
|
|
274
|
+
: authHeader.trim();
|
|
275
|
+
if (!token) {
|
|
276
|
+
return undefined;
|
|
277
|
+
}
|
|
278
|
+
return { accessToken: token, gitlabUrl: gitlabUrlHeader };
|
|
279
|
+
}
|
|
280
|
+
/**
|
|
281
|
+
* Shared handler for Streamable HTTP requests (used by both / and /mcp endpoints)
|
|
282
|
+
*/
|
|
283
|
+
async handleStreamableHTTP(req, res) {
|
|
284
|
+
try {
|
|
285
|
+
// Debug logging to understand what's happening
|
|
286
|
+
const hasBody = req.body && Object.keys(req.body).length > 0;
|
|
287
|
+
const bodyPreview = hasBody ? JSON.stringify(req.body).substring(0, 100) : 'empty';
|
|
288
|
+
// Validate Accept header per MCP spec
|
|
289
|
+
const acceptHeader = req.headers['accept'] || '';
|
|
290
|
+
const supportsJson = acceptHeader.includes('application/json');
|
|
291
|
+
const supportsSse = acceptHeader.includes('text/event-stream');
|
|
292
|
+
if (!supportsJson && !supportsSse) {
|
|
293
|
+
res.status(400).json({
|
|
294
|
+
jsonrpc: '2.0',
|
|
295
|
+
error: {
|
|
296
|
+
code: -32000,
|
|
297
|
+
message: 'Bad Request: Accept header must include application/json or text/event-stream'
|
|
298
|
+
},
|
|
299
|
+
id: null,
|
|
300
|
+
});
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
303
|
+
// Get session ID from header (check both lowercase and capitalized)
|
|
304
|
+
const sessionIdHeader = req.headers['mcp-session-id'] ||
|
|
305
|
+
req.headers['Mcp-Session-Id'] || '';
|
|
306
|
+
console.error(`[MCP] Request: ${req.method} session=${sessionIdHeader || 'none'} body=${bodyPreview}`);
|
|
307
|
+
if (sessionIdHeader && this.httpSessions.has(sessionIdHeader)) {
|
|
308
|
+
// Existing session: reuse transport and update credentials
|
|
309
|
+
const sessionData = this.httpSessions.get(sessionIdHeader);
|
|
310
|
+
const userConfig = this.extractUserCredentials(req);
|
|
311
|
+
// Update session-specific credentials if provided
|
|
312
|
+
if (userConfig) {
|
|
313
|
+
sessionData.userConfig = userConfig;
|
|
314
|
+
}
|
|
315
|
+
// Update last activity timestamp
|
|
316
|
+
sessionData.lastActivity = Date.now();
|
|
317
|
+
// Don't log every request, only session changes
|
|
318
|
+
await sessionData.transport.handleRequest(req, res, req.body);
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
// New session initialization
|
|
322
|
+
if (req.method === 'POST') {
|
|
323
|
+
// If we have too many sessions, clean up old ones immediately
|
|
324
|
+
if (this.httpSessions.size > 10) {
|
|
325
|
+
const now = Date.now();
|
|
326
|
+
const oldSessions = [];
|
|
327
|
+
// Find sessions older than 5 minutes
|
|
328
|
+
for (const [sessionId, data] of this.httpSessions.entries()) {
|
|
329
|
+
if (now - data.lastActivity > 5 * 60 * 1000) {
|
|
330
|
+
oldSessions.push(sessionId);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
// Close and remove old sessions
|
|
334
|
+
for (const sessionId of oldSessions) {
|
|
335
|
+
const data = this.httpSessions.get(sessionId);
|
|
336
|
+
if (data) {
|
|
337
|
+
console.error(`[MCP] Force-closing old session ${sessionId}`);
|
|
338
|
+
data.server.close().catch(() => { });
|
|
339
|
+
data.transport.close().catch(() => { });
|
|
340
|
+
this.httpSessions.delete(sessionId);
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
if (oldSessions.length > 0) {
|
|
344
|
+
console.error(`[MCP] Emergency cleanup: removed ${oldSessions.length} old sessions (total now: ${this.httpSessions.size})`);
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
// Create a new Server instance for this session
|
|
348
|
+
const server = this.createServer();
|
|
349
|
+
const transport = new StreamableHTTPServerTransport({
|
|
350
|
+
sessionIdGenerator: () => randomUUID(),
|
|
351
|
+
onsessioninitialized: (sessionId) => {
|
|
352
|
+
const userConfig = this.extractUserCredentials(req);
|
|
353
|
+
this.httpSessions.set(sessionId, {
|
|
354
|
+
server,
|
|
355
|
+
transport,
|
|
356
|
+
userConfig,
|
|
357
|
+
lastActivity: Date.now()
|
|
358
|
+
});
|
|
359
|
+
console.error(`[MCP] Session ${sessionId} initialized with ${userConfig ? 'user' : 'shared'} credentials (total sessions: ${this.httpSessions.size})`);
|
|
360
|
+
},
|
|
361
|
+
});
|
|
362
|
+
transport.onclose = () => {
|
|
363
|
+
if (transport.sessionId) {
|
|
364
|
+
console.error(`[MCP] Session ${transport.sessionId} closed (remaining sessions: ${this.httpSessions.size - 1})`);
|
|
365
|
+
const sessionData = this.httpSessions.get(transport.sessionId);
|
|
366
|
+
if (sessionData) {
|
|
367
|
+
sessionData.server.close().catch(() => { });
|
|
368
|
+
}
|
|
369
|
+
this.httpSessions.delete(transport.sessionId);
|
|
370
|
+
}
|
|
371
|
+
};
|
|
372
|
+
// Handle errors on the transport
|
|
373
|
+
transport.onerror = (error) => {
|
|
374
|
+
console.error(`[MCP] Transport error for session ${transport.sessionId}:`, error.message);
|
|
375
|
+
};
|
|
376
|
+
await server.connect(transport);
|
|
377
|
+
await transport.handleRequest(req, res, req.body);
|
|
378
|
+
return;
|
|
379
|
+
}
|
|
380
|
+
// No valid session and not a POST request
|
|
381
|
+
res.status(400).json({
|
|
382
|
+
jsonrpc: '2.0',
|
|
383
|
+
error: {
|
|
384
|
+
code: -32000,
|
|
385
|
+
message: 'Bad Request: No valid session ID provided. Initialize with POST request.'
|
|
386
|
+
},
|
|
387
|
+
id: null,
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
catch (error) {
|
|
391
|
+
console.error('[MCP] Error in Streamable HTTP endpoint:', error);
|
|
392
|
+
if (!res.headersSent) {
|
|
393
|
+
res.status(500).json({
|
|
394
|
+
jsonrpc: '2.0',
|
|
395
|
+
error: { code: -32603, message: 'Internal server error' },
|
|
396
|
+
id: null,
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
async run() {
|
|
402
|
+
try {
|
|
403
|
+
const config = loadConfig();
|
|
404
|
+
// Try to introspect schema on startup if we have a shared token
|
|
405
|
+
if (config.sharedAccessToken) {
|
|
406
|
+
try {
|
|
407
|
+
await this.gitlabClient.introspectSchema();
|
|
408
|
+
console.error('GitLab GraphQL schema introspected successfully using shared token');
|
|
409
|
+
}
|
|
410
|
+
catch (error) {
|
|
411
|
+
console.error('Warning: Failed to introspect schema with shared token:', error);
|
|
412
|
+
console.error('Schema will be introspected when user credentials are provided');
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
console.error('No shared access token provided. Schema will be introspected when user credentials are provided.');
|
|
417
|
+
}
|
|
418
|
+
// Determine transport based on environment
|
|
419
|
+
// Note: For Smithery TypeScript runtime, run in stdio; their wrapper provides HTTP.
|
|
420
|
+
const port = process.env.GITLAB_MCP_PORT ? parseInt(process.env.GITLAB_MCP_PORT) : null;
|
|
421
|
+
const useHttp = process.env.MCP_TRANSPORT === 'http';
|
|
422
|
+
if (useHttp && port) {
|
|
423
|
+
// Streamable HTTP transport for LibreChat and modern MCP clients
|
|
424
|
+
const app = express();
|
|
425
|
+
// Disable X-Powered-By header
|
|
426
|
+
app.disable('x-powered-by');
|
|
427
|
+
// Parse JSON bodies - but NOT for /message endpoint (SSE transport needs raw stream)
|
|
428
|
+
app.use((req, res, next) => {
|
|
429
|
+
if (req.path === '/message') {
|
|
430
|
+
// Skip JSON parsing for SSE message endpoint
|
|
431
|
+
next();
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
express.json()(req, res, next);
|
|
435
|
+
}
|
|
436
|
+
});
|
|
437
|
+
// CORS and headers
|
|
438
|
+
app.use((req, res, next) => {
|
|
439
|
+
res.header('Access-Control-Allow-Origin', '*');
|
|
440
|
+
res.header('Access-Control-Allow-Methods', 'GET, POST, DELETE, OPTIONS');
|
|
441
|
+
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-GitLab-Url, Mcp-Session-Id, Accept, Last-Event-ID, Cache-Control');
|
|
442
|
+
res.header('Access-Control-Expose-Headers', 'Mcp-Session-Id, MCP-Protocol-Version');
|
|
443
|
+
res.header('MCP-Protocol-Version', '2025-11-25');
|
|
444
|
+
// Disable buffering for SSE streams
|
|
445
|
+
if (req.headers.accept?.includes('text/event-stream')) {
|
|
446
|
+
res.setHeader('Cache-Control', 'no-cache');
|
|
447
|
+
res.setHeader('Connection', 'keep-alive');
|
|
448
|
+
res.setHeader('X-Accel-Buffering', 'no');
|
|
449
|
+
}
|
|
450
|
+
if (req.method === 'OPTIONS') {
|
|
451
|
+
res.sendStatus(200);
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
454
|
+
next();
|
|
455
|
+
});
|
|
456
|
+
// Streamable HTTP endpoint at root (primary transport)
|
|
457
|
+
app.all('/', (req, res) => this.handleStreamableHTTP(req, res));
|
|
458
|
+
// Alternative /mcp endpoint for container compatibility
|
|
459
|
+
app.all('/mcp', (req, res) => this.handleStreamableHTTP(req, res));
|
|
460
|
+
// DELETE support for explicit session termination (per MCP spec)
|
|
461
|
+
app.delete('/', async (req, res) => {
|
|
462
|
+
const sessionIdHeader = req.headers['mcp-session-id'] || '';
|
|
463
|
+
if (sessionIdHeader && this.httpSessions.has(sessionIdHeader)) {
|
|
464
|
+
const sessionData = this.httpSessions.get(sessionIdHeader);
|
|
465
|
+
await sessionData.server.close();
|
|
466
|
+
await sessionData.transport.close();
|
|
467
|
+
this.httpSessions.delete(sessionIdHeader);
|
|
468
|
+
console.error(`[MCP] Session ${sessionIdHeader} terminated by client`);
|
|
469
|
+
res.sendStatus(200);
|
|
470
|
+
}
|
|
471
|
+
else {
|
|
472
|
+
res.status(404).json({
|
|
473
|
+
jsonrpc: '2.0',
|
|
474
|
+
error: { code: -32001, message: 'Session not found' },
|
|
475
|
+
id: null,
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
});
|
|
479
|
+
app.delete('/mcp', async (req, res) => {
|
|
480
|
+
const sessionIdHeader = req.headers['mcp-session-id'] || '';
|
|
481
|
+
if (sessionIdHeader && this.httpSessions.has(sessionIdHeader)) {
|
|
482
|
+
const sessionData = this.httpSessions.get(sessionIdHeader);
|
|
483
|
+
await sessionData.server.close();
|
|
484
|
+
await sessionData.transport.close();
|
|
485
|
+
this.httpSessions.delete(sessionIdHeader);
|
|
486
|
+
console.error(`[MCP] Session ${sessionIdHeader} terminated by client`);
|
|
487
|
+
res.sendStatus(200);
|
|
488
|
+
}
|
|
489
|
+
else {
|
|
490
|
+
res.status(404).json({
|
|
491
|
+
jsonrpc: '2.0',
|
|
492
|
+
error: { code: -32001, message: 'Session not found' },
|
|
493
|
+
id: null,
|
|
494
|
+
});
|
|
495
|
+
}
|
|
496
|
+
});
|
|
497
|
+
// Container-runtime compatibility: serve config schema
|
|
498
|
+
app.get('/.well-known/mcp-config', (req, res) => {
|
|
499
|
+
res.set('Content-Type', 'application/schema+json; charset=utf-8');
|
|
500
|
+
const baseSchema = toJsonSchema(configSchema);
|
|
501
|
+
const configJsonSchema = {
|
|
502
|
+
$schema: 'https://json-schema.org/draft/2020-12/schema',
|
|
503
|
+
$id: `${req.protocol}://${req.get('host')}/.well-known/mcp-config`,
|
|
504
|
+
title: 'MCP Session Configuration',
|
|
505
|
+
description: 'Schema for the /mcp endpoint configuration',
|
|
506
|
+
'x-mcp-version': '1.0',
|
|
507
|
+
'x-query-style': 'dot+bracket',
|
|
508
|
+
...baseSchema,
|
|
509
|
+
};
|
|
510
|
+
res.json(configJsonSchema);
|
|
511
|
+
});
|
|
512
|
+
// Health check endpoint
|
|
513
|
+
app.get('/health', (req, res) => {
|
|
514
|
+
res.json({
|
|
515
|
+
status: 'healthy',
|
|
516
|
+
timestamp: new Date().toISOString(),
|
|
517
|
+
sessions: this.httpSessions.size,
|
|
518
|
+
protocol: '2025-11-25'
|
|
519
|
+
});
|
|
520
|
+
});
|
|
521
|
+
app.listen(port, () => {
|
|
522
|
+
console.error('='.repeat(60));
|
|
523
|
+
console.error('GitLab MCP Server - HTTP Mode');
|
|
524
|
+
console.error('='.repeat(60));
|
|
525
|
+
console.error(`Server: http://localhost:${port}`);
|
|
526
|
+
console.error(`Streamable HTTP: http://localhost:${port}/ (recommended)`);
|
|
527
|
+
console.error(`Alternative: http://localhost:${port}/mcp`);
|
|
528
|
+
console.error(`Health check: http://localhost:${port}/health`);
|
|
529
|
+
console.error(`Protocol: MCP 2025-11-25`);
|
|
530
|
+
console.error('');
|
|
531
|
+
console.error('Configuration:');
|
|
532
|
+
console.error(` Auth mode: ${loadConfig().authMode}`);
|
|
533
|
+
console.error(` GitLab URL: ${loadConfig().gitlabUrl}`);
|
|
534
|
+
console.error(` Session cleanup: 10min timeout, checked every 2min`);
|
|
535
|
+
console.error('');
|
|
536
|
+
console.error('For LibreChat: Use streamable-http transport in librechat.yml');
|
|
537
|
+
console.error('='.repeat(60));
|
|
538
|
+
// Start session cleanup
|
|
539
|
+
this.startSessionCleanup();
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
else {
|
|
543
|
+
// Default to stdio transport
|
|
544
|
+
const config = loadConfig();
|
|
545
|
+
console.error('='.repeat(60));
|
|
546
|
+
console.error('GitLab MCP Server - stdio Mode');
|
|
547
|
+
console.error('='.repeat(60));
|
|
548
|
+
console.error('Transport: stdio (for Claude Desktop, Claude Code, VS Code)');
|
|
549
|
+
console.error(`Protocol: MCP 2025-11-25`);
|
|
550
|
+
console.error('');
|
|
551
|
+
console.error('Configuration:');
|
|
552
|
+
console.error(` Auth mode: ${config.authMode}`);
|
|
553
|
+
console.error(` GitLab URL: ${config.gitlabUrl}`);
|
|
554
|
+
console.error(` Shared token: ${config.sharedAccessToken ? '✓ configured' : '✗ not set'}`);
|
|
555
|
+
console.error('');
|
|
556
|
+
console.error('Tip: Set GITLAB_MCP_PORT to enable HTTP mode for LibreChat');
|
|
557
|
+
console.error('='.repeat(60));
|
|
558
|
+
// Create server for stdio mode
|
|
559
|
+
this.server = this.createServer();
|
|
560
|
+
const transport = new StdioServerTransport();
|
|
561
|
+
await this.server.connect(transport);
|
|
562
|
+
}
|
|
563
|
+
// Setup process signal handlers
|
|
564
|
+
this.setupProcessHandlers();
|
|
565
|
+
}
|
|
566
|
+
catch (error) {
|
|
567
|
+
console.error('Failed to start server:', error);
|
|
568
|
+
process.exit(1);
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
// Smithery TypeScript runtime expects a default export that returns an MCP Server instance.
|
|
573
|
+
// This factory prepares the server with all handlers but does not bind transports.
|
|
574
|
+
export default function createMcpServer(_args) {
|
|
575
|
+
const instance = new GitLabMCPServer();
|
|
576
|
+
// Create and return a new Server instance; the host (e.g., Smithery) will call connect(transport)
|
|
577
|
+
// and manage the Streamable HTTP session lifecycle.
|
|
578
|
+
// @ts-ignore accessing private for integration factory
|
|
579
|
+
return instance.createServer();
|
|
580
|
+
}
|
|
581
|
+
// Optional: expose a (currently empty) config schema for /.well-known/mcp-config
|
|
582
|
+
export const configSchema = z.object({});
|
|
583
|
+
// Run in CLI mode only if this file is the program entry-point
|
|
584
|
+
const isMain = (() => {
|
|
585
|
+
try {
|
|
586
|
+
const thisFile = fileURLToPath(import.meta.url);
|
|
587
|
+
return process.argv[1] && thisFile === process.argv[1];
|
|
588
|
+
}
|
|
589
|
+
catch {
|
|
590
|
+
return false;
|
|
591
|
+
}
|
|
592
|
+
})();
|
|
593
|
+
if (isMain) {
|
|
594
|
+
const cli = new GitLabMCPServer();
|
|
595
|
+
cli.run().catch((error) => {
|
|
596
|
+
console.error('Server failed:', error);
|
|
597
|
+
process.exit(1);
|
|
598
|
+
});
|
|
599
|
+
}
|
|
600
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.d.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { GitLabGraphQLClient } from './gitlab-client.js';
|
|
3
|
+
import { type UserConfig } from './config.js';
|
|
4
|
+
export interface Tool {
|
|
5
|
+
name: string;
|
|
6
|
+
title?: string;
|
|
7
|
+
description: string;
|
|
8
|
+
inputSchema: z.ZodSchema;
|
|
9
|
+
outputSchema?: z.ZodSchema;
|
|
10
|
+
requiresAuth: boolean;
|
|
11
|
+
requiresWrite: boolean;
|
|
12
|
+
annotations?: {
|
|
13
|
+
readOnlyHint?: boolean;
|
|
14
|
+
destructiveHint?: boolean;
|
|
15
|
+
idempotentHint?: boolean;
|
|
16
|
+
};
|
|
17
|
+
icon?: {
|
|
18
|
+
type: 'base64' | 'url';
|
|
19
|
+
mediaType?: string;
|
|
20
|
+
data: string;
|
|
21
|
+
};
|
|
22
|
+
handler: (input: any, client: GitLabGraphQLClient, userConfig?: UserConfig) => Promise<any>;
|
|
23
|
+
}
|
|
24
|
+
export declare const readOnlyTools: Tool[];
|
|
25
|
+
export declare const userAuthTools: Tool[];
|
|
26
|
+
export declare const writeTools: Tool[];
|
|
27
|
+
export declare const searchTools: Tool[];
|
|
28
|
+
export declare const tools: Tool[];
|
|
29
|
+
//# sourceMappingURL=tools.d.ts.map
|