@zereight/mcp-gitlab 2.0.8 → 2.0.9
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 +22 -0
- package/build/index.js +202 -14
- package/build/schemas.js +37 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,6 +67,28 @@ When using with the Claude App, you need to set up your API key and URLs directl
|
|
|
67
67
|
}
|
|
68
68
|
```
|
|
69
69
|
|
|
70
|
+
#### Strands Agents SDK (MCP Tools)
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
env_vars = {
|
|
74
|
+
"GITLAB_PERSONAL_ACCESS_TOKEN": gitlab_access_token,
|
|
75
|
+
"GITLAB_API_URL": gitlab_api_url,
|
|
76
|
+
"USE_GITLAB_WIKI": use_gitlab_wiki
|
|
77
|
+
# ......the rest of the optional parameters
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
stdio_gitlab_mcp_client = MCPClient(
|
|
81
|
+
lambda: stdio_client(
|
|
82
|
+
StdioServerParameters(
|
|
83
|
+
command="npx",
|
|
84
|
+
args=["-y", "@zereight/mcp-gitlab"],
|
|
85
|
+
env=env_vars,
|
|
86
|
+
)
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
|
|
70
92
|
#### Docker
|
|
71
93
|
|
|
72
94
|
- stdio mcp.json
|
package/build/index.js
CHANGED
|
@@ -22,7 +22,7 @@ import { Agent } from "http";
|
|
|
22
22
|
import { Agent as HttpsAgent } from "https";
|
|
23
23
|
import { URL } from "url";
|
|
24
24
|
import { BulkPublishDraftNotesSchema, CancelPipelineJobSchema, CancelPipelineSchema, CreateBranchSchema, CreateDraftNoteSchema, CreateIssueLinkSchema, CreateIssueNoteSchema, CreateIssueSchema, CreateLabelSchema, // Added
|
|
25
|
-
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
|
+
CreateMergeRequestNoteSchema, CreateMergeRequestDiscussionNoteSchema, CreateMergeRequestSchema, CreateMergeRequestThreadSchema, CreateNoteSchema, CreateOrUpdateFileSchema, CreatePipelineSchema, CreateProjectMilestoneSchema, CreateRepositorySchema, CreateWikiPageSchema, DeleteDraftNoteSchema, DeleteIssueLinkSchema, DeleteIssueSchema, DeleteLabelSchema, DeleteProjectMilestoneSchema, DeleteWikiPageSchema, DeleteMergeRequestNoteSchema, EditProjectMilestoneSchema, ForkRepositorySchema, GetBranchDiffsSchema, GetCommitDiffSchema, GetCommitSchema, GetDraftNoteSchema, GetFileContentsSchema, GetIssueLinkSchema, GetIssueSchema, GetLabelSchema, GetMergeRequestDiffsSchema, GetMergeRequestSchema, GetMilestoneBurndownEventsSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, GetNamespaceSchema,
|
|
26
26
|
// pipeline job schemas
|
|
27
27
|
GetPipelineJobOutputSchema, GetPipelineSchema, GetProjectMilestoneSchema, GetProjectSchema, GetRepositoryTreeSchema, GetUsersSchema, GetWikiPageSchema, GitLabCommitSchema, GitLabCompareResultSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabDiffSchema,
|
|
28
28
|
// Discussion Schemas
|
|
@@ -30,7 +30,7 @@ GitLabDiscussionNoteSchema, // Added
|
|
|
30
30
|
GitLabDiscussionSchema,
|
|
31
31
|
// Draft Notes Schemas
|
|
32
32
|
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
|
|
33
|
-
ListMergeRequestDiscussionsSchema, ListMergeRequestsSchema, ListNamespacesSchema, ListPipelineJobsSchema, ListPipelinesSchema, ListPipelineTriggerJobsSchema, ListProjectMembersSchema, ListProjectMilestonesSchema, ListProjectsSchema, ListWikiPagesSchema, MarkdownUploadSchema, DownloadAttachmentSchema, MergeMergeRequestSchema, MyIssuesSchema, PaginatedDiscussionsResponseSchema, PromoteProjectMilestoneSchema, PublishDraftNoteSchema, PlayPipelineJobSchema, PushFilesSchema, RetryPipelineJobSchema, RetryPipelineSchema, SearchRepositoriesSchema, UpdateDraftNoteSchema, UpdateIssueNoteSchema, UpdateIssueSchema, UpdateLabelSchema, UpdateMergeRequestNoteSchema, UpdateMergeRequestSchema, UpdateWikiPageSchema, VerifyNamespaceSchema, GitLabEventSchema, ListEventsSchema, GetProjectEventsSchema, ExecuteGraphQLSchema, GitLabReleaseSchema, ListReleasesSchema, GetReleaseSchema, CreateReleaseSchema, UpdateReleaseSchema, DeleteReleaseSchema, CreateReleaseEvidenceSchema, DownloadReleaseAssetSchema, } from "./schemas.js";
|
|
33
|
+
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, UpdateMergeRequestDiscussionNoteSchema, UpdateMergeRequestSchema, UpdateWikiPageSchema, VerifyNamespaceSchema, GitLabEventSchema, ListEventsSchema, GetProjectEventsSchema, ExecuteGraphQLSchema, GitLabReleaseSchema, ListReleasesSchema, GetReleaseSchema, CreateReleaseSchema, UpdateReleaseSchema, DeleteReleaseSchema, CreateReleaseEvidenceSchema, DownloadReleaseAssetSchema, GetMergeRequestNotesSchema, GetMergeRequestNoteSchema, DeleteMergeRequestDiscussionNoteSchema, ResolveMergeRequestThreadSchema } from "./schemas.js";
|
|
34
34
|
import { randomUUID } from "crypto";
|
|
35
35
|
import { pino } from "pino";
|
|
36
36
|
const logger = pino({
|
|
@@ -395,21 +395,56 @@ const allTools = [
|
|
|
395
395
|
description: "Create a new thread on a merge request",
|
|
396
396
|
inputSchema: toJSONSchema(CreateMergeRequestThreadSchema),
|
|
397
397
|
},
|
|
398
|
+
{
|
|
399
|
+
name: 'resolve_merge_request_thread',
|
|
400
|
+
description: "Resolve a thread on a merge request",
|
|
401
|
+
inputSchema: toJSONSchema(ResolveMergeRequestThreadSchema),
|
|
402
|
+
},
|
|
398
403
|
{
|
|
399
404
|
name: "mr_discussions",
|
|
400
405
|
description: "List discussion items for a merge request",
|
|
401
406
|
inputSchema: toJSONSchema(ListMergeRequestDiscussionsSchema),
|
|
402
407
|
},
|
|
403
408
|
{
|
|
404
|
-
name: "
|
|
405
|
-
description: "
|
|
406
|
-
inputSchema: toJSONSchema(
|
|
409
|
+
name: "delete_merge_request_discussion_note",
|
|
410
|
+
description: "Delete a discussion note on a merge request",
|
|
411
|
+
inputSchema: toJSONSchema(DeleteMergeRequestDiscussionNoteSchema),
|
|
412
|
+
},
|
|
413
|
+
{
|
|
414
|
+
name: "update_merge_request_discussion_note",
|
|
415
|
+
description: "Update a discussion note on a merge request",
|
|
416
|
+
inputSchema: toJSONSchema(UpdateMergeRequestDiscussionNoteSchema),
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
name: "create_merge_request_discussion_note",
|
|
420
|
+
description: "Add a new discussion note to an existing merge request thread",
|
|
421
|
+
inputSchema: toJSONSchema(CreateMergeRequestDiscussionNoteSchema),
|
|
407
422
|
},
|
|
408
423
|
{
|
|
409
424
|
name: "create_merge_request_note",
|
|
410
|
-
description: "Add a new note to
|
|
425
|
+
description: "Add a new note to a merge request",
|
|
411
426
|
inputSchema: toJSONSchema(CreateMergeRequestNoteSchema),
|
|
412
427
|
},
|
|
428
|
+
{
|
|
429
|
+
name: "delete_merge_request_note",
|
|
430
|
+
description: "Delete an existing merge request note",
|
|
431
|
+
inputSchema: toJSONSchema(DeleteMergeRequestNoteSchema),
|
|
432
|
+
},
|
|
433
|
+
{
|
|
434
|
+
name: "get_merge_request_note",
|
|
435
|
+
description: "Get a specific note for a merge request",
|
|
436
|
+
inputSchema: toJSONSchema(GetMergeRequestNoteSchema),
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
name: 'get_merge_request_notes',
|
|
440
|
+
description: "List notes for a merge request",
|
|
441
|
+
inputSchema: toJSONSchema(GetMergeRequestNotesSchema),
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
name: "update_merge_request_note",
|
|
445
|
+
description: "Modify an existing merge request note",
|
|
446
|
+
inputSchema: toJSONSchema(UpdateMergeRequestNoteSchema),
|
|
447
|
+
},
|
|
413
448
|
{
|
|
414
449
|
name: "get_draft_note",
|
|
415
450
|
description: "Get a single draft note from a merge request",
|
|
@@ -1429,6 +1464,18 @@ async function listMergeRequestDiscussions(projectId, mergeRequestIid, options =
|
|
|
1429
1464
|
async function listIssueDiscussions(projectId, issueIid, options = {}) {
|
|
1430
1465
|
return listDiscussions(projectId, "issues", issueIid, options);
|
|
1431
1466
|
}
|
|
1467
|
+
async function deleteMergeRequestDiscussionNote(projectId, mergeRequestIid, discussionId, noteId) {
|
|
1468
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
1469
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/discussions/${discussionId}/notes/${noteId}`);
|
|
1470
|
+
const response = await fetch(url.toString(), {
|
|
1471
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1472
|
+
method: "DELETE",
|
|
1473
|
+
});
|
|
1474
|
+
if (!response.ok) {
|
|
1475
|
+
const errorText = await response.text();
|
|
1476
|
+
throw new Error(`GitLab API error: ${response.status} ${response.statusText}\n${errorText}`);
|
|
1477
|
+
}
|
|
1478
|
+
}
|
|
1432
1479
|
/**
|
|
1433
1480
|
* Modify an existing merge request thread note
|
|
1434
1481
|
* 병합 요청 토론 노트 수정
|
|
@@ -1441,7 +1488,7 @@ async function listIssueDiscussions(projectId, issueIid, options = {}) {
|
|
|
1441
1488
|
* @param {boolean} [resolved] - Resolve/unresolve state
|
|
1442
1489
|
* @returns {Promise<GitLabDiscussionNote>} The updated note
|
|
1443
1490
|
*/
|
|
1444
|
-
async function
|
|
1491
|
+
async function updateMergeRequestDiscussionNote(projectId, mergeRequestIid, discussionId, noteId, body, resolved) {
|
|
1445
1492
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
1446
1493
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/discussions/${discussionId}/notes/${noteId}`);
|
|
1447
1494
|
// Only one of body or resolved can be sent according to GitLab API
|
|
@@ -1509,7 +1556,7 @@ async function createIssueNote(projectId, issueIid, discussionId, body, createdA
|
|
|
1509
1556
|
return GitLabDiscussionNoteSchema.parse(data);
|
|
1510
1557
|
}
|
|
1511
1558
|
/**
|
|
1512
|
-
* Add a new note to an existing merge request thread
|
|
1559
|
+
* Add a new discussion note to an existing merge request thread
|
|
1513
1560
|
* 기존 병합 요청 스레드에 새 노트 추가
|
|
1514
1561
|
*
|
|
1515
1562
|
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
@@ -1519,7 +1566,7 @@ async function createIssueNote(projectId, issueIid, discussionId, body, createdA
|
|
|
1519
1566
|
* @param {string} [createdAt] - The creation date of the note (ISO 8601 format)
|
|
1520
1567
|
* @returns {Promise<GitLabDiscussionNote>} The created note
|
|
1521
1568
|
*/
|
|
1522
|
-
async function
|
|
1569
|
+
async function createMergeRequestDiscussionNote(projectId, mergeRequestIid, discussionId, body, createdAt) {
|
|
1523
1570
|
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
1524
1571
|
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/discussions/${discussionId}/notes`);
|
|
1525
1572
|
const payload = { body };
|
|
@@ -1535,6 +1582,81 @@ async function createMergeRequestNote(projectId, mergeRequestIid, discussionId,
|
|
|
1535
1582
|
const data = await response.json();
|
|
1536
1583
|
return GitLabDiscussionNoteSchema.parse(data);
|
|
1537
1584
|
}
|
|
1585
|
+
async function createMergeRequestNote(projectId, mergeRequestIid, body) {
|
|
1586
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
1587
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/notes`);
|
|
1588
|
+
const payload = {
|
|
1589
|
+
id: projectId,
|
|
1590
|
+
merge_request_iid: mergeRequestIid,
|
|
1591
|
+
body,
|
|
1592
|
+
};
|
|
1593
|
+
const response = await fetch(url.toString(), {
|
|
1594
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1595
|
+
method: "POST",
|
|
1596
|
+
body: JSON.stringify(payload),
|
|
1597
|
+
});
|
|
1598
|
+
await handleGitLabError(response);
|
|
1599
|
+
const data = await response.json();
|
|
1600
|
+
return GitLabDiscussionNoteSchema.parse(data);
|
|
1601
|
+
}
|
|
1602
|
+
async function deleteMergeRequestNote(projectId, mergeRequestIid, noteId) {
|
|
1603
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
1604
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/notes/${noteId}`);
|
|
1605
|
+
const response = await fetch(url.toString(), {
|
|
1606
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1607
|
+
method: "DELETE",
|
|
1608
|
+
});
|
|
1609
|
+
if (!response.ok) {
|
|
1610
|
+
const errorText = await response.text();
|
|
1611
|
+
throw new Error(`GitLab API error: ${response.status} ${response.statusText}\n${errorText}`);
|
|
1612
|
+
}
|
|
1613
|
+
}
|
|
1614
|
+
async function getMergeRequestNote(projectId, mergeRequestIid, noteId) {
|
|
1615
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
1616
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/notes/${noteId}`);
|
|
1617
|
+
const response = await fetch(url.toString(), {
|
|
1618
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1619
|
+
method: "GET",
|
|
1620
|
+
});
|
|
1621
|
+
await handleGitLabError(response);
|
|
1622
|
+
const data = await response.json();
|
|
1623
|
+
return GitLabDiscussionNoteSchema.parse(data);
|
|
1624
|
+
}
|
|
1625
|
+
async function getMergeRequestNotes(projectId, mergeRequestIid, sort, order_by) {
|
|
1626
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
1627
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/notes`);
|
|
1628
|
+
if (sort) {
|
|
1629
|
+
url.searchParams.append("sort", sort);
|
|
1630
|
+
}
|
|
1631
|
+
if (order_by) {
|
|
1632
|
+
url.searchParams.append("order_by", order_by);
|
|
1633
|
+
}
|
|
1634
|
+
const response = await fetch(url.toString(), {
|
|
1635
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1636
|
+
method: "GET",
|
|
1637
|
+
});
|
|
1638
|
+
await handleGitLabError(response);
|
|
1639
|
+
const data = await response.json();
|
|
1640
|
+
return z.array(GitLabDiscussionNoteSchema).parse(data);
|
|
1641
|
+
}
|
|
1642
|
+
async function updateMergeRequestNote(projectId, mergeRequestIid, noteId, body) {
|
|
1643
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
1644
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/notes/${noteId}`);
|
|
1645
|
+
const payload = {
|
|
1646
|
+
id: projectId,
|
|
1647
|
+
merge_request_iid: mergeRequestIid,
|
|
1648
|
+
note_id: noteId,
|
|
1649
|
+
body,
|
|
1650
|
+
};
|
|
1651
|
+
const response = await fetch(url.toString(), {
|
|
1652
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1653
|
+
method: "PUT",
|
|
1654
|
+
body: JSON.stringify(payload),
|
|
1655
|
+
});
|
|
1656
|
+
await handleGitLabError(response);
|
|
1657
|
+
const data = await response.json();
|
|
1658
|
+
return GitLabDiscussionNoteSchema.parse(data);
|
|
1659
|
+
}
|
|
1538
1660
|
/**
|
|
1539
1661
|
* Create or update a file in a GitLab project
|
|
1540
1662
|
* 파일 생성 또는 업데이트
|
|
@@ -2145,6 +2267,21 @@ async function bulkPublishDraftNotes(projectId, mergeRequestIid) {
|
|
|
2145
2267
|
return [];
|
|
2146
2268
|
}
|
|
2147
2269
|
}
|
|
2270
|
+
async function resolveMergeRequestThread(projectId, mergeRequestIid, discussionId, resolved) {
|
|
2271
|
+
projectId = decodeURIComponent(projectId);
|
|
2272
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(getEffectiveProjectId(projectId))}/merge_requests/${mergeRequestIid}/discussions/${discussionId}`);
|
|
2273
|
+
if (resolved !== undefined) {
|
|
2274
|
+
url.searchParams.append("resolved", resolved ? "true" : "false");
|
|
2275
|
+
}
|
|
2276
|
+
const response = await fetch(url.toString(), {
|
|
2277
|
+
...DEFAULT_FETCH_CONFIG,
|
|
2278
|
+
method: "PUT",
|
|
2279
|
+
});
|
|
2280
|
+
if (!response.ok) {
|
|
2281
|
+
const errorText = await response.text();
|
|
2282
|
+
throw new Error(`GitLab API error: ${response.status} ${response.statusText}\n${errorText}`);
|
|
2283
|
+
}
|
|
2284
|
+
}
|
|
2148
2285
|
/**
|
|
2149
2286
|
* Create a new thread on a merge request
|
|
2150
2287
|
* 📦 새로운 함수: createMergeRequestThread - 병합 요청에 새로운 스레드(토론)를 생성하는 함수
|
|
@@ -3762,18 +3899,61 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3762
3899
|
content: [{ type: "text", text: JSON.stringify(mergeRequest, null, 2) }],
|
|
3763
3900
|
};
|
|
3764
3901
|
}
|
|
3765
|
-
case "
|
|
3766
|
-
const args =
|
|
3767
|
-
const
|
|
3902
|
+
case "delete_merge_request_discussion_note": {
|
|
3903
|
+
const args = DeleteMergeRequestDiscussionNoteSchema.parse(request.params.arguments);
|
|
3904
|
+
const { project_id, merge_request_iid, discussion_id, note_id } = args;
|
|
3905
|
+
await deleteMergeRequestDiscussionNote(project_id, merge_request_iid, discussion_id, note_id);
|
|
3906
|
+
return {
|
|
3907
|
+
content: [{ type: "text", text: "Merge request discussion note deleted successfully" }],
|
|
3908
|
+
};
|
|
3909
|
+
}
|
|
3910
|
+
case "update_merge_request_discussion_note": {
|
|
3911
|
+
const args = UpdateMergeRequestDiscussionNoteSchema.parse(request.params.arguments);
|
|
3912
|
+
const note = await updateMergeRequestDiscussionNote(args.project_id, args.merge_request_iid, args.discussion_id, args.note_id, args.body, // Now optional
|
|
3768
3913
|
args.resolved // Now one of body or resolved must be provided, not both
|
|
3769
3914
|
);
|
|
3770
3915
|
return {
|
|
3771
3916
|
content: [{ type: "text", text: JSON.stringify(note, null, 2) }],
|
|
3772
3917
|
};
|
|
3773
3918
|
}
|
|
3919
|
+
case "create_merge_request_discussion_note": {
|
|
3920
|
+
const args = CreateMergeRequestDiscussionNoteSchema.parse(request.params.arguments);
|
|
3921
|
+
const note = await createMergeRequestDiscussionNote(args.project_id, args.merge_request_iid, args.discussion_id, args.body, args.created_at);
|
|
3922
|
+
return {
|
|
3923
|
+
content: [{ type: "text", text: JSON.stringify(note, null, 2) }],
|
|
3924
|
+
};
|
|
3925
|
+
}
|
|
3774
3926
|
case "create_merge_request_note": {
|
|
3775
3927
|
const args = CreateMergeRequestNoteSchema.parse(request.params.arguments);
|
|
3776
|
-
const note = await createMergeRequestNote(args.project_id, args.merge_request_iid, args.
|
|
3928
|
+
const note = await createMergeRequestNote(args.project_id, args.merge_request_iid, args.body);
|
|
3929
|
+
return {
|
|
3930
|
+
content: [{ type: "text", text: JSON.stringify(note, null, 2) }],
|
|
3931
|
+
};
|
|
3932
|
+
}
|
|
3933
|
+
case "delete_merge_request_note": {
|
|
3934
|
+
const args = DeleteMergeRequestNoteSchema.parse(request.params.arguments);
|
|
3935
|
+
await deleteMergeRequestNote(args.project_id, args.merge_request_iid, args.note_id);
|
|
3936
|
+
return {
|
|
3937
|
+
content: [{ type: "text", text: "Merge request note deleted successfully" }],
|
|
3938
|
+
};
|
|
3939
|
+
}
|
|
3940
|
+
case 'get_merge_request_note': {
|
|
3941
|
+
const args = GetMergeRequestNoteSchema.parse(request.params.arguments);
|
|
3942
|
+
const note = await getMergeRequestNote(args.project_id, args.merge_request_iid, args.note_id);
|
|
3943
|
+
return {
|
|
3944
|
+
content: [{ type: "text", text: JSON.stringify(note, null, 2) }],
|
|
3945
|
+
};
|
|
3946
|
+
}
|
|
3947
|
+
case 'get_merge_request_notes': {
|
|
3948
|
+
const args = GetMergeRequestNotesSchema.parse(request.params.arguments);
|
|
3949
|
+
const notes = await getMergeRequestNotes(args.project_id, args.merge_request_iid, args.sort, args.order_by);
|
|
3950
|
+
return {
|
|
3951
|
+
content: [{ type: "text", text: JSON.stringify(notes, null, 2) }],
|
|
3952
|
+
};
|
|
3953
|
+
}
|
|
3954
|
+
case 'update_merge_request_note': {
|
|
3955
|
+
const args = UpdateMergeRequestNoteSchema.parse(request.params.arguments);
|
|
3956
|
+
const note = await updateMergeRequestNote(args.project_id, args.merge_request_iid, args.note_id, args.body);
|
|
3777
3957
|
return {
|
|
3778
3958
|
content: [{ type: "text", text: JSON.stringify(note, null, 2) }],
|
|
3779
3959
|
};
|
|
@@ -3995,6 +4175,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3995
4175
|
content: [{ type: "text", text: JSON.stringify(thread, null, 2) }],
|
|
3996
4176
|
};
|
|
3997
4177
|
}
|
|
4178
|
+
case "resolve_merge_request_thread": {
|
|
4179
|
+
const args = ResolveMergeRequestThreadSchema.parse(request.params.arguments);
|
|
4180
|
+
const { project_id, merge_request_iid, discussion_id, resolved } = args;
|
|
4181
|
+
await resolveMergeRequestThread(project_id, merge_request_iid, discussion_id, resolved);
|
|
4182
|
+
return {
|
|
4183
|
+
content: [{ type: "text", text: "Thread resolved successfully" }],
|
|
4184
|
+
};
|
|
4185
|
+
}
|
|
3998
4186
|
case "list_issues": {
|
|
3999
4187
|
const args = ListIssuesSchema.parse(request.params.arguments);
|
|
4000
4188
|
const { project_id, ...options } = args;
|
|
@@ -4675,7 +4863,7 @@ async function startStreamableHTTPServer() {
|
|
|
4675
4863
|
// GitLab PAT format: glpat-xxxxx (min 20 chars)
|
|
4676
4864
|
if (token.length < 20)
|
|
4677
4865
|
return false;
|
|
4678
|
-
if (!/^[a-zA-Z0-9_
|
|
4866
|
+
if (!/^[a-zA-Z0-9_\.-]+$/.test(token))
|
|
4679
4867
|
return false;
|
|
4680
4868
|
return true;
|
|
4681
4869
|
};
|
package/build/schemas.js
CHANGED
|
@@ -852,8 +852,38 @@ export const ListIssueDiscussionsSchema = z
|
|
|
852
852
|
export const ListMergeRequestDiscussionsSchema = ProjectParamsSchema.extend({
|
|
853
853
|
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
854
854
|
}).merge(PaginationOptionsSchema);
|
|
855
|
-
|
|
855
|
+
export const GetMergeRequestNotesSchema = ProjectParamsSchema.extend({
|
|
856
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
857
|
+
sort: z.enum(["asc", "desc"]).optional().describe("The sort order of the notes"),
|
|
858
|
+
order_by: z.enum(["created_at", "updated_at"]).optional().describe("The field to sort the notes by"),
|
|
859
|
+
});
|
|
860
|
+
export const GetMergeRequestNoteSchema = ProjectParamsSchema.extend({
|
|
861
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
862
|
+
note_id: z.coerce.string().describe("The ID of a thread note"),
|
|
863
|
+
});
|
|
864
|
+
// Input schema for updating merge request notes
|
|
856
865
|
export const UpdateMergeRequestNoteSchema = ProjectParamsSchema.extend({
|
|
866
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
867
|
+
note_id: z.coerce.string().describe("The ID of a thread note"),
|
|
868
|
+
body: z.string().describe("The content of the note or reply"),
|
|
869
|
+
});
|
|
870
|
+
// Input schema for adding a note to a merge request
|
|
871
|
+
export const CreateMergeRequestNoteSchema = ProjectParamsSchema.extend({
|
|
872
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
873
|
+
body: z.string().describe("The content of the note or reply"),
|
|
874
|
+
});
|
|
875
|
+
// delete a merge request note
|
|
876
|
+
export const DeleteMergeRequestNoteSchema = ProjectParamsSchema.extend({
|
|
877
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
878
|
+
note_id: z.coerce.string().describe("The ID of a thread note"),
|
|
879
|
+
});
|
|
880
|
+
export const DeleteMergeRequestDiscussionNoteSchema = ProjectParamsSchema.extend({
|
|
881
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
882
|
+
discussion_id: z.coerce.string().describe("The ID of a thread"),
|
|
883
|
+
note_id: z.coerce.string().describe("The ID of a thread note"),
|
|
884
|
+
});
|
|
885
|
+
// Input schema for updating a merge request discussion note
|
|
886
|
+
export const UpdateMergeRequestDiscussionNoteSchema = ProjectParamsSchema.extend({
|
|
857
887
|
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
858
888
|
discussion_id: z.coerce.string().describe("The ID of a thread"),
|
|
859
889
|
note_id: z.coerce.string().describe("The ID of a thread note"),
|
|
@@ -867,7 +897,7 @@ export const UpdateMergeRequestNoteSchema = ProjectParamsSchema.extend({
|
|
|
867
897
|
message: "Only one of 'body' or 'resolved' can be provided, not both",
|
|
868
898
|
});
|
|
869
899
|
// Input schema for adding a note to an existing merge request discussion
|
|
870
|
-
export const
|
|
900
|
+
export const CreateMergeRequestDiscussionNoteSchema = ProjectParamsSchema.extend({
|
|
871
901
|
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
872
902
|
discussion_id: z.coerce.string().describe("The ID of a thread"),
|
|
873
903
|
body: z.string().describe("The content of the note or reply"),
|
|
@@ -1504,6 +1534,11 @@ export const CreateMergeRequestThreadSchema = ProjectParamsSchema.extend({
|
|
|
1504
1534
|
position: MergeRequestThreadPositionSchema.optional().describe("Position when creating a diff note"),
|
|
1505
1535
|
created_at: z.string().optional().describe("Date the thread was created at (ISO 8601 format)"),
|
|
1506
1536
|
});
|
|
1537
|
+
export const ResolveMergeRequestThreadSchema = ProjectParamsSchema.extend({
|
|
1538
|
+
merge_request_iid: z.coerce.string().describe("The IID of a merge request"),
|
|
1539
|
+
discussion_id: z.coerce.string().describe("The ID of a thread"),
|
|
1540
|
+
resolved: z.boolean().describe("Whether to resolve the thread"),
|
|
1541
|
+
});
|
|
1507
1542
|
// Milestone related schemas
|
|
1508
1543
|
// Schema for listing project milestones
|
|
1509
1544
|
export const ListProjectMilestonesSchema = ProjectParamsSchema.extend({
|