@zereight/mcp-gitlab 1.0.64 → 1.0.65
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 +61 -54
- package/build/index.js +170 -1
- package/build/schemas.js +76 -22
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -36,7 +36,9 @@ When using with the Claude App, you need to set up your API key and URLs directl
|
|
|
36
36
|
```
|
|
37
37
|
|
|
38
38
|
#### Docker
|
|
39
|
+
|
|
39
40
|
- stdio
|
|
41
|
+
|
|
40
42
|
```mcp.json
|
|
41
43
|
{
|
|
42
44
|
"mcpServers": {
|
|
@@ -74,6 +76,7 @@ When using with the Claude App, you need to set up your API key and URLs directl
|
|
|
74
76
|
```
|
|
75
77
|
|
|
76
78
|
- sse
|
|
79
|
+
|
|
77
80
|
```shell
|
|
78
81
|
docker run -i --rm \
|
|
79
82
|
-e GITLAB_PERSONAL_ACCESS_TOKEN=your_gitlab_token \
|
|
@@ -113,9 +116,12 @@ $ sh scripts/image_push.sh docker_user_name
|
|
|
113
116
|
- `USE_PIPELINE`: When set to 'true', enables the pipeline-related tools (list_pipelines, get_pipeline, list_pipeline_jobs, get_pipeline_job, get_pipeline_job_output, create_pipeline, retry_pipeline, cancel_pipeline). By default, pipeline features are disabled.
|
|
114
117
|
- `GITLAB_AUTH_COOKIE_PATH`: Path to an authentication cookie file for GitLab instances that require cookie-based authentication. When provided, the cookie will be included in all GitLab API requests.
|
|
115
118
|
|
|
119
|
+
[](https://www.star-history.com/#zereight/gitlab-mcp&Date)
|
|
120
|
+
|
|
116
121
|
## Tools 🛠️
|
|
117
122
|
|
|
118
123
|
+<!-- TOOLS-START -->
|
|
124
|
+
|
|
119
125
|
1. `create_or_update_file` - Create or update a single file in a GitLab project
|
|
120
126
|
2. `search_repositories` - Search for GitLab projects
|
|
121
127
|
3. `create_repository` - Create a new GitLab project
|
|
@@ -127,58 +133,59 @@ $ sh scripts/image_push.sh docker_user_name
|
|
|
127
133
|
9. `create_branch` - Create a new branch in a GitLab project
|
|
128
134
|
10. `get_merge_request` - Get details of a merge request (Either mergeRequestIid or branchName must be provided)
|
|
129
135
|
11. `get_merge_request_diffs` - Get the changes/diffs of a merge request (Either mergeRequestIid or branchName must be provided)
|
|
130
|
-
12. `
|
|
131
|
-
13. `
|
|
132
|
-
14. `
|
|
133
|
-
15. `
|
|
134
|
-
16. `
|
|
135
|
-
17. `
|
|
136
|
-
18. `
|
|
137
|
-
19. `
|
|
138
|
-
20. `
|
|
139
|
-
21. `
|
|
140
|
-
22. `
|
|
141
|
-
23. `
|
|
142
|
-
24. `
|
|
143
|
-
25. `
|
|
144
|
-
26. `
|
|
145
|
-
27. `
|
|
146
|
-
28. `
|
|
147
|
-
29. `
|
|
148
|
-
30. `
|
|
149
|
-
31. `
|
|
150
|
-
32. `
|
|
151
|
-
33. `
|
|
152
|
-
34. `
|
|
153
|
-
35. `
|
|
154
|
-
36. `
|
|
155
|
-
37. `
|
|
156
|
-
38. `
|
|
157
|
-
39. `
|
|
158
|
-
40. `
|
|
159
|
-
41. `
|
|
160
|
-
42. `
|
|
161
|
-
43. `
|
|
162
|
-
44. `
|
|
163
|
-
45. `
|
|
164
|
-
46. `
|
|
165
|
-
47. `
|
|
166
|
-
48. `
|
|
167
|
-
49. `
|
|
168
|
-
50. `
|
|
169
|
-
51. `
|
|
170
|
-
52. `
|
|
171
|
-
53. `
|
|
172
|
-
54. `
|
|
173
|
-
55. `
|
|
174
|
-
56. `
|
|
175
|
-
57. `
|
|
176
|
-
58. `
|
|
177
|
-
59. `
|
|
178
|
-
60. `
|
|
179
|
-
61. `
|
|
180
|
-
62. `
|
|
181
|
-
63. `
|
|
182
|
-
64. `
|
|
183
|
-
65. `
|
|
136
|
+
12. `list_merge_request_diffs` - List merge request diffs with pagination support (Either mergeRequestIid or branchName must be provided)
|
|
137
|
+
13. `get_branch_diffs` - Get the changes/diffs between two branches or commits in a GitLab project
|
|
138
|
+
14. `update_merge_request` - Update a merge request (Either mergeRequestIid or branchName must be provided)
|
|
139
|
+
15. `create_note` - Create a new note (comment) to an issue or merge request
|
|
140
|
+
16. `create_merge_request_thread` - Create a new thread on a merge request
|
|
141
|
+
17. `mr_discussions` - List discussion items for a merge request
|
|
142
|
+
18. `update_merge_request_note` - Modify an existing merge request thread note
|
|
143
|
+
19. `create_merge_request_note` - Add a new note to an existing merge request thread
|
|
144
|
+
20. `update_issue_note` - Modify an existing issue thread note
|
|
145
|
+
21. `create_issue_note` - Add a new note to an existing issue thread
|
|
146
|
+
22. `list_issues` - List issues in a GitLab project with filtering options
|
|
147
|
+
23. `get_issue` - Get details of a specific issue in a GitLab project
|
|
148
|
+
24. `update_issue` - Update an issue in a GitLab project
|
|
149
|
+
25. `delete_issue` - Delete an issue from a GitLab project
|
|
150
|
+
26. `list_issue_links` - List all issue links for a specific issue
|
|
151
|
+
27. `list_issue_discussions` - List discussions for an issue in a GitLab project
|
|
152
|
+
28. `get_issue_link` - Get a specific issue link
|
|
153
|
+
29. `create_issue_link` - Create an issue link between two issues
|
|
154
|
+
30. `delete_issue_link` - Delete an issue link
|
|
155
|
+
31. `list_namespaces` - List all namespaces available to the current user
|
|
156
|
+
32. `get_namespace` - Get details of a namespace by ID or path
|
|
157
|
+
33. `verify_namespace` - Verify if a namespace path exists
|
|
158
|
+
34. `get_project` - Get details of a specific project
|
|
159
|
+
35. `list_projects` - List projects accessible by the current user
|
|
160
|
+
36. `list_labels` - List labels for a project
|
|
161
|
+
37. `get_label` - Get a single label from a project
|
|
162
|
+
38. `create_label` - Create a new label in a project
|
|
163
|
+
39. `update_label` - Update an existing label in a project
|
|
164
|
+
40. `delete_label` - Delete a label from a project
|
|
165
|
+
41. `list_group_projects` - List projects in a GitLab group with filtering options
|
|
166
|
+
42. `list_wiki_pages` - List wiki pages in a GitLab project
|
|
167
|
+
43. `get_wiki_page` - Get details of a specific wiki page
|
|
168
|
+
44. `create_wiki_page` - Create a new wiki page in a GitLab project
|
|
169
|
+
45. `update_wiki_page` - Update an existing wiki page in a GitLab project
|
|
170
|
+
46. `delete_wiki_page` - Delete a wiki page from a GitLab project
|
|
171
|
+
47. `get_repository_tree` - Get the repository tree for a GitLab project (list files and directories)
|
|
172
|
+
48. `list_pipelines` - List pipelines in a GitLab project with filtering options
|
|
173
|
+
49. `get_pipeline` - Get details of a specific pipeline in a GitLab project
|
|
174
|
+
50. `list_pipeline_jobs` - List all jobs in a specific pipeline
|
|
175
|
+
51. `get_pipeline_job` - Get details of a GitLab pipeline job number
|
|
176
|
+
52. `get_pipeline_job_output` - Get the output/trace of a GitLab pipeline job number
|
|
177
|
+
53. `create_pipeline` - Create a new pipeline for a branch or tag
|
|
178
|
+
54. `retry_pipeline` - Retry a failed or canceled pipeline
|
|
179
|
+
55. `cancel_pipeline` - Cancel a running pipeline
|
|
180
|
+
56. `list_merge_requests` - List merge requests in a GitLab project with filtering options
|
|
181
|
+
57. `list_milestones` - List milestones in a GitLab project with filtering options
|
|
182
|
+
58. `get_milestone` - Get details of a specific milestone
|
|
183
|
+
59. `create_milestone` - Create a new milestone in a GitLab project
|
|
184
|
+
60. `edit_milestone` - Edit an existing milestone in a GitLab project
|
|
185
|
+
61. `delete_milestone` - Delete a milestone from a GitLab project
|
|
186
|
+
62. `get_milestone_issue` - Get issues associated with a specific milestone
|
|
187
|
+
63. `get_milestone_merge_requests` - Get merge requests associated with a specific milestone
|
|
188
|
+
64. `promote_milestone` - Promote a milestone to the next stage
|
|
189
|
+
65. `get_milestone_burndown_events` - Get burndown events for a specific milestone
|
|
190
|
+
66. `get_users` - Get GitLab user details by usernames
|
|
184
191
|
<!-- TOOLS-END -->
|
package/build/index.js
CHANGED
|
@@ -27,7 +27,7 @@ GetPipelineJobOutputSchema, GitLabPipelineJobSchema,
|
|
|
27
27
|
GitLabDiscussionNoteSchema, // Added
|
|
28
28
|
GitLabDiscussionSchema, PaginatedDiscussionsResponseSchema, UpdateMergeRequestNoteSchema, // Added
|
|
29
29
|
CreateMergeRequestNoteSchema, // Added
|
|
30
|
-
ListMergeRequestDiscussionsSchema, UpdateIssueNoteSchema, CreateIssueNoteSchema, ListMergeRequestsSchema, GitLabMilestonesSchema, ListProjectMilestonesSchema, GetProjectMilestoneSchema, CreateProjectMilestoneSchema, EditProjectMilestoneSchema, DeleteProjectMilestoneSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, PromoteProjectMilestoneSchema, GetMilestoneBurndownEventsSchema, GitLabCompareResultSchema, GetBranchDiffsSchema, } from "./schemas.js";
|
|
30
|
+
ListMergeRequestDiscussionsSchema, UpdateIssueNoteSchema, CreateIssueNoteSchema, ListMergeRequestsSchema, GitLabMilestonesSchema, ListProjectMilestonesSchema, GetProjectMilestoneSchema, CreateProjectMilestoneSchema, EditProjectMilestoneSchema, DeleteProjectMilestoneSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, PromoteProjectMilestoneSchema, GetMilestoneBurndownEventsSchema, GitLabCompareResultSchema, GetBranchDiffsSchema, ListCommitsSchema, GetCommitSchema, GetCommitDiffSchema, ListMergeRequestDiffsSchema, } from "./schemas.js";
|
|
31
31
|
/**
|
|
32
32
|
* Read version from package.json
|
|
33
33
|
*/
|
|
@@ -242,6 +242,11 @@ const allTools = [
|
|
|
242
242
|
description: "Get the changes/diffs of a merge request (Either mergeRequestIid or branchName must be provided)",
|
|
243
243
|
inputSchema: zodToJsonSchema(GetMergeRequestDiffsSchema),
|
|
244
244
|
},
|
|
245
|
+
{
|
|
246
|
+
name: "list_merge_request_diffs",
|
|
247
|
+
description: "List merge request diffs with pagination support (Either mergeRequestIid or branchName must be provided)",
|
|
248
|
+
inputSchema: zodToJsonSchema(ListMergeRequestDiffsSchema),
|
|
249
|
+
},
|
|
245
250
|
{
|
|
246
251
|
name: "get_branch_diffs",
|
|
247
252
|
description: "Get the changes/diffs between two branches or commits in a GitLab project",
|
|
@@ -512,6 +517,21 @@ const allTools = [
|
|
|
512
517
|
description: "Get GitLab user details by usernames",
|
|
513
518
|
inputSchema: zodToJsonSchema(GetUsersSchema),
|
|
514
519
|
},
|
|
520
|
+
{
|
|
521
|
+
name: "list_commits",
|
|
522
|
+
description: "List repository commits with filtering options",
|
|
523
|
+
inputSchema: zodToJsonSchema(ListCommitsSchema),
|
|
524
|
+
},
|
|
525
|
+
{
|
|
526
|
+
name: "get_commit",
|
|
527
|
+
description: "Get details of a specific commit",
|
|
528
|
+
inputSchema: zodToJsonSchema(GetCommitSchema),
|
|
529
|
+
},
|
|
530
|
+
{
|
|
531
|
+
name: "get_commit_diff",
|
|
532
|
+
description: "Get changes/diffs of a specific commit",
|
|
533
|
+
inputSchema: zodToJsonSchema(GetCommitDiffSchema),
|
|
534
|
+
},
|
|
515
535
|
];
|
|
516
536
|
// Define which tools are read-only
|
|
517
537
|
const readOnlyTools = [
|
|
@@ -549,6 +569,9 @@ const readOnlyTools = [
|
|
|
549
569
|
"list_wiki_pages",
|
|
550
570
|
"get_wiki_page",
|
|
551
571
|
"get_users",
|
|
572
|
+
"list_commits",
|
|
573
|
+
"get_commit",
|
|
574
|
+
"get_commit_diff",
|
|
552
575
|
];
|
|
553
576
|
// Define which tools are related to wiki and can be toggled by USE_GITLAB_WIKI
|
|
554
577
|
const wikiToolNames = [
|
|
@@ -1456,6 +1479,41 @@ async function getMergeRequestDiffs(projectId, mergeRequestIid, branchName, view
|
|
|
1456
1479
|
const data = (await response.json());
|
|
1457
1480
|
return z.array(GitLabDiffSchema).parse(data.changes);
|
|
1458
1481
|
}
|
|
1482
|
+
/**
|
|
1483
|
+
* Get merge request changes with detailed information including commits, diff_refs, and more
|
|
1484
|
+
* 마지막으로 추가된 상세한 MR 변경사항 조회 함수 (Detailed merge request changes retrieval function)
|
|
1485
|
+
*
|
|
1486
|
+
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
1487
|
+
* @param {number} mergeRequestIid - The internal ID of the merge request (Either mergeRequestIid or branchName must be provided)
|
|
1488
|
+
* @param {string} [branchName] - The name of the branch to search for merge request by branch name (Either mergeRequestIid or branchName must be provided)
|
|
1489
|
+
* @param {boolean} [unidiff] - Return diff in unidiff format
|
|
1490
|
+
* @returns {Promise<any>} The complete merge request changes response
|
|
1491
|
+
*/
|
|
1492
|
+
async function listMergeRequestDiffs(projectId, mergeRequestIid, branchName, page, perPage, unidiff) {
|
|
1493
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
1494
|
+
if (!mergeRequestIid && !branchName) {
|
|
1495
|
+
throw new Error("Either mergeRequestIid or branchName must be provided");
|
|
1496
|
+
}
|
|
1497
|
+
if (branchName && !mergeRequestIid) {
|
|
1498
|
+
const mergeRequest = await getMergeRequest(projectId, undefined, branchName);
|
|
1499
|
+
mergeRequestIid = mergeRequest.iid;
|
|
1500
|
+
}
|
|
1501
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/merge_requests/${mergeRequestIid}/diffs`);
|
|
1502
|
+
if (page) {
|
|
1503
|
+
url.searchParams.append("page", page.toString());
|
|
1504
|
+
}
|
|
1505
|
+
if (perPage) {
|
|
1506
|
+
url.searchParams.append("per_page", perPage.toString());
|
|
1507
|
+
}
|
|
1508
|
+
if (unidiff) {
|
|
1509
|
+
url.searchParams.append("unidiff", "true");
|
|
1510
|
+
}
|
|
1511
|
+
const response = await fetch(url.toString(), {
|
|
1512
|
+
...DEFAULT_FETCH_CONFIG,
|
|
1513
|
+
});
|
|
1514
|
+
await handleGitLabError(response);
|
|
1515
|
+
return await response.json(); // Return full response including commits, diff_refs, changes, etc.
|
|
1516
|
+
}
|
|
1459
1517
|
/**
|
|
1460
1518
|
* Get branch comparison diffs
|
|
1461
1519
|
*
|
|
@@ -2395,6 +2453,89 @@ async function getUsers(usernames) {
|
|
|
2395
2453
|
}
|
|
2396
2454
|
return GitLabUsersResponseSchema.parse(users);
|
|
2397
2455
|
}
|
|
2456
|
+
/**
|
|
2457
|
+
* List repository commits
|
|
2458
|
+
* 저장소 커밋 목록 조회
|
|
2459
|
+
*
|
|
2460
|
+
* @param {string} projectId - Project ID or URL-encoded path
|
|
2461
|
+
* @param {ListCommitsOptions} options - List commits options
|
|
2462
|
+
* @returns {Promise<GitLabCommit[]>} List of commits
|
|
2463
|
+
*/
|
|
2464
|
+
async function listCommits(projectId, options = {}) {
|
|
2465
|
+
projectId = decodeURIComponent(projectId);
|
|
2466
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/commits`);
|
|
2467
|
+
// Add query parameters
|
|
2468
|
+
if (options.ref_name)
|
|
2469
|
+
url.searchParams.append("ref_name", options.ref_name);
|
|
2470
|
+
if (options.since)
|
|
2471
|
+
url.searchParams.append("since", options.since);
|
|
2472
|
+
if (options.until)
|
|
2473
|
+
url.searchParams.append("until", options.until);
|
|
2474
|
+
if (options.path)
|
|
2475
|
+
url.searchParams.append("path", options.path);
|
|
2476
|
+
if (options.author)
|
|
2477
|
+
url.searchParams.append("author", options.author);
|
|
2478
|
+
if (options.all)
|
|
2479
|
+
url.searchParams.append("all", options.all.toString());
|
|
2480
|
+
if (options.with_stats)
|
|
2481
|
+
url.searchParams.append("with_stats", options.with_stats.toString());
|
|
2482
|
+
if (options.first_parent)
|
|
2483
|
+
url.searchParams.append("first_parent", options.first_parent.toString());
|
|
2484
|
+
if (options.order)
|
|
2485
|
+
url.searchParams.append("order", options.order);
|
|
2486
|
+
if (options.trailers)
|
|
2487
|
+
url.searchParams.append("trailers", options.trailers.toString());
|
|
2488
|
+
if (options.page)
|
|
2489
|
+
url.searchParams.append("page", options.page.toString());
|
|
2490
|
+
if (options.per_page)
|
|
2491
|
+
url.searchParams.append("per_page", options.per_page.toString());
|
|
2492
|
+
const response = await fetch(url.toString(), {
|
|
2493
|
+
...DEFAULT_FETCH_CONFIG,
|
|
2494
|
+
});
|
|
2495
|
+
await handleGitLabError(response);
|
|
2496
|
+
const data = await response.json();
|
|
2497
|
+
return z.array(GitLabCommitSchema).parse(data);
|
|
2498
|
+
}
|
|
2499
|
+
/**
|
|
2500
|
+
* Get a single commit
|
|
2501
|
+
* 단일 커밋 정보 조회
|
|
2502
|
+
*
|
|
2503
|
+
* @param {string} projectId - Project ID or URL-encoded path
|
|
2504
|
+
* @param {string} sha - The commit hash or name of a repository branch or tag
|
|
2505
|
+
* @param {boolean} [stats] - Include commit stats
|
|
2506
|
+
* @returns {Promise<GitLabCommit>} The commit details
|
|
2507
|
+
*/
|
|
2508
|
+
async function getCommit(projectId, sha, stats) {
|
|
2509
|
+
projectId = decodeURIComponent(projectId);
|
|
2510
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/commits/${encodeURIComponent(sha)}`);
|
|
2511
|
+
if (stats) {
|
|
2512
|
+
url.searchParams.append("stats", "true");
|
|
2513
|
+
}
|
|
2514
|
+
const response = await fetch(url.toString(), {
|
|
2515
|
+
...DEFAULT_FETCH_CONFIG,
|
|
2516
|
+
});
|
|
2517
|
+
await handleGitLabError(response);
|
|
2518
|
+
const data = await response.json();
|
|
2519
|
+
return GitLabCommitSchema.parse(data);
|
|
2520
|
+
}
|
|
2521
|
+
/**
|
|
2522
|
+
* Get commit diff
|
|
2523
|
+
* 커밋 변경사항 조회
|
|
2524
|
+
*
|
|
2525
|
+
* @param {string} projectId - Project ID or URL-encoded path
|
|
2526
|
+
* @param {string} sha - The commit hash or name of a repository branch or tag
|
|
2527
|
+
* @returns {Promise<GitLabMergeRequestDiff[]>} The commit diffs
|
|
2528
|
+
*/
|
|
2529
|
+
async function getCommitDiff(projectId, sha) {
|
|
2530
|
+
projectId = decodeURIComponent(projectId);
|
|
2531
|
+
const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/repository/commits/${encodeURIComponent(sha)}/diff`);
|
|
2532
|
+
const response = await fetch(url.toString(), {
|
|
2533
|
+
...DEFAULT_FETCH_CONFIG,
|
|
2534
|
+
});
|
|
2535
|
+
await handleGitLabError(response);
|
|
2536
|
+
const data = await response.json();
|
|
2537
|
+
return z.array(GitLabDiffSchema).parse(data);
|
|
2538
|
+
}
|
|
2398
2539
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
2399
2540
|
// Apply read-only filter first
|
|
2400
2541
|
const tools0 = GITLAB_READ_ONLY_MODE
|
|
@@ -2591,6 +2732,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
2591
2732
|
content: [{ type: "text", text: JSON.stringify(diffs, null, 2) }],
|
|
2592
2733
|
};
|
|
2593
2734
|
}
|
|
2735
|
+
case "list_merge_request_diffs": {
|
|
2736
|
+
const args = ListMergeRequestDiffsSchema.parse(request.params.arguments);
|
|
2737
|
+
const changes = await listMergeRequestDiffs(args.project_id, args.merge_request_iid, args.source_branch, args.page, args.per_page, args.unidiff);
|
|
2738
|
+
return {
|
|
2739
|
+
content: [{ type: "text", text: JSON.stringify(changes, null, 2) }],
|
|
2740
|
+
};
|
|
2741
|
+
}
|
|
2594
2742
|
case "update_merge_request": {
|
|
2595
2743
|
const args = UpdateMergeRequestSchema.parse(request.params.arguments);
|
|
2596
2744
|
const { project_id, merge_request_iid, source_branch, ...options } = args;
|
|
@@ -3088,6 +3236,27 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3088
3236
|
],
|
|
3089
3237
|
};
|
|
3090
3238
|
}
|
|
3239
|
+
case "list_commits": {
|
|
3240
|
+
const args = ListCommitsSchema.parse(request.params.arguments);
|
|
3241
|
+
const commits = await listCommits(args.project_id, args);
|
|
3242
|
+
return {
|
|
3243
|
+
content: [{ type: "text", text: JSON.stringify(commits, null, 2) }],
|
|
3244
|
+
};
|
|
3245
|
+
}
|
|
3246
|
+
case "get_commit": {
|
|
3247
|
+
const args = GetCommitSchema.parse(request.params.arguments);
|
|
3248
|
+
const commit = await getCommit(args.project_id, args.sha, args.stats);
|
|
3249
|
+
return {
|
|
3250
|
+
content: [{ type: "text", text: JSON.stringify(commit, null, 2) }],
|
|
3251
|
+
};
|
|
3252
|
+
}
|
|
3253
|
+
case "get_commit_diff": {
|
|
3254
|
+
const args = GetCommitDiffSchema.parse(request.params.arguments);
|
|
3255
|
+
const diff = await getCommitDiff(args.project_id, args.sha);
|
|
3256
|
+
return {
|
|
3257
|
+
content: [{ type: "text", text: JSON.stringify(diff, null, 2) }],
|
|
3258
|
+
};
|
|
3259
|
+
}
|
|
3091
3260
|
default:
|
|
3092
3261
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
3093
3262
|
}
|
package/build/schemas.js
CHANGED
|
@@ -374,8 +374,17 @@ export const GitLabCommitSchema = z.object({
|
|
|
374
374
|
committer_name: z.string(),
|
|
375
375
|
committer_email: z.string(),
|
|
376
376
|
committed_date: z.string(),
|
|
377
|
+
created_at: z.string().optional(), // Add created_at field
|
|
378
|
+
message: z.string().optional(), // Add full message field
|
|
377
379
|
web_url: z.string(), // Changed from html_url to match GitLab API
|
|
378
380
|
parent_ids: z.array(z.string()), // Changed from parents to match GitLab API
|
|
381
|
+
stats: z.object({
|
|
382
|
+
additions: z.number().optional().nullable(),
|
|
383
|
+
deletions: z.number().optional().nullable(),
|
|
384
|
+
total: z.number().optional().nullable(),
|
|
385
|
+
}).optional(), // Only present when with_stats=true
|
|
386
|
+
trailers: z.record(z.string()).optional().default({}), // Git trailers, may be empty object
|
|
387
|
+
extended_trailers: z.record(z.array(z.string())).optional().default({}), // Extended trailers, may be empty object
|
|
379
388
|
});
|
|
380
389
|
// Reference schema
|
|
381
390
|
export const GitLabReferenceSchema = z.object({
|
|
@@ -596,6 +605,20 @@ export const GitLabMergeRequestSchema = z.object({
|
|
|
596
605
|
squash: z.boolean().optional(),
|
|
597
606
|
labels: z.array(z.string()).optional(),
|
|
598
607
|
});
|
|
608
|
+
export const LineRangeSchema = z.object({
|
|
609
|
+
start: z.object({
|
|
610
|
+
line_code: z.string().nullable().optional().describe("CRITICAL: Line identifier in format '{file_path_sha1_hash}_{old_line_number}_{new_line_number}'. USUALLY REQUIRED for GitLab diff comments despite being optional in schema. Example: 'a1b2c3d4e5f6_10_15'. Get this from GitLab diff API response, never fabricate."),
|
|
611
|
+
type: z.enum(["new", "old"]).nullable().optional().describe("Line type: 'old' = deleted/original line, 'new' = added/modified line, null = unchanged context. MUST match the line_code format and old_line/new_line values."),
|
|
612
|
+
old_line: z.number().nullable().optional().describe("Line number in original file (before changes). REQUIRED when type='old', NULL when type='new' (for purely added lines), can be present for context lines."),
|
|
613
|
+
new_line: z.number().nullable().optional().describe("Line number in modified file (after changes). REQUIRED when type='new', NULL when type='old' (for purely deleted lines), can be present for context lines."),
|
|
614
|
+
}).describe("Start line position for multiline comment range. MUST specify either old_line OR new_line (or both for context), never neither."),
|
|
615
|
+
end: z.object({
|
|
616
|
+
line_code: z.string().nullable().optional().describe("CRITICAL: Line identifier in format '{file_path_sha1_hash}_{old_line_number}_{new_line_number}'. USUALLY REQUIRED for GitLab diff comments despite being optional in schema. Example: 'a1b2c3d4e5f6_12_17'. Must be from same file as start.line_code."),
|
|
617
|
+
type: z.enum(["new", "old"]).nullable().optional().describe("Line type: 'old' = deleted/original line, 'new' = added/modified line, null = unchanged context. SHOULD MATCH start.type for consistent ranges (don't mix old/new types)."),
|
|
618
|
+
old_line: z.number().nullable().optional().describe("Line number in original file (before changes). REQUIRED when type='old', NULL when type='new' (for purely added lines), can be present for context lines. MUST be >= start.old_line if both specified."),
|
|
619
|
+
new_line: z.number().nullable().optional().describe("Line number in modified file (after changes). REQUIRED when type='new', NULL when type='old' (for purely deleted lines), can be present for context lines. MUST be >= start.new_line if both specified."),
|
|
620
|
+
}).describe("End line position for multiline comment range. MUST specify either old_line OR new_line (or both for context), never neither. Range must be valid (end >= start)."),
|
|
621
|
+
}).describe("Line range for multiline comments on GitLab merge request diffs. VALIDATION RULES: 1) line_code is critical for GitLab API success, 2) start/end must have consistent types, 3) line numbers must form valid range, 4) get line_code from GitLab diff API, never generate manually.");
|
|
599
622
|
// Discussion related schemas
|
|
600
623
|
export const GitLabDiscussionNoteSchema = z.object({
|
|
601
624
|
id: z.number(),
|
|
@@ -620,24 +643,24 @@ export const GitLabDiscussionNoteSchema = z.object({
|
|
|
620
643
|
base_sha: z.string(),
|
|
621
644
|
start_sha: z.string(),
|
|
622
645
|
head_sha: z.string(),
|
|
623
|
-
old_path: z.string(),
|
|
624
|
-
new_path: z.string(),
|
|
646
|
+
old_path: z.string().optional().describe("File path before change"),
|
|
647
|
+
new_path: z.string().optional().describe("File path after change"),
|
|
625
648
|
position_type: z.enum(["text", "image", "file"]),
|
|
626
|
-
|
|
627
|
-
|
|
649
|
+
new_line: z.number().nullable().optional().describe("Line number in the modified file (after changes). Used for added lines and context lines. Null for deleted lines."),
|
|
650
|
+
old_line: z.number().nullable().optional().describe("Line number in the original file (before changes). Used for deleted lines and context lines. Null for newly added lines."),
|
|
628
651
|
line_range: z
|
|
629
652
|
.object({
|
|
630
653
|
start: z.object({
|
|
631
|
-
line_code: z.string(),
|
|
654
|
+
line_code: z.string().nullable().optional().describe("Line identifier in format: '{file_path_sha1_hash}_{old_line_number}_{new_line_number}'. Used to uniquely identify a specific line in the diff."),
|
|
632
655
|
type: z.enum(["new", "old", "expanded"]),
|
|
633
|
-
old_line: z.number().
|
|
634
|
-
new_line: z.number().
|
|
656
|
+
old_line: z.number().nullable().optional().describe("Line number in the original file (before changes). Null for newly added lines or unchanged context lines."),
|
|
657
|
+
new_line: z.number().nullable().optional().describe("Line number in the modified file (after changes). Null for deleted lines or unchanged context lines."),
|
|
635
658
|
}),
|
|
636
659
|
end: z.object({
|
|
637
|
-
line_code: z.string(),
|
|
660
|
+
line_code: z.string().nullable().optional().describe("Line identifier in format: '{file_path_sha1_hash}_{old_line_number}_{new_line_number}'. Used to uniquely identify a specific line in the diff."),
|
|
638
661
|
type: z.enum(["new", "old", "expanded"]),
|
|
639
|
-
old_line: z.number().
|
|
640
|
-
new_line: z.number().
|
|
662
|
+
old_line: z.number().nullable().optional().describe("Line number in the original file (before changes). Null for newly added lines or unchanged context lines."),
|
|
663
|
+
new_line: z.number().nullable().optional().describe("Line number in the modified file (after changes). Null for deleted lines or unchanged context lines."),
|
|
641
664
|
}),
|
|
642
665
|
})
|
|
643
666
|
.nullable()
|
|
@@ -818,6 +841,11 @@ export const UpdateMergeRequestSchema = GetMergeRequestSchema.extend({
|
|
|
818
841
|
export const GetMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
819
842
|
view: z.enum(["inline", "parallel"]).optional().describe("Diff view type"),
|
|
820
843
|
});
|
|
844
|
+
export const ListMergeRequestDiffsSchema = GetMergeRequestSchema.extend({
|
|
845
|
+
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
846
|
+
per_page: z.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
847
|
+
unidiff: z.boolean().optional().describe("Present diffs in the unified diff format. Default is false. Introduced in GitLab 16.5."),
|
|
848
|
+
});
|
|
821
849
|
export const CreateNoteSchema = z.object({
|
|
822
850
|
project_id: z.string().describe("Project ID or namespace/project_path"),
|
|
823
851
|
noteable_type: z
|
|
@@ -1124,18 +1152,19 @@ export const GitLabWikiPageSchema = z.object({
|
|
|
1124
1152
|
});
|
|
1125
1153
|
// Merge Request Thread position schema - used for diff notes
|
|
1126
1154
|
export const MergeRequestThreadPositionSchema = z.object({
|
|
1127
|
-
base_sha: z.string().describe("Base commit SHA in the source branch"),
|
|
1128
|
-
head_sha: z.string().describe("SHA referencing HEAD of the source branch"),
|
|
1129
|
-
start_sha: z.string().describe("SHA referencing the start commit of the source branch"),
|
|
1130
|
-
position_type: z.enum(["text", "image", "file"]).describe("
|
|
1131
|
-
new_path: z.string().optional().describe("File path after
|
|
1132
|
-
old_path: z.string().optional().describe("File path before
|
|
1133
|
-
new_line: z.number().nullable().optional().describe("Line number after
|
|
1134
|
-
old_line: z.number().nullable().optional().describe("Line number before
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1155
|
+
base_sha: z.string().describe("REQUIRED: Base commit SHA in the source branch. Get this from merge request diff_refs.base_sha."),
|
|
1156
|
+
head_sha: z.string().describe("REQUIRED: SHA referencing HEAD of the source branch. Get this from merge request diff_refs.head_sha."),
|
|
1157
|
+
start_sha: z.string().describe("REQUIRED: SHA referencing the start commit of the source branch. Get this from merge request diff_refs.start_sha."),
|
|
1158
|
+
position_type: z.enum(["text", "image", "file"]).describe("REQUIRED: Position type. Use 'text' for code diffs, 'image' for image diffs, 'file' for file-level comments."),
|
|
1159
|
+
new_path: z.string().optional().describe("File path after changes. REQUIRED for most diff comments. Use same as old_path if file wasn't renamed."),
|
|
1160
|
+
old_path: z.string().optional().describe("File path before changes. REQUIRED for most diff comments. Use same as new_path if file wasn't renamed."),
|
|
1161
|
+
new_line: z.number().nullable().optional().describe("Line number in modified file (after changes). Use for added lines or context lines. NULL for deleted lines. For single-line comments on new lines."),
|
|
1162
|
+
old_line: z.number().nullable().optional().describe("Line number in original file (before changes). Use for deleted lines or context lines. NULL for added lines. For single-line comments on old lines."),
|
|
1163
|
+
line_range: LineRangeSchema.optional().describe("MULTILINE COMMENTS: Specify start/end line positions for commenting on multiple lines. Alternative to single old_line/new_line."),
|
|
1164
|
+
width: z.number().optional().describe("IMAGE DIFFS ONLY: Width of the image (for position_type='image')."),
|
|
1165
|
+
height: z.number().optional().describe("IMAGE DIFFS ONLY: Height of the image (for position_type='image')."),
|
|
1166
|
+
x: z.number().optional().describe("IMAGE DIFFS ONLY: X coordinate on the image (for position_type='image')."),
|
|
1167
|
+
y: z.number().optional().describe("IMAGE DIFFS ONLY: Y coordinate on the image (for position_type='image')."),
|
|
1139
1168
|
});
|
|
1140
1169
|
// Schema for creating a new merge request thread
|
|
1141
1170
|
export const CreateMergeRequestThreadSchema = ProjectParamsSchema.extend({
|
|
@@ -1202,3 +1231,28 @@ export const GetMilestoneMergeRequestsSchema = GetProjectMilestoneSchema.merge(P
|
|
|
1202
1231
|
export const PromoteProjectMilestoneSchema = GetProjectMilestoneSchema;
|
|
1203
1232
|
// Schema for getting burndown chart events for a milestone
|
|
1204
1233
|
export const GetMilestoneBurndownEventsSchema = GetProjectMilestoneSchema.merge(PaginationOptionsSchema);
|
|
1234
|
+
// Add schemas for commit operations
|
|
1235
|
+
export const ListCommitsSchema = z.object({
|
|
1236
|
+
project_id: z.string().describe("Project ID or complete URL-encoded path to project"),
|
|
1237
|
+
ref_name: z.string().optional().describe("The name of a repository branch, tag or revision range, or if not given the default branch"),
|
|
1238
|
+
since: z.string().optional().describe("Only commits after or on this date are returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ"),
|
|
1239
|
+
until: z.string().optional().describe("Only commits before or on this date are returned in ISO 8601 format YYYY-MM-DDTHH:MM:SSZ"),
|
|
1240
|
+
path: z.string().optional().describe("The file path"),
|
|
1241
|
+
author: z.string().optional().describe("Search commits by commit author"),
|
|
1242
|
+
all: z.boolean().optional().describe("Retrieve every commit from the repository"),
|
|
1243
|
+
with_stats: z.boolean().optional().describe("Stats about each commit are added to the response"),
|
|
1244
|
+
first_parent: z.boolean().optional().describe("Follow only the first parent commit upon seeing a merge commit"),
|
|
1245
|
+
order: z.enum(["default", "topo"]).optional().describe("List commits in order"),
|
|
1246
|
+
trailers: z.boolean().optional().describe("Parse and include Git trailers for every commit"),
|
|
1247
|
+
page: z.number().optional().describe("Page number for pagination (default: 1)"),
|
|
1248
|
+
per_page: z.number().optional().describe("Number of items per page (max: 100, default: 20)"),
|
|
1249
|
+
});
|
|
1250
|
+
export const GetCommitSchema = z.object({
|
|
1251
|
+
project_id: z.string().describe("Project ID or complete URL-encoded path to project"),
|
|
1252
|
+
sha: z.string().describe("The commit hash or name of a repository branch or tag"),
|
|
1253
|
+
stats: z.boolean().optional().describe("Include commit stats"),
|
|
1254
|
+
});
|
|
1255
|
+
export const GetCommitDiffSchema = z.object({
|
|
1256
|
+
project_id: z.string().describe("Project ID or complete URL-encoded path to project"),
|
|
1257
|
+
sha: z.string().describe("The commit hash or name of a repository branch or tag"),
|
|
1258
|
+
});
|