@zereight/mcp-gitlab 2.1.70 → 2.2.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.
Files changed (157) hide show
  1. package/README.ko.md +3 -1
  2. package/README.md +6 -2
  3. package/README.pt-BR.md +1 -1
  4. package/README.zh-CN.md +3 -1
  5. package/build/config.js +12 -4
  6. package/build/deprecated-env.js +47 -0
  7. package/build/index.js +369 -184
  8. package/build/oauth-device-flow.js +80 -0
  9. package/build/oauth.js +135 -18
  10. package/build/schemas.js +1 -1
  11. package/build/server/remote-http-stack.js +39 -0
  12. package/build/tools/discover-activation.js +38 -0
  13. package/build/tools/exposed-tools.js +35 -0
  14. package/build/tools/listed-tools.js +76 -0
  15. package/build/tools/registry.js +226 -57
  16. package/build/tools/tool-profile.js +66 -0
  17. package/build/utils/compact-tool-allowlist.js +14 -0
  18. package/build/utils/logger.js +34 -12
  19. package/package.json +3 -3
  20. package/build/scripts/check-skill-sync.js +0 -143
  21. package/build/scripts/generate-server-card.js +0 -39
  22. package/build/scripts/generate-tool-coverage.js +0 -58
  23. package/build/scripts/generate-tool-docs.js +0 -430
  24. package/build/scripts/tool-coverage/coverage.js +0 -341
  25. package/build/scripts/tool-coverage/coverage.test.js +0 -142
  26. package/build/test/callback-proxy-tests.js +0 -321
  27. package/build/test/cli/args.test.js +0 -175
  28. package/build/test/cli/boolean-flags.test.js +0 -106
  29. package/build/test/cli/compact-mcp-result.test.js +0 -93
  30. package/build/test/cli/credentials.test.js +0 -153
  31. package/build/test/cli/exposure.test.js +0 -104
  32. package/build/test/cli/load-config-snapshot.js +0 -5
  33. package/build/test/cli/output.test.js +0 -74
  34. package/build/test/cli/replay-command.test.js +0 -37
  35. package/build/test/cli/router.test.js +0 -183
  36. package/build/test/client-pool-test.js +0 -109
  37. package/build/test/clients/client.js +0 -34
  38. package/build/test/clients/custom-header-client.js +0 -122
  39. package/build/test/clients/sse-client.js +0 -95
  40. package/build/test/clients/stdio-client.js +0 -113
  41. package/build/test/clients/streamable-http-client.js +0 -95
  42. package/build/test/config-allowed-groups.test.js +0 -97
  43. package/build/test/create-commit-actions.test.js +0 -102
  44. package/build/test/draft-note-schema.test.js +0 -44
  45. package/build/test/dynamic-api-url-allowlist.test.js +0 -121
  46. package/build/test/dynamic-api-url-test.js +0 -304
  47. package/build/test/dynamic-routing-tests.js +0 -495
  48. package/build/test/get-merge-request-discussion-schema.test.js +0 -30
  49. package/build/test/gitlab-api-tool-errors.test.js +0 -112
  50. package/build/test/gitlab-artifact-entry-schema.test.js +0 -44
  51. package/build/test/gitlab-diff-schema.test.js +0 -36
  52. package/build/test/gitlab-pipeline-schedule-schema.test.js +0 -32
  53. package/build/test/gitlab-tag-schema.test.js +0 -51
  54. package/build/test/group-milestone-schema.test.js +0 -45
  55. package/build/test/mcp-oauth-tests.js +0 -905
  56. package/build/test/mcp-server-name.test.js +0 -87
  57. package/build/test/merge-merge-request-schema.test.js +0 -75
  58. package/build/test/multi-server-test.js +0 -190
  59. package/build/test/no-proxy-integration-test.js +0 -183
  60. package/build/test/no-proxy-test.js +0 -149
  61. package/build/test/nullable-gitlab-response-fields.test.js +0 -37
  62. package/build/test/nullish-tool-arguments-schema.test.js +0 -118
  63. package/build/test/oauth-device-flow-tests.js +0 -450
  64. package/build/test/oauth-download-url.test.js +0 -157
  65. package/build/test/oauth-startup.test.js +0 -204
  66. package/build/test/oauth-tests.js +0 -428
  67. package/build/test/path-segment-encoding.test.js +0 -98
  68. package/build/test/remote-auth-simple-test.js +0 -277
  69. package/build/test/remote-auth-tests.js +0 -314
  70. package/build/test/response-masking.test.js +0 -445
  71. package/build/test/schema-tests.js +0 -1679
  72. package/build/test/server/metrics.test.js +0 -47
  73. package/build/test/server/request-helpers.test.js +0 -48
  74. package/build/test/server/version.test.js +0 -13
  75. package/build/test/sse-auth-guard.test.js +0 -96
  76. package/build/test/sse-session-limits.test.js +0 -273
  77. package/build/test/stateless/callback-proxy.test.js +0 -510
  78. package/build/test/stateless/client-id.test.js +0 -177
  79. package/build/test/stateless/codec.test.js +0 -328
  80. package/build/test/stateless/config-ttl.test.js +0 -149
  81. package/build/test/stateless/consumed-proxy-code-cache.test.js +0 -150
  82. package/build/test/stateless/session-id-integration.test.js +0 -675
  83. package/build/test/stateless/session-id.test.js +0 -157
  84. package/build/test/streamable-http-concurrent-session.test.js +0 -171
  85. package/build/test/streamable-http-dns-rebinding.test.js +0 -185
  86. package/build/test/streamable-http-sse-stream.test.js +0 -350
  87. package/build/test/streamable-http-static-token-auth.test.js +0 -157
  88. package/build/test/streamable-http-unauthenticated-discovery.test.js +0 -207
  89. package/build/test/test-all-transport-server.js +0 -255
  90. package/build/test/test-auth-retry.js +0 -195
  91. package/build/test/test-blank-filters.js +0 -156
  92. package/build/test/test-ci-catalog.js +0 -177
  93. package/build/test/test-ci-lint.js +0 -191
  94. package/build/test/test-ci-variables.js +0 -309
  95. package/build/test/test-create-repository.js +0 -120
  96. package/build/test/test-dependency-proxy.js +0 -195
  97. package/build/test/test-deployment-tools.js +0 -463
  98. package/build/test/test-download-attachment.js +0 -190
  99. package/build/test/test-dynamic-project-scope.js +0 -524
  100. package/build/test/test-empty-toolsets.js +0 -535
  101. package/build/test/test-get-file-blame.js +0 -145
  102. package/build/test/test-get-file-contents.js +0 -128
  103. package/build/test/test-geteffectiveprojectid.js +0 -804
  104. package/build/test/test-health-check.js +0 -115
  105. package/build/test/test-issue-description-patch.js +0 -256
  106. package/build/test/test-job-artifacts.js +0 -275
  107. package/build/test/test-json-schema.js +0 -166
  108. package/build/test/test-list-group-members.js +0 -150
  109. package/build/test/test-list-group-merge-requests.js +0 -165
  110. package/build/test/test-list-issues.js +0 -170
  111. package/build/test/test-list-merge-requests.js +0 -201
  112. package/build/test/test-list-milestones.js +0 -145
  113. package/build/test/test-list-project-members.js +0 -132
  114. package/build/test/test-merge-request-approval-state-tools.js +0 -213
  115. package/build/test/test-merge-request-approvals.js +0 -187
  116. package/build/test/test-merge-request-pipelines.js +0 -106
  117. package/build/test/test-mr-diffs-filter.js +0 -132
  118. package/build/test/test-mr-file-diffs.js +0 -251
  119. package/build/test/test-oauth-proxy-rate-limit.js +0 -133
  120. package/build/test/test-orbit.js +0 -155
  121. package/build/test/test-permission-mode.js +0 -424
  122. package/build/test/test-pipeline-schedules.js +0 -484
  123. package/build/test/test-protected-branches.js +0 -174
  124. package/build/test/test-remote-downloads.js +0 -510
  125. package/build/test/test-search-code.js +0 -275
  126. package/build/test/test-snippets.js +0 -735
  127. package/build/test/test-tags.js +0 -220
  128. package/build/test/test-todos.js +0 -195
  129. package/build/test/test-token-optimizations.js +0 -691
  130. package/build/test/test-toolset-filtering.js +0 -499
  131. package/build/test/test-update-issue-slim.js +0 -141
  132. package/build/test/test-update-project.js +0 -112
  133. package/build/test/test-upload-markdown.js +0 -206
  134. package/build/test/test-vulnerabilities.js +0 -399
  135. package/build/test/test-webhooks.js +0 -218
  136. package/build/test/tool-description-quality.test.js +0 -50
  137. package/build/test/utils/bulk-publish-options.test.js +0 -32
  138. package/build/test/utils/download-token.test.js +0 -35
  139. package/build/test/utils/forwarded-public-base-url.test.js +0 -46
  140. package/build/test/utils/gitlab-instance-version.test.js +0 -32
  141. package/build/test/utils/gitlab-version-gate.test.js +0 -74
  142. package/build/test/utils/graphql-query.test.js +0 -168
  143. package/build/test/utils/helpers-path.test.js +0 -104
  144. package/build/test/utils/jmespath-tool-result.test.js +0 -91
  145. package/build/test/utils/masking.test.js +0 -384
  146. package/build/test/utils/merge-request-position.test.js +0 -57
  147. package/build/test/utils/mock-gitlab-server.js +0 -614
  148. package/build/test/utils/proxy-client-ip.test.js +0 -28
  149. package/build/test/utils/redact-sensitive.test.js +0 -32
  150. package/build/test/utils/safe-redirect-fetch.test.js +0 -463
  151. package/build/test/utils/server-launcher.js +0 -231
  152. package/build/test/utils/tool-args.test.js +0 -210
  153. package/build/test/utils/url.test.js +0 -141
  154. package/build/test/utils/version-check.test.js +0 -239
  155. package/build/test/utils/wiki-title.test.js +0 -21
  156. package/build/test-note.js +0 -54
  157. package/build/test-resolve-issue-note.js +0 -127
@@ -1,5 +1,5 @@
1
1
  import { toJSONSchema } from "../utils/schema.js";
2
- import { USE_GITLAB_WIKI, USE_MILESTONE, USE_PIPELINE, SSE, STREAMABLE_HTTP, } from "../config.js";
2
+ import { USE_GITLAB_WIKI, USE_MILESTONE, USE_PIPELINE, SSE, STREAMABLE_HTTP } from "../config.js";
3
3
  import { getToolDescription } from "./tool-descriptions.js";
4
4
  import { ApproveMergeRequestSchema, BulkPublishDraftNotesSchema, CancelPipelineJobSchema, ErasePipelineJobSchema, CancelPipelineSchema, ConvertWorkItemTypeSchema, CreateBranchSchema, CreateDraftNoteSchema, CreateGroupSchema, CreateGroupWikiPageSchema, CreateIssueLinkSchema, CreateIssueNoteSchema, CreateIssueSchema, CreateIssueEmojiReactionSchema, CreateIssueNoteEmojiReactionSchema, ListIssueEmojiReactionsSchema, ListIssueNoteEmojiReactionsSchema, CreateLabelSchema, MarkAllTodosDoneSchema, ListTodosSchema, MarkTodoDoneSchema, CreateMergeRequestDiscussionNoteSchema, CreateMergeRequestEmojiReactionSchema, ListMergeRequestEmojiReactionsSchema, ListMergeRequestNoteEmojiReactionsSchema, CreateMergeRequestNoteSchema, CreateMergeRequestNoteEmojiReactionSchema, CreateMergeRequestSchema, CreateMergeRequestThreadSchema, CreateNoteSchema, CreateCommitStatusSchema, CreateOrUpdateFileSchema, CreatePipelineSchema, CreateProjectMilestoneSchema, CreateGroupMilestoneSchema, CreateReleaseEvidenceSchema, CreateReleaseSchema, CreateRepositorySchema, CreateTagSchema, CreateTimelineEventSchema, CreateWebhookSchema, CreateWikiPageSchema, CreateWorkItemNoteSchema, CreateWorkItemEmojiReactionSchema, CreateWorkItemNoteEmojiReactionSchema, ListWorkItemEmojiReactionsSchema, ListWorkItemNoteEmojiReactionsSchema, CreateWorkItemSchema, DeleteBranchSchema, GetProtectedBranchSchema, ListProtectedBranchesSchema, ProtectBranchSchema, UnprotectBranchSchema, UpdateDefaultBranchSchema, DeleteDraftNoteSchema, DeleteGroupMilestoneSchema, DeleteGroupWikiPageSchema, DeleteIssueLinkSchema, DeleteIssueSchema, DeleteIssueEmojiReactionSchema, DeleteIssueNoteEmojiReactionSchema, DeleteLabelSchema, DeleteMergeRequestDiscussionNoteSchema, DeleteMergeRequestNoteSchema, DeleteMergeRequestEmojiReactionSchema, DeleteMergeRequestNoteEmojiReactionSchema, DeleteProjectMilestoneSchema, DeleteReleaseSchema, DeleteTagSchema, DeleteWebhookSchema, DeleteWikiPageSchema, DeleteWorkItemEmojiReactionSchema, DeleteWorkItemNoteEmojiReactionSchema, DownloadAttachmentSchema, DownloadAttachmentRemoteSchema, DownloadJobArtifactsSchema, DownloadJobArtifactsRemoteSchema, DownloadReleaseAssetSchema, EditProjectMilestoneSchema, EditGroupMilestoneSchema, ExecuteGraphQLSchema, ForkRepositorySchema, HealthCheckSchema, GetBranchSchema, GetBranchDiffsSchema, GetCommitDiffSchema, GetCommitSchema, GetFileBlameSchema, GetDeploymentSchema, CreateDeploymentSchema, UpdateDeploymentSchema, DeploymentApprovalSchema, ListDeploymentMergeRequestsSchema, GetDraftNoteSchema, GetEnvironmentSchema, UpdateEnvironmentSchema, StopEnvironmentSchema, StopStaleEnvironmentsSchema, DeleteReviewAppEnvironmentsSchema, PipelineTriggerIdSchema, ListPipelineTriggersSchema, CreatePipelineTriggerSchema, UpdatePipelineTriggerSchema, TriggerPipelineSchema, GetFileContentsSchema, GetGroupWikiPageSchema, GetIssueLinkSchema, GetIssueSchema, GetJobArtifactFileSchema, GetLabelSchema, GetMergeRequestApprovalStateSchema, GetMergeRequestConflictsSchema, GetMergeRequestDiffsSchema, GetMergeRequestFileDiffSchema, GetMergeRequestDiscussionSchema, GetMergeRequestNoteSchema, GetMergeRequestNotesSchema, GetMergeRequestSchema, GetMergeRequestVersionSchema, GetMilestoneBurndownEventsSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, GetGroupMilestoneSchema, GetGroupMilestoneIssuesSchema, GetGroupMilestoneMergeRequestsSchema, GetGroupMilestoneBurndownEventsSchema, GetNamespaceSchema, GetPipelineJobOutputSchema, PipelineJobControlSchema, GetPipelineSchema, GetPipelineVariablesSchema, UpdatePipelineMetadataSchema, DeletePipelineSchema, PipelineReportSchema, WaitForPipelineSchema, WaitForPipelineJobSchema, PlayPipelineJobsSchema, GetProjectEventsSchema, GetProjectMilestoneSchema, GetProjectSchema, GetReleaseSchema, GetRepositoryTreeSchema, GetTagSchema, GetTagSignatureSchema, GetTimelineEventsSchema, GetUsersSchema, GetUserSchema, WhoAmISchema, GetWebhookEventSchema, GetWikiPageSchema, GetWorkItemSchema, ListBranchesSchema, ListCommitsSchema, ListCommitStatusesSchema, ListCustomFieldDefinitionsSchema, ListDeploymentsSchema, ListDraftNotesSchema, ListEnvironmentsSchema, ListEventsSchema, ListGroupIterationsSchema, ListGroupMilestonesSchema, ListGroupProjectsSchema, ListGroupWikiPagesSchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListJobArtifactsSchema, ListLabelsSchema, ListMergeRequestChangedFilesSchema, ListMergeRequestDiffsSchema, ListMergeRequestDiscussionsSchema, ListMergeRequestPipelinesSchema, ListMergeRequestVersionsSchema, ListMergeRequestsSchema, ListGroupMergeRequestsSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelineTriggerJobsSchema, ValidateCiLintSchema, ValidateProjectCiLintSchema, ListCiCatalogResourcesSchema, GetCiCatalogResourceSchema, ListPipelinesSchema, ListPipelineSchedulesSchema, GetPipelineScheduleSchema, ListPipelineSchedulePipelinesSchema, CreatePipelineScheduleSchema, UpdatePipelineScheduleSchema, DeletePipelineScheduleSchema, PlayPipelineScheduleSchema, TakeOwnershipPipelineScheduleSchema, GetPipelineScheduleVariableSchema, CreatePipelineScheduleVariableSchema, UpdatePipelineScheduleVariableSchema, DeletePipelineScheduleVariableSchema, ListGroupMembersSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListReleasesSchema, ListTagsSchema, ListWebhookEventsSchema, ListWebhooksSchema, ListWikiPagesSchema, ListWorkItemNotesSchema, ListWorkItemStatusesSchema, ListWorkItemsSchema, MarkdownUploadSchema, MarkdownUploadRemoteSchema, MergeMergeRequestSchema, MoveWorkItemSchema, MyIssuesSchema, OrbitQuerySchema, OrbitSchemaSchema, OrbitStatusSchema, OrbitToolsSchema, PlayPipelineJobSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PushFilesSchema, ResolveMergeRequestThreadSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchCodeSchema, SearchGroupCodeSchema, SearchProjectCodeSchema, SearchRepositoriesSchema, ListSnippetsSchema, GetSnippetSchema, CreateSnippetSchema, UpdateSnippetSchema, DeleteSnippetSchema, UnapproveMergeRequestSchema, UpdateDraftNoteSchema, UpdateGroupWikiPageSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateIssueDescriptionPatchSchema, UpdateLabelSchema, UpdateProjectSchema, UpdateMergeRequestDiscussionNoteSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestSchema, UpdateReleaseSchema, UpdateWebhookSchema, UpdateWikiPageSchema, UpdateWorkItemSchema, VerifyNamespaceSchema, ListProjectVariablesSchema, GetProjectVariableSchema, CreateProjectVariableSchema, UpdateProjectVariableSchema, DeleteProjectVariableSchema, ListGroupVariablesSchema, GetGroupVariableSchema, CreateGroupVariableSchema, UpdateGroupVariableSchema, DeleteGroupVariableSchema, GetDependencyProxySettingsSchema, UpdateDependencyProxySettingsSchema, ListDependencyProxyBlobsSchema, PurgeDependencyProxyCacheSchema, ListProjectVulnerabilitiesSchema, GetVulnerabilitySchema, DismissVulnerabilitySchema, ConfirmVulnerabilitySchema, } from "../schemas.js";
5
5
  const IS_REMOTE = SSE || STREAMABLE_HTTP;
@@ -359,7 +359,7 @@ export const allTools = [
359
359
  },
360
360
  {
361
361
  name: "get_issue",
362
- description: "Get details of a specific issue. Returns a slim milestone by default; set full_response=true for the complete milestone object",
362
+ description: "Get details of a specific issue. Returns the issue with a slim nested milestone by default; set full_response=true for the complete milestone object",
363
363
  inputSchema: toJSONSchema(GetIssueSchema),
364
364
  },
365
365
  {
@@ -559,10 +559,26 @@ export const allTools = [
559
559
  description: "Get variables configured for a pipeline",
560
560
  inputSchema: toJSONSchema(GetPipelineVariablesSchema),
561
561
  },
562
- { name: "get_pipeline_test_report", description: "Get pipeline test report", inputSchema: toJSONSchema(PipelineReportSchema) },
563
- { name: "get_pipeline_test_report_summary", description: "Get pipeline test report summary", inputSchema: toJSONSchema(PipelineReportSchema) },
564
- { name: "delete_pipeline", description: "Delete a pipeline. Requires the project Owner role, cannot be undone, and does not automatically delete child pipelines.", inputSchema: toJSONSchema(DeletePipelineSchema) },
565
- { name: "update_pipeline_metadata", description: "Update pipeline metadata", inputSchema: toJSONSchema(UpdatePipelineMetadataSchema) },
562
+ {
563
+ name: "get_pipeline_test_report",
564
+ description: "Get pipeline test report",
565
+ inputSchema: toJSONSchema(PipelineReportSchema),
566
+ },
567
+ {
568
+ name: "get_pipeline_test_report_summary",
569
+ description: "Get pipeline test report summary",
570
+ inputSchema: toJSONSchema(PipelineReportSchema),
571
+ },
572
+ {
573
+ name: "delete_pipeline",
574
+ description: "Delete a pipeline. Requires the project Owner role, cannot be undone, and does not automatically delete child pipelines.",
575
+ inputSchema: toJSONSchema(DeletePipelineSchema),
576
+ },
577
+ {
578
+ name: "update_pipeline_metadata",
579
+ description: "Update pipeline metadata",
580
+ inputSchema: toJSONSchema(UpdatePipelineMetadataSchema),
581
+ },
566
582
  {
567
583
  name: "list_deployments",
568
584
  description: "List deployments with filtering options",
@@ -573,11 +589,31 @@ export const allTools = [
573
589
  description: "Get deployment details, including approval_summary, approvals, and pending_approval_count when GitLab provides them",
574
590
  inputSchema: toJSONSchema(GetDeploymentSchema),
575
591
  },
576
- { name: "create_deployment", description: "Create a deployment", inputSchema: toJSONSchema(CreateDeploymentSchema) },
577
- { name: "update_deployment", description: "Update a deployment status", inputSchema: toJSONSchema(UpdateDeploymentSchema) },
578
- { name: "delete_deployment", description: "Delete a deployment", inputSchema: toJSONSchema(GetDeploymentSchema) },
579
- { name: "list_deployment_merge_requests", description: "List merge requests shipped with a deployment", inputSchema: toJSONSchema(ListDeploymentMergeRequestsSchema) },
580
- { name: "approve_deployment", description: "Approve or reject a protected-environment deployment", inputSchema: toJSONSchema(DeploymentApprovalSchema) },
592
+ {
593
+ name: "create_deployment",
594
+ description: "Create a deployment",
595
+ inputSchema: toJSONSchema(CreateDeploymentSchema),
596
+ },
597
+ {
598
+ name: "update_deployment",
599
+ description: "Update a deployment status",
600
+ inputSchema: toJSONSchema(UpdateDeploymentSchema),
601
+ },
602
+ {
603
+ name: "delete_deployment",
604
+ description: "Delete a deployment",
605
+ inputSchema: toJSONSchema(GetDeploymentSchema),
606
+ },
607
+ {
608
+ name: "list_deployment_merge_requests",
609
+ description: "List merge requests shipped with a deployment",
610
+ inputSchema: toJSONSchema(ListDeploymentMergeRequestsSchema),
611
+ },
612
+ {
613
+ name: "approve_deployment",
614
+ description: "Approve or reject a protected-environment deployment",
615
+ inputSchema: toJSONSchema(DeploymentApprovalSchema),
616
+ },
581
617
  {
582
618
  name: "list_environments",
583
619
  description: "List environments in a project",
@@ -588,17 +624,61 @@ export const allTools = [
588
624
  description: "Get details of a specific environment",
589
625
  inputSchema: toJSONSchema(GetEnvironmentSchema),
590
626
  },
591
- { name: "update_environment", description: "Update an environment", inputSchema: toJSONSchema(UpdateEnvironmentSchema) },
592
- { name: "delete_environment", description: "Delete a stopped environment", inputSchema: toJSONSchema(GetEnvironmentSchema) },
593
- { name: "stop_environment", description: "Stop an environment", inputSchema: toJSONSchema(StopEnvironmentSchema) },
594
- { name: "stop_stale_environments", description: "Stop eligible stale environments; protected environments are excluded and environments are stopped, not deleted", inputSchema: toJSONSchema(StopStaleEnvironmentsSchema) },
595
- { name: "delete_review_app_environments", description: "Schedule deletion of stopped review-app environments one week later; dry_run defaults to true and actual scheduling requires dry_run=false", inputSchema: toJSONSchema(DeleteReviewAppEnvironmentsSchema) },
596
- { name: "list_pipeline_triggers", description: "List project pipeline trigger tokens", inputSchema: toJSONSchema(ListPipelineTriggersSchema) },
597
- { name: "get_pipeline_trigger", description: "Get a project pipeline trigger", inputSchema: toJSONSchema(PipelineTriggerIdSchema) },
598
- { name: "create_pipeline_trigger", description: "Create a project pipeline trigger", inputSchema: toJSONSchema(CreatePipelineTriggerSchema) },
599
- { name: "update_pipeline_trigger", description: "Update a project pipeline trigger", inputSchema: toJSONSchema(UpdatePipelineTriggerSchema) },
600
- { name: "delete_pipeline_trigger", description: "Delete a project pipeline trigger", inputSchema: toJSONSchema(PipelineTriggerIdSchema) },
601
- { name: "trigger_pipeline", description: "Trigger a pipeline with a pipeline trigger token", inputSchema: toJSONSchema(TriggerPipelineSchema) },
627
+ {
628
+ name: "update_environment",
629
+ description: "Update an environment",
630
+ inputSchema: toJSONSchema(UpdateEnvironmentSchema),
631
+ },
632
+ {
633
+ name: "delete_environment",
634
+ description: "Delete a stopped environment",
635
+ inputSchema: toJSONSchema(GetEnvironmentSchema),
636
+ },
637
+ {
638
+ name: "stop_environment",
639
+ description: "Stop an environment",
640
+ inputSchema: toJSONSchema(StopEnvironmentSchema),
641
+ },
642
+ {
643
+ name: "stop_stale_environments",
644
+ description: "Stop eligible stale environments; protected environments are excluded and environments are stopped, not deleted",
645
+ inputSchema: toJSONSchema(StopStaleEnvironmentsSchema),
646
+ },
647
+ {
648
+ name: "delete_review_app_environments",
649
+ description: "Schedule deletion of stopped review-app environments one week later; dry_run defaults to true and actual scheduling requires dry_run=false",
650
+ inputSchema: toJSONSchema(DeleteReviewAppEnvironmentsSchema),
651
+ },
652
+ {
653
+ name: "list_pipeline_triggers",
654
+ description: "List project pipeline trigger tokens",
655
+ inputSchema: toJSONSchema(ListPipelineTriggersSchema),
656
+ },
657
+ {
658
+ name: "get_pipeline_trigger",
659
+ description: "Get a project pipeline trigger",
660
+ inputSchema: toJSONSchema(PipelineTriggerIdSchema),
661
+ },
662
+ {
663
+ name: "create_pipeline_trigger",
664
+ description: "Create a project pipeline trigger",
665
+ inputSchema: toJSONSchema(CreatePipelineTriggerSchema),
666
+ },
667
+ {
668
+ name: "update_pipeline_trigger",
669
+ description: "Update a project pipeline trigger",
670
+ inputSchema: toJSONSchema(UpdatePipelineTriggerSchema),
671
+ },
672
+ {
673
+ name: "delete_pipeline_trigger",
674
+ description: "Delete a project pipeline trigger",
675
+ inputSchema: toJSONSchema(PipelineTriggerIdSchema),
676
+ },
677
+ {
678
+ name: "trigger_pipeline",
679
+ description: "Trigger a pipeline with a pipeline trigger token",
680
+ inputSchema: toJSONSchema(TriggerPipelineSchema),
681
+ },
602
682
  {
603
683
  name: "list_pipeline_jobs",
604
684
  description: "List all jobs in a specific pipeline",
@@ -734,9 +814,21 @@ export const allTools = [
734
814
  description: "Cancel a running pipeline job",
735
815
  inputSchema: toJSONSchema(CancelPipelineJobSchema),
736
816
  },
737
- { name: "erase_pipeline_job", description: "Erase a pipeline job log and artifacts", inputSchema: toJSONSchema(ErasePipelineJobSchema) },
738
- { name: "wait_for_pipeline", description: "Wait for a pipeline to reach a terminal status", inputSchema: toJSONSchema(WaitForPipelineSchema) },
739
- { name: "wait_for_job", description: "Wait for a job to reach a terminal status", inputSchema: toJSONSchema(WaitForPipelineJobSchema) },
817
+ {
818
+ name: "erase_pipeline_job",
819
+ description: "Erase a pipeline job log and artifacts",
820
+ inputSchema: toJSONSchema(ErasePipelineJobSchema),
821
+ },
822
+ {
823
+ name: "wait_for_pipeline",
824
+ description: "Wait for a pipeline to reach a terminal status",
825
+ inputSchema: toJSONSchema(WaitForPipelineSchema),
826
+ },
827
+ {
828
+ name: "wait_for_job",
829
+ description: "Wait for a job to reach a terminal status",
830
+ inputSchema: toJSONSchema(WaitForPipelineJobSchema),
831
+ },
740
832
  {
741
833
  name: "list_job_artifacts",
742
834
  description: "List artifact files in a job's archive",
@@ -1432,6 +1524,12 @@ export const readOnlyTools = new Set([
1432
1524
  "orbit_get_status",
1433
1525
  "orbit_list_tools",
1434
1526
  ]);
1527
+ // Stays in readOnlyTools so readonly mode can still run queries, but mutations
1528
+ // are allowed in other permission modes and rejected only at call time.
1529
+ const MIXED_ACCESS_TOOLS = new Set(["execute_graphql"]);
1530
+ export function advertisesReadOnly(toolName) {
1531
+ return readOnlyTools.has(toolName) && !MIXED_ACCESS_TOOLS.has(toolName);
1532
+ }
1435
1533
  // Define which tools are destructive (data loss potential)
1436
1534
  export const destructiveTools = new Set([
1437
1535
  "delete_pipeline",
@@ -1620,8 +1718,52 @@ export const pipelineToolNames = new Set([
1620
1718
  ]);
1621
1719
  export const TOOLSET_DEFINITIONS = [
1622
1720
  {
1623
- id: "merge_requests",
1721
+ id: "core",
1624
1722
  isDefault: true,
1723
+ tools: new Set([
1724
+ "list_merge_requests",
1725
+ "get_merge_request",
1726
+ "get_merge_request_approval_state",
1727
+ "list_merge_request_changed_files",
1728
+ "get_merge_request_file_diff",
1729
+ "list_merge_request_diffs",
1730
+ "get_merge_request_diffs",
1731
+ "mr_discussions",
1732
+ "get_merge_request_discussion",
1733
+ "get_merge_request_note",
1734
+ "get_merge_request_notes",
1735
+ "create_merge_request",
1736
+ "create_merge_request_thread",
1737
+ "resolve_merge_request_thread",
1738
+ "update_merge_request",
1739
+ "list_issues",
1740
+ "my_issues",
1741
+ "get_issue",
1742
+ "create_issue",
1743
+ "update_issue",
1744
+ "create_issue_note",
1745
+ "list_issue_discussions",
1746
+ "update_issue_description_patch",
1747
+ "get_file_contents",
1748
+ "get_repository_tree",
1749
+ "search_repositories",
1750
+ "get_branch",
1751
+ "list_branches",
1752
+ "list_commits",
1753
+ "get_commit",
1754
+ "get_commit_diff",
1755
+ "get_file_blame",
1756
+ "get_project",
1757
+ "list_projects",
1758
+ "list_project_members",
1759
+ "list_labels",
1760
+ "whoami",
1761
+ "health_check",
1762
+ ]),
1763
+ },
1764
+ {
1765
+ id: "merge_requests",
1766
+ isDefault: false,
1625
1767
  tools: new Set([
1626
1768
  "merge_merge_request",
1627
1769
  "approve_merge_request",
@@ -1672,7 +1814,7 @@ export const TOOLSET_DEFINITIONS = [
1672
1814
  },
1673
1815
  {
1674
1816
  id: "issues",
1675
- isDefault: true,
1817
+ isDefault: false,
1676
1818
  tools: new Set([
1677
1819
  "create_issue",
1678
1820
  "list_issues",
@@ -1702,7 +1844,7 @@ export const TOOLSET_DEFINITIONS = [
1702
1844
  },
1703
1845
  {
1704
1846
  id: "repositories",
1705
- isDefault: true,
1847
+ isDefault: false,
1706
1848
  tools: new Set([
1707
1849
  "search_repositories",
1708
1850
  "create_repository",
@@ -1715,7 +1857,7 @@ export const TOOLSET_DEFINITIONS = [
1715
1857
  },
1716
1858
  {
1717
1859
  id: "branches",
1718
- isDefault: true,
1860
+ isDefault: false,
1719
1861
  tools: new Set([
1720
1862
  "create_branch",
1721
1863
  "get_branch",
@@ -1736,7 +1878,7 @@ export const TOOLSET_DEFINITIONS = [
1736
1878
  },
1737
1879
  {
1738
1880
  id: "projects",
1739
- isDefault: true,
1881
+ isDefault: false,
1740
1882
  tools: new Set([
1741
1883
  "get_project",
1742
1884
  "list_projects",
@@ -1753,18 +1895,12 @@ export const TOOLSET_DEFINITIONS = [
1753
1895
  },
1754
1896
  {
1755
1897
  id: "labels",
1756
- isDefault: true,
1757
- tools: new Set([
1758
- "list_labels",
1759
- "get_label",
1760
- "create_label",
1761
- "update_label",
1762
- "delete_label",
1763
- ]),
1898
+ isDefault: false,
1899
+ tools: new Set(["list_labels", "get_label", "create_label", "update_label", "delete_label"]),
1764
1900
  },
1765
1901
  {
1766
1902
  id: "ci",
1767
- isDefault: true,
1903
+ isDefault: false,
1768
1904
  tools: new Set([
1769
1905
  "validate_ci_lint",
1770
1906
  "validate_project_ci_lint",
@@ -1774,7 +1910,7 @@ export const TOOLSET_DEFINITIONS = [
1774
1910
  },
1775
1911
  {
1776
1912
  id: "groups",
1777
- isDefault: true,
1913
+ isDefault: false,
1778
1914
  tools: new Set(["create_group"]),
1779
1915
  },
1780
1916
  {
@@ -1894,13 +2030,7 @@ export const TOOLSET_DEFINITIONS = [
1894
2030
  {
1895
2031
  id: "tags",
1896
2032
  isDefault: false,
1897
- tools: new Set([
1898
- "list_tags",
1899
- "get_tag",
1900
- "create_tag",
1901
- "delete_tag",
1902
- "get_tag_signature",
1903
- ]),
2033
+ tools: new Set(["list_tags", "get_tag", "create_tag", "delete_tag", "get_tag_signature"]),
1904
2034
  },
1905
2035
  {
1906
2036
  id: "snippets",
@@ -1915,7 +2045,7 @@ export const TOOLSET_DEFINITIONS = [
1915
2045
  },
1916
2046
  {
1917
2047
  id: "users",
1918
- isDefault: true,
2048
+ isDefault: false,
1919
2049
  tools: new Set([
1920
2050
  "get_users",
1921
2051
  "get_user",
@@ -2009,18 +2139,29 @@ export const TOOLSET_DEFINITIONS = [
2009
2139
  tools: new Set(["orbit_query", "orbit_get_schema", "orbit_get_status", "orbit_list_tools"]),
2010
2140
  },
2011
2141
  ];
2012
- // Derived lookup: tool name → toolset ID
2013
- export const TOOLSET_BY_TOOL_NAME = new Map();
2142
+ // Derived lookup: tool name → toolset IDs. Most tools belong to one category.
2143
+ // The default `core` toolset intentionally overlaps with the full opt-in
2144
+ // categories so users get a small starter surface without losing the ability
2145
+ // to enable complete categories later.
2146
+ export const TOOLSETS_BY_TOOL_NAME = new Map();
2014
2147
  for (const def of TOOLSET_DEFINITIONS) {
2015
2148
  for (const tool of def.tools) {
2016
- if (TOOLSET_BY_TOOL_NAME.has(tool)) {
2017
- console.warn(`Tool "${tool}" is defined in multiple toolsets: "${TOOLSET_BY_TOOL_NAME.get(tool)}" and "${def.id}"`);
2018
- }
2019
- TOOLSET_BY_TOOL_NAME.set(tool, def.id);
2149
+ const toolsets = TOOLSETS_BY_TOOL_NAME.get(tool) ?? new Set();
2150
+ toolsets.add(def.id);
2151
+ TOOLSETS_BY_TOOL_NAME.set(tool, toolsets);
2020
2152
  }
2021
2153
  }
2022
2154
  export const DEFAULT_TOOLSET_IDS = new Set(TOOLSET_DEFINITIONS.filter(d => d.isDefault).map(d => d.id));
2023
2155
  export const ALL_TOOLSET_IDS = new Set(TOOLSET_DEFINITIONS.map(d => d.id));
2156
+ /**
2157
+ * Smallest toolset containing the tool, i.e. the cheapest category to activate for it.
2158
+ * Returns undefined for tools outside every toolset (e.g. `execute_graphql`) and unknown names.
2159
+ */
2160
+ export function findSmallestToolsetForTool(toolName) {
2161
+ const candidates = TOOLSET_DEFINITIONS.filter(d => d.tools.has(toolName));
2162
+ const smallest = candidates.reduce((best, d) => (best === undefined || d.tools.size < best.tools.size ? d : best), undefined);
2163
+ return smallest?.id;
2164
+ }
2024
2165
  // Update discover_tools description with all known categories (must be after TOOLSET_DEFINITIONS)
2025
2166
  const discoverTool = allTools.find(t => t.name === "discover_tools");
2026
2167
  if (discoverTool) {
@@ -2080,9 +2221,37 @@ export function buildFeatureFlagOverrides() {
2080
2221
  return overrides;
2081
2222
  }
2082
2223
  export function isToolInEnabledToolset(toolName, enabledToolsets) {
2083
- const toolsetId = TOOLSET_BY_TOOL_NAME.get(toolName);
2224
+ const toolsetIds = TOOLSETS_BY_TOOL_NAME.get(toolName);
2084
2225
  // Tools not in any toolset (e.g. execute_graphql) are excluded by default
2085
- if (toolsetId === undefined)
2226
+ if (toolsetIds === undefined)
2086
2227
  return false;
2087
- return enabledToolsets.has(toolsetId);
2228
+ for (const toolsetId of toolsetIds) {
2229
+ if (enabledToolsets.has(toolsetId))
2230
+ return true;
2231
+ }
2232
+ return false;
2233
+ }
2234
+ /**
2235
+ * True only when every tool in the set is already exposed.
2236
+ * Partial overlap (for example `core` sharing names with `merge_requests`) is not active.
2237
+ * `isExcluded` covers tools the caller will not list; those do not keep the toolset inactive.
2238
+ * An empty set is fully active, matching `Array.prototype.every`.
2239
+ */
2240
+ export function isToolsetFullyActive(tools, currentToolNames, isExcluded) {
2241
+ for (const toolName of tools) {
2242
+ if (currentToolNames.has(toolName) || isExcluded?.(toolName)) {
2243
+ continue;
2244
+ }
2245
+ return false;
2246
+ }
2247
+ return true;
2248
+ }
2249
+ /** Category listing returned by `discover_tools` when no category argument is given. */
2250
+ export function listDiscoverableCategories(currentToolNames, isExcluded) {
2251
+ return TOOLSET_DEFINITIONS.map(def => ({
2252
+ id: def.id,
2253
+ toolCount: def.tools.size,
2254
+ active: isToolsetFullyActive(def.tools, currentToolNames, isExcluded),
2255
+ isDefault: def.isDefault,
2256
+ }));
2088
2257
  }
@@ -0,0 +1,66 @@
1
+ export const TOOL_PROFILES = ["full", "slim"];
2
+ /**
3
+ * Tools omitted from the initial list when `GITLAB_TOOL_PROFILE=slim` and
4
+ * `GITLAB_TOOLSETS` is unset. `discover_tools` does not add them back.
5
+ * `GITLAB_TOOLS` can still name one explicitly.
6
+ */
7
+ export const SLIM_PROFILE_EXCLUDED_TOOLS = new Set([
8
+ "get_draft_note",
9
+ "list_draft_notes",
10
+ "create_draft_note",
11
+ "update_draft_note",
12
+ "delete_draft_note",
13
+ "publish_draft_note",
14
+ "bulk_publish_draft_notes",
15
+ "list_merge_request_emoji_reactions",
16
+ "list_merge_request_note_emoji_reactions",
17
+ "create_merge_request_emoji_reaction",
18
+ "delete_merge_request_emoji_reaction",
19
+ "create_merge_request_note_emoji_reaction",
20
+ "delete_merge_request_note_emoji_reaction",
21
+ "list_issue_emoji_reactions",
22
+ "list_issue_note_emoji_reactions",
23
+ "create_issue_emoji_reaction",
24
+ "delete_issue_emoji_reaction",
25
+ "create_issue_note_emoji_reaction",
26
+ "delete_issue_note_emoji_reaction",
27
+ "list_labels",
28
+ "get_label",
29
+ "create_label",
30
+ "update_label",
31
+ "delete_label",
32
+ "validate_ci_lint",
33
+ "validate_project_ci_lint",
34
+ "list_ci_catalog_resources",
35
+ "get_ci_catalog_resource",
36
+ "create_group",
37
+ ]);
38
+ export function parseToolProfile(raw) {
39
+ if (raw === undefined) {
40
+ return "full";
41
+ }
42
+ const normalized = raw.trim().toLowerCase();
43
+ if (normalized === "" || normalized === "full") {
44
+ return "full";
45
+ }
46
+ if (normalized === "slim") {
47
+ return "slim";
48
+ }
49
+ throw new Error(`Invalid GITLAB_TOOL_PROFILE: "${raw}". Expected one of: ${TOOL_PROFILES.join(", ")}`);
50
+ }
51
+ /** Slim applies only when the caller did not pin an explicit toolset list. */
52
+ export function shouldApplySlimToolProfile(profile, toolsetsRaw) {
53
+ if (profile !== "slim") {
54
+ return false;
55
+ }
56
+ return toolsetsRaw === undefined || toolsetsRaw.trim() === "";
57
+ }
58
+ export function isExcludedBySlimProfile(toolName, applySlimProfile, explicitlyEnabledTools) {
59
+ if (!applySlimProfile) {
60
+ return false;
61
+ }
62
+ if (explicitlyEnabledTools.has(toolName)) {
63
+ return false;
64
+ }
65
+ return SLIM_PROFILE_EXCLUDED_TOOLS.has(toolName);
66
+ }
@@ -0,0 +1,14 @@
1
+ /** Tool names that compact oversized replies even when global compact mode is off. */
2
+ export function parseCompactToolAllowlist(raw) {
3
+ if (raw === undefined || raw.trim() === "") {
4
+ return new Set();
5
+ }
6
+ const names = raw
7
+ .split(",")
8
+ .map(name => name.trim())
9
+ .filter(name => name.length > 0);
10
+ return new Set(names);
11
+ }
12
+ export function shouldCompactToolResult(toolName, globalEnabled, allowlist) {
13
+ return globalEnabled || allowlist.has(toolName);
14
+ }
@@ -1,4 +1,6 @@
1
+ import { createRequire } from "node:module";
1
2
  import { pino } from "pino";
3
+ const require = createRequire(import.meta.url);
2
4
  const REDACT_PATHS = [
3
5
  "token",
4
6
  "*.token",
@@ -23,6 +25,31 @@ const REDACT_PATHS = [
23
25
  "arguments.approval_password",
24
26
  "params.arguments.approval_password",
25
27
  ];
28
+ function isPrettyFactory(value) {
29
+ return typeof value === "function";
30
+ }
31
+ function isPrettyModule(value) {
32
+ if (typeof value !== "object" || value === null || !("default" in value)) {
33
+ return false;
34
+ }
35
+ return isPrettyFactory(value.default);
36
+ }
37
+ /**
38
+ * Pretty-print in process. The worker transport has the same text format, but
39
+ * it spawns a thread on every logger, including stdio MCP startup.
40
+ * LOG_FORMAT=json still skips pino-pretty entirely.
41
+ */
42
+ function createPrettyStream() {
43
+ const loaded = require("pino-pretty");
44
+ const options = { colorize: true, levelFirst: true, destination: 2 };
45
+ if (isPrettyFactory(loaded)) {
46
+ return loaded(options);
47
+ }
48
+ if (isPrettyModule(loaded)) {
49
+ return loaded.default(options);
50
+ }
51
+ throw new Error("pino-pretty did not export a stream factory");
52
+ }
26
53
  /**
27
54
  * Create a pino logger with consistent redaction, level, format, and
28
55
  * destination across the entire codebase.
@@ -30,26 +57,21 @@ const REDACT_PATHS = [
30
57
  * - LOG_LEVEL (default "info") controls the minimum severity.
31
58
  * - LOG_FORMAT=json disables pino-pretty and outputs newline-delimited JSON
32
59
  * to stderr.
60
+ * - Any other value, including unset, keeps human-readable pino-pretty output.
33
61
  * - All loggers redact the same set of sensitive fields.
34
62
  */
35
63
  export function createLogger(name) {
36
64
  const isJson = process.env.LOG_FORMAT === "json";
37
- return pino({
65
+ const options = {
38
66
  ...(name && { name }),
39
67
  level: process.env.LOG_LEVEL || "info",
40
68
  redact: {
41
69
  paths: REDACT_PATHS,
42
70
  censor: "[REDACTED]",
43
71
  },
44
- ...(!isJson && {
45
- transport: {
46
- target: "pino-pretty",
47
- options: {
48
- colorize: true,
49
- levelFirst: true,
50
- destination: 2,
51
- },
52
- },
53
- }),
54
- }, ...(isJson ? [pino.destination(2)] : []));
72
+ };
73
+ if (isJson) {
74
+ return pino(options, pino.destination(2));
75
+ }
76
+ return pino(options, createPrettyStream());
55
77
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zereight/mcp-gitlab",
3
- "version": "2.1.70",
3
+ "version": "2.2.0",
4
4
  "mcpName": "io.github.zereight/gitlab-mcp",
5
5
  "description": "GitLab MCP server for projects, merge requests, issues, pipelines, wiki, releases, and more",
6
6
  "keywords": [
@@ -44,10 +44,10 @@
44
44
  "npm": ">=9.0.0"
45
45
  },
46
46
  "scripts": {
47
- "build": "tsc && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
47
+ "build": "node -e \"require('fs').rmSync('build',{recursive:true,force:true})\" && tsc -p tsconfig.build.json && node -e \"require('fs').chmodSync('build/index.js', '755')\"",
48
48
  "prepare": "npm run build",
49
49
  "dev": "npm run build && node build/index.js",
50
- "watch": "tsc --watch",
50
+ "watch": "tsc -p tsconfig.build.json --watch",
51
51
  "deploy": "npm publish --access public",
52
52
  "changelog": "auto-changelog -p",
53
53
  "test": "npm run test:all",