@zereight/mcp-gitlab 2.1.52 → 2.1.54
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.ko.md +3 -7
- package/README.md +116 -103
- package/README.zh-CN.md +3 -7
- package/build/index.js +484 -20
- package/build/schemas.js +233 -0
- package/build/test/test-list-group-merge-requests.js +165 -0
- package/build/test/test-pipeline-schedules.js +482 -0
- package/build/test/test-toolset-filtering.js +2 -2
- package/build/tools/registry.js +100 -1
- package/build/tools/tool-descriptions.js +12 -0
- package/package.json +1 -2
package/build/index.js
CHANGED
|
@@ -62,7 +62,7 @@ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
|
62
62
|
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
|
|
63
63
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
64
64
|
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
|
|
65
|
-
import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
|
|
65
|
+
import { CallToolRequestSchema, ListToolsRequestSchema, ListPromptsRequestSchema, GetPromptRequestSchema, } from "@modelcontextprotocol/sdk/types.js";
|
|
66
66
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
67
67
|
import express from "express";
|
|
68
68
|
import fetchCookie from "fetch-cookie";
|
|
@@ -110,12 +110,59 @@ CreateMergeRequestNoteSchema, CreateMergeRequestDiscussionNoteSchema, CreateMerg
|
|
|
110
110
|
GitLabDiscussionNoteSchema, // Added
|
|
111
111
|
GitLabDiscussionSchema,
|
|
112
112
|
// Draft Notes Schemas
|
|
113
|
-
GitLabDraftNoteSchema, GitLabForkSchema, GitLabBranchSchema, GitLabProtectedBranchSchema, GitLabGroupSchema, GitLabIssueLinkSchema, GitLabIssueSchema, GitLabIssueWithLinkDetailsSchema, GitLabMarkdownUploadSchema, GitLabMergeRequestPipelineSchema, GitLabMergeRequestSchema, GitLabMilestonesSchema, GitLabGroupMilestonesSchema, 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, GitLabCiVariableSchema, ListProjectVariablesSchema, GetProjectVariableSchema, CreateProjectVariableSchema, UpdateProjectVariableSchema, DeleteProjectVariableSchema, ListGroupVariablesSchema, GetGroupVariableSchema, CreateGroupVariableSchema, UpdateGroupVariableSchema, DeleteGroupVariableSchema, GitLabDependencyProxySchema, GitLabDependencyProxyBlobSchema, GetDependencyProxySettingsSchema, UpdateDependencyProxySettingsSchema, ListDependencyProxyBlobsSchema, PurgeDependencyProxyCacheSchema, ListProjectVulnerabilitiesSchema, GetVulnerabilitySchema, DismissVulnerabilitySchema, ConfirmVulnerabilitySchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListTodosSchema, ListLabelsSchema, ListMergeRequestDiffsSchema, // Added
|
|
114
|
-
GetMergeRequestFileDiffSchema, ListMergeRequestChangedFilesSchema, ListMergeRequestDiscussionsSchema, ListMergeRequestPipelinesSchema, ListMergeRequestsSchema, ListMergeRequestVersionsSchema, GetMergeRequestVersionSchema, GitLabMergeRequestVersionSchema, GitLabMergeRequestVersionDetailSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListDeploymentsSchema, ListEnvironmentsSchema, ListPipelineTriggerJobsSchema, ValidateCiLintSchema, ValidateProjectCiLintSchema, ListCiCatalogResourcesSchema, GetCiCatalogResourceSchema, ListProjectMembersSchema, ListGroupMembersSchema, ListProjectMilestonesSchema, ListGroupMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, GetGroupWikiPageSchema, ListGroupWikiPagesSchema, UpdateGroupWikiPageSchema, MarkdownUploadSchema, MarkdownUploadRemoteSchema, 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, UpdateProjectSchema, 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";
|
|
113
|
+
GitLabDraftNoteSchema, GitLabForkSchema, GitLabBranchSchema, GitLabProtectedBranchSchema, GitLabGroupSchema, GitLabIssueLinkSchema, GitLabIssueSchema, GitLabIssueWithLinkDetailsSchema, GitLabMarkdownUploadSchema, GitLabMergeRequestPipelineSchema, GitLabMergeRequestSchema, GitLabMilestonesSchema, GitLabGroupMilestonesSchema, GitLabNamespaceExistsResponseSchema, GitLabNamespaceSchema, GitLabPipelineJobSchema, GitLabDeploymentSchema, GitLabEnvironmentSchema, GitLabPipelineSchema, GitLabPipelineScheduleSchema, GitLabPipelineScheduleVariableSchema, GitLabPipelineSchedulePlayResultSchema, ListPipelineSchedulesSchema, GetPipelineScheduleSchema, ListPipelineSchedulePipelinesSchema, CreatePipelineScheduleSchema, UpdatePipelineScheduleSchema, DeletePipelineScheduleSchema, PlayPipelineScheduleSchema, TakeOwnershipPipelineScheduleSchema, GetPipelineScheduleVariableSchema, CreatePipelineScheduleVariableSchema, UpdatePipelineScheduleVariableSchema, DeletePipelineScheduleVariableSchema, GitLabPipelineTriggerJobSchema, GitLabProjectMemberSchema, GitLabProjectSchema, GitLabTodoSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabSearchBlobResultSchema, GitLabSearchResponseSchema, GitLabTreeItemSchema, GitLabUserSchema, GitLabUsersResponseSchema, GitLabWikiPageSchema, GroupIteration, ListCommitStatusesSchema, ListBranchesSchema, ListCommitsSchema, ListDraftNotesSchema, ListGroupIterationsSchema, ListGroupProjectsSchema, GitLabCiVariableSchema, ListProjectVariablesSchema, GetProjectVariableSchema, CreateProjectVariableSchema, UpdateProjectVariableSchema, DeleteProjectVariableSchema, ListGroupVariablesSchema, GetGroupVariableSchema, CreateGroupVariableSchema, UpdateGroupVariableSchema, DeleteGroupVariableSchema, GitLabDependencyProxySchema, GitLabDependencyProxyBlobSchema, GetDependencyProxySettingsSchema, UpdateDependencyProxySettingsSchema, ListDependencyProxyBlobsSchema, PurgeDependencyProxyCacheSchema, ListProjectVulnerabilitiesSchema, GetVulnerabilitySchema, DismissVulnerabilitySchema, ConfirmVulnerabilitySchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListTodosSchema, ListLabelsSchema, ListMergeRequestDiffsSchema, // Added
|
|
114
|
+
GetMergeRequestFileDiffSchema, ListMergeRequestChangedFilesSchema, ListMergeRequestDiscussionsSchema, ListMergeRequestPipelinesSchema, ListMergeRequestsSchema, ListGroupMergeRequestsSchema, ListMergeRequestVersionsSchema, GetMergeRequestVersionSchema, GitLabMergeRequestVersionSchema, GitLabMergeRequestVersionDetailSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListDeploymentsSchema, ListEnvironmentsSchema, ListPipelineTriggerJobsSchema, ValidateCiLintSchema, ValidateProjectCiLintSchema, ListCiCatalogResourcesSchema, GetCiCatalogResourceSchema, ListProjectMembersSchema, ListGroupMembersSchema, ListProjectMilestonesSchema, ListGroupMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, GetGroupWikiPageSchema, ListGroupWikiPagesSchema, UpdateGroupWikiPageSchema, MarkdownUploadSchema, MarkdownUploadRemoteSchema, 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, UpdateProjectSchema, 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";
|
|
115
115
|
import { randomUUID, timingSafeEqual, } from "node:crypto";
|
|
116
116
|
import { createLogger } from "./utils/logger.js";
|
|
117
117
|
const logger = createLogger();
|
|
118
118
|
const SERVER_NAME = process.env.MCP_SERVER_NAME?.trim() || "zereight-gitlab-mcp-server";
|
|
119
|
+
/**
|
|
120
|
+
* Static MCP prompt catalog. These wrap the multi-step tool workflows documented in
|
|
121
|
+
* skills/gitlab-mcp/ so MCP clients that surface prompts (e.g. slash commands) can
|
|
122
|
+
* trigger them without the agent needing to read the Skill first. Kept inline (not
|
|
123
|
+
* loaded from skills/gitlab-mcp/*.md) since only "build" ships in the npm package.
|
|
124
|
+
*/
|
|
125
|
+
const MCP_PROMPTS = [
|
|
126
|
+
{
|
|
127
|
+
name: "review_merge_request",
|
|
128
|
+
description: "Review a merge request's diff in batches and leave threaded comments.",
|
|
129
|
+
arguments: [
|
|
130
|
+
{ name: "project_id", description: "Numeric project ID or URL-encoded path", required: true },
|
|
131
|
+
{ name: "merge_request_iid", description: "Merge request IID", required: true },
|
|
132
|
+
],
|
|
133
|
+
render: (args) => `Review merge request !${args.merge_request_iid ?? "<iid>"} in project ${args.project_id ?? "<project_id>"}:\n` +
|
|
134
|
+
`1. Call list_merge_request_changed_files to get the changed file list (use excluded_file_patterns for lockfiles/dist/generated files).\n` +
|
|
135
|
+
`2. Call get_merge_request_file_diff in batches of 3-5 files, prioritizing source over config/tests.\n` +
|
|
136
|
+
`3. Leave findings with create_merge_request_thread (inline, position: new_path/new_line) or create_merge_request_note (general).\n` +
|
|
137
|
+
`4. Summarize the review verdict in a final top-level note.`,
|
|
138
|
+
},
|
|
139
|
+
{
|
|
140
|
+
name: "triage_pipeline_failure",
|
|
141
|
+
description: "Find the failing job in a pipeline and pull its log tail for diagnosis.",
|
|
142
|
+
arguments: [
|
|
143
|
+
{ name: "project_id", description: "Numeric project ID or URL-encoded path", required: true },
|
|
144
|
+
{ name: "pipeline_id", description: "Pipeline ID", required: true },
|
|
145
|
+
],
|
|
146
|
+
render: (args) => `Diagnose pipeline ${args.pipeline_id ?? "<pipeline_id>"} in project ${args.project_id ?? "<project_id>"}:\n` +
|
|
147
|
+
`1. Call list_pipeline_jobs to find jobs with status "failed".\n` +
|
|
148
|
+
`2. Call get_pipeline_job_output (or the job trace tool) on each failed job, focusing on the tail of the log.\n` +
|
|
149
|
+
`3. Identify the root cause (compile error, test failure, timeout, runner issue) and quote the relevant log lines.\n` +
|
|
150
|
+
`4. Suggest the fix or the next diagnostic step.`,
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
name: "triage_vulnerabilities",
|
|
154
|
+
description: "List a project's open vulnerabilities and propose a remediation priority order.",
|
|
155
|
+
arguments: [
|
|
156
|
+
{ name: "project_id", description: "Numeric project ID or URL-encoded path", required: true },
|
|
157
|
+
],
|
|
158
|
+
render: (args) => `Triage vulnerabilities for project ${args.project_id ?? "<project_id>"}:\n` +
|
|
159
|
+
`1. Call list_project_vulnerabilities once with state=detected and once with state=confirmed ` +
|
|
160
|
+
`(the tool only accepts one state per call). Follow pageInfo.endCursor with the "after" ` +
|
|
161
|
+
`param while pageInfo.hasNextPage is true, and aggregate both states' results.\n` +
|
|
162
|
+
`2. Group the aggregated results by severity (critical > high > medium > low) and by whether a fix is already available.\n` +
|
|
163
|
+
`3. Propose a remediation order, calling out any critical/high items with no available fix.`,
|
|
164
|
+
},
|
|
165
|
+
];
|
|
119
166
|
/**
|
|
120
167
|
* Create a new MCP Server instance with request handlers registered.
|
|
121
168
|
* Each transport connection gets its own Server instance to prevent
|
|
@@ -168,8 +215,35 @@ function createServer() {
|
|
|
168
215
|
tools: {
|
|
169
216
|
listChanged: true,
|
|
170
217
|
},
|
|
218
|
+
prompts: {},
|
|
171
219
|
},
|
|
172
220
|
});
|
|
221
|
+
mcpServer.server.setRequestHandler(ListPromptsRequestSchema, async () => ({
|
|
222
|
+
prompts: MCP_PROMPTS.map(({ name, description, arguments: args }) => ({
|
|
223
|
+
name,
|
|
224
|
+
description,
|
|
225
|
+
arguments: args,
|
|
226
|
+
})),
|
|
227
|
+
}));
|
|
228
|
+
mcpServer.server.setRequestHandler(GetPromptRequestSchema, async (request) => {
|
|
229
|
+
const prompt = MCP_PROMPTS.find(p => p.name === request.params.name);
|
|
230
|
+
if (!prompt) {
|
|
231
|
+
throw new Error(`Unknown prompt: ${request.params.name}`);
|
|
232
|
+
}
|
|
233
|
+
const args = (request.params.arguments ?? {});
|
|
234
|
+
return {
|
|
235
|
+
description: prompt.description,
|
|
236
|
+
messages: [
|
|
237
|
+
{
|
|
238
|
+
role: "user",
|
|
239
|
+
content: {
|
|
240
|
+
type: "text",
|
|
241
|
+
text: prompt.render(args),
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
],
|
|
245
|
+
};
|
|
246
|
+
});
|
|
173
247
|
mcpServer.server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
174
248
|
// Step 6: Gemini $schema cleanup + annotations (only dynamic step per request)
|
|
175
249
|
// <<< START: Remove $schema for Gemini compatibility >>>
|
|
@@ -1381,6 +1455,28 @@ async function markAllTodosDone() {
|
|
|
1381
1455
|
});
|
|
1382
1456
|
await handleGitLabError(response);
|
|
1383
1457
|
}
|
|
1458
|
+
/**
|
|
1459
|
+
* Serialize merge request list filters onto a URL, honouring GitLab's per-parameter array forms
|
|
1460
|
+
*/
|
|
1461
|
+
function appendMergeRequestFilters(url, options) {
|
|
1462
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
1463
|
+
if (value === undefined) {
|
|
1464
|
+
return;
|
|
1465
|
+
}
|
|
1466
|
+
if (key === "labels" && Array.isArray(value)) {
|
|
1467
|
+
url.searchParams.append(key, value.join(","));
|
|
1468
|
+
}
|
|
1469
|
+
else if (key === "approved_by_usernames" && Array.isArray(value)) {
|
|
1470
|
+
// GitLab expects array-bracket form: approved_by_usernames[]=alice&approved_by_usernames[]=bob
|
|
1471
|
+
for (const v of value) {
|
|
1472
|
+
url.searchParams.append(`${key}[]`, String(v));
|
|
1473
|
+
}
|
|
1474
|
+
}
|
|
1475
|
+
else {
|
|
1476
|
+
url.searchParams.append(key, String(value));
|
|
1477
|
+
}
|
|
1478
|
+
});
|
|
1479
|
+
}
|
|
1384
1480
|
/**
|
|
1385
1481
|
* List merge requests globally or for a specific GitLab project
|
|
1386
1482
|
*
|
|
@@ -1395,24 +1491,25 @@ async function listMergeRequests(projectId, options = {}) {
|
|
|
1395
1491
|
? `${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(decodedProjectId))}/merge_requests`
|
|
1396
1492
|
: `${getEffectiveApiUrl()}/merge_requests`;
|
|
1397
1493
|
const url = new URL(endpoint);
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
if (key === "labels" && Array.isArray(value)) {
|
|
1402
|
-
// Handle array of labels
|
|
1403
|
-
url.searchParams.append(key, value.join(","));
|
|
1404
|
-
}
|
|
1405
|
-
else if (key === "approved_by_usernames" && Array.isArray(value)) {
|
|
1406
|
-
// GitLab expects array-bracket form: approved_by_usernames[]=alice&approved_by_usernames[]=bob
|
|
1407
|
-
for (const v of value) {
|
|
1408
|
-
url.searchParams.append(`${key}[]`, String(v));
|
|
1409
|
-
}
|
|
1410
|
-
}
|
|
1411
|
-
else {
|
|
1412
|
-
url.searchParams.append(key, String(value));
|
|
1413
|
-
}
|
|
1414
|
-
}
|
|
1494
|
+
appendMergeRequestFilters(url, options);
|
|
1495
|
+
const response = await fetch(url.toString(), {
|
|
1496
|
+
...getFetchConfig(),
|
|
1415
1497
|
});
|
|
1498
|
+
await handleGitLabError(response);
|
|
1499
|
+
const data = await response.json();
|
|
1500
|
+
return z.array(GitLabMergeRequestSchema).parse(data);
|
|
1501
|
+
}
|
|
1502
|
+
/**
|
|
1503
|
+
* List merge requests across every project of a GitLab group and its subgroups
|
|
1504
|
+
*
|
|
1505
|
+
* @param {string} groupId - The ID or URL-encoded path of the group
|
|
1506
|
+
* @param {Object} options - Optional filtering parameters
|
|
1507
|
+
* @returns {Promise<GitLabMergeRequest[]>} List of merge requests
|
|
1508
|
+
*/
|
|
1509
|
+
async function listGroupMergeRequests(groupId, options = {}) {
|
|
1510
|
+
const decodedGroupId = decodeURIComponent(groupId);
|
|
1511
|
+
const url = new URL(`${getEffectiveApiUrl()}/groups/${encodeURIComponent(decodedGroupId)}/merge_requests`);
|
|
1512
|
+
appendMergeRequestFilters(url, options);
|
|
1416
1513
|
const response = await fetch(url.toString(), {
|
|
1417
1514
|
...getFetchConfig(),
|
|
1418
1515
|
});
|
|
@@ -5374,6 +5471,235 @@ async function cancelPipeline(projectId, pipelineId) {
|
|
|
5374
5471
|
const data = await response.json();
|
|
5375
5472
|
return GitLabPipelineSchema.parse(data);
|
|
5376
5473
|
}
|
|
5474
|
+
/**
|
|
5475
|
+
* List pipeline schedules in a GitLab project
|
|
5476
|
+
*
|
|
5477
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5478
|
+
* @param {ListPipelineSchedulesOptions} options - Options for filtering pipeline schedules
|
|
5479
|
+
* @returns {Promise<GitLabPipelineSchedule[]>} List of pipeline schedules
|
|
5480
|
+
*/
|
|
5481
|
+
async function listPipelineSchedules(projectId, options = {}) {
|
|
5482
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5483
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules`);
|
|
5484
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
5485
|
+
if (value !== undefined) {
|
|
5486
|
+
url.searchParams.append(key, value.toString());
|
|
5487
|
+
}
|
|
5488
|
+
});
|
|
5489
|
+
const response = await fetch(url.toString(), {
|
|
5490
|
+
...getFetchConfig(),
|
|
5491
|
+
});
|
|
5492
|
+
await handleGitLabError(response);
|
|
5493
|
+
const data = await response.json();
|
|
5494
|
+
return z.array(GitLabPipelineScheduleSchema).parse(data);
|
|
5495
|
+
}
|
|
5496
|
+
/**
|
|
5497
|
+
* Get details of a specific pipeline schedule
|
|
5498
|
+
*
|
|
5499
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5500
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule
|
|
5501
|
+
* @returns {Promise<GitLabPipelineSchedule>} Pipeline schedule details
|
|
5502
|
+
*/
|
|
5503
|
+
async function getPipelineSchedule(projectId, pipelineScheduleId) {
|
|
5504
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5505
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}`);
|
|
5506
|
+
const response = await fetch(url.toString(), {
|
|
5507
|
+
...getFetchConfig(),
|
|
5508
|
+
});
|
|
5509
|
+
await handleGitLabError(response);
|
|
5510
|
+
const data = await response.json();
|
|
5511
|
+
return GitLabPipelineScheduleSchema.parse(data);
|
|
5512
|
+
}
|
|
5513
|
+
/**
|
|
5514
|
+
* List the pipelines triggered by a pipeline schedule
|
|
5515
|
+
*
|
|
5516
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5517
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule
|
|
5518
|
+
* @param {ListPipelineSchedulePipelinesOptions} options - Pagination options
|
|
5519
|
+
* @returns {Promise<GitLabPipeline[]>} List of pipelines the schedule triggered
|
|
5520
|
+
*/
|
|
5521
|
+
async function listPipelineSchedulePipelines(projectId, pipelineScheduleId, options = {}) {
|
|
5522
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5523
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}/pipelines`);
|
|
5524
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
5525
|
+
if (value !== undefined) {
|
|
5526
|
+
url.searchParams.append(key, value.toString());
|
|
5527
|
+
}
|
|
5528
|
+
});
|
|
5529
|
+
const response = await fetch(url.toString(), {
|
|
5530
|
+
...getFetchConfig(),
|
|
5531
|
+
});
|
|
5532
|
+
await handleGitLabError(response);
|
|
5533
|
+
const data = await response.json();
|
|
5534
|
+
return z.array(GitLabPipelineSchema).parse(data);
|
|
5535
|
+
}
|
|
5536
|
+
/**
|
|
5537
|
+
* Create a new pipeline schedule
|
|
5538
|
+
*
|
|
5539
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5540
|
+
* @param {CreatePipelineScheduleOptions} options - The schedule's cron, description, ref and options
|
|
5541
|
+
* @returns {Promise<GitLabPipelineSchedule>} The created pipeline schedule
|
|
5542
|
+
*/
|
|
5543
|
+
async function createPipelineSchedule(projectId, options) {
|
|
5544
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5545
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules`);
|
|
5546
|
+
const response = await fetch(url.toString(), {
|
|
5547
|
+
...getFetchConfig(),
|
|
5548
|
+
method: "POST",
|
|
5549
|
+
body: JSON.stringify(options),
|
|
5550
|
+
});
|
|
5551
|
+
await handleGitLabError(response);
|
|
5552
|
+
const data = await response.json();
|
|
5553
|
+
return GitLabPipelineScheduleSchema.parse(data);
|
|
5554
|
+
}
|
|
5555
|
+
/**
|
|
5556
|
+
* Update an existing pipeline schedule
|
|
5557
|
+
*
|
|
5558
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5559
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule to update
|
|
5560
|
+
* @param {UpdatePipelineScheduleOptions} options - The fields to change
|
|
5561
|
+
* @returns {Promise<GitLabPipelineSchedule>} The updated pipeline schedule
|
|
5562
|
+
*/
|
|
5563
|
+
async function updatePipelineSchedule(projectId, pipelineScheduleId, options) {
|
|
5564
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5565
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}`);
|
|
5566
|
+
const response = await fetch(url.toString(), {
|
|
5567
|
+
...getFetchConfig(),
|
|
5568
|
+
method: "PUT",
|
|
5569
|
+
body: JSON.stringify(options),
|
|
5570
|
+
});
|
|
5571
|
+
await handleGitLabError(response);
|
|
5572
|
+
const data = await response.json();
|
|
5573
|
+
return GitLabPipelineScheduleSchema.parse(data);
|
|
5574
|
+
}
|
|
5575
|
+
/**
|
|
5576
|
+
* Delete a pipeline schedule
|
|
5577
|
+
*
|
|
5578
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5579
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule to delete
|
|
5580
|
+
* @returns {Promise<void>}
|
|
5581
|
+
*/
|
|
5582
|
+
async function deletePipelineSchedule(projectId, pipelineScheduleId) {
|
|
5583
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5584
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}`);
|
|
5585
|
+
const response = await fetch(url.toString(), {
|
|
5586
|
+
...getFetchConfig(),
|
|
5587
|
+
method: "DELETE",
|
|
5588
|
+
});
|
|
5589
|
+
await handleGitLabError(response);
|
|
5590
|
+
}
|
|
5591
|
+
/**
|
|
5592
|
+
* Run a pipeline schedule immediately, without changing its next scheduled run
|
|
5593
|
+
*
|
|
5594
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5595
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule to run
|
|
5596
|
+
* @returns {Promise<GitLabPipelineSchedulePlayResult>} GitLab's acknowledgement message
|
|
5597
|
+
*/
|
|
5598
|
+
async function playPipelineSchedule(projectId, pipelineScheduleId) {
|
|
5599
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5600
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}/play`);
|
|
5601
|
+
const response = await fetch(url.toString(), {
|
|
5602
|
+
...getFetchConfig(),
|
|
5603
|
+
method: "POST",
|
|
5604
|
+
});
|
|
5605
|
+
await handleGitLabError(response);
|
|
5606
|
+
const data = await response.json();
|
|
5607
|
+
return GitLabPipelineSchedulePlayResultSchema.parse(data);
|
|
5608
|
+
}
|
|
5609
|
+
/**
|
|
5610
|
+
* Take ownership of a pipeline schedule
|
|
5611
|
+
*
|
|
5612
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5613
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule
|
|
5614
|
+
* @returns {Promise<GitLabPipelineSchedule>} The pipeline schedule with its new owner
|
|
5615
|
+
*/
|
|
5616
|
+
async function takeOwnershipPipelineSchedule(projectId, pipelineScheduleId) {
|
|
5617
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5618
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}/take_ownership`);
|
|
5619
|
+
const response = await fetch(url.toString(), {
|
|
5620
|
+
...getFetchConfig(),
|
|
5621
|
+
method: "POST",
|
|
5622
|
+
});
|
|
5623
|
+
await handleGitLabError(response);
|
|
5624
|
+
const data = await response.json();
|
|
5625
|
+
return GitLabPipelineScheduleSchema.parse(data);
|
|
5626
|
+
}
|
|
5627
|
+
/**
|
|
5628
|
+
* Get a single variable of a pipeline schedule
|
|
5629
|
+
*
|
|
5630
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5631
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule
|
|
5632
|
+
* @param {string} key - The key of the variable
|
|
5633
|
+
* @returns {Promise<GitLabPipelineScheduleVariable>} The pipeline schedule variable
|
|
5634
|
+
*/
|
|
5635
|
+
async function getPipelineScheduleVariable(projectId, pipelineScheduleId, key) {
|
|
5636
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5637
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}/variables/${encodeGitLabPathSegment(key)}`);
|
|
5638
|
+
const response = await fetch(url.toString(), {
|
|
5639
|
+
...getFetchConfig(),
|
|
5640
|
+
});
|
|
5641
|
+
await handleGitLabError(response);
|
|
5642
|
+
const data = await response.json();
|
|
5643
|
+
return GitLabPipelineScheduleVariableSchema.parse(data);
|
|
5644
|
+
}
|
|
5645
|
+
/**
|
|
5646
|
+
* Create a variable for a pipeline schedule
|
|
5647
|
+
*
|
|
5648
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5649
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule
|
|
5650
|
+
* @param {CreatePipelineScheduleVariableOptions} options - The variable's key, value and type
|
|
5651
|
+
* @returns {Promise<GitLabPipelineScheduleVariable>} The created pipeline schedule variable
|
|
5652
|
+
*/
|
|
5653
|
+
async function createPipelineScheduleVariable(projectId, pipelineScheduleId, options) {
|
|
5654
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5655
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}/variables`);
|
|
5656
|
+
const response = await fetch(url.toString(), {
|
|
5657
|
+
...getFetchConfig(),
|
|
5658
|
+
method: "POST",
|
|
5659
|
+
body: JSON.stringify(options),
|
|
5660
|
+
});
|
|
5661
|
+
await handleGitLabError(response);
|
|
5662
|
+
const data = await response.json();
|
|
5663
|
+
return GitLabPipelineScheduleVariableSchema.parse(data);
|
|
5664
|
+
}
|
|
5665
|
+
/**
|
|
5666
|
+
* Update a variable of a pipeline schedule
|
|
5667
|
+
*
|
|
5668
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5669
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule
|
|
5670
|
+
* @param {string} key - The key of the variable to update
|
|
5671
|
+
* @param {UpdatePipelineScheduleVariableOptions} options - The new value and type
|
|
5672
|
+
* @returns {Promise<GitLabPipelineScheduleVariable>} The updated pipeline schedule variable
|
|
5673
|
+
*/
|
|
5674
|
+
async function updatePipelineScheduleVariable(projectId, pipelineScheduleId, key, options) {
|
|
5675
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5676
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}/variables/${encodeGitLabPathSegment(key)}`);
|
|
5677
|
+
const response = await fetch(url.toString(), {
|
|
5678
|
+
...getFetchConfig(),
|
|
5679
|
+
method: "PUT",
|
|
5680
|
+
body: JSON.stringify(options),
|
|
5681
|
+
});
|
|
5682
|
+
await handleGitLabError(response);
|
|
5683
|
+
const data = await response.json();
|
|
5684
|
+
return GitLabPipelineScheduleVariableSchema.parse(data);
|
|
5685
|
+
}
|
|
5686
|
+
/**
|
|
5687
|
+
* Delete a variable from a pipeline schedule
|
|
5688
|
+
*
|
|
5689
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
5690
|
+
* @param {number|string} pipelineScheduleId - The ID of the pipeline schedule
|
|
5691
|
+
* @param {string} key - The key of the variable to delete
|
|
5692
|
+
* @returns {Promise<void>}
|
|
5693
|
+
*/
|
|
5694
|
+
async function deletePipelineScheduleVariable(projectId, pipelineScheduleId, key) {
|
|
5695
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
5696
|
+
const url = new URL(`${getEffectiveApiUrl()}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/pipeline_schedules/${encodeGitLabPathSegment(pipelineScheduleId)}/variables/${encodeGitLabPathSegment(key)}`);
|
|
5697
|
+
const response = await fetch(url.toString(), {
|
|
5698
|
+
...getFetchConfig(),
|
|
5699
|
+
method: "DELETE",
|
|
5700
|
+
});
|
|
5701
|
+
await handleGitLabError(response);
|
|
5702
|
+
}
|
|
5377
5703
|
/**
|
|
5378
5704
|
* Run a manual job
|
|
5379
5705
|
*
|
|
@@ -8602,6 +8928,136 @@ async function handleToolCall(params) {
|
|
|
8602
8928
|
],
|
|
8603
8929
|
};
|
|
8604
8930
|
}
|
|
8931
|
+
case "list_pipeline_schedules": {
|
|
8932
|
+
const args = ListPipelineSchedulesSchema.parse(params.arguments);
|
|
8933
|
+
const { project_id, ...options } = args;
|
|
8934
|
+
const schedules = await listPipelineSchedules(project_id, options);
|
|
8935
|
+
return {
|
|
8936
|
+
content: [{ type: "text", text: JSON.stringify(schedules, null, 2) }],
|
|
8937
|
+
};
|
|
8938
|
+
}
|
|
8939
|
+
case "get_pipeline_schedule": {
|
|
8940
|
+
const { project_id, pipeline_schedule_id } = GetPipelineScheduleSchema.parse(params.arguments);
|
|
8941
|
+
const schedule = await getPipelineSchedule(project_id, pipeline_schedule_id);
|
|
8942
|
+
return {
|
|
8943
|
+
content: [{ type: "text", text: JSON.stringify(schedule, null, 2) }],
|
|
8944
|
+
};
|
|
8945
|
+
}
|
|
8946
|
+
case "list_pipeline_schedule_pipelines": {
|
|
8947
|
+
const args = ListPipelineSchedulePipelinesSchema.parse(params.arguments);
|
|
8948
|
+
const { project_id, pipeline_schedule_id, ...options } = args;
|
|
8949
|
+
const pipelines = await listPipelineSchedulePipelines(project_id, pipeline_schedule_id, options);
|
|
8950
|
+
return {
|
|
8951
|
+
content: [{ type: "text", text: JSON.stringify(pipelines, null, 2) }],
|
|
8952
|
+
};
|
|
8953
|
+
}
|
|
8954
|
+
case "create_pipeline_schedule": {
|
|
8955
|
+
const args = CreatePipelineScheduleSchema.parse(params.arguments);
|
|
8956
|
+
const { project_id, ...options } = args;
|
|
8957
|
+
const schedule = await createPipelineSchedule(project_id, options);
|
|
8958
|
+
return {
|
|
8959
|
+
content: [
|
|
8960
|
+
{
|
|
8961
|
+
type: "text",
|
|
8962
|
+
text: `Created pipeline schedule #${schedule.id} "${schedule.description}" on ${schedule.ref} (cron: ${schedule.cron} ${schedule.cron_timezone ?? "UTC"}). Active: ${schedule.active}\nNext run: ${schedule.next_run_at ?? "not scheduled"}`,
|
|
8963
|
+
},
|
|
8964
|
+
],
|
|
8965
|
+
};
|
|
8966
|
+
}
|
|
8967
|
+
case "update_pipeline_schedule": {
|
|
8968
|
+
const args = UpdatePipelineScheduleSchema.parse(params.arguments);
|
|
8969
|
+
const { project_id, pipeline_schedule_id, ...options } = args;
|
|
8970
|
+
const schedule = await updatePipelineSchedule(project_id, pipeline_schedule_id, options);
|
|
8971
|
+
return {
|
|
8972
|
+
content: [
|
|
8973
|
+
{
|
|
8974
|
+
type: "text",
|
|
8975
|
+
text: `Updated pipeline schedule #${schedule.id} "${schedule.description}" on ${schedule.ref} (cron: ${schedule.cron} ${schedule.cron_timezone ?? "UTC"}). Active: ${schedule.active}\nNext run: ${schedule.next_run_at ?? "not scheduled"}`,
|
|
8976
|
+
},
|
|
8977
|
+
],
|
|
8978
|
+
};
|
|
8979
|
+
}
|
|
8980
|
+
case "delete_pipeline_schedule": {
|
|
8981
|
+
const { project_id, pipeline_schedule_id } = DeletePipelineScheduleSchema.parse(params.arguments);
|
|
8982
|
+
await deletePipelineSchedule(project_id, pipeline_schedule_id);
|
|
8983
|
+
return {
|
|
8984
|
+
content: [
|
|
8985
|
+
{
|
|
8986
|
+
type: "text",
|
|
8987
|
+
text: `Deleted pipeline schedule #${pipeline_schedule_id}`,
|
|
8988
|
+
},
|
|
8989
|
+
],
|
|
8990
|
+
};
|
|
8991
|
+
}
|
|
8992
|
+
case "play_pipeline_schedule": {
|
|
8993
|
+
const { project_id, pipeline_schedule_id } = PlayPipelineScheduleSchema.parse(params.arguments);
|
|
8994
|
+
const result = await playPipelineSchedule(project_id, pipeline_schedule_id);
|
|
8995
|
+
return {
|
|
8996
|
+
content: [
|
|
8997
|
+
{
|
|
8998
|
+
type: "text",
|
|
8999
|
+
text: `Ran pipeline schedule #${pipeline_schedule_id} immediately; the next scheduled run is unchanged. GitLab responded: ${result.message ?? "accepted"}`,
|
|
9000
|
+
},
|
|
9001
|
+
],
|
|
9002
|
+
};
|
|
9003
|
+
}
|
|
9004
|
+
case "take_ownership_pipeline_schedule": {
|
|
9005
|
+
const { project_id, pipeline_schedule_id } = TakeOwnershipPipelineScheduleSchema.parse(params.arguments);
|
|
9006
|
+
const schedule = await takeOwnershipPipelineSchedule(project_id, pipeline_schedule_id);
|
|
9007
|
+
return {
|
|
9008
|
+
content: [
|
|
9009
|
+
{
|
|
9010
|
+
type: "text",
|
|
9011
|
+
text: `Took ownership of pipeline schedule #${schedule.id} "${schedule.description}". Owner: ${schedule.owner?.username ?? "unknown"}`,
|
|
9012
|
+
},
|
|
9013
|
+
],
|
|
9014
|
+
};
|
|
9015
|
+
}
|
|
9016
|
+
case "get_pipeline_schedule_variable": {
|
|
9017
|
+
const { project_id, pipeline_schedule_id, key } = GetPipelineScheduleVariableSchema.parse(params.arguments);
|
|
9018
|
+
const variable = await getPipelineScheduleVariable(project_id, pipeline_schedule_id, key);
|
|
9019
|
+
return {
|
|
9020
|
+
content: [{ type: "text", text: JSON.stringify(variable, null, 2) }],
|
|
9021
|
+
};
|
|
9022
|
+
}
|
|
9023
|
+
case "create_pipeline_schedule_variable": {
|
|
9024
|
+
const args = CreatePipelineScheduleVariableSchema.parse(params.arguments);
|
|
9025
|
+
const { project_id, pipeline_schedule_id, ...options } = args;
|
|
9026
|
+
const variable = await createPipelineScheduleVariable(project_id, pipeline_schedule_id, options);
|
|
9027
|
+
return {
|
|
9028
|
+
content: [
|
|
9029
|
+
{
|
|
9030
|
+
type: "text",
|
|
9031
|
+
text: `Created variable '${variable.key}' on pipeline schedule #${pipeline_schedule_id}`,
|
|
9032
|
+
},
|
|
9033
|
+
],
|
|
9034
|
+
};
|
|
9035
|
+
}
|
|
9036
|
+
case "update_pipeline_schedule_variable": {
|
|
9037
|
+
const args = UpdatePipelineScheduleVariableSchema.parse(params.arguments);
|
|
9038
|
+
const { project_id, pipeline_schedule_id, key, ...options } = args;
|
|
9039
|
+
const variable = await updatePipelineScheduleVariable(project_id, pipeline_schedule_id, key, options);
|
|
9040
|
+
return {
|
|
9041
|
+
content: [
|
|
9042
|
+
{
|
|
9043
|
+
type: "text",
|
|
9044
|
+
text: `Updated variable '${variable.key}' on pipeline schedule #${pipeline_schedule_id}`,
|
|
9045
|
+
},
|
|
9046
|
+
],
|
|
9047
|
+
};
|
|
9048
|
+
}
|
|
9049
|
+
case "delete_pipeline_schedule_variable": {
|
|
9050
|
+
const { project_id, pipeline_schedule_id, key } = DeletePipelineScheduleVariableSchema.parse(params.arguments);
|
|
9051
|
+
await deletePipelineScheduleVariable(project_id, pipeline_schedule_id, key);
|
|
9052
|
+
return {
|
|
9053
|
+
content: [
|
|
9054
|
+
{
|
|
9055
|
+
type: "text",
|
|
9056
|
+
text: `Deleted variable '${key}' from pipeline schedule #${pipeline_schedule_id}`,
|
|
9057
|
+
},
|
|
9058
|
+
],
|
|
9059
|
+
};
|
|
9060
|
+
}
|
|
8605
9061
|
case "play_pipeline_job": {
|
|
8606
9062
|
const { project_id, job_id, job_variables_attributes } = PlayPipelineJobSchema.parse(params.arguments);
|
|
8607
9063
|
const job = await playPipelineJob(project_id, job_id, job_variables_attributes);
|
|
@@ -8691,6 +9147,14 @@ async function handleToolCall(params) {
|
|
|
8691
9147
|
content: [{ type: "text", text: JSON.stringify(mergeRequests) }],
|
|
8692
9148
|
};
|
|
8693
9149
|
}
|
|
9150
|
+
case "list_group_merge_requests": {
|
|
9151
|
+
const { group_id, ...options } = ListGroupMergeRequestsSchema.parse(params.arguments);
|
|
9152
|
+
const cleanedOptions = cleanMutuallyExclusiveIdUsernameOptions(options, LIST_MERGE_REQUESTS_ID_USERNAME_PAIRS);
|
|
9153
|
+
const mergeRequests = await listGroupMergeRequests(group_id, cleanedOptions);
|
|
9154
|
+
return {
|
|
9155
|
+
content: [{ type: "text", text: JSON.stringify(mergeRequests) }],
|
|
9156
|
+
};
|
|
9157
|
+
}
|
|
8694
9158
|
case "list_milestones": {
|
|
8695
9159
|
const { project_id, ...options } = ListProjectMilestonesSchema.parse(params.arguments);
|
|
8696
9160
|
const milestones = await listProjectMilestones(project_id, options);
|