@zereight/mcp-gitlab 2.0.4 → 2.0.6
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 +24 -18
- package/build/index.js +332 -96
- package/build/schemas.js +169 -99
- package/build/test/comprehensive-mcp-tests.js +378 -0
- package/build/test/readonly-mcp-tests.js +381 -0
- package/build/test/simple-mcp-tests.js +190 -0
- package/package.json +5 -1
package/build/index.js
CHANGED
|
@@ -20,7 +20,7 @@ import { zodToJsonSchema } from "zod-to-json-schema";
|
|
|
20
20
|
import { Agent } from "http";
|
|
21
21
|
import { Agent as HttpsAgent } from "https";
|
|
22
22
|
import { URL } from "url";
|
|
23
|
-
import { BulkPublishDraftNotesSchema, CancelPipelineSchema, CreateBranchSchema, CreateDraftNoteSchema, CreateIssueLinkSchema, CreateIssueNoteSchema, CreateIssueSchema, CreateLabelSchema, // Added
|
|
23
|
+
import { BulkPublishDraftNotesSchema, CancelPipelineJobSchema, CancelPipelineSchema, CreateBranchSchema, CreateDraftNoteSchema, CreateIssueLinkSchema, CreateIssueNoteSchema, CreateIssueSchema, CreateLabelSchema, // Added
|
|
24
24
|
CreateMergeRequestNoteSchema, CreateMergeRequestSchema, CreateMergeRequestThreadSchema, CreateNoteSchema, CreateOrUpdateFileSchema, CreatePipelineSchema, CreateProjectMilestoneSchema, CreateRepositorySchema, CreateWikiPageSchema, DeleteDraftNoteSchema, DeleteIssueLinkSchema, DeleteIssueSchema, DeleteLabelSchema, DeleteProjectMilestoneSchema, DeleteWikiPageSchema, EditProjectMilestoneSchema, ForkRepositorySchema, GetBranchDiffsSchema, GetCommitDiffSchema, GetCommitSchema, GetDraftNoteSchema, GetFileContentsSchema, GetIssueLinkSchema, GetIssueSchema, GetLabelSchema, GetMergeRequestDiffsSchema, GetMergeRequestSchema, GetMilestoneBurndownEventsSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, GetNamespaceSchema,
|
|
25
25
|
// pipeline job schemas
|
|
26
26
|
GetPipelineJobOutputSchema, GetPipelineSchema, GetProjectMilestoneSchema, GetProjectSchema, GetRepositoryTreeSchema, GetUsersSchema, GetWikiPageSchema, GitLabCommitSchema, GitLabCompareResultSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabDiffSchema,
|
|
@@ -29,7 +29,7 @@ GitLabDiscussionNoteSchema, // Added
|
|
|
29
29
|
GitLabDiscussionSchema,
|
|
30
30
|
// Draft Notes Schemas
|
|
31
31
|
GitLabDraftNoteSchema, GitLabForkSchema, GitLabIssueLinkSchema, GitLabIssueSchema, GitLabIssueWithLinkDetailsSchema, GitLabMarkdownUploadSchema, GitLabMergeRequestSchema, GitLabMilestonesSchema, GitLabNamespaceExistsResponseSchema, GitLabNamespaceSchema, GitLabPipelineJobSchema, GitLabPipelineSchema, GitLabPipelineTriggerJobSchema, GitLabProjectMemberSchema, GitLabProjectSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabSearchResponseSchema, GitLabTreeItemSchema, GitLabTreeSchema, GitLabUserSchema, GitLabUsersResponseSchema, GitLabWikiPageSchema, GroupIteration, ListCommitsSchema, ListDraftNotesSchema, ListGroupIterationsSchema, ListGroupProjectsSchema, ListIssueDiscussionsSchema, ListIssueLinksSchema, ListIssuesSchema, ListLabelsSchema, ListMergeRequestDiffsSchema, // Added
|
|
32
|
-
ListMergeRequestDiscussionsSchema, ListMergeRequestsSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListPipelineTriggerJobsSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, MarkdownUploadSchema, DownloadAttachmentSchema, MergeMergeRequestSchema, MyIssuesSchema, PaginatedDiscussionsResponseSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PushFilesSchema, RetryPipelineSchema, SearchRepositoriesSchema, UpdateDraftNoteSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateLabelSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestSchema, UpdateWikiPageSchema, VerifyNamespaceSchema } from "./schemas.js";
|
|
32
|
+
ListMergeRequestDiscussionsSchema, ListMergeRequestsSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListPipelineTriggerJobsSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, MarkdownUploadSchema, DownloadAttachmentSchema, MergeMergeRequestSchema, MyIssuesSchema, PaginatedDiscussionsResponseSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PlayPipelineJobSchema, PushFilesSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchRepositoriesSchema, UpdateDraftNoteSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateLabelSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestSchema, UpdateWikiPageSchema, VerifyNamespaceSchema, GitLabEventSchema, ListEventsSchema, GetProjectEventsSchema } from "./schemas.js";
|
|
33
33
|
import { randomUUID } from "crypto";
|
|
34
34
|
import { pino } from "pino";
|
|
35
35
|
const logger = pino({
|
|
@@ -213,422 +213,448 @@ const DEFAULT_FETCH_CONFIG = {
|
|
|
213
213
|
return httpAgent;
|
|
214
214
|
},
|
|
215
215
|
};
|
|
216
|
+
const toJSONSchema = (schema) => zodToJsonSchema(schema, { $refStrategy: 'none' });
|
|
216
217
|
// Define all available tools
|
|
217
218
|
const allTools = [
|
|
218
219
|
{
|
|
219
220
|
name: "merge_merge_request",
|
|
220
221
|
description: "Merge a merge request in a GitLab project",
|
|
221
|
-
inputSchema:
|
|
222
|
+
inputSchema: toJSONSchema(MergeMergeRequestSchema),
|
|
222
223
|
},
|
|
223
224
|
{
|
|
224
225
|
name: "create_or_update_file",
|
|
225
226
|
description: "Create or update a single file in a GitLab project",
|
|
226
|
-
inputSchema:
|
|
227
|
+
inputSchema: toJSONSchema(CreateOrUpdateFileSchema),
|
|
227
228
|
},
|
|
228
229
|
{
|
|
229
230
|
name: "search_repositories",
|
|
230
231
|
description: "Search for GitLab projects",
|
|
231
|
-
inputSchema:
|
|
232
|
+
inputSchema: toJSONSchema(SearchRepositoriesSchema),
|
|
232
233
|
},
|
|
233
234
|
{
|
|
234
235
|
name: "create_repository",
|
|
235
236
|
description: "Create a new GitLab project",
|
|
236
|
-
inputSchema:
|
|
237
|
+
inputSchema: toJSONSchema(CreateRepositorySchema),
|
|
237
238
|
},
|
|
238
239
|
{
|
|
239
240
|
name: "get_file_contents",
|
|
240
241
|
description: "Get the contents of a file or directory from a GitLab project",
|
|
241
|
-
inputSchema:
|
|
242
|
+
inputSchema: toJSONSchema(GetFileContentsSchema),
|
|
242
243
|
},
|
|
243
244
|
{
|
|
244
245
|
name: "push_files",
|
|
245
246
|
description: "Push multiple files to a GitLab project in a single commit",
|
|
246
|
-
inputSchema:
|
|
247
|
+
inputSchema: toJSONSchema(PushFilesSchema),
|
|
247
248
|
},
|
|
248
249
|
{
|
|
249
250
|
name: "create_issue",
|
|
250
251
|
description: "Create a new issue in a GitLab project",
|
|
251
|
-
inputSchema:
|
|
252
|
+
inputSchema: toJSONSchema(CreateIssueSchema),
|
|
252
253
|
},
|
|
253
254
|
{
|
|
254
255
|
name: "create_merge_request",
|
|
255
256
|
description: "Create a new merge request in a GitLab project",
|
|
256
|
-
inputSchema:
|
|
257
|
+
inputSchema: toJSONSchema(CreateMergeRequestSchema),
|
|
257
258
|
},
|
|
258
259
|
{
|
|
259
260
|
name: "fork_repository",
|
|
260
261
|
description: "Fork a GitLab project to your account or specified namespace",
|
|
261
|
-
inputSchema:
|
|
262
|
+
inputSchema: toJSONSchema(ForkRepositorySchema),
|
|
262
263
|
},
|
|
263
264
|
{
|
|
264
265
|
name: "create_branch",
|
|
265
266
|
description: "Create a new branch in a GitLab project",
|
|
266
|
-
inputSchema:
|
|
267
|
+
inputSchema: toJSONSchema(CreateBranchSchema),
|
|
267
268
|
},
|
|
268
269
|
{
|
|
269
270
|
name: "get_merge_request",
|
|
270
271
|
description: "Get details of a merge request (Either mergeRequestIid or branchName must be provided)",
|
|
271
|
-
inputSchema:
|
|
272
|
+
inputSchema: toJSONSchema(GetMergeRequestSchema),
|
|
272
273
|
},
|
|
273
274
|
{
|
|
274
275
|
name: "get_merge_request_diffs",
|
|
275
276
|
description: "Get the changes/diffs of a merge request (Either mergeRequestIid or branchName must be provided)",
|
|
276
|
-
inputSchema:
|
|
277
|
+
inputSchema: toJSONSchema(GetMergeRequestDiffsSchema),
|
|
277
278
|
},
|
|
278
279
|
{
|
|
279
280
|
name: "list_merge_request_diffs",
|
|
280
281
|
description: "List merge request diffs with pagination support (Either mergeRequestIid or branchName must be provided)",
|
|
281
|
-
inputSchema:
|
|
282
|
+
inputSchema: toJSONSchema(ListMergeRequestDiffsSchema),
|
|
282
283
|
},
|
|
283
284
|
{
|
|
284
285
|
name: "get_branch_diffs",
|
|
285
286
|
description: "Get the changes/diffs between two branches or commits in a GitLab project",
|
|
286
|
-
inputSchema:
|
|
287
|
+
inputSchema: toJSONSchema(GetBranchDiffsSchema),
|
|
287
288
|
},
|
|
288
289
|
{
|
|
289
290
|
name: "update_merge_request",
|
|
290
291
|
description: "Update a merge request (Either mergeRequestIid or branchName must be provided)",
|
|
291
|
-
inputSchema:
|
|
292
|
+
inputSchema: toJSONSchema(UpdateMergeRequestSchema),
|
|
292
293
|
},
|
|
293
294
|
{
|
|
294
295
|
name: "create_note",
|
|
295
296
|
description: "Create a new note (comment) to an issue or merge request",
|
|
296
|
-
inputSchema:
|
|
297
|
+
inputSchema: toJSONSchema(CreateNoteSchema),
|
|
297
298
|
},
|
|
298
299
|
{
|
|
299
300
|
name: "create_merge_request_thread",
|
|
300
301
|
description: "Create a new thread on a merge request",
|
|
301
|
-
inputSchema:
|
|
302
|
+
inputSchema: toJSONSchema(CreateMergeRequestThreadSchema),
|
|
302
303
|
},
|
|
303
304
|
{
|
|
304
305
|
name: "mr_discussions",
|
|
305
306
|
description: "List discussion items for a merge request",
|
|
306
|
-
inputSchema:
|
|
307
|
+
inputSchema: toJSONSchema(ListMergeRequestDiscussionsSchema),
|
|
307
308
|
},
|
|
308
309
|
{
|
|
309
310
|
name: "update_merge_request_note",
|
|
310
311
|
description: "Modify an existing merge request thread note",
|
|
311
|
-
inputSchema:
|
|
312
|
+
inputSchema: toJSONSchema(UpdateMergeRequestNoteSchema),
|
|
312
313
|
},
|
|
313
314
|
{
|
|
314
315
|
name: "create_merge_request_note",
|
|
315
316
|
description: "Add a new note to an existing merge request thread",
|
|
316
|
-
inputSchema:
|
|
317
|
+
inputSchema: toJSONSchema(CreateMergeRequestNoteSchema),
|
|
317
318
|
},
|
|
318
319
|
{
|
|
319
320
|
name: "get_draft_note",
|
|
320
321
|
description: "Get a single draft note from a merge request",
|
|
321
|
-
inputSchema:
|
|
322
|
+
inputSchema: toJSONSchema(GetDraftNoteSchema),
|
|
322
323
|
},
|
|
323
324
|
{
|
|
324
325
|
name: "list_draft_notes",
|
|
325
326
|
description: "List draft notes for a merge request",
|
|
326
|
-
inputSchema:
|
|
327
|
+
inputSchema: toJSONSchema(ListDraftNotesSchema),
|
|
327
328
|
},
|
|
328
329
|
{
|
|
329
330
|
name: "create_draft_note",
|
|
330
331
|
description: "Create a draft note for a merge request",
|
|
331
|
-
inputSchema:
|
|
332
|
+
inputSchema: toJSONSchema(CreateDraftNoteSchema),
|
|
332
333
|
},
|
|
333
334
|
{
|
|
334
335
|
name: "update_draft_note",
|
|
335
336
|
description: "Update an existing draft note",
|
|
336
|
-
inputSchema:
|
|
337
|
+
inputSchema: toJSONSchema(UpdateDraftNoteSchema),
|
|
337
338
|
},
|
|
338
339
|
{
|
|
339
340
|
name: "delete_draft_note",
|
|
340
341
|
description: "Delete a draft note",
|
|
341
|
-
inputSchema:
|
|
342
|
+
inputSchema: toJSONSchema(DeleteDraftNoteSchema),
|
|
342
343
|
},
|
|
343
344
|
{
|
|
344
345
|
name: "publish_draft_note",
|
|
345
346
|
description: "Publish a single draft note",
|
|
346
|
-
inputSchema:
|
|
347
|
+
inputSchema: toJSONSchema(PublishDraftNoteSchema),
|
|
347
348
|
},
|
|
348
349
|
{
|
|
349
350
|
name: "bulk_publish_draft_notes",
|
|
350
351
|
description: "Publish all draft notes for a merge request",
|
|
351
|
-
inputSchema:
|
|
352
|
+
inputSchema: toJSONSchema(BulkPublishDraftNotesSchema),
|
|
352
353
|
},
|
|
353
354
|
{
|
|
354
355
|
name: "update_issue_note",
|
|
355
356
|
description: "Modify an existing issue thread note",
|
|
356
|
-
inputSchema:
|
|
357
|
+
inputSchema: toJSONSchema(UpdateIssueNoteSchema),
|
|
357
358
|
},
|
|
358
359
|
{
|
|
359
360
|
name: "create_issue_note",
|
|
360
361
|
description: "Add a new note to an existing issue thread",
|
|
361
|
-
inputSchema:
|
|
362
|
+
inputSchema: toJSONSchema(CreateIssueNoteSchema),
|
|
362
363
|
},
|
|
363
364
|
{
|
|
364
365
|
name: "list_issues",
|
|
365
366
|
description: "List issues (default: created by current user only; use scope='all' for all accessible issues)",
|
|
366
|
-
inputSchema:
|
|
367
|
+
inputSchema: toJSONSchema(ListIssuesSchema),
|
|
367
368
|
},
|
|
368
369
|
{
|
|
369
370
|
name: "my_issues",
|
|
370
371
|
description: "List issues assigned to the authenticated user (defaults to open issues)",
|
|
371
|
-
inputSchema:
|
|
372
|
+
inputSchema: toJSONSchema(MyIssuesSchema),
|
|
372
373
|
},
|
|
373
374
|
{
|
|
374
375
|
name: "get_issue",
|
|
375
376
|
description: "Get details of a specific issue in a GitLab project",
|
|
376
|
-
inputSchema:
|
|
377
|
+
inputSchema: toJSONSchema(GetIssueSchema),
|
|
377
378
|
},
|
|
378
379
|
{
|
|
379
380
|
name: "update_issue",
|
|
380
381
|
description: "Update an issue in a GitLab project",
|
|
381
|
-
inputSchema:
|
|
382
|
+
inputSchema: toJSONSchema(UpdateIssueSchema),
|
|
382
383
|
},
|
|
383
384
|
{
|
|
384
385
|
name: "delete_issue",
|
|
385
386
|
description: "Delete an issue from a GitLab project",
|
|
386
|
-
inputSchema:
|
|
387
|
+
inputSchema: toJSONSchema(DeleteIssueSchema),
|
|
387
388
|
},
|
|
388
389
|
{
|
|
389
390
|
name: "list_issue_links",
|
|
390
391
|
description: "List all issue links for a specific issue",
|
|
391
|
-
inputSchema:
|
|
392
|
+
inputSchema: toJSONSchema(ListIssueLinksSchema),
|
|
392
393
|
},
|
|
393
394
|
{
|
|
394
395
|
name: "list_issue_discussions",
|
|
395
396
|
description: "List discussions for an issue in a GitLab project",
|
|
396
|
-
inputSchema:
|
|
397
|
+
inputSchema: toJSONSchema(ListIssueDiscussionsSchema),
|
|
397
398
|
},
|
|
398
399
|
{
|
|
399
400
|
name: "get_issue_link",
|
|
400
401
|
description: "Get a specific issue link",
|
|
401
|
-
inputSchema:
|
|
402
|
+
inputSchema: toJSONSchema(GetIssueLinkSchema),
|
|
402
403
|
},
|
|
403
404
|
{
|
|
404
405
|
name: "create_issue_link",
|
|
405
406
|
description: "Create an issue link between two issues",
|
|
406
|
-
inputSchema:
|
|
407
|
+
inputSchema: toJSONSchema(CreateIssueLinkSchema),
|
|
407
408
|
},
|
|
408
409
|
{
|
|
409
410
|
name: "delete_issue_link",
|
|
410
411
|
description: "Delete an issue link",
|
|
411
|
-
inputSchema:
|
|
412
|
+
inputSchema: toJSONSchema(DeleteIssueLinkSchema),
|
|
412
413
|
},
|
|
413
414
|
{
|
|
414
415
|
name: "list_namespaces",
|
|
415
416
|
description: "List all namespaces available to the current user",
|
|
416
|
-
inputSchema:
|
|
417
|
+
inputSchema: toJSONSchema(ListNamespacesSchema),
|
|
417
418
|
},
|
|
418
419
|
{
|
|
419
420
|
name: "get_namespace",
|
|
420
421
|
description: "Get details of a namespace by ID or path",
|
|
421
|
-
inputSchema:
|
|
422
|
+
inputSchema: toJSONSchema(GetNamespaceSchema),
|
|
422
423
|
},
|
|
423
424
|
{
|
|
424
425
|
name: "verify_namespace",
|
|
425
426
|
description: "Verify if a namespace path exists",
|
|
426
|
-
inputSchema:
|
|
427
|
+
inputSchema: toJSONSchema(VerifyNamespaceSchema),
|
|
427
428
|
},
|
|
428
429
|
{
|
|
429
430
|
name: "get_project",
|
|
430
431
|
description: "Get details of a specific project",
|
|
431
|
-
inputSchema:
|
|
432
|
+
inputSchema: toJSONSchema(GetProjectSchema),
|
|
432
433
|
},
|
|
433
434
|
{
|
|
434
435
|
name: "list_projects",
|
|
435
436
|
description: "List projects accessible by the current user",
|
|
436
|
-
inputSchema:
|
|
437
|
+
inputSchema: toJSONSchema(ListProjectsSchema),
|
|
437
438
|
},
|
|
438
439
|
{
|
|
439
440
|
name: "list_project_members",
|
|
440
441
|
description: "List members of a GitLab project",
|
|
441
|
-
inputSchema:
|
|
442
|
+
inputSchema: toJSONSchema(ListProjectMembersSchema),
|
|
442
443
|
},
|
|
443
444
|
{
|
|
444
445
|
name: "list_labels",
|
|
445
446
|
description: "List labels for a project",
|
|
446
|
-
inputSchema:
|
|
447
|
+
inputSchema: toJSONSchema(ListLabelsSchema),
|
|
447
448
|
},
|
|
448
449
|
{
|
|
449
450
|
name: "get_label",
|
|
450
451
|
description: "Get a single label from a project",
|
|
451
|
-
inputSchema:
|
|
452
|
+
inputSchema: toJSONSchema(GetLabelSchema),
|
|
452
453
|
},
|
|
453
454
|
{
|
|
454
455
|
name: "create_label",
|
|
455
456
|
description: "Create a new label in a project",
|
|
456
|
-
inputSchema:
|
|
457
|
+
inputSchema: toJSONSchema(CreateLabelSchema),
|
|
457
458
|
},
|
|
458
459
|
{
|
|
459
460
|
name: "update_label",
|
|
460
461
|
description: "Update an existing label in a project",
|
|
461
|
-
inputSchema:
|
|
462
|
+
inputSchema: toJSONSchema(UpdateLabelSchema),
|
|
462
463
|
},
|
|
463
464
|
{
|
|
464
465
|
name: "delete_label",
|
|
465
466
|
description: "Delete a label from a project",
|
|
466
|
-
inputSchema:
|
|
467
|
+
inputSchema: toJSONSchema(DeleteLabelSchema),
|
|
467
468
|
},
|
|
468
469
|
{
|
|
469
470
|
name: "list_group_projects",
|
|
470
471
|
description: "List projects in a GitLab group with filtering options",
|
|
471
|
-
inputSchema:
|
|
472
|
+
inputSchema: toJSONSchema(ListGroupProjectsSchema),
|
|
472
473
|
},
|
|
473
474
|
{
|
|
474
475
|
name: "list_wiki_pages",
|
|
475
476
|
description: "List wiki pages in a GitLab project",
|
|
476
|
-
inputSchema:
|
|
477
|
+
inputSchema: toJSONSchema(ListWikiPagesSchema),
|
|
477
478
|
},
|
|
478
479
|
{
|
|
479
480
|
name: "get_wiki_page",
|
|
480
481
|
description: "Get details of a specific wiki page",
|
|
481
|
-
inputSchema:
|
|
482
|
+
inputSchema: toJSONSchema(GetWikiPageSchema),
|
|
482
483
|
},
|
|
483
484
|
{
|
|
484
485
|
name: "create_wiki_page",
|
|
485
486
|
description: "Create a new wiki page in a GitLab project",
|
|
486
|
-
inputSchema:
|
|
487
|
+
inputSchema: toJSONSchema(CreateWikiPageSchema),
|
|
487
488
|
},
|
|
488
489
|
{
|
|
489
490
|
name: "update_wiki_page",
|
|
490
491
|
description: "Update an existing wiki page in a GitLab project",
|
|
491
|
-
inputSchema:
|
|
492
|
+
inputSchema: toJSONSchema(UpdateWikiPageSchema),
|
|
492
493
|
},
|
|
493
494
|
{
|
|
494
495
|
name: "delete_wiki_page",
|
|
495
496
|
description: "Delete a wiki page from a GitLab project",
|
|
496
|
-
inputSchema:
|
|
497
|
+
inputSchema: toJSONSchema(DeleteWikiPageSchema),
|
|
497
498
|
},
|
|
498
499
|
{
|
|
499
500
|
name: "get_repository_tree",
|
|
500
501
|
description: "Get the repository tree for a GitLab project (list files and directories)",
|
|
501
|
-
inputSchema:
|
|
502
|
+
inputSchema: toJSONSchema(GetRepositoryTreeSchema),
|
|
502
503
|
},
|
|
503
504
|
{
|
|
504
505
|
name: "list_pipelines",
|
|
505
506
|
description: "List pipelines in a GitLab project with filtering options",
|
|
506
|
-
inputSchema:
|
|
507
|
+
inputSchema: toJSONSchema(ListPipelinesSchema),
|
|
507
508
|
},
|
|
508
509
|
{
|
|
509
510
|
name: "get_pipeline",
|
|
510
511
|
description: "Get details of a specific pipeline in a GitLab project",
|
|
511
|
-
inputSchema:
|
|
512
|
+
inputSchema: toJSONSchema(GetPipelineSchema),
|
|
512
513
|
},
|
|
513
514
|
{
|
|
514
515
|
name: "list_pipeline_jobs",
|
|
515
516
|
description: "List all jobs in a specific pipeline",
|
|
516
|
-
inputSchema:
|
|
517
|
+
inputSchema: toJSONSchema(ListPipelineJobsSchema),
|
|
517
518
|
},
|
|
518
519
|
{
|
|
519
520
|
name: "list_pipeline_trigger_jobs",
|
|
520
521
|
description: "List all trigger jobs (bridges) in a specific pipeline that trigger downstream pipelines",
|
|
521
|
-
inputSchema:
|
|
522
|
+
inputSchema: toJSONSchema(ListPipelineTriggerJobsSchema),
|
|
522
523
|
},
|
|
523
524
|
{
|
|
524
525
|
name: "get_pipeline_job",
|
|
525
526
|
description: "Get details of a GitLab pipeline job number",
|
|
526
|
-
inputSchema:
|
|
527
|
+
inputSchema: toJSONSchema(GetPipelineJobOutputSchema),
|
|
527
528
|
},
|
|
528
529
|
{
|
|
529
530
|
name: "get_pipeline_job_output",
|
|
530
531
|
description: "Get the output/trace of a GitLab pipeline job with optional pagination to limit context window usage",
|
|
531
|
-
inputSchema:
|
|
532
|
+
inputSchema: toJSONSchema(GetPipelineJobOutputSchema),
|
|
532
533
|
},
|
|
533
534
|
{
|
|
534
535
|
name: "create_pipeline",
|
|
535
536
|
description: "Create a new pipeline for a branch or tag",
|
|
536
|
-
inputSchema:
|
|
537
|
+
inputSchema: toJSONSchema(CreatePipelineSchema),
|
|
537
538
|
},
|
|
538
539
|
{
|
|
539
540
|
name: "retry_pipeline",
|
|
540
541
|
description: "Retry a failed or canceled pipeline",
|
|
541
|
-
inputSchema:
|
|
542
|
+
inputSchema: toJSONSchema(RetryPipelineSchema),
|
|
542
543
|
},
|
|
543
544
|
{
|
|
544
545
|
name: "cancel_pipeline",
|
|
545
546
|
description: "Cancel a running pipeline",
|
|
546
|
-
inputSchema:
|
|
547
|
+
inputSchema: toJSONSchema(CancelPipelineSchema),
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
name: "play_pipeline_job",
|
|
551
|
+
description: "Run a manual pipeline job",
|
|
552
|
+
inputSchema: toJSONSchema(PlayPipelineJobSchema),
|
|
553
|
+
},
|
|
554
|
+
{
|
|
555
|
+
name: "retry_pipeline_job",
|
|
556
|
+
description: "Retry a failed or canceled pipeline job",
|
|
557
|
+
inputSchema: toJSONSchema(RetryPipelineJobSchema),
|
|
558
|
+
},
|
|
559
|
+
{
|
|
560
|
+
name: "cancel_pipeline_job",
|
|
561
|
+
description: "Cancel a running pipeline job",
|
|
562
|
+
inputSchema: toJSONSchema(CancelPipelineJobSchema),
|
|
547
563
|
},
|
|
548
564
|
{
|
|
549
565
|
name: "list_merge_requests",
|
|
550
566
|
description: "List merge requests in a GitLab project with filtering options",
|
|
551
|
-
inputSchema:
|
|
567
|
+
inputSchema: toJSONSchema(ListMergeRequestsSchema),
|
|
552
568
|
},
|
|
553
569
|
{
|
|
554
570
|
name: "list_milestones",
|
|
555
571
|
description: "List milestones in a GitLab project with filtering options",
|
|
556
|
-
inputSchema:
|
|
572
|
+
inputSchema: toJSONSchema(ListProjectMilestonesSchema),
|
|
557
573
|
},
|
|
558
574
|
{
|
|
559
575
|
name: "get_milestone",
|
|
560
576
|
description: "Get details of a specific milestone",
|
|
561
|
-
inputSchema:
|
|
577
|
+
inputSchema: toJSONSchema(GetProjectMilestoneSchema),
|
|
562
578
|
},
|
|
563
579
|
{
|
|
564
580
|
name: "create_milestone",
|
|
565
581
|
description: "Create a new milestone in a GitLab project",
|
|
566
|
-
inputSchema:
|
|
582
|
+
inputSchema: toJSONSchema(CreateProjectMilestoneSchema),
|
|
567
583
|
},
|
|
568
584
|
{
|
|
569
585
|
name: "edit_milestone",
|
|
570
586
|
description: "Edit an existing milestone in a GitLab project",
|
|
571
|
-
inputSchema:
|
|
587
|
+
inputSchema: toJSONSchema(EditProjectMilestoneSchema),
|
|
572
588
|
},
|
|
573
589
|
{
|
|
574
590
|
name: "delete_milestone",
|
|
575
591
|
description: "Delete a milestone from a GitLab project",
|
|
576
|
-
inputSchema:
|
|
592
|
+
inputSchema: toJSONSchema(DeleteProjectMilestoneSchema),
|
|
577
593
|
},
|
|
578
594
|
{
|
|
579
595
|
name: "get_milestone_issue",
|
|
580
596
|
description: "Get issues associated with a specific milestone",
|
|
581
|
-
inputSchema:
|
|
597
|
+
inputSchema: toJSONSchema(GetMilestoneIssuesSchema),
|
|
582
598
|
},
|
|
583
599
|
{
|
|
584
600
|
name: "get_milestone_merge_requests",
|
|
585
601
|
description: "Get merge requests associated with a specific milestone",
|
|
586
|
-
inputSchema:
|
|
602
|
+
inputSchema: toJSONSchema(GetMilestoneMergeRequestsSchema),
|
|
587
603
|
},
|
|
588
604
|
{
|
|
589
605
|
name: "promote_milestone",
|
|
590
606
|
description: "Promote a milestone to the next stage",
|
|
591
|
-
inputSchema:
|
|
607
|
+
inputSchema: toJSONSchema(PromoteProjectMilestoneSchema),
|
|
592
608
|
},
|
|
593
609
|
{
|
|
594
610
|
name: "get_milestone_burndown_events",
|
|
595
611
|
description: "Get burndown events for a specific milestone",
|
|
596
|
-
inputSchema:
|
|
612
|
+
inputSchema: toJSONSchema(GetMilestoneBurndownEventsSchema),
|
|
597
613
|
},
|
|
598
614
|
{
|
|
599
615
|
name: "get_users",
|
|
600
616
|
description: "Get GitLab user details by usernames",
|
|
601
|
-
inputSchema:
|
|
617
|
+
inputSchema: toJSONSchema(GetUsersSchema),
|
|
602
618
|
},
|
|
603
619
|
{
|
|
604
620
|
name: "list_commits",
|
|
605
621
|
description: "List repository commits with filtering options",
|
|
606
|
-
inputSchema:
|
|
622
|
+
inputSchema: toJSONSchema(ListCommitsSchema),
|
|
607
623
|
},
|
|
608
624
|
{
|
|
609
625
|
name: "get_commit",
|
|
610
626
|
description: "Get details of a specific commit",
|
|
611
|
-
inputSchema:
|
|
627
|
+
inputSchema: toJSONSchema(GetCommitSchema),
|
|
612
628
|
},
|
|
613
629
|
{
|
|
614
630
|
name: "get_commit_diff",
|
|
615
631
|
description: "Get changes/diffs of a specific commit",
|
|
616
|
-
inputSchema:
|
|
632
|
+
inputSchema: toJSONSchema(GetCommitDiffSchema),
|
|
617
633
|
},
|
|
618
634
|
{
|
|
619
635
|
name: "list_group_iterations",
|
|
620
636
|
description: "List group iterations with filtering options",
|
|
621
|
-
inputSchema:
|
|
637
|
+
inputSchema: toJSONSchema(ListGroupIterationsSchema),
|
|
622
638
|
},
|
|
623
639
|
{
|
|
624
640
|
name: "upload_markdown",
|
|
625
641
|
description: "Upload a file to a GitLab project for use in markdown content",
|
|
626
|
-
inputSchema:
|
|
642
|
+
inputSchema: toJSONSchema(MarkdownUploadSchema),
|
|
627
643
|
},
|
|
628
644
|
{
|
|
629
645
|
name: "download_attachment",
|
|
630
646
|
description: "Download an uploaded file from a GitLab project by secret and filename",
|
|
631
|
-
inputSchema:
|
|
647
|
+
inputSchema: toJSONSchema(DownloadAttachmentSchema),
|
|
648
|
+
},
|
|
649
|
+
{
|
|
650
|
+
name: "list_events",
|
|
651
|
+
description: "List all events for the currently authenticated user. Note: before/after parameters accept date format YYYY-MM-DD only",
|
|
652
|
+
inputSchema: toJSONSchema(ListEventsSchema),
|
|
653
|
+
},
|
|
654
|
+
{
|
|
655
|
+
name: "get_project_events",
|
|
656
|
+
description: "List all visible events for a specified project. Note: before/after parameters accept date format YYYY-MM-DD only",
|
|
657
|
+
inputSchema: toJSONSchema(GetProjectEventsSchema),
|
|
632
658
|
},
|
|
633
659
|
];
|
|
634
660
|
// Define which tools are read-only
|
|
@@ -676,6 +702,8 @@ const readOnlyTools = [
|
|
|
676
702
|
"list_group_iterations",
|
|
677
703
|
"get_group_iteration",
|
|
678
704
|
"download_attachment",
|
|
705
|
+
"list_events",
|
|
706
|
+
"get_project_events",
|
|
679
707
|
];
|
|
680
708
|
// Define which tools are related to wiki and can be toggled by USE_GITLAB_WIKI
|
|
681
709
|
const wikiToolNames = [
|
|
@@ -709,6 +737,9 @@ const pipelineToolNames = [
|
|
|
709
737
|
"create_pipeline",
|
|
710
738
|
"retry_pipeline",
|
|
711
739
|
"cancel_pipeline",
|
|
740
|
+
"play_pipeline_job",
|
|
741
|
+
"retry_pipeline_job",
|
|
742
|
+
"cancel_pipeline_job",
|
|
712
743
|
];
|
|
713
744
|
/**
|
|
714
745
|
* Smart URL handling for GitLab API
|
|
@@ -733,6 +764,7 @@ function normalizeGitLabApiUrl(url) {
|
|
|
733
764
|
const GITLAB_API_URL = normalizeGitLabApiUrl(process.env.GITLAB_API_URL || "");
|
|
734
765
|
const GITLAB_PROJECT_ID = process.env.GITLAB_PROJECT_ID;
|
|
735
766
|
const GITLAB_ALLOWED_PROJECT_IDS = process.env.GITLAB_ALLOWED_PROJECT_IDS?.split(',').map(id => id.trim()).filter(Boolean) || [];
|
|
767
|
+
const GITLAB_COMMIT_FILES_PER_PAGE = process.env.GITLAB_COMMIT_FILES_PER_PAGE ? parseInt(process.env.GITLAB_COMMIT_FILES_PER_PAGE) : 20;
|
|
736
768
|
if (!GITLAB_PERSONAL_ACCESS_TOKEN) {
|
|
737
769
|
logger.error("GITLAB_PERSONAL_ACCESS_TOKEN environment variable is not set");
|
|
738
770
|
process.exit(1);
|
|
@@ -2592,6 +2624,70 @@ async function cancelPipeline(projectId, pipelineId) {
|
|
|
2592
2624
|
const data = await response.json();
|
|
2593
2625
|
return GitLabPipelineSchema.parse(data);
|
|
2594
2626
|
}
|
|
2627
|
+
/**
|
|
2628
|
+
* Run a manual job
|
|
2629
|
+
*
|
|
2630
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
2631
|
+
* @param {number} jobId - The ID of the job to run
|
|
2632
|
+
* @param {Object} variables - Optional job variables
|
|
2633
|
+
* @returns {Promise<GitLabPipelineJob>} The run job
|
|
2634
|
+
*/
|
|
2635
|
+
async function playPipelineJob(projectId, jobId, variables) {
|
|
2636
|
+
projectId = decodeURIComponent(projectId);
|
|
2637
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/jobs/${jobId}/play`);
|
|
2638
|
+
const body = {};
|
|
2639
|
+
if (variables && variables.length > 0) {
|
|
2640
|
+
body.job_variables_attributes = variables;
|
|
2641
|
+
}
|
|
2642
|
+
const response = await fetch(url.toString(), {
|
|
2643
|
+
...DEFAULT_FETCH_CONFIG,
|
|
2644
|
+
method: "POST",
|
|
2645
|
+
body: Object.keys(body).length > 0 ? JSON.stringify(body) : undefined,
|
|
2646
|
+
});
|
|
2647
|
+
await handleGitLabError(response);
|
|
2648
|
+
const data = await response.json();
|
|
2649
|
+
return GitLabPipelineJobSchema.parse(data);
|
|
2650
|
+
}
|
|
2651
|
+
/**
|
|
2652
|
+
* Retry a job
|
|
2653
|
+
*
|
|
2654
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
2655
|
+
* @param {number} jobId - The ID of the job to retry
|
|
2656
|
+
* @returns {Promise<GitLabPipelineJob>} The retried job
|
|
2657
|
+
*/
|
|
2658
|
+
async function retryPipelineJob(projectId, jobId) {
|
|
2659
|
+
projectId = decodeURIComponent(projectId);
|
|
2660
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/jobs/${jobId}/retry`);
|
|
2661
|
+
const response = await fetch(url.toString(), {
|
|
2662
|
+
...DEFAULT_FETCH_CONFIG,
|
|
2663
|
+
method: "POST",
|
|
2664
|
+
});
|
|
2665
|
+
await handleGitLabError(response);
|
|
2666
|
+
const data = await response.json();
|
|
2667
|
+
return GitLabPipelineJobSchema.parse(data);
|
|
2668
|
+
}
|
|
2669
|
+
/**
|
|
2670
|
+
* Cancel a job
|
|
2671
|
+
*
|
|
2672
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
2673
|
+
* @param {number} jobId - The ID of the job to cancel
|
|
2674
|
+
* @param {boolean} force - Force cancellation of the job
|
|
2675
|
+
* @returns {Promise<GitLabPipelineJob>} The canceled job
|
|
2676
|
+
*/
|
|
2677
|
+
async function cancelPipelineJob(projectId, jobId, force) {
|
|
2678
|
+
projectId = decodeURIComponent(projectId);
|
|
2679
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/jobs/${jobId}/cancel`);
|
|
2680
|
+
if (force !== undefined) {
|
|
2681
|
+
url.searchParams.append('force', force.toString());
|
|
2682
|
+
}
|
|
2683
|
+
const response = await fetch(url.toString(), {
|
|
2684
|
+
...DEFAULT_FETCH_CONFIG,
|
|
2685
|
+
method: "POST",
|
|
2686
|
+
});
|
|
2687
|
+
await handleGitLabError(response);
|
|
2688
|
+
const data = await response.json();
|
|
2689
|
+
return GitLabPipelineJobSchema.parse(data);
|
|
2690
|
+
}
|
|
2595
2691
|
/**
|
|
2596
2692
|
* Get the repository tree for a project
|
|
2597
2693
|
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
@@ -2918,17 +3014,35 @@ async function getCommit(projectId, sha, stats) {
|
|
|
2918
3014
|
*
|
|
2919
3015
|
* @param {string} projectId - Project ID or URL-encoded path
|
|
2920
3016
|
* @param {string} sha - The commit hash or name of a repository branch or tag
|
|
3017
|
+
* @param {boolean} [full_diff] - Whether to return the full diff or only first page
|
|
2921
3018
|
* @returns {Promise<GitLabMergeRequestDiff[]>} The commit diffs
|
|
2922
3019
|
*/
|
|
2923
|
-
async function getCommitDiff(projectId, sha) {
|
|
3020
|
+
async function getCommitDiff(projectId, sha, full_diff) {
|
|
2924
3021
|
projectId = decodeURIComponent(projectId);
|
|
2925
|
-
const
|
|
2926
|
-
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
|
|
3022
|
+
const baseUrl = `${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/repository/commits/${encodeURIComponent(sha)}/diff`;
|
|
3023
|
+
let allDiffs = [];
|
|
3024
|
+
let page = 1;
|
|
3025
|
+
while (true) {
|
|
3026
|
+
const url = new URL(baseUrl);
|
|
3027
|
+
if (full_diff) {
|
|
3028
|
+
url.searchParams.append("page", page.toString());
|
|
3029
|
+
}
|
|
3030
|
+
const response = await fetch(url.toString(), {
|
|
3031
|
+
...DEFAULT_FETCH_CONFIG,
|
|
3032
|
+
});
|
|
3033
|
+
await handleGitLabError(response);
|
|
3034
|
+
const data = await response.json();
|
|
3035
|
+
const diffs = z.array(GitLabDiffSchema).parse(data);
|
|
3036
|
+
allDiffs.push(...diffs);
|
|
3037
|
+
if (!full_diff) {
|
|
3038
|
+
break;
|
|
3039
|
+
}
|
|
3040
|
+
if (diffs.length < GITLAB_COMMIT_FILES_PER_PAGE) {
|
|
3041
|
+
break;
|
|
3042
|
+
}
|
|
3043
|
+
page++;
|
|
3044
|
+
}
|
|
3045
|
+
return allDiffs;
|
|
2932
3046
|
}
|
|
2933
3047
|
/**
|
|
2934
3048
|
* Get the current authenticated user
|
|
@@ -3020,8 +3134,8 @@ async function listGroupIterations(groupId, options = {}) {
|
|
|
3020
3134
|
url.searchParams.append("state", options.state);
|
|
3021
3135
|
if (options.search)
|
|
3022
3136
|
url.searchParams.append("search", options.search);
|
|
3023
|
-
if (options.
|
|
3024
|
-
url.searchParams.append("in", options.
|
|
3137
|
+
if (options.search_in)
|
|
3138
|
+
url.searchParams.append("in", options.search_in.join(","));
|
|
3025
3139
|
if (options.include_ancestors !== undefined)
|
|
3026
3140
|
url.searchParams.append("include_ancestors", options.include_ancestors.toString());
|
|
3027
3141
|
if (options.include_descendants !== undefined)
|
|
@@ -3099,6 +3213,54 @@ async function downloadAttachment(projectId, secret, filename, localPath) {
|
|
|
3099
3213
|
fs.writeFileSync(savePath, Buffer.from(buffer));
|
|
3100
3214
|
return savePath;
|
|
3101
3215
|
}
|
|
3216
|
+
/**
|
|
3217
|
+
* List all events for the currently authenticated user
|
|
3218
|
+
* @param {Object} options - Options for listing events
|
|
3219
|
+
* @returns {Promise<GitLabEvent[]>} List of events
|
|
3220
|
+
*/
|
|
3221
|
+
async function listEvents(options = {}) {
|
|
3222
|
+
const url = new URL(`${GITLAB_API_URL}/events`);
|
|
3223
|
+
// Add all query parameters
|
|
3224
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
3225
|
+
if (value !== undefined) {
|
|
3226
|
+
url.searchParams.append(key, value.toString());
|
|
3227
|
+
}
|
|
3228
|
+
});
|
|
3229
|
+
const response = await fetch(url.toString(), {
|
|
3230
|
+
method: "GET",
|
|
3231
|
+
headers: DEFAULT_HEADERS,
|
|
3232
|
+
});
|
|
3233
|
+
if (!response.ok) {
|
|
3234
|
+
await handleGitLabError(response);
|
|
3235
|
+
}
|
|
3236
|
+
const data = await response.json();
|
|
3237
|
+
return GitLabEventSchema.array().parse(data);
|
|
3238
|
+
}
|
|
3239
|
+
/**
|
|
3240
|
+
* List all visible events for a specified project
|
|
3241
|
+
* @param {string} projectId - Project ID or URL-encoded path
|
|
3242
|
+
* @param {Object} options - Options for getting project events
|
|
3243
|
+
* @returns {Promise<GitLabEvent[]>} List of project events
|
|
3244
|
+
*/
|
|
3245
|
+
async function getProjectEvents(projectId, options = {}) {
|
|
3246
|
+
const effectiveProjectId = getEffectiveProjectId(projectId);
|
|
3247
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(effectiveProjectId)}/events`);
|
|
3248
|
+
// Add all query parameters
|
|
3249
|
+
Object.entries(options).forEach(([key, value]) => {
|
|
3250
|
+
if (value !== undefined) {
|
|
3251
|
+
url.searchParams.append(key, value.toString());
|
|
3252
|
+
}
|
|
3253
|
+
});
|
|
3254
|
+
const response = await fetch(url.toString(), {
|
|
3255
|
+
method: "GET",
|
|
3256
|
+
headers: DEFAULT_HEADERS,
|
|
3257
|
+
});
|
|
3258
|
+
if (!response.ok) {
|
|
3259
|
+
await handleGitLabError(response);
|
|
3260
|
+
}
|
|
3261
|
+
const data = await response.json();
|
|
3262
|
+
return GitLabEventSchema.array().parse(data);
|
|
3263
|
+
}
|
|
3102
3264
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
3103
3265
|
// Apply read-only filter first
|
|
3104
3266
|
const tools0 = GITLAB_READ_ONLY_MODE
|
|
@@ -3784,6 +3946,42 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3784
3946
|
],
|
|
3785
3947
|
};
|
|
3786
3948
|
}
|
|
3949
|
+
case "play_pipeline_job": {
|
|
3950
|
+
const { project_id, job_id, job_variables_attributes } = PlayPipelineJobSchema.parse(request.params.arguments);
|
|
3951
|
+
const job = await playPipelineJob(project_id, job_id, job_variables_attributes);
|
|
3952
|
+
return {
|
|
3953
|
+
content: [
|
|
3954
|
+
{
|
|
3955
|
+
type: "text",
|
|
3956
|
+
text: `Ran job #${job.id} (${job.name}). Status: ${job.status}\nWeb URL: ${job.web_url}`,
|
|
3957
|
+
},
|
|
3958
|
+
],
|
|
3959
|
+
};
|
|
3960
|
+
}
|
|
3961
|
+
case "retry_pipeline_job": {
|
|
3962
|
+
const { project_id, job_id } = RetryPipelineJobSchema.parse(request.params.arguments);
|
|
3963
|
+
const job = await retryPipelineJob(project_id, job_id);
|
|
3964
|
+
return {
|
|
3965
|
+
content: [
|
|
3966
|
+
{
|
|
3967
|
+
type: "text",
|
|
3968
|
+
text: `Retried job #${job.id} (${job.name}). Status: ${job.status}\nWeb URL: ${job.web_url}`,
|
|
3969
|
+
},
|
|
3970
|
+
],
|
|
3971
|
+
};
|
|
3972
|
+
}
|
|
3973
|
+
case "cancel_pipeline_job": {
|
|
3974
|
+
const { project_id, job_id, force } = CancelPipelineJobSchema.parse(request.params.arguments);
|
|
3975
|
+
const job = await cancelPipelineJob(project_id, job_id, force);
|
|
3976
|
+
return {
|
|
3977
|
+
content: [
|
|
3978
|
+
{
|
|
3979
|
+
type: "text",
|
|
3980
|
+
text: `Canceled job #${job.id} (${job.name}). Status: ${job.status}\nWeb URL: ${job.web_url}`,
|
|
3981
|
+
},
|
|
3982
|
+
],
|
|
3983
|
+
};
|
|
3984
|
+
}
|
|
3787
3985
|
case "list_merge_requests": {
|
|
3788
3986
|
const args = ListMergeRequestsSchema.parse(request.params.arguments);
|
|
3789
3987
|
const mergeRequests = await listMergeRequests(args.project_id, args);
|
|
@@ -3918,7 +4116,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3918
4116
|
}
|
|
3919
4117
|
case "get_commit_diff": {
|
|
3920
4118
|
const args = GetCommitDiffSchema.parse(request.params.arguments);
|
|
3921
|
-
const diff = await getCommitDiff(args.project_id, args.sha);
|
|
4119
|
+
const diff = await getCommitDiff(args.project_id, args.sha, args.full_diff);
|
|
3922
4120
|
return {
|
|
3923
4121
|
content: [{ type: "text", text: JSON.stringify(diff, null, 2) }],
|
|
3924
4122
|
};
|
|
@@ -3944,6 +4142,21 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3944
4142
|
content: [{ type: "text", text: JSON.stringify({ success: true, file_path: filePath }, null, 2) }],
|
|
3945
4143
|
};
|
|
3946
4144
|
}
|
|
4145
|
+
case "list_events": {
|
|
4146
|
+
const args = ListEventsSchema.parse(request.params.arguments);
|
|
4147
|
+
const events = await listEvents(args);
|
|
4148
|
+
return {
|
|
4149
|
+
content: [{ type: "text", text: JSON.stringify(events, null, 2) }],
|
|
4150
|
+
};
|
|
4151
|
+
}
|
|
4152
|
+
case "get_project_events": {
|
|
4153
|
+
const args = GetProjectEventsSchema.parse(request.params.arguments);
|
|
4154
|
+
const { project_id, ...options } = args;
|
|
4155
|
+
const events = await getProjectEvents(project_id, options);
|
|
4156
|
+
return {
|
|
4157
|
+
content: [{ type: "text", text: JSON.stringify(events, null, 2) }],
|
|
4158
|
+
};
|
|
4159
|
+
}
|
|
3947
4160
|
default:
|
|
3948
4161
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
3949
4162
|
}
|
|
@@ -4076,6 +4289,29 @@ async function startStreamableHTTPServer() {
|
|
|
4076
4289
|
});
|
|
4077
4290
|
}
|
|
4078
4291
|
});
|
|
4292
|
+
// to delete a mcp server session explicitly
|
|
4293
|
+
app.delete("/mcp", async (req, res) => {
|
|
4294
|
+
const sessionId = req.headers["mcp-session-id"];
|
|
4295
|
+
if (!sessionId) {
|
|
4296
|
+
res.status(400).json({ error: "mcp-session-id header is required" });
|
|
4297
|
+
return;
|
|
4298
|
+
}
|
|
4299
|
+
const transport = streamableTransports[sessionId];
|
|
4300
|
+
if (transport) {
|
|
4301
|
+
try {
|
|
4302
|
+
await transport.close();
|
|
4303
|
+
logger.info(`Explicitly closed session via DELETE request: ${sessionId}`);
|
|
4304
|
+
res.status(204).send();
|
|
4305
|
+
}
|
|
4306
|
+
catch (error) {
|
|
4307
|
+
logger.error(`Error closing session ${sessionId}:`, error);
|
|
4308
|
+
res.status(500).json({ error: "Failed to close session" });
|
|
4309
|
+
}
|
|
4310
|
+
}
|
|
4311
|
+
else {
|
|
4312
|
+
res.status(404).json({ error: "Session not found" });
|
|
4313
|
+
}
|
|
4314
|
+
});
|
|
4079
4315
|
// Health check endpoint
|
|
4080
4316
|
app.get("/health", (_, res) => {
|
|
4081
4317
|
res.status(200).json({
|