@zereight/mcp-gitlab 2.1.10 → 2.1.12
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/README.md +106 -104
- package/build/index.js +215 -5
- package/build/schemas.js +140 -0
- package/build/test/schema-tests.js +140 -3
- package/build/test/test-issue-description-patch.js +256 -0
- package/build/test/test-merge-request-pipelines.js +106 -0
- package/build/test/test-token-optimizations.js +1 -1
- package/build/test/test-toolset-filtering.js +7 -6
- package/build/test/utils/mock-gitlab-server.js +46 -0
- package/build/test/utils/server-launcher.js +2 -1
- package/build/tools/registry.js +61 -1
- package/build/utils/patch-helper.js +145 -0
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -540,110 +540,112 @@ Register the skill directory in your AI client to get optimal tool usage guidanc
|
|
|
540
540
|
47. `my_issues` - List issues assigned to the authenticated user (defaults to open issues)
|
|
541
541
|
48. `get_issue` - Get details of a specific issue in a GitLab project
|
|
542
542
|
49. `update_issue` - Update an issue in a GitLab project
|
|
543
|
-
50. `
|
|
544
|
-
51. `
|
|
545
|
-
52. `
|
|
546
|
-
53. `
|
|
547
|
-
54. `
|
|
548
|
-
55. `
|
|
549
|
-
56. `
|
|
550
|
-
57. `
|
|
551
|
-
58. `
|
|
552
|
-
59. `
|
|
553
|
-
60. `
|
|
554
|
-
61. `
|
|
555
|
-
62. `
|
|
556
|
-
63. `
|
|
557
|
-
64. `
|
|
558
|
-
65. `
|
|
559
|
-
66. `
|
|
560
|
-
67. `
|
|
561
|
-
68. `
|
|
562
|
-
69. `
|
|
563
|
-
70. `
|
|
564
|
-
71. `
|
|
565
|
-
72. `
|
|
566
|
-
73. `
|
|
567
|
-
74. `
|
|
568
|
-
75. `
|
|
569
|
-
76. `
|
|
570
|
-
77. `
|
|
571
|
-
78. `
|
|
572
|
-
79. `
|
|
573
|
-
80. `
|
|
574
|
-
81. `
|
|
575
|
-
82. `
|
|
576
|
-
83. `
|
|
577
|
-
84. `
|
|
578
|
-
85. `
|
|
579
|
-
86. `
|
|
580
|
-
87. `
|
|
581
|
-
88. `
|
|
582
|
-
89. `
|
|
583
|
-
90. `
|
|
584
|
-
91. `
|
|
585
|
-
92. `
|
|
586
|
-
93. `
|
|
587
|
-
94. `
|
|
588
|
-
95. `
|
|
589
|
-
96. `
|
|
590
|
-
97. `
|
|
591
|
-
98. `
|
|
592
|
-
99. `
|
|
593
|
-
100. `
|
|
594
|
-
101. `
|
|
595
|
-
102. `
|
|
596
|
-
103. `
|
|
597
|
-
104. `
|
|
598
|
-
105. `
|
|
599
|
-
106. `
|
|
600
|
-
107. `
|
|
601
|
-
108. `
|
|
602
|
-
109. `
|
|
603
|
-
110. `
|
|
604
|
-
111. `
|
|
605
|
-
112. `
|
|
606
|
-
113. `
|
|
607
|
-
114. `
|
|
608
|
-
115. `
|
|
609
|
-
116. `
|
|
610
|
-
117. `
|
|
611
|
-
118. `
|
|
612
|
-
119. `
|
|
613
|
-
120. `
|
|
614
|
-
121. `
|
|
615
|
-
122. `
|
|
616
|
-
123. `
|
|
617
|
-
124. `
|
|
618
|
-
125. `
|
|
619
|
-
126. `
|
|
620
|
-
127. `
|
|
621
|
-
128. `
|
|
622
|
-
129. `
|
|
623
|
-
130. `
|
|
624
|
-
131. `
|
|
625
|
-
132. `
|
|
626
|
-
133. `
|
|
627
|
-
134. `
|
|
628
|
-
135. `
|
|
629
|
-
136. `
|
|
630
|
-
137. `
|
|
631
|
-
138. `
|
|
632
|
-
139. `
|
|
633
|
-
140. `
|
|
634
|
-
141. `
|
|
635
|
-
142. `
|
|
636
|
-
143. `
|
|
637
|
-
144. `
|
|
638
|
-
145. `
|
|
639
|
-
146. `
|
|
640
|
-
147. `
|
|
641
|
-
148. `
|
|
642
|
-
149. `
|
|
643
|
-
150. `
|
|
644
|
-
151. `
|
|
645
|
-
152. `
|
|
646
|
-
153. `
|
|
543
|
+
50. `update_issue_description_patch` - Apply a patch (search/replace or unified diff) to an issue description. Reduces token usage by sending only the change instead of the full description. Supports `dry_run` to preview and `create_note` to summarize.
|
|
544
|
+
51. `delete_issue` - Delete an issue from a GitLab project
|
|
545
|
+
52. `list_todos` - List GitLab to-do items for the current user
|
|
546
|
+
53. `mark_todo_done` - Mark a GitLab to-do item as done
|
|
547
|
+
54. `mark_all_todos_done` - Mark all pending GitLab to-do items as done for the current user
|
|
548
|
+
55. `list_issue_links` - List all issue links for a specific issue
|
|
549
|
+
56. `list_issue_discussions` - List discussions for an issue in a GitLab project
|
|
550
|
+
57. `get_issue_link` - Get a specific issue link
|
|
551
|
+
58. `create_issue_link` - Create an issue link between two issues
|
|
552
|
+
59. `delete_issue_link` - Delete an issue link
|
|
553
|
+
60. `list_namespaces` - List all namespaces available to the current user
|
|
554
|
+
61. `get_namespace` - Get details of a namespace by ID or path
|
|
555
|
+
62. `verify_namespace` - Verify if a namespace path exists
|
|
556
|
+
63. `get_project` - Get details of a specific project
|
|
557
|
+
64. `list_projects` - List projects accessible by the current user
|
|
558
|
+
65. `list_project_members` - List members of a GitLab project
|
|
559
|
+
66. `list_group_projects` - List projects in a GitLab group with filtering options
|
|
560
|
+
67. `list_group_iterations` - List group iterations with filtering options
|
|
561
|
+
68. `list_labels` - List labels for a project
|
|
562
|
+
69. `get_label` - Get a single label from a project
|
|
563
|
+
70. `create_label` - Create a new label in a project
|
|
564
|
+
71. `update_label` - Update an existing label in a project
|
|
565
|
+
72. `delete_label` - Delete a label from a project
|
|
566
|
+
73. `list_pipelines` - List pipelines in a GitLab project with filtering options
|
|
567
|
+
74. `get_pipeline` - Get details of a specific pipeline in a GitLab project
|
|
568
|
+
75. `list_pipeline_jobs` - List all jobs in a specific pipeline
|
|
569
|
+
76. `list_pipeline_trigger_jobs` - List all trigger jobs (bridges) in a specific pipeline that trigger downstream pipelines
|
|
570
|
+
77. `get_pipeline_job` - Get details of a GitLab pipeline job number
|
|
571
|
+
78. `get_pipeline_job_output` - Get the output/trace of a GitLab pipeline job with optional pagination to limit context window usage
|
|
572
|
+
79. `validate_ci_lint` - Validate provided GitLab CI/CD YAML content for a project
|
|
573
|
+
80. `validate_project_ci_lint` - Validate an existing `.gitlab-ci.yml` configuration for a project
|
|
574
|
+
81. `create_pipeline` - Create a new pipeline for a branch or tag
|
|
575
|
+
82. `retry_pipeline` - Retry a failed or canceled pipeline
|
|
576
|
+
83. `cancel_pipeline` - Cancel a running pipeline
|
|
577
|
+
84. `play_pipeline_job` - Run a manual pipeline job
|
|
578
|
+
85. `retry_pipeline_job` - Retry a failed or canceled pipeline job
|
|
579
|
+
86. `cancel_pipeline_job` - Cancel a running pipeline job
|
|
580
|
+
87. `list_deployments` - List deployments in a GitLab project with filtering options
|
|
581
|
+
88. `get_deployment` - Get details of a specific deployment in a GitLab project
|
|
582
|
+
89. `list_environments` - List environments in a GitLab project
|
|
583
|
+
90. `get_environment` - Get details of a specific environment in a GitLab project
|
|
584
|
+
91. `list_job_artifacts` - List artifact files in a job's artifacts archive. Returns file names, paths, types, and sizes
|
|
585
|
+
92. `download_job_artifacts` - Download the entire artifact archive (zip) for a job to a local path. Returns the saved file path
|
|
586
|
+
93. `get_job_artifact_file` - Get the content of a single file from a job's artifacts by its path within the archive
|
|
587
|
+
94. `list_milestones` - List milestones in a GitLab project with filtering options
|
|
588
|
+
95. `get_milestone` - Get details of a specific milestone
|
|
589
|
+
96. `create_milestone` - Create a new milestone in a GitLab project
|
|
590
|
+
97. `edit_milestone` - Edit an existing milestone in a GitLab project
|
|
591
|
+
98. `delete_milestone` - Delete a milestone from a GitLab project
|
|
592
|
+
99. `get_milestone_issue` - Get issues associated with a specific milestone
|
|
593
|
+
100. `get_milestone_merge_requests` - Get merge requests associated with a specific milestone
|
|
594
|
+
101. `promote_milestone` - Promote a milestone to the next stage
|
|
595
|
+
102. `get_milestone_burndown_events` - Get burndown events for a specific milestone
|
|
596
|
+
103. `list_wiki_pages` - List wiki pages in a GitLab project
|
|
597
|
+
104. `get_wiki_page` - Get details of a specific wiki page
|
|
598
|
+
105. `create_wiki_page` - Create a new wiki page in a GitLab project
|
|
599
|
+
106. `update_wiki_page` - Update an existing wiki page in a GitLab project
|
|
600
|
+
107. `delete_wiki_page` - Delete a wiki page from a GitLab project
|
|
601
|
+
108. `list_group_wiki_pages` - List wiki pages in a GitLab group
|
|
602
|
+
109. `get_group_wiki_page` - Get details of a specific group wiki page
|
|
603
|
+
110. `create_group_wiki_page` - Create a new wiki page in a GitLab group
|
|
604
|
+
111. `update_group_wiki_page` - Update an existing wiki page in a GitLab group
|
|
605
|
+
112. `delete_group_wiki_page` - Delete a wiki page from a GitLab group
|
|
606
|
+
113. `get_repository_tree` - Get the repository tree for a GitLab project (list files and directories)
|
|
607
|
+
114. `list_commits` - List repository commits with filtering options
|
|
608
|
+
115. `get_commit` - Get details of a specific commit
|
|
609
|
+
116. `get_commit_diff` - Get changes/diffs of a specific commit
|
|
610
|
+
117. `list_commit_statuses` - List statuses for a specific commit
|
|
611
|
+
118. `create_commit_status` - Create or update the status of a specific commit
|
|
612
|
+
119. `list_releases` - List all releases for a project
|
|
613
|
+
120. `get_release` - Get a release by tag name
|
|
614
|
+
121. `create_release` - Create a new release in a GitLab project
|
|
615
|
+
122. `update_release` - Update an existing release in a GitLab project
|
|
616
|
+
123. `delete_release` - Delete a release from a GitLab project (does not delete the associated tag)
|
|
617
|
+
124. `create_release_evidence` - Create release evidence for an existing release (GitLab Premium/Ultimate only)
|
|
618
|
+
125. `download_release_asset` - Download a release asset file by direct asset path
|
|
619
|
+
126. `list_tags` - List repository tags with filtering and pagination support
|
|
620
|
+
127. `get_tag` - Get details of a specific repository tag
|
|
621
|
+
128. `create_tag` - Create a new tag in the repository
|
|
622
|
+
129. `delete_tag` - Delete a tag from the repository
|
|
623
|
+
130. `get_tag_signature` - Get the signature of a signed tag
|
|
624
|
+
131. `get_users` - Get GitLab user details by usernames
|
|
625
|
+
132. `list_events` - List all events for the currently authenticated user
|
|
626
|
+
133. `get_project_events` - List all visible events for a specified project
|
|
627
|
+
134. `upload_markdown` - Upload a file to a GitLab project for use in markdown content
|
|
628
|
+
135. `download_attachment` - Download an uploaded file from a GitLab project by secret and filename
|
|
629
|
+
136. `get_work_item` - Get a single work item with full details including status, hierarchy (parent/children), type, labels, assignees, and all widgets
|
|
630
|
+
137. `list_work_items` - List work items in a project with filters (type, state, search, assignees, labels). Returns items with status and hierarchy info
|
|
631
|
+
138. `create_work_item` - Create a new work item (issue, task, incident, test_case, epic, key_result, objective, requirement, ticket). Supports setting title, description, labels, assignees, weight, parent, health status, start/due dates, milestone, and confidentiality
|
|
632
|
+
139. `update_work_item` - Update a work item. Can modify title, description, labels, assignees, weight, state, status, parent hierarchy, children, health status, start/due dates, milestone, confidentiality, linked items, and custom fields
|
|
633
|
+
140. `convert_work_item_type` - Convert a work item to a different type (e.g. issue to task, task to incident)
|
|
634
|
+
141. `list_work_item_statuses` - List available statuses for a work item type in a project. Requires GitLab Premium/Ultimate with configurable statuses
|
|
635
|
+
142. `list_custom_field_definitions` - List available custom field definitions for a work item type in a project. Returns field names, types, and IDs needed for setting custom fields via update_work_item
|
|
636
|
+
143. `move_work_item` - Move a work item (issue, task, etc.) to a different project. Uses GitLab GraphQL issueMove mutation
|
|
637
|
+
144. `list_work_item_notes` - List notes and discussions on a work item. Returns threaded discussions with author, body, timestamps, and system/internal flags
|
|
638
|
+
145. `create_work_item_note` - Add a note/comment to a work item. Supports Markdown, internal notes, and threaded replies
|
|
639
|
+
146. `get_timeline_events` - List timeline events for an incident. Returns chronological events with notes, timestamps, and tags
|
|
640
|
+
147. `create_timeline_event` - Create a timeline event on an incident. Supports tags: 'Start time', 'End time', 'Impact detected', 'Response initiated', 'Impact mitigated', 'Cause identified'
|
|
641
|
+
148. `list_webhooks` - List all configured webhooks for a GitLab project or group. Provide either project_id or group_id
|
|
642
|
+
149. `list_webhook_events` - List recent webhook events (past 7 days) for a project or group webhook. Use summary mode for overview, then get_webhook_event for full details
|
|
643
|
+
150. `get_webhook_event` - Get full details of a specific webhook event by ID, including request/response payloads
|
|
644
|
+
151. `search_code` - Search for code across all projects on the GitLab instance (requires advanced search or exact code search to be enabled)
|
|
645
|
+
152. `search_project_code` - Search for code within a specific GitLab project (requires advanced search or exact code search to be enabled)
|
|
646
|
+
153. `search_group_code` - Search for code within a specific GitLab group (requires advanced search or exact code search to be enabled)
|
|
647
|
+
154. `execute_graphql` - Execute a GitLab GraphQL query
|
|
648
|
+
155. `list_merge_request_pipelines` - List pipelines for a merge request with pagination support
|
|
647
649
|
|
|
648
650
|
<!-- TOOLS-END -->
|
|
649
651
|
|
package/build/index.js
CHANGED
|
@@ -21,17 +21,18 @@ import { createGitLabOAuthProvider } from "./oauth-proxy.js";
|
|
|
21
21
|
import { mcpAuthRouter } from "@modelcontextprotocol/sdk/server/auth/router.js";
|
|
22
22
|
import { normalizeGitLabApiUrl } from "./utils/url.js";
|
|
23
23
|
import { estimateMergeCommitCount, filterDiffsByPatterns, summarizeWebhookEvents } from "./utils/helpers.js";
|
|
24
|
+
import { parseSearchReplaceBlocks, applySearchReplace, applyUnifiedDiff, } from "./utils/patch-helper.js";
|
|
24
25
|
import { requireBearerAuth } from "@modelcontextprotocol/sdk/server/auth/middleware/bearerAuth.js";
|
|
25
26
|
import { GitLabClientPool } from "./gitlab-client-pool.js";
|
|
26
27
|
import { allTools, readOnlyTools, destructiveTools, parseEnabledToolsets, parseIndividualTools, buildFeatureFlagOverrides, isToolInEnabledToolset, TOOLSET_DEFINITIONS, ALL_TOOLSET_IDS, } from "./tools/registry.js";
|
|
27
28
|
import { BulkPublishDraftNotesSchema, CancelPipelineJobSchema, CancelPipelineSchema, CreateBranchSchema, CreateDraftNoteSchema, CreateIssueLinkSchema, CreateIssueNoteSchema, CreateIssueSchema, CreateIssueEmojiReactionSchema, CreateIssueNoteEmojiReactionSchema, ListIssueEmojiReactionsSchema, ListIssueNoteEmojiReactionsSchema, CreateLabelSchema, // Added
|
|
28
|
-
CreateMergeRequestNoteSchema, CreateMergeRequestDiscussionNoteSchema, CreateMergeRequestEmojiReactionSchema, CreateMergeRequestNoteEmojiReactionSchema, ListMergeRequestEmojiReactionsSchema, ListMergeRequestNoteEmojiReactionsSchema, CreateMergeRequestSchema, CreateMergeRequestThreadSchema, CreateNoteSchema, CreateCommitStatusSchema, CreateOrUpdateFileSchema, CreatePipelineSchema, CreateProjectMilestoneSchema, CreateRepositorySchema, CreateWikiPageSchema, CreateGroupWikiPageSchema, DeleteDraftNoteSchema, DeleteGroupWikiPageSchema, DeleteIssueLinkSchema, DeleteIssueSchema, DeleteIssueEmojiReactionSchema, DeleteIssueNoteEmojiReactionSchema, DeleteLabelSchema, DeleteProjectMilestoneSchema, DeleteWikiPageSchema, DeleteMergeRequestNoteSchema, DeleteMergeRequestEmojiReactionSchema, DeleteMergeRequestNoteEmojiReactionSchema, EditProjectMilestoneSchema, ForkRepositorySchema, GetBranchDiffsSchema, GetCommitDiffSchema, GetCommitSchema, GetDraftNoteSchema, GetFileContentsSchema, GetIssueLinkSchema, GetIssueSchema, GetLabelSchema, GetMergeRequestDiffsSchema, GetMergeRequestSchema, GetMilestoneBurndownEventsSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, GetDeploymentSchema, GetEnvironmentSchema, GetNamespaceSchema, GitLabCiLintResultSchema, GetPipelineJobOutputSchema, GetPipelineSchema, GetProjectMilestoneSchema, GetProjectSchema, GetRepositoryTreeSchema, GetUsersSchema, GetWikiPageSchema, GitLabCommitSchema, GitLabCommitStatusSchema, GitLabCompareResultSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabDiffSchema,
|
|
29
|
+
CreateMergeRequestNoteSchema, CreateMergeRequestDiscussionNoteSchema, CreateMergeRequestEmojiReactionSchema, CreateMergeRequestNoteEmojiReactionSchema, ListMergeRequestEmojiReactionsSchema, ListMergeRequestNoteEmojiReactionsSchema, CreateMergeRequestSchema, CreateMergeRequestThreadSchema, CreateNoteSchema, CreateCommitStatusSchema, CreateOrUpdateFileSchema, CreatePipelineSchema, CreateProjectMilestoneSchema, CreateRepositorySchema, CreateWikiPageSchema, CreateGroupWikiPageSchema, DeleteBranchSchema, DeleteDraftNoteSchema, DeleteGroupWikiPageSchema, DeleteIssueLinkSchema, DeleteIssueSchema, DeleteIssueEmojiReactionSchema, DeleteIssueNoteEmojiReactionSchema, DeleteLabelSchema, DeleteProjectMilestoneSchema, DeleteWikiPageSchema, DeleteMergeRequestNoteSchema, DeleteMergeRequestEmojiReactionSchema, DeleteMergeRequestNoteEmojiReactionSchema, EditProjectMilestoneSchema, ForkRepositorySchema, GetBranchDiffsSchema, GetBranchSchema, GetCommitDiffSchema, GetCommitSchema, GetDraftNoteSchema, GetFileContentsSchema, GetIssueLinkSchema, GetIssueSchema, GetLabelSchema, GetMergeRequestDiffsSchema, GetMergeRequestSchema, GetMilestoneBurndownEventsSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, GetDeploymentSchema, GetEnvironmentSchema, GetNamespaceSchema, GitLabCiLintResultSchema, GetPipelineJobOutputSchema, GetPipelineSchema, GetProjectMilestoneSchema, GetProjectSchema, GetRepositoryTreeSchema, GetUsersSchema, GetUserSchema, GitLabUserFullSchema, WhoAmISchema, GitLabCurrentUserSchema, GetWikiPageSchema, GitLabCommitSchema, GitLabCommitStatusSchema, GitLabCompareResultSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabDiffSchema,
|
|
29
30
|
// Discussion Schemas
|
|
30
31
|
GitLabDiscussionNoteSchema, // Added
|
|
31
32
|
GitLabDiscussionSchema,
|
|
32
33
|
// Draft Notes Schemas
|
|
33
|
-
GitLabDraftNoteSchema, GitLabForkSchema, GitLabIssueLinkSchema, GitLabIssueSchema, GitLabIssueWithLinkDetailsSchema, GitLabMarkdownUploadSchema, GitLabMergeRequestSchema, GitLabMilestonesSchema, GitLabNamespaceExistsResponseSchema, GitLabNamespaceSchema, GitLabPipelineJobSchema, GitLabDeploymentSchema, GitLabEnvironmentSchema, GitLabPipelineSchema, GitLabPipelineTriggerJobSchema, GitLabProjectMemberSchema, GitLabProjectSchema, GitLabTodoSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabSearchBlobResultSchema, GitLabSearchResponseSchema, GitLabTreeItemSchema, GitLabUserSchema, GitLabUsersResponseSchema, GitLabWikiPageSchema, GroupIteration, ListCommitStatusesSchema, ListCommitsSchema, ListDraftNotesSchema, ListGroupIterationsSchema, ListGroupProjectsSchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListTodosSchema, ListLabelsSchema, ListMergeRequestDiffsSchema, // Added
|
|
34
|
-
GetMergeRequestFileDiffSchema, ListMergeRequestChangedFilesSchema, ListMergeRequestDiscussionsSchema, ListMergeRequestsSchema, ListMergeRequestVersionsSchema, GetMergeRequestVersionSchema, GitLabMergeRequestVersionSchema, GitLabMergeRequestVersionDetailSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListDeploymentsSchema, ListEnvironmentsSchema, ListPipelineTriggerJobsSchema, ValidateCiLintSchema, ValidateProjectCiLintSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, GetGroupWikiPageSchema, ListGroupWikiPagesSchema, UpdateGroupWikiPageSchema, MarkdownUploadSchema, DownloadAttachmentSchema, DownloadJobArtifactsSchema, GetJobArtifactFileSchema, GitLabArtifactEntrySchema, ListJobArtifactsSchema, MergeMergeRequestSchema, ApproveMergeRequestSchema, UnapproveMergeRequestSchema, GetMergeRequestApprovalStateSchema, GetMergeRequestConflictsSchema, GitLabMergeRequestApprovalsResponseSchema, GitLabMergeRequestApprovalStateSchema, MyIssuesSchema, MarkAllTodosDoneSchema, MarkTodoDoneSchema, PaginatedDiscussionsResponseSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PlayPipelineJobSchema, PushFilesSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchCodeSchema, SearchGroupCodeSchema, SearchProjectCodeSchema, SearchRepositoriesSchema, UpdateDraftNoteSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateLabelSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestDiscussionNoteSchema, UpdateMergeRequestSchema, UpdateWikiPageSchema, VerifyNamespaceSchema, GitLabEventSchema, ListEventsSchema, GetProjectEventsSchema, ExecuteGraphQLSchema, GitLabReleaseSchema, ListReleasesSchema, GetReleaseSchema, CreateReleaseSchema, UpdateReleaseSchema, DeleteReleaseSchema, CreateReleaseEvidenceSchema, DownloadReleaseAssetSchema, ListTagsSchema, GetTagSchema, CreateTagSchema, DeleteTagSchema, GetTagSignatureSchema, GitLabTagSchema, GitLabTagSignatureSchema, GetMergeRequestNotesSchema, GetMergeRequestNoteSchema, DeleteMergeRequestDiscussionNoteSchema, ResolveMergeRequestThreadSchema, GetWorkItemSchema, ListWorkItemsSchema, CreateWorkItemSchema, UpdateWorkItemSchema, ConvertWorkItemTypeSchema, ListWorkItemStatusesSchema, ListWorkItemNotesSchema, CreateWorkItemNoteSchema, CreateWorkItemEmojiReactionSchema, CreateWorkItemNoteEmojiReactionSchema, ListWorkItemEmojiReactionsSchema, ListWorkItemNoteEmojiReactionsSchema, DeleteWorkItemEmojiReactionSchema, DeleteWorkItemNoteEmojiReactionSchema, MoveWorkItemSchema, ListCustomFieldDefinitionsSchema, GetTimelineEventsSchema, CreateTimelineEventSchema, ListWebhooksSchema, ListWebhookEventsSchema, GetWebhookEventSchema, } from "./schemas.js";
|
|
34
|
+
GitLabDraftNoteSchema, GitLabForkSchema, GitLabBranchSchema, GitLabIssueLinkSchema, GitLabIssueSchema, GitLabIssueWithLinkDetailsSchema, GitLabMarkdownUploadSchema, GitLabMergeRequestPipelineSchema, GitLabMergeRequestSchema, GitLabMilestonesSchema, GitLabNamespaceExistsResponseSchema, GitLabNamespaceSchema, GitLabPipelineJobSchema, GitLabDeploymentSchema, GitLabEnvironmentSchema, GitLabPipelineSchema, GitLabPipelineTriggerJobSchema, GitLabProjectMemberSchema, GitLabProjectSchema, GitLabTodoSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabSearchBlobResultSchema, GitLabSearchResponseSchema, GitLabTreeItemSchema, GitLabUserSchema, GitLabUsersResponseSchema, GitLabWikiPageSchema, GroupIteration, ListCommitStatusesSchema, ListBranchesSchema, ListCommitsSchema, ListDraftNotesSchema, ListGroupIterationsSchema, ListGroupProjectsSchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListTodosSchema, ListLabelsSchema, ListMergeRequestDiffsSchema, // Added
|
|
35
|
+
GetMergeRequestFileDiffSchema, ListMergeRequestChangedFilesSchema, ListMergeRequestDiscussionsSchema, ListMergeRequestPipelinesSchema, ListMergeRequestsSchema, ListMergeRequestVersionsSchema, GetMergeRequestVersionSchema, GitLabMergeRequestVersionSchema, GitLabMergeRequestVersionDetailSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListDeploymentsSchema, ListEnvironmentsSchema, ListPipelineTriggerJobsSchema, ValidateCiLintSchema, ValidateProjectCiLintSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, GetGroupWikiPageSchema, ListGroupWikiPagesSchema, UpdateGroupWikiPageSchema, MarkdownUploadSchema, DownloadAttachmentSchema, DownloadJobArtifactsSchema, GetJobArtifactFileSchema, GitLabArtifactEntrySchema, ListJobArtifactsSchema, MergeMergeRequestSchema, ApproveMergeRequestSchema, UnapproveMergeRequestSchema, GetMergeRequestApprovalStateSchema, GetMergeRequestConflictsSchema, GitLabMergeRequestApprovalsResponseSchema, GitLabMergeRequestApprovalStateSchema, MyIssuesSchema, MarkAllTodosDoneSchema, MarkTodoDoneSchema, PaginatedDiscussionsResponseSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PlayPipelineJobSchema, PushFilesSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchCodeSchema, SearchGroupCodeSchema, SearchProjectCodeSchema, SearchRepositoriesSchema, UpdateDraftNoteSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateIssueDescriptionPatchSchema, UpdateLabelSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestDiscussionNoteSchema, UpdateMergeRequestSchema, UpdateWikiPageSchema, VerifyNamespaceSchema, GitLabEventSchema, ListEventsSchema, GetProjectEventsSchema, ExecuteGraphQLSchema, GitLabReleaseSchema, ListReleasesSchema, GetReleaseSchema, CreateReleaseSchema, UpdateReleaseSchema, DeleteReleaseSchema, CreateReleaseEvidenceSchema, DownloadReleaseAssetSchema, ListTagsSchema, GetTagSchema, CreateTagSchema, DeleteTagSchema, GetTagSignatureSchema, GitLabTagSchema, GitLabTagSignatureSchema, GetMergeRequestNotesSchema, GetMergeRequestNoteSchema, DeleteMergeRequestDiscussionNoteSchema, ResolveMergeRequestThreadSchema, GetWorkItemSchema, ListWorkItemsSchema, CreateWorkItemSchema, UpdateWorkItemSchema, ConvertWorkItemTypeSchema, ListWorkItemStatusesSchema, ListWorkItemNotesSchema, CreateWorkItemNoteSchema, CreateWorkItemEmojiReactionSchema, CreateWorkItemNoteEmojiReactionSchema, ListWorkItemEmojiReactionsSchema, ListWorkItemNoteEmojiReactionsSchema, DeleteWorkItemEmojiReactionSchema, DeleteWorkItemNoteEmojiReactionSchema, MoveWorkItemSchema, ListCustomFieldDefinitionsSchema, GetTimelineEventsSchema, CreateTimelineEventSchema, ListWebhooksSchema, ListWebhookEventsSchema, GetWebhookEventSchema, HealthCheckSchema, } from "./schemas.js";
|
|
35
36
|
import { randomUUID } from "node:crypto";
|
|
36
37
|
import { pino } from "pino";
|
|
37
38
|
const logger = pino({
|
|
@@ -783,6 +784,15 @@ function buildAuthHeaders() {
|
|
|
783
784
|
}
|
|
784
785
|
return {};
|
|
785
786
|
}
|
|
787
|
+
function usesJobTokenHeader() {
|
|
788
|
+
if (GITLAB_JOB_TOKEN)
|
|
789
|
+
return true;
|
|
790
|
+
if (REMOTE_AUTHORIZATION || GITLAB_MCP_OAUTH) {
|
|
791
|
+
const ctx = sessionAuthStore.getStore();
|
|
792
|
+
return ctx?.header === "JOB-TOKEN";
|
|
793
|
+
}
|
|
794
|
+
return false;
|
|
795
|
+
}
|
|
786
796
|
/**
|
|
787
797
|
* Get the effective GitLab API URL for the current request
|
|
788
798
|
* In REMOTE_AUTHORIZATION mode with ENABLE_DYNAMIC_API_URL, reads from session context
|
|
@@ -3263,6 +3273,21 @@ async function getMergeRequestSourceCommitCount(projectId, mergeRequestIid) {
|
|
|
3263
3273
|
}
|
|
3264
3274
|
return totalCount;
|
|
3265
3275
|
}
|
|
3276
|
+
async function listMergeRequestPipelines(projectId, mergeRequestIid, options = {}) {
|
|
3277
|
+
projectId = decodeURIComponent(projectId);
|
|
3278
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/pipelines`);
|
|
3279
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
3280
|
+
if (value !== undefined) {
|
|
3281
|
+
url.searchParams.append(key, value.toString());
|
|
3282
|
+
}
|
|
3283
|
+
});
|
|
3284
|
+
const response = await fetch(url.toString(), {
|
|
3285
|
+
...getFetchConfig(),
|
|
3286
|
+
});
|
|
3287
|
+
await handleGitLabError(response);
|
|
3288
|
+
const data = await response.json();
|
|
3289
|
+
return z.array(GitLabMergeRequestPipelineSchema).parse(data);
|
|
3290
|
+
}
|
|
3266
3291
|
async function getProjectMergeMethod(projectId) {
|
|
3267
3292
|
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}`);
|
|
3268
3293
|
const response = await fetch(url.toString(), {
|
|
@@ -5449,9 +5474,21 @@ async function createCommitStatus(projectId, sha, options) {
|
|
|
5449
5474
|
*/
|
|
5450
5475
|
async function getCurrentUser() {
|
|
5451
5476
|
const response = await fetch(`${getEffectiveApiUrl()}/user`, getFetchConfig());
|
|
5477
|
+
if (response.ok) {
|
|
5478
|
+
const data = await response.json();
|
|
5479
|
+
return GitLabUserSchema.parse(data);
|
|
5480
|
+
}
|
|
5481
|
+
if ((response.status === 401 || response.status === 403) && usesJobTokenHeader()) {
|
|
5482
|
+
const jobResponse = await fetch(`${getEffectiveApiUrl()}/job`, getFetchConfig());
|
|
5483
|
+
if (jobResponse.ok) {
|
|
5484
|
+
const jobData = await jobResponse.json();
|
|
5485
|
+
if (jobData.user) {
|
|
5486
|
+
return GitLabUserSchema.parse(jobData.user);
|
|
5487
|
+
}
|
|
5488
|
+
}
|
|
5489
|
+
}
|
|
5452
5490
|
await handleGitLabError(response);
|
|
5453
|
-
|
|
5454
|
-
return GitLabUserSchema.parse(data);
|
|
5491
|
+
throw new Error(`GitLab API error: ${response.status} ${response.statusText}`);
|
|
5455
5492
|
}
|
|
5456
5493
|
/**
|
|
5457
5494
|
* List issues assigned to the current authenticated user
|
|
@@ -6329,6 +6366,14 @@ async function handleToolCall(params) {
|
|
|
6329
6366
|
content: [{ type: "text", text: JSON.stringify(files, null, 2) }],
|
|
6330
6367
|
};
|
|
6331
6368
|
}
|
|
6369
|
+
case "list_merge_request_pipelines": {
|
|
6370
|
+
const args = ListMergeRequestPipelinesSchema.parse(params.arguments);
|
|
6371
|
+
const { project_id, merge_request_iid, ...options } = args;
|
|
6372
|
+
const pipelines = await listMergeRequestPipelines(project_id, merge_request_iid, options);
|
|
6373
|
+
return {
|
|
6374
|
+
content: [{ type: "text", text: JSON.stringify(pipelines, null, 2) }],
|
|
6375
|
+
};
|
|
6376
|
+
}
|
|
6332
6377
|
case "list_merge_request_diffs": {
|
|
6333
6378
|
const args = ListMergeRequestDiffsSchema.parse(params.arguments);
|
|
6334
6379
|
const changes = await listMergeRequestDiffs(args.project_id, args.merge_request_iid, args.source_branch, args.page, args.per_page, args.unidiff);
|
|
@@ -6503,6 +6548,32 @@ async function handleToolCall(params) {
|
|
|
6503
6548
|
content: [{ type: "text", text: JSON.stringify(usersMap, null, 2) }],
|
|
6504
6549
|
};
|
|
6505
6550
|
}
|
|
6551
|
+
case "get_user": {
|
|
6552
|
+
const args = GetUserSchema.parse(params.arguments);
|
|
6553
|
+
const url = new URL(`${getEffectiveApiUrl()}/users/${encodeURIComponent(args.user_id)}`);
|
|
6554
|
+
const response = await fetch(url.toString(), {
|
|
6555
|
+
...getFetchConfig(),
|
|
6556
|
+
});
|
|
6557
|
+
await handleGitLabError(response);
|
|
6558
|
+
const data = await response.json();
|
|
6559
|
+
const user = GitLabUserFullSchema.parse(data);
|
|
6560
|
+
return {
|
|
6561
|
+
content: [{ type: "text", text: JSON.stringify(user, null, 2) }],
|
|
6562
|
+
};
|
|
6563
|
+
}
|
|
6564
|
+
case "whoami": {
|
|
6565
|
+
WhoAmISchema.parse(params.arguments ?? {});
|
|
6566
|
+
const url = new URL(`${getEffectiveApiUrl()}/user`);
|
|
6567
|
+
const response = await fetch(url.toString(), {
|
|
6568
|
+
...getFetchConfig(),
|
|
6569
|
+
});
|
|
6570
|
+
await handleGitLabError(response);
|
|
6571
|
+
const data = await response.json();
|
|
6572
|
+
const user = GitLabCurrentUserSchema.parse(data);
|
|
6573
|
+
return {
|
|
6574
|
+
content: [{ type: "text", text: JSON.stringify(user, null, 2) }],
|
|
6575
|
+
};
|
|
6576
|
+
}
|
|
6506
6577
|
case "create_note": {
|
|
6507
6578
|
const args = CreateNoteSchema.parse(params.arguments);
|
|
6508
6579
|
const { project_id, noteable_type, noteable_iid, body } = args;
|
|
@@ -6613,6 +6684,81 @@ async function handleToolCall(params) {
|
|
|
6613
6684
|
content: [{ type: "text", text: JSON.stringify(issue, null, 2) }],
|
|
6614
6685
|
};
|
|
6615
6686
|
}
|
|
6687
|
+
case "update_issue_description_patch": {
|
|
6688
|
+
const args = UpdateIssueDescriptionPatchSchema.parse(params.arguments);
|
|
6689
|
+
const { project_id, issue_iid, patch_type, patch, dry_run, create_note, allow_multiple } = args;
|
|
6690
|
+
// Fetch current issue description
|
|
6691
|
+
const currentIssue = await getIssue(project_id, issue_iid);
|
|
6692
|
+
const currentDescription = currentIssue.description ?? "";
|
|
6693
|
+
// Apply the patch
|
|
6694
|
+
let result;
|
|
6695
|
+
if (patch_type === "search_replace") {
|
|
6696
|
+
const blocks = parseSearchReplaceBlocks(patch);
|
|
6697
|
+
if (blocks.length === 0) {
|
|
6698
|
+
throw new Error("No valid search/replace blocks found. Expected format: <<<<<<< SEARCH\\ntext\\n=======\\nnew text\\n>>>>>>> REPLACE");
|
|
6699
|
+
}
|
|
6700
|
+
result = applySearchReplace(currentDescription, blocks, allow_multiple);
|
|
6701
|
+
}
|
|
6702
|
+
else {
|
|
6703
|
+
// unified_diff
|
|
6704
|
+
result = applyUnifiedDiff(currentDescription, patch);
|
|
6705
|
+
}
|
|
6706
|
+
// Dry-run: return preview without updating
|
|
6707
|
+
if (dry_run) {
|
|
6708
|
+
return {
|
|
6709
|
+
content: [
|
|
6710
|
+
{
|
|
6711
|
+
type: "text",
|
|
6712
|
+
text: JSON.stringify({
|
|
6713
|
+
status: "preview",
|
|
6714
|
+
dry_run: true,
|
|
6715
|
+
changes: result.changes,
|
|
6716
|
+
summary: result.summary,
|
|
6717
|
+
preview: result.preview,
|
|
6718
|
+
}, null, 2),
|
|
6719
|
+
},
|
|
6720
|
+
],
|
|
6721
|
+
};
|
|
6722
|
+
}
|
|
6723
|
+
// Apply the update
|
|
6724
|
+
const updatedIssue = await updateIssue(project_id, issue_iid, {
|
|
6725
|
+
description: result.description,
|
|
6726
|
+
});
|
|
6727
|
+
// Optionally create a note summarizing the change
|
|
6728
|
+
let noteResult = null;
|
|
6729
|
+
if (create_note) {
|
|
6730
|
+
try {
|
|
6731
|
+
const noteBody = `Updated issue description using patch-based tool.\n\n${result.summary}`;
|
|
6732
|
+
await createIssueNote(project_id, issue_iid, undefined, noteBody);
|
|
6733
|
+
noteResult = { status: "created" };
|
|
6734
|
+
}
|
|
6735
|
+
catch (noteError) {
|
|
6736
|
+
noteResult = {
|
|
6737
|
+
status: "failed",
|
|
6738
|
+
message: `Note creation failed: ${noteError.message ?? noteError}`,
|
|
6739
|
+
};
|
|
6740
|
+
}
|
|
6741
|
+
}
|
|
6742
|
+
return {
|
|
6743
|
+
content: [
|
|
6744
|
+
{
|
|
6745
|
+
type: "text",
|
|
6746
|
+
text: JSON.stringify({
|
|
6747
|
+
status: "success",
|
|
6748
|
+
changes: result.changes,
|
|
6749
|
+
summary: result.summary,
|
|
6750
|
+
note: noteResult,
|
|
6751
|
+
issue: {
|
|
6752
|
+
iid: updatedIssue.iid,
|
|
6753
|
+
title: updatedIssue.title,
|
|
6754
|
+
web_url: updatedIssue.web_url,
|
|
6755
|
+
updated_at: updatedIssue.updated_at,
|
|
6756
|
+
},
|
|
6757
|
+
}, null, 2),
|
|
6758
|
+
},
|
|
6759
|
+
],
|
|
6760
|
+
};
|
|
6761
|
+
}
|
|
6616
6762
|
case "delete_issue": {
|
|
6617
6763
|
const args = DeleteIssueSchema.parse(params.arguments);
|
|
6618
6764
|
await deleteIssue(args.project_id, args.issue_iid);
|
|
@@ -7528,6 +7674,70 @@ async function handleToolCall(params) {
|
|
|
7528
7674
|
content: [{ type: "text", text: JSON.stringify(event, null, 2) }],
|
|
7529
7675
|
};
|
|
7530
7676
|
}
|
|
7677
|
+
case "health_check": {
|
|
7678
|
+
HealthCheckSchema.parse(params.arguments ?? {});
|
|
7679
|
+
const url = new URL(`${getEffectiveApiUrl()}/user`);
|
|
7680
|
+
const response = await fetch(url.toString(), getFetchConfig());
|
|
7681
|
+
let authenticated = response.ok;
|
|
7682
|
+
if (!authenticated && (response.status === 401 || response.status === 403) && (GITLAB_JOB_TOKEN || usesJobTokenHeader())) {
|
|
7683
|
+
const jobUrl = new URL(`${getEffectiveApiUrl()}/job`);
|
|
7684
|
+
const jobResponse = await fetch(jobUrl.toString(), getFetchConfig());
|
|
7685
|
+
authenticated = jobResponse.ok;
|
|
7686
|
+
}
|
|
7687
|
+
return {
|
|
7688
|
+
content: [{ type: "text", text: JSON.stringify({ status: authenticated ? "ok" : "error", authenticated, gitlab_url: getEffectiveApiUrl() }) }],
|
|
7689
|
+
};
|
|
7690
|
+
}
|
|
7691
|
+
case "get_branch": {
|
|
7692
|
+
const args = GetBranchSchema.parse(params.arguments);
|
|
7693
|
+
const projectId = decodeURIComponent(args.project_id);
|
|
7694
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/repository/branches/${encodeURIComponent(args.branch_name)}`);
|
|
7695
|
+
const response = await fetch(url.toString(), {
|
|
7696
|
+
...getFetchConfig(),
|
|
7697
|
+
});
|
|
7698
|
+
await handleGitLabError(response);
|
|
7699
|
+
const data = await response.json();
|
|
7700
|
+
const branch = GitLabBranchSchema.parse(data);
|
|
7701
|
+
return {
|
|
7702
|
+
content: [{ type: "text", text: JSON.stringify(branch, null, 2) }],
|
|
7703
|
+
};
|
|
7704
|
+
}
|
|
7705
|
+
case "list_branches": {
|
|
7706
|
+
const args = ListBranchesSchema.parse(params.arguments);
|
|
7707
|
+
const projectId = decodeURIComponent(args.project_id);
|
|
7708
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/repository/branches`);
|
|
7709
|
+
if (args.search) {
|
|
7710
|
+
url.searchParams.append("search", args.search);
|
|
7711
|
+
}
|
|
7712
|
+
if (args.page) {
|
|
7713
|
+
url.searchParams.append("page", args.page.toString());
|
|
7714
|
+
}
|
|
7715
|
+
if (args.per_page) {
|
|
7716
|
+
url.searchParams.append("per_page", args.per_page.toString());
|
|
7717
|
+
}
|
|
7718
|
+
const response = await fetch(url.toString(), {
|
|
7719
|
+
...getFetchConfig(),
|
|
7720
|
+
});
|
|
7721
|
+
await handleGitLabError(response);
|
|
7722
|
+
const data = await response.json();
|
|
7723
|
+
const branches = z.array(GitLabBranchSchema).parse(data);
|
|
7724
|
+
return {
|
|
7725
|
+
content: [{ type: "text", text: JSON.stringify(branches, null, 2) }],
|
|
7726
|
+
};
|
|
7727
|
+
}
|
|
7728
|
+
case "delete_branch": {
|
|
7729
|
+
const args = DeleteBranchSchema.parse(params.arguments);
|
|
7730
|
+
const projectId = decodeURIComponent(args.project_id);
|
|
7731
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/repository/branches/${encodeURIComponent(args.branch_name)}`);
|
|
7732
|
+
const response = await fetch(url.toString(), {
|
|
7733
|
+
...getFetchConfig(),
|
|
7734
|
+
method: "DELETE",
|
|
7735
|
+
});
|
|
7736
|
+
await handleGitLabError(response);
|
|
7737
|
+
return {
|
|
7738
|
+
content: [{ type: "text", text: JSON.stringify({ status: "deleted", branch: args.branch_name }, null, 2) }],
|
|
7739
|
+
};
|
|
7740
|
+
}
|
|
7531
7741
|
default:
|
|
7532
7742
|
throw new Error(`Unknown tool: ${params.name}`);
|
|
7533
7743
|
}
|