Skip to content

Commit 3f2b355

Browse files
author
Nicholas Crum
committed
feat: Implement add_merge_request_thread_note function for adding notes to existing MR threads
1 parent 026dd58 commit 3f2b355

File tree

3 files changed

+98
-25
lines changed

3 files changed

+98
-25
lines changed

README.md

Lines changed: 26 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -58,29 +58,30 @@ When using with the Claude App, you need to set up your API key and URLs directl
5858
14. `create_merge_request_thread` - Create a new thread on a merge request
5959
15. `mr_discussions` - List discussion items for a merge request
6060
16. `update_merge_request_note` - Modify an existing merge request thread note
61-
17. `list_issues` - List issues in a GitLab project with filtering options
62-
18. `get_issue` - Get details of a specific issue in a GitLab project
63-
19. `update_issue` - Update an issue in a GitLab project
64-
20. `delete_issue` - Delete an issue from a GitLab project
65-
21. `list_issue_links` - List all issue links for a specific issue
66-
22. `get_issue_link` - Get a specific issue link
67-
23. `create_issue_link` - Create an issue link between two issues
68-
24. `delete_issue_link` - Delete an issue link
69-
25. `list_namespaces` - List all namespaces available to the current user
70-
26. `get_namespace` - Get details of a namespace by ID or path
71-
27. `verify_namespace` - Verify if a namespace path exists
72-
28. `get_project` - Get details of a specific project
73-
29. `list_projects` - List projects accessible by the current user
74-
30. `list_labels` - List labels for a project
75-
31. `get_label` - Get a single label from a project
76-
32. `create_label` - Create a new label in a project
77-
33. `update_label` - Update an existing label in a project
78-
34. `delete_label` - Delete a label from a project
79-
35. `list_group_projects` - List projects in a GitLab group with filtering options
80-
36. `list_wiki_pages` - List wiki pages in a GitLab project
81-
37. `get_wiki_page` - Get details of a specific wiki page
82-
38. `create_wiki_page` - Create a new wiki page in a GitLab project
83-
39. `update_wiki_page` - Update an existing wiki page in a GitLab project
84-
40. `delete_wiki_page` - Delete a wiki page from a GitLab project
85-
41. `get_repository_tree` - Get the repository tree for a GitLab project (list files and directories)
61+
17. `add_merge_request_thread_note` - Add a new note to an existing merge request thread
62+
18. `list_issues` - List issues in a GitLab project with filtering options
63+
19. `get_issue` - Get details of a specific issue in a GitLab project
64+
20. `update_issue` - Update an issue in a GitLab project
65+
21. `delete_issue` - Delete an issue from a GitLab project
66+
22. `list_issue_links` - List all issue links for a specific issue
67+
23. `get_issue_link` - Get a specific issue link
68+
24. `create_issue_link` - Create an issue link between two issues
69+
25. `delete_issue_link` - Delete an issue link
70+
26. `list_namespaces` - List all namespaces available to the current user
71+
27. `get_namespace` - Get details of a namespace by ID or path
72+
28. `verify_namespace` - Verify if a namespace path exists
73+
29. `get_project` - Get details of a specific project
74+
30. `list_projects` - List projects accessible by the current user
75+
31. `list_labels` - List labels for a project
76+
32. `get_label` - Get a single label from a project
77+
33. `create_label` - Create a new label in a project
78+
34. `update_label` - Update an existing label in a project
79+
35. `delete_label` - Delete a label from a project
80+
36. `list_group_projects` - List projects in a GitLab group with filtering options
81+
37. `list_wiki_pages` - List wiki pages in a GitLab project
82+
38. `get_wiki_page` - Get details of a specific wiki page
83+
39. `create_wiki_page` - Create a new wiki page in a GitLab project
84+
40. `update_wiki_page` - Update an existing wiki page in a GitLab project
85+
41. `delete_wiki_page` - Delete a wiki page from a GitLab project
86+
42. `get_repository_tree` - Get the repository tree for a GitLab project (list files and directories)
8687
<!-- TOOLS-END -->

index.ts

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ import {
8787
GitLabDiscussionNoteSchema, // Added
8888
GitLabDiscussionSchema,
8989
UpdateMergeRequestNoteSchema, // Added
90+
AddMergeRequestThreadNoteSchema, // Added
9091
ListMergeRequestDiscussionsSchema,
9192
type GitLabFork,
9293
type GitLabReference,
@@ -280,6 +281,11 @@ const allTools = [
280281
description: "Modify an existing merge request thread note",
281282
inputSchema: zodToJsonSchema(UpdateMergeRequestNoteSchema),
282283
},
284+
{
285+
name: "add_merge_request_thread_note",
286+
description: "Add a new note to an existing merge request thread",
287+
inputSchema: zodToJsonSchema(AddMergeRequestThreadNoteSchema),
288+
},
283289
{
284290
name: "list_issues",
285291
description: "List issues in a GitLab project with filtering options",
@@ -1060,6 +1066,47 @@ async function updateMergeRequestNote(
10601066
return GitLabDiscussionNoteSchema.parse(data);
10611067
}
10621068

1069+
/**
1070+
* Add a new note to an existing merge request thread
1071+
* 기존 병합 요청 스레드에 새 노트 추가
1072+
*
1073+
* @param {string} projectId - The ID or URL-encoded path of the project
1074+
* @param {number} mergeRequestIid - The IID of a merge request
1075+
* @param {string} discussionId - The ID of a thread
1076+
* @param {string} body - The content of the new note
1077+
* @param {string} [createdAt] - The creation date of the note (ISO 8601 format)
1078+
* @returns {Promise<GitLabDiscussionNote>} The created note
1079+
*/
1080+
async function addMergeRequestThreadNote(
1081+
projectId: string,
1082+
mergeRequestIid: number,
1083+
discussionId: string,
1084+
body: string,
1085+
createdAt?: string
1086+
): Promise<GitLabDiscussionNote> {
1087+
projectId = decodeURIComponent(projectId); // Decode project ID
1088+
const url = new URL(
1089+
`${GITLAB_API_URL}/projects/${encodeURIComponent(
1090+
projectId
1091+
)}/merge_requests/${mergeRequestIid}/discussions/${discussionId}/notes`
1092+
);
1093+
1094+
const payload: { body: string; created_at?: string } = { body };
1095+
if (createdAt) {
1096+
payload.created_at = createdAt;
1097+
}
1098+
1099+
const response = await fetch(url.toString(), {
1100+
...DEFAULT_FETCH_CONFIG,
1101+
method: "POST",
1102+
body: JSON.stringify(payload),
1103+
});
1104+
1105+
await handleGitLabError(response);
1106+
const data = await response.json();
1107+
return GitLabDiscussionNoteSchema.parse(data);
1108+
}
1109+
10631110
/**
10641111
* Create or update a file in a GitLab project
10651112
* 파일 생성 또는 업데이트
@@ -2337,6 +2384,22 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
23372384
content: [{ type: "text", text: JSON.stringify(note, null, 2) }],
23382385
};
23392386
}
2387+
2388+
case "add_merge_request_thread_note": {
2389+
const args = AddMergeRequestThreadNoteSchema.parse(
2390+
request.params.arguments
2391+
);
2392+
const note = await addMergeRequestThreadNote(
2393+
args.project_id,
2394+
args.merge_request_iid,
2395+
args.discussion_id,
2396+
args.body,
2397+
args.created_at
2398+
);
2399+
return {
2400+
content: [{ type: "text", text: JSON.stringify(note, null, 2) }],
2401+
};
2402+
}
23402403

23412404
case "get_merge_request": {
23422405
const args = GetMergeRequestSchema.parse(request.params.arguments);

schemas.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,14 @@ export const UpdateMergeRequestNoteSchema = ProjectParamsSchema.extend({
479479
resolved: z.boolean().optional().describe("Resolve or unresolve the note"), // Optional based on API docs
480480
});
481481

482+
// Input schema for adding a note to an existing merge request discussion
483+
export const AddMergeRequestThreadNoteSchema = ProjectParamsSchema.extend({
484+
merge_request_iid: z.number().describe("The IID of a merge request"),
485+
discussion_id: z.string().describe("The ID of a thread"),
486+
body: z.string().describe("The content of the note or reply"),
487+
created_at: z.string().optional().describe("Date the note was created at (ISO 8601 format)"),
488+
});
489+
482490
// API Operation Parameter Schemas
483491

484492
export const CreateOrUpdateFileSchema = ProjectParamsSchema.extend({
@@ -1079,3 +1087,4 @@ export type GitLabTreeItem = z.infer<typeof GitLabTreeItemSchema>;
10791087
export type GetRepositoryTreeOptions = z.infer<typeof GetRepositoryTreeSchema>;
10801088
export type MergeRequestThreadPosition = z.infer<typeof MergeRequestThreadPositionSchema>;
10811089
export type CreateMergeRequestThreadOptions = z.infer<typeof CreateMergeRequestThreadSchema>;
1090+
export type AddMergeRequestThreadNoteOptions = z.infer<typeof AddMergeRequestThreadNoteSchema>;

0 commit comments

Comments
 (0)