@zereight/mcp-gitlab 2.0.5 → 2.0.7

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,7 @@ GitLabDiscussionNoteSchema, // Added
29
29
  GitLabDiscussionSchema,
30
30
  // Draft Notes Schemas
31
31
  GitLabDraftNoteSchema, GitLabForkSchema, GitLabIssueLinkSchema, GitLabIssueSchema, GitLabIssueWithLinkDetailsSchema, GitLabMarkdownUploadSchema, GitLabMergeRequestSchema, GitLabMilestonesSchema, GitLabNamespaceExistsResponseSchema, GitLabNamespaceSchema, GitLabPipelineJobSchema, GitLabPipelineSchema, GitLabPipelineTriggerJobSchema, GitLabProjectMemberSchema, GitLabProjectSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabSearchResponseSchema, GitLabTreeItemSchema, GitLabTreeSchema, GitLabUserSchema, GitLabUsersResponseSchema, GitLabWikiPageSchema, GroupIteration, ListCommitsSchema, ListDraftNotesSchema, ListGroupIterationsSchema, ListGroupProjectsSchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListLabelsSchema, ListMergeRequestDiffsSchema, // Added
32
- ListMergeRequestDiscussionsSchema, ListMergeRequestsSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListPipelineTriggerJobsSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, MarkdownUploadSchema, DownloadAttachmentSchema, MergeMergeRequestSchema, MyIssuesSchema, PaginatedDiscussionsResponseSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PlayPipelineJobSchema, PushFilesSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchRepositoriesSchema, UpdateDraftNoteSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateLabelSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestSchema, UpdateWikiPageSchema, VerifyNamespaceSchema, GitLabEventSchema, ListEventsSchema, GetProjectEventsSchema } from "./schemas.js";
32
+ ListMergeRequestDiscussionsSchema, ListMergeRequestsSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListPipelineTriggerJobsSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, MarkdownUploadSchema, DownloadAttachmentSchema, MergeMergeRequestSchema, MyIssuesSchema, PaginatedDiscussionsResponseSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PlayPipelineJobSchema, PushFilesSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchRepositoriesSchema, UpdateDraftNoteSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateLabelSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestSchema, UpdateWikiPageSchema, VerifyNamespaceSchema, GitLabEventSchema, ListEventsSchema, GetProjectEventsSchema, ExecuteGraphQLSchema } from "./schemas.js";
33
33
  import { randomUUID } from "crypto";
34
34
  import { pino } from "pino";
35
35
  const logger = pino({
@@ -213,452 +213,459 @@ const DEFAULT_FETCH_CONFIG = {
213
213
  return httpAgent;
214
214
  },
215
215
  };
216
+ const toJSONSchema = (schema) => zodToJsonSchema(schema, { $refStrategy: 'none' });
216
217
  // Define all available tools
217
218
  const allTools = [
218
219
  {
219
220
  name: "merge_merge_request",
220
221
  description: "Merge a merge request in a GitLab project",
221
- inputSchema: zodToJsonSchema(MergeMergeRequestSchema),
222
+ inputSchema: toJSONSchema(MergeMergeRequestSchema),
223
+ },
224
+ {
225
+ name: "execute_graphql",
226
+ description: "Execute a GitLab GraphQL query",
227
+ inputSchema: zodToJsonSchema(ExecuteGraphQLSchema),
222
228
  },
223
229
  {
224
230
  name: "create_or_update_file",
225
231
  description: "Create or update a single file in a GitLab project",
226
- inputSchema: zodToJsonSchema(CreateOrUpdateFileSchema),
232
+ inputSchema: toJSONSchema(CreateOrUpdateFileSchema),
227
233
  },
228
234
  {
229
235
  name: "search_repositories",
230
236
  description: "Search for GitLab projects",
231
- inputSchema: zodToJsonSchema(SearchRepositoriesSchema),
237
+ inputSchema: toJSONSchema(SearchRepositoriesSchema),
232
238
  },
233
239
  {
234
240
  name: "create_repository",
235
241
  description: "Create a new GitLab project",
236
- inputSchema: zodToJsonSchema(CreateRepositorySchema),
242
+ inputSchema: toJSONSchema(CreateRepositorySchema),
237
243
  },
238
244
  {
239
245
  name: "get_file_contents",
240
246
  description: "Get the contents of a file or directory from a GitLab project",
241
- inputSchema: zodToJsonSchema(GetFileContentsSchema),
247
+ inputSchema: toJSONSchema(GetFileContentsSchema),
242
248
  },
243
249
  {
244
250
  name: "push_files",
245
251
  description: "Push multiple files to a GitLab project in a single commit",
246
- inputSchema: zodToJsonSchema(PushFilesSchema),
252
+ inputSchema: toJSONSchema(PushFilesSchema),
247
253
  },
248
254
  {
249
255
  name: "create_issue",
250
256
  description: "Create a new issue in a GitLab project",
251
- inputSchema: zodToJsonSchema(CreateIssueSchema),
257
+ inputSchema: toJSONSchema(CreateIssueSchema),
252
258
  },
253
259
  {
254
260
  name: "create_merge_request",
255
261
  description: "Create a new merge request in a GitLab project",
256
- inputSchema: zodToJsonSchema(CreateMergeRequestSchema),
262
+ inputSchema: toJSONSchema(CreateMergeRequestSchema),
257
263
  },
258
264
  {
259
265
  name: "fork_repository",
260
266
  description: "Fork a GitLab project to your account or specified namespace",
261
- inputSchema: zodToJsonSchema(ForkRepositorySchema),
267
+ inputSchema: toJSONSchema(ForkRepositorySchema),
262
268
  },
263
269
  {
264
270
  name: "create_branch",
265
271
  description: "Create a new branch in a GitLab project",
266
- inputSchema: zodToJsonSchema(CreateBranchSchema),
272
+ inputSchema: toJSONSchema(CreateBranchSchema),
267
273
  },
268
274
  {
269
275
  name: "get_merge_request",
270
276
  description: "Get details of a merge request (Either mergeRequestIid or branchName must be provided)",
271
- inputSchema: zodToJsonSchema(GetMergeRequestSchema),
277
+ inputSchema: toJSONSchema(GetMergeRequestSchema),
272
278
  },
273
279
  {
274
280
  name: "get_merge_request_diffs",
275
281
  description: "Get the changes/diffs of a merge request (Either mergeRequestIid or branchName must be provided)",
276
- inputSchema: zodToJsonSchema(GetMergeRequestDiffsSchema),
282
+ inputSchema: toJSONSchema(GetMergeRequestDiffsSchema),
277
283
  },
278
284
  {
279
285
  name: "list_merge_request_diffs",
280
286
  description: "List merge request diffs with pagination support (Either mergeRequestIid or branchName must be provided)",
281
- inputSchema: zodToJsonSchema(ListMergeRequestDiffsSchema),
287
+ inputSchema: toJSONSchema(ListMergeRequestDiffsSchema),
282
288
  },
283
289
  {
284
290
  name: "get_branch_diffs",
285
291
  description: "Get the changes/diffs between two branches or commits in a GitLab project",
286
- inputSchema: zodToJsonSchema(GetBranchDiffsSchema),
292
+ inputSchema: toJSONSchema(GetBranchDiffsSchema),
287
293
  },
288
294
  {
289
295
  name: "update_merge_request",
290
296
  description: "Update a merge request (Either mergeRequestIid or branchName must be provided)",
291
- inputSchema: zodToJsonSchema(UpdateMergeRequestSchema),
297
+ inputSchema: toJSONSchema(UpdateMergeRequestSchema),
292
298
  },
293
299
  {
294
300
  name: "create_note",
295
301
  description: "Create a new note (comment) to an issue or merge request",
296
- inputSchema: zodToJsonSchema(CreateNoteSchema),
302
+ inputSchema: toJSONSchema(CreateNoteSchema),
297
303
  },
298
304
  {
299
305
  name: "create_merge_request_thread",
300
306
  description: "Create a new thread on a merge request",
301
- inputSchema: zodToJsonSchema(CreateMergeRequestThreadSchema),
307
+ inputSchema: toJSONSchema(CreateMergeRequestThreadSchema),
302
308
  },
303
309
  {
304
310
  name: "mr_discussions",
305
311
  description: "List discussion items for a merge request",
306
- inputSchema: zodToJsonSchema(ListMergeRequestDiscussionsSchema),
312
+ inputSchema: toJSONSchema(ListMergeRequestDiscussionsSchema),
307
313
  },
308
314
  {
309
315
  name: "update_merge_request_note",
310
316
  description: "Modify an existing merge request thread note",
311
- inputSchema: zodToJsonSchema(UpdateMergeRequestNoteSchema),
317
+ inputSchema: toJSONSchema(UpdateMergeRequestNoteSchema),
312
318
  },
313
319
  {
314
320
  name: "create_merge_request_note",
315
321
  description: "Add a new note to an existing merge request thread",
316
- inputSchema: zodToJsonSchema(CreateMergeRequestNoteSchema),
322
+ inputSchema: toJSONSchema(CreateMergeRequestNoteSchema),
317
323
  },
318
324
  {
319
325
  name: "get_draft_note",
320
326
  description: "Get a single draft note from a merge request",
321
- inputSchema: zodToJsonSchema(GetDraftNoteSchema),
327
+ inputSchema: toJSONSchema(GetDraftNoteSchema),
322
328
  },
323
329
  {
324
330
  name: "list_draft_notes",
325
331
  description: "List draft notes for a merge request",
326
- inputSchema: zodToJsonSchema(ListDraftNotesSchema),
332
+ inputSchema: toJSONSchema(ListDraftNotesSchema),
327
333
  },
328
334
  {
329
335
  name: "create_draft_note",
330
336
  description: "Create a draft note for a merge request",
331
- inputSchema: zodToJsonSchema(CreateDraftNoteSchema),
337
+ inputSchema: toJSONSchema(CreateDraftNoteSchema),
332
338
  },
333
339
  {
334
340
  name: "update_draft_note",
335
341
  description: "Update an existing draft note",
336
- inputSchema: zodToJsonSchema(UpdateDraftNoteSchema),
342
+ inputSchema: toJSONSchema(UpdateDraftNoteSchema),
337
343
  },
338
344
  {
339
345
  name: "delete_draft_note",
340
346
  description: "Delete a draft note",
341
- inputSchema: zodToJsonSchema(DeleteDraftNoteSchema),
347
+ inputSchema: toJSONSchema(DeleteDraftNoteSchema),
342
348
  },
343
349
  {
344
350
  name: "publish_draft_note",
345
351
  description: "Publish a single draft note",
346
- inputSchema: zodToJsonSchema(PublishDraftNoteSchema),
352
+ inputSchema: toJSONSchema(PublishDraftNoteSchema),
347
353
  },
348
354
  {
349
355
  name: "bulk_publish_draft_notes",
350
356
  description: "Publish all draft notes for a merge request",
351
- inputSchema: zodToJsonSchema(BulkPublishDraftNotesSchema),
357
+ inputSchema: toJSONSchema(BulkPublishDraftNotesSchema),
352
358
  },
353
359
  {
354
360
  name: "update_issue_note",
355
361
  description: "Modify an existing issue thread note",
356
- inputSchema: zodToJsonSchema(UpdateIssueNoteSchema),
362
+ inputSchema: toJSONSchema(UpdateIssueNoteSchema),
357
363
  },
358
364
  {
359
365
  name: "create_issue_note",
360
366
  description: "Add a new note to an existing issue thread",
361
- inputSchema: zodToJsonSchema(CreateIssueNoteSchema),
367
+ inputSchema: toJSONSchema(CreateIssueNoteSchema),
362
368
  },
363
369
  {
364
370
  name: "list_issues",
365
371
  description: "List issues (default: created by current user only; use scope='all' for all accessible issues)",
366
- inputSchema: zodToJsonSchema(ListIssuesSchema),
372
+ inputSchema: toJSONSchema(ListIssuesSchema),
367
373
  },
368
374
  {
369
375
  name: "my_issues",
370
376
  description: "List issues assigned to the authenticated user (defaults to open issues)",
371
- inputSchema: zodToJsonSchema(MyIssuesSchema),
377
+ inputSchema: toJSONSchema(MyIssuesSchema),
372
378
  },
373
379
  {
374
380
  name: "get_issue",
375
381
  description: "Get details of a specific issue in a GitLab project",
376
- inputSchema: zodToJsonSchema(GetIssueSchema),
382
+ inputSchema: toJSONSchema(GetIssueSchema),
377
383
  },
378
384
  {
379
385
  name: "update_issue",
380
386
  description: "Update an issue in a GitLab project",
381
- inputSchema: zodToJsonSchema(UpdateIssueSchema),
387
+ inputSchema: toJSONSchema(UpdateIssueSchema),
382
388
  },
383
389
  {
384
390
  name: "delete_issue",
385
391
  description: "Delete an issue from a GitLab project",
386
- inputSchema: zodToJsonSchema(DeleteIssueSchema),
392
+ inputSchema: toJSONSchema(DeleteIssueSchema),
387
393
  },
388
394
  {
389
395
  name: "list_issue_links",
390
396
  description: "List all issue links for a specific issue",
391
- inputSchema: zodToJsonSchema(ListIssueLinksSchema),
397
+ inputSchema: toJSONSchema(ListIssueLinksSchema),
392
398
  },
393
399
  {
394
400
  name: "list_issue_discussions",
395
401
  description: "List discussions for an issue in a GitLab project",
396
- inputSchema: zodToJsonSchema(ListIssueDiscussionsSchema),
402
+ inputSchema: toJSONSchema(ListIssueDiscussionsSchema),
397
403
  },
398
404
  {
399
405
  name: "get_issue_link",
400
406
  description: "Get a specific issue link",
401
- inputSchema: zodToJsonSchema(GetIssueLinkSchema),
407
+ inputSchema: toJSONSchema(GetIssueLinkSchema),
402
408
  },
403
409
  {
404
410
  name: "create_issue_link",
405
411
  description: "Create an issue link between two issues",
406
- inputSchema: zodToJsonSchema(CreateIssueLinkSchema),
412
+ inputSchema: toJSONSchema(CreateIssueLinkSchema),
407
413
  },
408
414
  {
409
415
  name: "delete_issue_link",
410
416
  description: "Delete an issue link",
411
- inputSchema: zodToJsonSchema(DeleteIssueLinkSchema),
417
+ inputSchema: toJSONSchema(DeleteIssueLinkSchema),
412
418
  },
413
419
  {
414
420
  name: "list_namespaces",
415
421
  description: "List all namespaces available to the current user",
416
- inputSchema: zodToJsonSchema(ListNamespacesSchema),
422
+ inputSchema: toJSONSchema(ListNamespacesSchema),
417
423
  },
418
424
  {
419
425
  name: "get_namespace",
420
426
  description: "Get details of a namespace by ID or path",
421
- inputSchema: zodToJsonSchema(GetNamespaceSchema),
427
+ inputSchema: toJSONSchema(GetNamespaceSchema),
422
428
  },
423
429
  {
424
430
  name: "verify_namespace",
425
431
  description: "Verify if a namespace path exists",
426
- inputSchema: zodToJsonSchema(VerifyNamespaceSchema),
432
+ inputSchema: toJSONSchema(VerifyNamespaceSchema),
427
433
  },
428
434
  {
429
435
  name: "get_project",
430
436
  description: "Get details of a specific project",
431
- inputSchema: zodToJsonSchema(GetProjectSchema),
437
+ inputSchema: toJSONSchema(GetProjectSchema),
432
438
  },
433
439
  {
434
440
  name: "list_projects",
435
441
  description: "List projects accessible by the current user",
436
- inputSchema: zodToJsonSchema(ListProjectsSchema),
442
+ inputSchema: toJSONSchema(ListProjectsSchema),
437
443
  },
438
444
  {
439
445
  name: "list_project_members",
440
446
  description: "List members of a GitLab project",
441
- inputSchema: zodToJsonSchema(ListProjectMembersSchema),
447
+ inputSchema: toJSONSchema(ListProjectMembersSchema),
442
448
  },
443
449
  {
444
450
  name: "list_labels",
445
451
  description: "List labels for a project",
446
- inputSchema: zodToJsonSchema(ListLabelsSchema),
452
+ inputSchema: toJSONSchema(ListLabelsSchema),
447
453
  },
448
454
  {
449
455
  name: "get_label",
450
456
  description: "Get a single label from a project",
451
- inputSchema: zodToJsonSchema(GetLabelSchema),
457
+ inputSchema: toJSONSchema(GetLabelSchema),
452
458
  },
453
459
  {
454
460
  name: "create_label",
455
461
  description: "Create a new label in a project",
456
- inputSchema: zodToJsonSchema(CreateLabelSchema),
462
+ inputSchema: toJSONSchema(CreateLabelSchema),
457
463
  },
458
464
  {
459
465
  name: "update_label",
460
466
  description: "Update an existing label in a project",
461
- inputSchema: zodToJsonSchema(UpdateLabelSchema),
467
+ inputSchema: toJSONSchema(UpdateLabelSchema),
462
468
  },
463
469
  {
464
470
  name: "delete_label",
465
471
  description: "Delete a label from a project",
466
- inputSchema: zodToJsonSchema(DeleteLabelSchema),
472
+ inputSchema: toJSONSchema(DeleteLabelSchema),
467
473
  },
468
474
  {
469
475
  name: "list_group_projects",
470
476
  description: "List projects in a GitLab group with filtering options",
471
- inputSchema: zodToJsonSchema(ListGroupProjectsSchema),
477
+ inputSchema: toJSONSchema(ListGroupProjectsSchema),
472
478
  },
473
479
  {
474
480
  name: "list_wiki_pages",
475
481
  description: "List wiki pages in a GitLab project",
476
- inputSchema: zodToJsonSchema(ListWikiPagesSchema),
482
+ inputSchema: toJSONSchema(ListWikiPagesSchema),
477
483
  },
478
484
  {
479
485
  name: "get_wiki_page",
480
486
  description: "Get details of a specific wiki page",
481
- inputSchema: zodToJsonSchema(GetWikiPageSchema),
487
+ inputSchema: toJSONSchema(GetWikiPageSchema),
482
488
  },
483
489
  {
484
490
  name: "create_wiki_page",
485
491
  description: "Create a new wiki page in a GitLab project",
486
- inputSchema: zodToJsonSchema(CreateWikiPageSchema),
492
+ inputSchema: toJSONSchema(CreateWikiPageSchema),
487
493
  },
488
494
  {
489
495
  name: "update_wiki_page",
490
496
  description: "Update an existing wiki page in a GitLab project",
491
- inputSchema: zodToJsonSchema(UpdateWikiPageSchema),
497
+ inputSchema: toJSONSchema(UpdateWikiPageSchema),
492
498
  },
493
499
  {
494
500
  name: "delete_wiki_page",
495
501
  description: "Delete a wiki page from a GitLab project",
496
- inputSchema: zodToJsonSchema(DeleteWikiPageSchema),
502
+ inputSchema: toJSONSchema(DeleteWikiPageSchema),
497
503
  },
498
504
  {
499
505
  name: "get_repository_tree",
500
506
  description: "Get the repository tree for a GitLab project (list files and directories)",
501
- inputSchema: zodToJsonSchema(GetRepositoryTreeSchema),
507
+ inputSchema: toJSONSchema(GetRepositoryTreeSchema),
502
508
  },
503
509
  {
504
510
  name: "list_pipelines",
505
511
  description: "List pipelines in a GitLab project with filtering options",
506
- inputSchema: zodToJsonSchema(ListPipelinesSchema),
512
+ inputSchema: toJSONSchema(ListPipelinesSchema),
507
513
  },
508
514
  {
509
515
  name: "get_pipeline",
510
516
  description: "Get details of a specific pipeline in a GitLab project",
511
- inputSchema: zodToJsonSchema(GetPipelineSchema),
517
+ inputSchema: toJSONSchema(GetPipelineSchema),
512
518
  },
513
519
  {
514
520
  name: "list_pipeline_jobs",
515
521
  description: "List all jobs in a specific pipeline",
516
- inputSchema: zodToJsonSchema(ListPipelineJobsSchema),
522
+ inputSchema: toJSONSchema(ListPipelineJobsSchema),
517
523
  },
518
524
  {
519
525
  name: "list_pipeline_trigger_jobs",
520
526
  description: "List all trigger jobs (bridges) in a specific pipeline that trigger downstream pipelines",
521
- inputSchema: zodToJsonSchema(ListPipelineTriggerJobsSchema),
527
+ inputSchema: toJSONSchema(ListPipelineTriggerJobsSchema),
522
528
  },
523
529
  {
524
530
  name: "get_pipeline_job",
525
531
  description: "Get details of a GitLab pipeline job number",
526
- inputSchema: zodToJsonSchema(GetPipelineJobOutputSchema),
532
+ inputSchema: toJSONSchema(GetPipelineJobOutputSchema),
527
533
  },
528
534
  {
529
535
  name: "get_pipeline_job_output",
530
536
  description: "Get the output/trace of a GitLab pipeline job with optional pagination to limit context window usage",
531
- inputSchema: zodToJsonSchema(GetPipelineJobOutputSchema),
537
+ inputSchema: toJSONSchema(GetPipelineJobOutputSchema),
532
538
  },
533
539
  {
534
540
  name: "create_pipeline",
535
541
  description: "Create a new pipeline for a branch or tag",
536
- inputSchema: zodToJsonSchema(CreatePipelineSchema),
542
+ inputSchema: toJSONSchema(CreatePipelineSchema),
537
543
  },
538
544
  {
539
545
  name: "retry_pipeline",
540
546
  description: "Retry a failed or canceled pipeline",
541
- inputSchema: zodToJsonSchema(RetryPipelineSchema),
547
+ inputSchema: toJSONSchema(RetryPipelineSchema),
542
548
  },
543
549
  {
544
550
  name: "cancel_pipeline",
545
551
  description: "Cancel a running pipeline",
546
- inputSchema: zodToJsonSchema(CancelPipelineSchema),
552
+ inputSchema: toJSONSchema(CancelPipelineSchema),
547
553
  },
548
554
  {
549
555
  name: "play_pipeline_job",
550
556
  description: "Run a manual pipeline job",
551
- inputSchema: zodToJsonSchema(PlayPipelineJobSchema),
557
+ inputSchema: toJSONSchema(PlayPipelineJobSchema),
552
558
  },
553
559
  {
554
560
  name: "retry_pipeline_job",
555
561
  description: "Retry a failed or canceled pipeline job",
556
- inputSchema: zodToJsonSchema(RetryPipelineJobSchema),
562
+ inputSchema: toJSONSchema(RetryPipelineJobSchema),
557
563
  },
558
564
  {
559
565
  name: "cancel_pipeline_job",
560
566
  description: "Cancel a running pipeline job",
561
- inputSchema: zodToJsonSchema(CancelPipelineJobSchema),
567
+ inputSchema: toJSONSchema(CancelPipelineJobSchema),
562
568
  },
563
569
  {
564
570
  name: "list_merge_requests",
565
571
  description: "List merge requests in a GitLab project with filtering options",
566
- inputSchema: zodToJsonSchema(ListMergeRequestsSchema),
572
+ inputSchema: toJSONSchema(ListMergeRequestsSchema),
567
573
  },
568
574
  {
569
575
  name: "list_milestones",
570
576
  description: "List milestones in a GitLab project with filtering options",
571
- inputSchema: zodToJsonSchema(ListProjectMilestonesSchema),
577
+ inputSchema: toJSONSchema(ListProjectMilestonesSchema),
572
578
  },
573
579
  {
574
580
  name: "get_milestone",
575
581
  description: "Get details of a specific milestone",
576
- inputSchema: zodToJsonSchema(GetProjectMilestoneSchema),
582
+ inputSchema: toJSONSchema(GetProjectMilestoneSchema),
577
583
  },
578
584
  {
579
585
  name: "create_milestone",
580
586
  description: "Create a new milestone in a GitLab project",
581
- inputSchema: zodToJsonSchema(CreateProjectMilestoneSchema),
587
+ inputSchema: toJSONSchema(CreateProjectMilestoneSchema),
582
588
  },
583
589
  {
584
590
  name: "edit_milestone",
585
591
  description: "Edit an existing milestone in a GitLab project",
586
- inputSchema: zodToJsonSchema(EditProjectMilestoneSchema),
592
+ inputSchema: toJSONSchema(EditProjectMilestoneSchema),
587
593
  },
588
594
  {
589
595
  name: "delete_milestone",
590
596
  description: "Delete a milestone from a GitLab project",
591
- inputSchema: zodToJsonSchema(DeleteProjectMilestoneSchema),
597
+ inputSchema: toJSONSchema(DeleteProjectMilestoneSchema),
592
598
  },
593
599
  {
594
600
  name: "get_milestone_issue",
595
601
  description: "Get issues associated with a specific milestone",
596
- inputSchema: zodToJsonSchema(GetMilestoneIssuesSchema),
602
+ inputSchema: toJSONSchema(GetMilestoneIssuesSchema),
597
603
  },
598
604
  {
599
605
  name: "get_milestone_merge_requests",
600
606
  description: "Get merge requests associated with a specific milestone",
601
- inputSchema: zodToJsonSchema(GetMilestoneMergeRequestsSchema),
607
+ inputSchema: toJSONSchema(GetMilestoneMergeRequestsSchema),
602
608
  },
603
609
  {
604
610
  name: "promote_milestone",
605
611
  description: "Promote a milestone to the next stage",
606
- inputSchema: zodToJsonSchema(PromoteProjectMilestoneSchema),
612
+ inputSchema: toJSONSchema(PromoteProjectMilestoneSchema),
607
613
  },
608
614
  {
609
615
  name: "get_milestone_burndown_events",
610
616
  description: "Get burndown events for a specific milestone",
611
- inputSchema: zodToJsonSchema(GetMilestoneBurndownEventsSchema),
617
+ inputSchema: toJSONSchema(GetMilestoneBurndownEventsSchema),
612
618
  },
613
619
  {
614
620
  name: "get_users",
615
621
  description: "Get GitLab user details by usernames",
616
- inputSchema: zodToJsonSchema(GetUsersSchema),
622
+ inputSchema: toJSONSchema(GetUsersSchema),
617
623
  },
618
624
  {
619
625
  name: "list_commits",
620
626
  description: "List repository commits with filtering options",
621
- inputSchema: zodToJsonSchema(ListCommitsSchema),
627
+ inputSchema: toJSONSchema(ListCommitsSchema),
622
628
  },
623
629
  {
624
630
  name: "get_commit",
625
631
  description: "Get details of a specific commit",
626
- inputSchema: zodToJsonSchema(GetCommitSchema),
632
+ inputSchema: toJSONSchema(GetCommitSchema),
627
633
  },
628
634
  {
629
635
  name: "get_commit_diff",
630
636
  description: "Get changes/diffs of a specific commit",
631
- inputSchema: zodToJsonSchema(GetCommitDiffSchema),
637
+ inputSchema: toJSONSchema(GetCommitDiffSchema),
632
638
  },
633
639
  {
634
640
  name: "list_group_iterations",
635
641
  description: "List group iterations with filtering options",
636
- inputSchema: zodToJsonSchema(ListGroupIterationsSchema),
642
+ inputSchema: toJSONSchema(ListGroupIterationsSchema),
637
643
  },
638
644
  {
639
645
  name: "upload_markdown",
640
646
  description: "Upload a file to a GitLab project for use in markdown content",
641
- inputSchema: zodToJsonSchema(MarkdownUploadSchema),
647
+ inputSchema: toJSONSchema(MarkdownUploadSchema),
642
648
  },
643
649
  {
644
650
  name: "download_attachment",
645
651
  description: "Download an uploaded file from a GitLab project by secret and filename",
646
- inputSchema: zodToJsonSchema(DownloadAttachmentSchema),
652
+ inputSchema: toJSONSchema(DownloadAttachmentSchema),
647
653
  },
648
654
  {
649
655
  name: "list_events",
650
656
  description: "List all events for the currently authenticated user. Note: before/after parameters accept date format YYYY-MM-DD only",
651
- inputSchema: zodToJsonSchema(ListEventsSchema),
657
+ inputSchema: toJSONSchema(ListEventsSchema),
652
658
  },
653
659
  {
654
660
  name: "get_project_events",
655
661
  description: "List all visible events for a specified project. Note: before/after parameters accept date format YYYY-MM-DD only",
656
- inputSchema: zodToJsonSchema(GetProjectEventsSchema),
662
+ inputSchema: toJSONSchema(GetProjectEventsSchema),
657
663
  },
658
664
  ];
659
665
  // Define which tools are read-only
660
666
  const readOnlyTools = [
661
667
  "search_repositories",
668
+ "execute_graphql",
662
669
  "get_file_contents",
663
670
  "get_merge_request",
664
671
  "get_merge_request_diffs",
@@ -763,6 +770,7 @@ function normalizeGitLabApiUrl(url) {
763
770
  const GITLAB_API_URL = normalizeGitLabApiUrl(process.env.GITLAB_API_URL || "");
764
771
  const GITLAB_PROJECT_ID = process.env.GITLAB_PROJECT_ID;
765
772
  const GITLAB_ALLOWED_PROJECT_IDS = process.env.GITLAB_ALLOWED_PROJECT_IDS?.split(',').map(id => id.trim()).filter(Boolean) || [];
773
+ const GITLAB_COMMIT_FILES_PER_PAGE = process.env.GITLAB_COMMIT_FILES_PER_PAGE ? parseInt(process.env.GITLAB_COMMIT_FILES_PER_PAGE) : 20;
766
774
  if (!GITLAB_PERSONAL_ACCESS_TOKEN) {
767
775
  logger.error("GITLAB_PERSONAL_ACCESS_TOKEN environment variable is not set");
768
776
  process.exit(1);
@@ -3012,17 +3020,35 @@ async function getCommit(projectId, sha, stats) {
3012
3020
  *
3013
3021
  * @param {string} projectId - Project ID or URL-encoded path
3014
3022
  * @param {string} sha - The commit hash or name of a repository branch or tag
3023
+ * @param {boolean} [full_diff] - Whether to return the full diff or only first page
3015
3024
  * @returns {Promise<GitLabMergeRequestDiff[]>} The commit diffs
3016
3025
  */
3017
- async function getCommitDiff(projectId, sha) {
3026
+ async function getCommitDiff(projectId, sha, full_diff) {
3018
3027
  projectId = decodeURIComponent(projectId);
3019
- const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/repository/commits/${encodeURIComponent(sha)}/diff`);
3020
- const response = await fetch(url.toString(), {
3021
- ...DEFAULT_FETCH_CONFIG,
3022
- });
3023
- await handleGitLabError(response);
3024
- const data = await response.json();
3025
- return z.array(GitLabDiffSchema).parse(data);
3028
+ const baseUrl = `${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/repository/commits/${encodeURIComponent(sha)}/diff`;
3029
+ let allDiffs = [];
3030
+ let page = 1;
3031
+ while (true) {
3032
+ const url = new URL(baseUrl);
3033
+ if (full_diff) {
3034
+ url.searchParams.append("page", page.toString());
3035
+ }
3036
+ const response = await fetch(url.toString(), {
3037
+ ...DEFAULT_FETCH_CONFIG,
3038
+ });
3039
+ await handleGitLabError(response);
3040
+ const data = await response.json();
3041
+ const diffs = z.array(GitLabDiffSchema).parse(data);
3042
+ allDiffs.push(...diffs);
3043
+ if (!full_diff) {
3044
+ break;
3045
+ }
3046
+ if (diffs.length < GITLAB_COMMIT_FILES_PER_PAGE) {
3047
+ break;
3048
+ }
3049
+ page++;
3050
+ }
3051
+ return allDiffs;
3026
3052
  }
3027
3053
  /**
3028
3054
  * Get the current authenticated user
@@ -3114,8 +3140,8 @@ async function listGroupIterations(groupId, options = {}) {
3114
3140
  url.searchParams.append("state", options.state);
3115
3141
  if (options.search)
3116
3142
  url.searchParams.append("search", options.search);
3117
- if (options.in)
3118
- url.searchParams.append("in", options.in.join(","));
3143
+ if (options.search_in)
3144
+ url.searchParams.append("in", options.search_in.join(","));
3119
3145
  if (options.include_ancestors !== undefined)
3120
3146
  url.searchParams.append("include_ancestors", options.include_ancestors.toString());
3121
3147
  if (options.include_descendants !== undefined)
@@ -3288,6 +3314,54 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
3288
3314
  }
3289
3315
  logger.info(request.params.name);
3290
3316
  switch (request.params.name) {
3317
+ case "execute_graphql": {
3318
+ const args = ExecuteGraphQLSchema.parse(request.params.arguments);
3319
+ const apiUrl = new URL(GITLAB_API_URL);
3320
+ // Build GraphQL endpoint preserving any instance subpath (e.g. /gitlab)
3321
+ const restPath = apiUrl.pathname || ""; // e.g. /api/v4 or /gitlab/api/v4
3322
+ const idx = restPath.lastIndexOf("/api/v4");
3323
+ const prefix = idx >= 0 ? restPath.slice(0, idx) : "";
3324
+ const graphqlUrl = process.env.GITLAB_GRAPHQL_URL || `${apiUrl.origin}${prefix}/api/graphql`;
3325
+ // Add timeout to avoid hanging requests
3326
+ const controller = new AbortController();
3327
+ const timeoutMs = 45000;
3328
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
3329
+ logger.info({ endpoint: graphqlUrl }, "execute_graphql request");
3330
+ try {
3331
+ const response = await fetch(graphqlUrl, {
3332
+ ...DEFAULT_FETCH_CONFIG,
3333
+ method: "POST",
3334
+ headers: {
3335
+ ...DEFAULT_HEADERS,
3336
+ "Content-Type": "application/json",
3337
+ Accept: "application/json",
3338
+ },
3339
+ body: JSON.stringify({ query: args.query, variables: args.variables || {} }),
3340
+ signal: controller.signal,
3341
+ });
3342
+ if (!response.ok) {
3343
+ await handleGitLabError(response);
3344
+ }
3345
+ const json = await response.json();
3346
+ return {
3347
+ content: [{ type: "text", text: JSON.stringify(json, null, 2) }],
3348
+ };
3349
+ }
3350
+ catch (err) {
3351
+ const message = err instanceof Error ? err.message : String(err);
3352
+ return {
3353
+ content: [
3354
+ {
3355
+ type: "text",
3356
+ text: JSON.stringify({ error: `GraphQL request failed: ${message}` }, null, 2),
3357
+ },
3358
+ ],
3359
+ };
3360
+ }
3361
+ finally {
3362
+ clearTimeout(timeout);
3363
+ }
3364
+ }
3291
3365
  case "fork_repository": {
3292
3366
  if (GITLAB_PROJECT_ID) {
3293
3367
  throw new Error("Direct project ID is set. So fork_repository is not allowed");
@@ -4096,7 +4170,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
4096
4170
  }
4097
4171
  case "get_commit_diff": {
4098
4172
  const args = GetCommitDiffSchema.parse(request.params.arguments);
4099
- const diff = await getCommitDiff(args.project_id, args.sha);
4173
+ const diff = await getCommitDiff(args.project_id, args.sha, args.full_diff);
4100
4174
  return {
4101
4175
  content: [{ type: "text", text: JSON.stringify(diff, null, 2) }],
4102
4176
  };
@@ -4269,6 +4343,29 @@ async function startStreamableHTTPServer() {
4269
4343
  });
4270
4344
  }
4271
4345
  });
4346
+ // to delete a mcp server session explicitly
4347
+ app.delete("/mcp", async (req, res) => {
4348
+ const sessionId = req.headers["mcp-session-id"];
4349
+ if (!sessionId) {
4350
+ res.status(400).json({ error: "mcp-session-id header is required" });
4351
+ return;
4352
+ }
4353
+ const transport = streamableTransports[sessionId];
4354
+ if (transport) {
4355
+ try {
4356
+ await transport.close();
4357
+ logger.info(`Explicitly closed session via DELETE request: ${sessionId}`);
4358
+ res.status(204).send();
4359
+ }
4360
+ catch (error) {
4361
+ logger.error(`Error closing session ${sessionId}:`, error);
4362
+ res.status(500).json({ error: "Failed to close session" });
4363
+ }
4364
+ }
4365
+ else {
4366
+ res.status(404).json({ error: "Session not found" });
4367
+ }
4368
+ });
4272
4369
  // Health check endpoint
4273
4370
  app.get("/health", (_, res) => {
4274
4371
  res.status(200).json({