@zereight/mcp-gitlab 1.0.69 → 1.0.70

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/build/index.js CHANGED
@@ -29,7 +29,19 @@ GitLabDiscussionNoteSchema, // Added
29
29
  GitLabDiscussionSchema, PaginatedDiscussionsResponseSchema, UpdateMergeRequestNoteSchema, // Added
30
30
  CreateMergeRequestNoteSchema, // Added
31
31
  ListMergeRequestDiscussionsSchema, UpdateIssueNoteSchema, CreateIssueNoteSchema, ListMergeRequestsSchema, GitLabMilestonesSchema, ListProjectMilestonesSchema, GetProjectMilestoneSchema, CreateProjectMilestoneSchema, EditProjectMilestoneSchema, DeleteProjectMilestoneSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, PromoteProjectMilestoneSchema, GetMilestoneBurndownEventsSchema, GitLabCompareResultSchema, GetBranchDiffsSchema, ListCommitsSchema, GetCommitSchema, GetCommitDiffSchema, ListMergeRequestDiffsSchema, } from "./schemas.js";
32
+ import { formatBoolean } from "./utils.js";
32
33
  import { randomUUID } from "crypto";
34
+ import { pino } from 'pino';
35
+ const logger = pino({
36
+ level: process.env.LOG_LEVEL || 'info',
37
+ transport: {
38
+ target: 'pino-pretty',
39
+ options: {
40
+ colorize: true,
41
+ levelFirst: true,
42
+ },
43
+ },
44
+ });
33
45
  /**
34
46
  * Available transport modes for MCP server
35
47
  */
@@ -72,7 +84,7 @@ const USE_MILESTONE = process.env.USE_MILESTONE === "true";
72
84
  const USE_PIPELINE = process.env.USE_PIPELINE === "true";
73
85
  const SSE = process.env.SSE === "true";
74
86
  const STREAMABLE_HTTP = process.env.STREAMABLE_HTTP === "true";
75
- const HOST = process.env.HOST || '127.0.0.1';
87
+ const HOST = process.env.HOST || '0.0.0.0';
76
88
  const PORT = process.env.PORT || 3002;
77
89
  // Add proxy configuration
78
90
  const HTTP_PROXY = process.env.HTTP_PROXY;
@@ -144,7 +156,7 @@ const createCookieJar = () => {
144
156
  return jar;
145
157
  }
146
158
  catch (error) {
147
- console.error("Error loading cookie file:", error);
159
+ logger.error("Error loading cookie file:", error);
148
160
  return null;
149
161
  }
150
162
  };
@@ -642,7 +654,7 @@ function normalizeGitLabApiUrl(url) {
642
654
  const GITLAB_API_URL = normalizeGitLabApiUrl(process.env.GITLAB_API_URL || "");
643
655
  const GITLAB_PROJECT_ID = process.env.GITLAB_PROJECT_ID;
644
656
  if (!GITLAB_PERSONAL_ACCESS_TOKEN) {
645
- console.error("GITLAB_PERSONAL_ACCESS_TOKEN environment variable is not set");
657
+ logger.error("GITLAB_PERSONAL_ACCESS_TOKEN environment variable is not set");
646
658
  process.exit(1);
647
659
  }
648
660
  /**
@@ -657,8 +669,8 @@ async function handleGitLabError(response) {
657
669
  const errorBody = await response.text();
658
670
  // Check specifically for Rate Limit error
659
671
  if (response.status === 403 && errorBody.includes("User API Key Rate limit exceeded")) {
660
- console.error("GitLab API Rate Limit Exceeded:", errorBody);
661
- console.log("User API Key Rate limit exceeded. Please try again later.");
672
+ logger.error("GitLab API Rate Limit Exceeded:", errorBody);
673
+ logger.error("User API Key Rate limit exceeded. Please try again later.");
662
674
  throw new Error(`GitLab API Rate Limit Exceeded: ${errorBody}`);
663
675
  }
664
676
  else {
@@ -1046,7 +1058,7 @@ async function createMergeRequest(projectId, options) {
1046
1058
  labels: options.labels?.join(","),
1047
1059
  allow_collaboration: options.allow_collaboration,
1048
1060
  draft: options.draft,
1049
- remove_source_branch: options.remove_source_branch,
1061
+ remove_source_branch: formatBoolean(options.remove_source_branch),
1050
1062
  squash: options.squash,
1051
1063
  }),
1052
1064
  });
@@ -2176,10 +2188,7 @@ async function createPipeline(projectId, ref, variables) {
2176
2188
  const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline`);
2177
2189
  const body = { ref };
2178
2190
  if (variables && variables.length > 0) {
2179
- body.variables = variables.reduce((acc, { key, value }) => {
2180
- acc[key] = value;
2181
- return acc;
2182
- }, {});
2191
+ body.variables = variables;
2183
2192
  }
2184
2193
  const response = await fetch(url.toString(), {
2185
2194
  method: "POST",
@@ -2256,7 +2265,7 @@ async function getRepositoryTree(options) {
2256
2265
  else {
2257
2266
  headers["Authorization"] = `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`;
2258
2267
  }
2259
- const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(options.project_id)}/repository/tree?${queryParams.toString()}`, {
2268
+ const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(options.project_id))}/repository/tree?${queryParams.toString()}`, {
2260
2269
  headers,
2261
2270
  });
2262
2271
  if (response.status === 404) {
@@ -2456,7 +2465,7 @@ async function getUser(username) {
2456
2465
  return null;
2457
2466
  }
2458
2467
  catch (error) {
2459
- console.error(`Error fetching user by username '${username}':`, error);
2468
+ logger.error(`Error fetching user by username '${username}':`, error);
2460
2469
  return null;
2461
2470
  }
2462
2471
  }
@@ -2475,7 +2484,7 @@ async function getUsers(usernames) {
2475
2484
  users[username] = user;
2476
2485
  }
2477
2486
  catch (error) {
2478
- console.error(`Error processing username '${username}':`, error);
2487
+ logger.error(`Error processing username '${username}':`, error);
2479
2488
  users[username] = null;
2480
2489
  }
2481
2490
  }
@@ -2621,7 +2630,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2621
2630
  };
2622
2631
  }
2623
2632
  catch (forkError) {
2624
- console.error("Error forking repository:", forkError);
2633
+ logger.error("Error forking repository:", forkError);
2625
2634
  let forkErrorMessage = "Failed to fork repository";
2626
2635
  if (forkError instanceof Error) {
2627
2636
  forkErrorMessage = `${forkErrorMessage}: ${forkError.message}`;
@@ -2842,7 +2851,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2842
2851
  }
2843
2852
  case "get_project": {
2844
2853
  const args = GetProjectSchema.parse(request.params.arguments);
2845
- const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(args.project_id)}`);
2854
+ const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(args.project_id))}`);
2846
2855
  const response = await fetch(url.toString(), {
2847
2856
  ...DEFAULT_FETCH_CONFIG,
2848
2857
  });
@@ -3368,10 +3377,10 @@ async function startSSEServer() {
3368
3377
  });
3369
3378
  });
3370
3379
  app.listen(Number(PORT), HOST, () => {
3371
- console.log(`GitLab MCP Server running with SSE transport`);
3380
+ logger.info(`GitLab MCP Server running with SSE transport`);
3372
3381
  const colorGreen = "\x1b[32m";
3373
3382
  const colorReset = "\x1b[0m";
3374
- console.log(`${colorGreen}Endpoint: http://${HOST}:${PORT}/sse${colorReset}`);
3383
+ logger.info(`${colorGreen}Endpoint: http://${HOST}:${PORT}/sse${colorReset}`);
3375
3384
  });
3376
3385
  }
3377
3386
  /**
@@ -3398,14 +3407,14 @@ async function startStreamableHTTPServer() {
3398
3407
  sessionIdGenerator: () => randomUUID(),
3399
3408
  onsessioninitialized: (newSessionId) => {
3400
3409
  streamableTransports[newSessionId] = transport;
3401
- console.warn(`Streamable HTTP session initialized: ${newSessionId}`);
3410
+ logger.warn(`Streamable HTTP session initialized: ${newSessionId}`);
3402
3411
  }
3403
3412
  });
3404
3413
  // Set up cleanup handler when transport closes
3405
3414
  transport.onclose = () => {
3406
3415
  const sid = transport.sessionId;
3407
3416
  if (sid && streamableTransports[sid]) {
3408
- console.warn(`Streamable HTTP transport closed for session ${sid}, cleaning up`);
3417
+ logger.warn(`Streamable HTTP transport closed for session ${sid}, cleaning up`);
3409
3418
  delete streamableTransports[sid];
3410
3419
  }
3411
3420
  };
@@ -3415,7 +3424,7 @@ async function startStreamableHTTPServer() {
3415
3424
  }
3416
3425
  }
3417
3426
  catch (error) {
3418
- console.error('Streamable HTTP error:', error);
3427
+ logger.error('Streamable HTTP error:', error);
3419
3428
  res.status(500).json({
3420
3429
  error: 'Internal server error',
3421
3430
  message: error instanceof Error ? error.message : 'Unknown error'
@@ -3433,8 +3442,8 @@ async function startStreamableHTTPServer() {
3433
3442
  });
3434
3443
  // Start server
3435
3444
  app.listen(Number(PORT), HOST, () => {
3436
- console.log(`GitLab MCP Server running with Streamable HTTP transport`);
3437
- console.log(`${colorGreen}Endpoint: http://${HOST}:${PORT}/mcp${colorReset}`);
3445
+ logger.info(`GitLab MCP Server running with Streamable HTTP transport`);
3446
+ logger.info(`${colorGreen}Endpoint: http://${HOST}:${PORT}/mcp${colorReset}`);
3438
3447
  });
3439
3448
  }
3440
3449
  /**
@@ -3442,18 +3451,18 @@ async function startStreamableHTTPServer() {
3442
3451
  * Handle transport-specific initialization logic
3443
3452
  */
3444
3453
  async function initializeServerByTransportMode(mode) {
3445
- console.log('Initializing server with transport mode:', mode);
3454
+ logger.info('Initializing server with transport mode:', mode);
3446
3455
  switch (mode) {
3447
3456
  case TransportMode.STDIO:
3448
- console.warn('Starting GitLab MCP Server with stdio transport');
3457
+ logger.warn('Starting GitLab MCP Server with stdio transport');
3449
3458
  await startStdioServer();
3450
3459
  break;
3451
3460
  case TransportMode.SSE:
3452
- console.warn('Starting GitLab MCP Server with SSE transport');
3461
+ logger.warn('Starting GitLab MCP Server with SSE transport');
3453
3462
  await startSSEServer();
3454
3463
  break;
3455
3464
  case TransportMode.STREAMABLE_HTTP:
3456
- console.warn('Starting GitLab MCP Server with Streamable HTTP transport');
3465
+ logger.warn('Starting GitLab MCP Server with Streamable HTTP transport');
3457
3466
  await startStreamableHTTPServer();
3458
3467
  break;
3459
3468
  default:
@@ -3472,11 +3481,11 @@ async function runServer() {
3472
3481
  await initializeServerByTransportMode(transportMode);
3473
3482
  }
3474
3483
  catch (error) {
3475
- console.error("Error initializing server:", error);
3484
+ logger.error("Error initializing server:", error);
3476
3485
  process.exit(1);
3477
3486
  }
3478
3487
  }
3479
3488
  runServer().catch(error => {
3480
- console.error("Fatal error in main():", error);
3489
+ logger.error("Fatal error in main():", error);
3481
3490
  process.exit(1);
3482
3491
  });
package/build/utils.js ADDED
@@ -0,0 +1,9 @@
1
+ export function formatBoolean(value) {
2
+ if (value == null) {
3
+ return value;
4
+ }
5
+ if (typeof value === 'string') {
6
+ return value == 'true';
7
+ }
8
+ return value;
9
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zereight/mcp-gitlab",
3
- "version": "1.0.69",
3
+ "version": "1.0.70",
4
4
  "description": "MCP server for using the GitLab API",
5
5
  "license": "MIT",
6
6
  "author": "zereight",
@@ -23,7 +23,7 @@
23
23
  "deploy": "npm publish --access public",
24
24
  "generate-tools": "npx ts-node scripts/generate-tools-readme.ts",
25
25
  "changelog": "auto-changelog -p",
26
- "test": "node test/validate-api.js && npm run test:server",
26
+ "test": "node test/validate-api.js",
27
27
  "test:integration": "node test/validate-api.js",
28
28
  "test:server": "npm run build && node build/test/test-all-transport-server.js",
29
29
  "lint": "eslint . --ext .ts",
@@ -40,6 +40,8 @@
40
40
  "http-proxy-agent": "^7.0.2",
41
41
  "https-proxy-agent": "^7.0.6",
42
42
  "node-fetch": "^3.3.2",
43
+ "pino": "^9.7.0",
44
+ "pino-pretty": "^13.0.0",
43
45
  "socks-proxy-agent": "^8.0.5",
44
46
  "tough-cookie": "^5.1.2",
45
47
  "zod-to-json-schema": "^3.23.5"
@@ -49,11 +51,11 @@
49
51
  "@types/node": "^22.13.10",
50
52
  "@typescript-eslint/eslint-plugin": "^8.21.0",
51
53
  "@typescript-eslint/parser": "^8.21.0",
54
+ "auto-changelog": "^2.4.0",
52
55
  "eslint": "^9.18.0",
53
56
  "prettier": "^3.4.2",
54
57
  "ts-node": "^10.9.2",
55
58
  "typescript": "^5.8.2",
56
- "zod": "^3.24.2",
57
- "auto-changelog": "^2.4.0"
59
+ "zod": "^3.24.2"
58
60
  }
59
61
  }