@zereight/mcp-gitlab 1.0.74 → 1.0.76
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/build/customSchemas.js +2 -0
- package/build/index.js +64 -7
- package/build/schemas.js +35 -8
- package/package.json +1 -1
package/build/customSchemas.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import { pino } from 'pino';
|
|
3
|
+
const DEFAULT_NULL = process.env.DEFAULT_NULL === "true";
|
|
3
4
|
const logger = pino({
|
|
4
5
|
level: process.env.LOG_LEVEL || 'info',
|
|
5
6
|
transport: {
|
|
@@ -17,3 +18,4 @@ export const flexibleBoolean = z.preprocess((val) => {
|
|
|
17
18
|
}
|
|
18
19
|
return val;
|
|
19
20
|
}, z.boolean());
|
|
21
|
+
export const flexibleBooleanNullable = DEFAULT_NULL ? flexibleBoolean.nullable().default(null) : flexibleBoolean.nullable();
|
package/build/index.js
CHANGED
|
@@ -28,7 +28,7 @@ GetPipelineJobOutputSchema, GitLabPipelineJobSchema,
|
|
|
28
28
|
GitLabDiscussionNoteSchema, // Added
|
|
29
29
|
GitLabDiscussionSchema, PaginatedDiscussionsResponseSchema, UpdateMergeRequestNoteSchema, // Added
|
|
30
30
|
CreateMergeRequestNoteSchema, // Added
|
|
31
|
-
ListMergeRequestDiscussionsSchema, UpdateIssueNoteSchema, CreateIssueNoteSchema, ListMergeRequestsSchema, GitLabMilestonesSchema, ListProjectMilestonesSchema, GetProjectMilestoneSchema, CreateProjectMilestoneSchema, EditProjectMilestoneSchema, DeleteProjectMilestoneSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, PromoteProjectMilestoneSchema, GetMilestoneBurndownEventsSchema, GitLabCompareResultSchema, GetBranchDiffsSchema, ListCommitsSchema, GetCommitSchema, GetCommitDiffSchema, ListMergeRequestDiffsSchema, } from "./schemas.js";
|
|
31
|
+
ListMergeRequestDiscussionsSchema, UpdateIssueNoteSchema, CreateIssueNoteSchema, ListMergeRequestsSchema, GitLabMilestonesSchema, ListProjectMilestonesSchema, GetProjectMilestoneSchema, CreateProjectMilestoneSchema, EditProjectMilestoneSchema, DeleteProjectMilestoneSchema, GetMilestoneIssuesSchema, GetMilestoneMergeRequestsSchema, PromoteProjectMilestoneSchema, GetMilestoneBurndownEventsSchema, GitLabCompareResultSchema, GetBranchDiffsSchema, ListCommitsSchema, GetCommitSchema, GetCommitDiffSchema, ListMergeRequestDiffsSchema, ListGroupIterationsSchema, GroupIteration, } from "./schemas.js";
|
|
32
32
|
import { randomUUID } from "crypto";
|
|
33
33
|
import { pino } from 'pino';
|
|
34
34
|
const logger = pino({
|
|
@@ -320,7 +320,7 @@ const allTools = [
|
|
|
320
320
|
},
|
|
321
321
|
{
|
|
322
322
|
name: "list_issues",
|
|
323
|
-
description: "List issues
|
|
323
|
+
description: "List issues (default: created by current user only; use scope='all' for all accessible issues)",
|
|
324
324
|
inputSchema: zodToJsonSchema(ListIssuesSchema),
|
|
325
325
|
},
|
|
326
326
|
{
|
|
@@ -558,6 +558,11 @@ const allTools = [
|
|
|
558
558
|
description: "Get changes/diffs of a specific commit",
|
|
559
559
|
inputSchema: zodToJsonSchema(GetCommitDiffSchema),
|
|
560
560
|
},
|
|
561
|
+
{
|
|
562
|
+
name: "list_group_iterations",
|
|
563
|
+
description: "List group iterations with filtering options",
|
|
564
|
+
inputSchema: zodToJsonSchema(ListGroupIterationsSchema),
|
|
565
|
+
},
|
|
561
566
|
];
|
|
562
567
|
// Define which tools are read-only
|
|
563
568
|
const readOnlyTools = [
|
|
@@ -598,6 +603,8 @@ const readOnlyTools = [
|
|
|
598
603
|
"list_commits",
|
|
599
604
|
"get_commit",
|
|
600
605
|
"get_commit_diff",
|
|
606
|
+
"list_group_iterations",
|
|
607
|
+
"get_group_iteration",
|
|
601
608
|
];
|
|
602
609
|
// Define which tools are related to wiki and can be toggled by USE_GITLAB_WIKI
|
|
603
610
|
const wikiToolNames = [
|
|
@@ -823,17 +830,23 @@ async function createIssue(projectId, options) {
|
|
|
823
830
|
return GitLabIssueSchema.parse(data);
|
|
824
831
|
}
|
|
825
832
|
/**
|
|
826
|
-
* List issues
|
|
833
|
+
* List issues across all accessible projects or within a specific project
|
|
827
834
|
* 프로젝트의 이슈 목록 조회
|
|
828
835
|
*
|
|
829
|
-
* @param {string} projectId - The ID or URL-encoded path of the project
|
|
836
|
+
* @param {string} projectId - The ID or URL-encoded path of the project (optional)
|
|
830
837
|
* @param {Object} options - Options for listing issues
|
|
831
838
|
* @returns {Promise<GitLabIssue[]>} List of issues
|
|
832
839
|
*/
|
|
833
840
|
async function listIssues(projectId, options = {}) {
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
841
|
+
let url;
|
|
842
|
+
if (projectId) {
|
|
843
|
+
projectId = decodeURIComponent(projectId); // Decode project ID
|
|
844
|
+
const effectiveProjectId = getEffectiveProjectId(projectId);
|
|
845
|
+
url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(effectiveProjectId)}/issues`);
|
|
846
|
+
}
|
|
847
|
+
else {
|
|
848
|
+
url = new URL(`${GITLAB_API_URL}/issues`);
|
|
849
|
+
}
|
|
837
850
|
// Add all query parameters
|
|
838
851
|
Object.entries(options).forEach(([key, value]) => {
|
|
839
852
|
if (value !== undefined) {
|
|
@@ -1053,6 +1066,7 @@ async function createMergeRequest(projectId, options) {
|
|
|
1053
1066
|
description: options.description,
|
|
1054
1067
|
source_branch: options.source_branch,
|
|
1055
1068
|
target_branch: options.target_branch,
|
|
1069
|
+
target_project_id: options.target_project_id,
|
|
1056
1070
|
assignee_ids: options.assignee_ids,
|
|
1057
1071
|
reviewer_ids: options.reviewer_ids,
|
|
1058
1072
|
labels: options.labels?.join(","),
|
|
@@ -2573,6 +2587,42 @@ async function getCommitDiff(projectId, sha) {
|
|
|
2573
2587
|
const data = await response.json();
|
|
2574
2588
|
return z.array(GitLabDiffSchema).parse(data);
|
|
2575
2589
|
}
|
|
2590
|
+
/**
|
|
2591
|
+
* list group iterations
|
|
2592
|
+
*
|
|
2593
|
+
* @param {string} groupId
|
|
2594
|
+
* @param {Omit<ListGroupIterationsOptions, "group_id">} options
|
|
2595
|
+
* @returns {Promise<GetIt[]>}
|
|
2596
|
+
*/
|
|
2597
|
+
async function listGroupIterations(groupId, options = {}) {
|
|
2598
|
+
groupId = decodeURIComponent(groupId);
|
|
2599
|
+
const url = new URL(`${GITLAB_API_URL}/groups/${encodeURIComponent(groupId)}/iterations`);
|
|
2600
|
+
// クエリパラメータの追加
|
|
2601
|
+
if (options.state)
|
|
2602
|
+
url.searchParams.append("state", options.state);
|
|
2603
|
+
if (options.search)
|
|
2604
|
+
url.searchParams.append("search", options.search);
|
|
2605
|
+
if (options.in)
|
|
2606
|
+
url.searchParams.append("in", options.in.join(","));
|
|
2607
|
+
if (options.include_ancestors !== undefined)
|
|
2608
|
+
url.searchParams.append("include_ancestors", options.include_ancestors.toString());
|
|
2609
|
+
if (options.include_descendants !== undefined)
|
|
2610
|
+
url.searchParams.append("include_descendants", options.include_descendants.toString());
|
|
2611
|
+
if (options.updated_before)
|
|
2612
|
+
url.searchParams.append("updated_before", options.updated_before);
|
|
2613
|
+
if (options.updated_after)
|
|
2614
|
+
url.searchParams.append("updated_after", options.updated_after);
|
|
2615
|
+
if (options.page)
|
|
2616
|
+
url.searchParams.append("page", options.page.toString());
|
|
2617
|
+
if (options.per_page)
|
|
2618
|
+
url.searchParams.append("per_page", options.per_page.toString());
|
|
2619
|
+
const response = await fetch(url.toString(), DEFAULT_FETCH_CONFIG);
|
|
2620
|
+
if (!response.ok) {
|
|
2621
|
+
await handleGitLabError(response);
|
|
2622
|
+
}
|
|
2623
|
+
const data = await response.json();
|
|
2624
|
+
return z.array(GroupIteration).parse(data);
|
|
2625
|
+
}
|
|
2576
2626
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
2577
2627
|
// Apply read-only filter first
|
|
2578
2628
|
const tools0 = GITLAB_READ_ONLY_MODE
|
|
@@ -3301,6 +3351,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
3301
3351
|
content: [{ type: "text", text: JSON.stringify(diff, null, 2) }],
|
|
3302
3352
|
};
|
|
3303
3353
|
}
|
|
3354
|
+
case "list_group_iterations": {
|
|
3355
|
+
const args = ListGroupIterationsSchema.parse(request.params.arguments);
|
|
3356
|
+
const iterations = await listGroupIterations(args.group_id, args);
|
|
3357
|
+
return {
|
|
3358
|
+
content: [{ type: "text", text: JSON.stringify(iterations, null, 2) }],
|
|
3359
|
+
};
|
|
3360
|
+
}
|
|
3304
3361
|
default:
|
|
3305
3362
|
throw new Error(`Unknown tool: ${request.params.name}`);
|
|
3306
3363
|
}
|
package/build/schemas.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { flexibleBoolean } from "./customSchemas.js";
|
|
2
|
+
import { flexibleBoolean, flexibleBooleanNullable } from "./customSchemas.js";
|
|
3
3
|
// Base schemas for common types
|
|
4
4
|
export const GitLabAuthorSchema = z.object({
|
|
5
5
|
name: z.string(),
|
|
@@ -294,7 +294,7 @@ export const GitLabRepositorySchema = z.object({
|
|
|
294
294
|
jobs_enabled: flexibleBoolean.optional(),
|
|
295
295
|
snippets_enabled: flexibleBoolean.optional(),
|
|
296
296
|
can_create_merge_request_in: flexibleBoolean.optional(),
|
|
297
|
-
resolve_outdated_diff_discussions:
|
|
297
|
+
resolve_outdated_diff_discussions: flexibleBooleanNullable.optional(),
|
|
298
298
|
shared_runners_enabled: flexibleBoolean.optional(),
|
|
299
299
|
shared_with_groups: z
|
|
300
300
|
.array(z.object({
|
|
@@ -518,7 +518,7 @@ export const GitLabIssueSchema = z.object({
|
|
|
518
518
|
.optional(),
|
|
519
519
|
confidential: flexibleBoolean.optional(),
|
|
520
520
|
due_date: z.string().nullable().optional(),
|
|
521
|
-
discussion_locked:
|
|
521
|
+
discussion_locked: flexibleBooleanNullable.optional(),
|
|
522
522
|
weight: z.number().nullable().optional(),
|
|
523
523
|
});
|
|
524
524
|
// NEW SCHEMA: For issue with link details (used in listing issue links)
|
|
@@ -576,8 +576,8 @@ export const GitLabMergeRequestSchema = z.object({
|
|
|
576
576
|
merge_error: z.string().nullable().optional(),
|
|
577
577
|
work_in_progress: flexibleBoolean.optional(),
|
|
578
578
|
blocking_discussions_resolved: flexibleBoolean.optional(),
|
|
579
|
-
should_remove_source_branch:
|
|
580
|
-
force_remove_source_branch:
|
|
579
|
+
should_remove_source_branch: flexibleBooleanNullable.optional(),
|
|
580
|
+
force_remove_source_branch: flexibleBooleanNullable.optional(),
|
|
581
581
|
allow_collaboration: flexibleBoolean.optional(),
|
|
582
582
|
allow_maintainer_to_push: flexibleBoolean.optional(),
|
|
583
583
|
changes_count: z.string().nullable().optional(),
|
|
@@ -752,6 +752,7 @@ const MergeRequestOptionsSchema = {
|
|
|
752
752
|
description: z.string().optional().describe("Merge request description"),
|
|
753
753
|
source_branch: z.string().describe("Branch containing changes"),
|
|
754
754
|
target_branch: z.string().describe("Branch to merge into"),
|
|
755
|
+
target_project_id: z.coerce.string().optional().describe("Numeric ID of the target project."),
|
|
755
756
|
assignee_ids: z
|
|
756
757
|
.array(z.number())
|
|
757
758
|
.optional()
|
|
@@ -766,8 +767,8 @@ const MergeRequestOptionsSchema = {
|
|
|
766
767
|
.boolean()
|
|
767
768
|
.optional()
|
|
768
769
|
.describe("Allow commits from upstream members"),
|
|
769
|
-
remove_source_branch:
|
|
770
|
-
squash:
|
|
770
|
+
remove_source_branch: flexibleBooleanNullable.optional().describe("Flag indicating if a merge request should remove the source branch when merging."),
|
|
771
|
+
squash: flexibleBooleanNullable.optional().describe("If true, squash all commits into a single commit on merge."),
|
|
771
772
|
};
|
|
772
773
|
export const CreateMergeRequestOptionsSchema = z.object(MergeRequestOptionsSchema);
|
|
773
774
|
export const CreateMergeRequestSchema = ProjectParamsSchema.extend(MergeRequestOptionsSchema);
|
|
@@ -831,7 +832,7 @@ export const CreateNoteSchema = z.object({
|
|
|
831
832
|
});
|
|
832
833
|
// Issues API operation schemas
|
|
833
834
|
export const ListIssuesSchema = z.object({
|
|
834
|
-
project_id: z.coerce.string().describe("Project ID or URL-encoded path"),
|
|
835
|
+
project_id: z.coerce.string().optional().describe("Project ID or URL-encoded path (optional - if not provided, lists issues across all accessible projects)"),
|
|
835
836
|
assignee_id: z.coerce.string().optional().describe("Return issues assigned to the given user ID. user id or none or any"),
|
|
836
837
|
assignee_username: z.array(z.string()).optional().describe("Return issues assigned to the given username"),
|
|
837
838
|
author_id: z.coerce.string().optional().describe("Return issues created by the given user ID"),
|
|
@@ -842,6 +843,8 @@ export const ListIssuesSchema = z.object({
|
|
|
842
843
|
due_date: z.string().optional().describe("Return issues that have the due date"),
|
|
843
844
|
labels: z.array(z.string()).optional().describe("Array of label names"),
|
|
844
845
|
milestone: z.string().optional().describe("Milestone title"),
|
|
846
|
+
issue_type: z.string().optional().nullable().describe("Filter to a given type of issue. One of issue, incident, test_case or task"),
|
|
847
|
+
iteration_id: z.coerce.string().optional().nullable().describe("Return issues assigned to the given iteration ID. None returns issues that do not belong to an iteration. Any returns issues that belong to an iteration. "),
|
|
845
848
|
scope: z
|
|
846
849
|
.enum(["created_by_me", "assigned_to_me", "all"])
|
|
847
850
|
.optional()
|
|
@@ -1227,3 +1230,27 @@ export const GetCommitDiffSchema = z.object({
|
|
|
1227
1230
|
project_id: z.coerce.string().describe("Project ID or complete URL-encoded path to project"),
|
|
1228
1231
|
sha: z.string().describe("The commit hash or name of a repository branch or tag"),
|
|
1229
1232
|
});
|
|
1233
|
+
export const GroupIteration = z.object({
|
|
1234
|
+
id: z.coerce.string(),
|
|
1235
|
+
iid: z.coerce.string(),
|
|
1236
|
+
sequence: z.number(),
|
|
1237
|
+
group_id: z.coerce.string(),
|
|
1238
|
+
title: z.string().optional().nullable(),
|
|
1239
|
+
description: z.string().optional().nullable(),
|
|
1240
|
+
state: z.number(),
|
|
1241
|
+
created_at: z.string(),
|
|
1242
|
+
updated_at: z.string(),
|
|
1243
|
+
due_date: z.string().optional().nullable(),
|
|
1244
|
+
start_date: z.string().optional().nullable(),
|
|
1245
|
+
web_url: z.string().optional().nullable(),
|
|
1246
|
+
});
|
|
1247
|
+
export const ListGroupIterationsSchema = z.object({
|
|
1248
|
+
group_id: z.coerce.string().describe("Group ID or URL-encoded path"),
|
|
1249
|
+
state: z.enum(["opened", "upcoming", "current", "closed", "all"]).optional().describe("Return opened, upcoming, current, closed, or all iterations."),
|
|
1250
|
+
search: z.string().optional().describe("Return only iterations with a title matching the provided string."),
|
|
1251
|
+
in: z.array(z.enum(["title", "cadence_title"])).optional().describe("Fields in which fuzzy search should be performed with the query given in the argument search. The available options are title and cadence_title. Default is [title]."),
|
|
1252
|
+
include_ancestors: flexibleBoolean.optional().describe("Include iterations for group and its ancestors. Defaults to true."),
|
|
1253
|
+
include_descendants: flexibleBoolean.optional().describe("Include iterations for group and its descendants. Defaults to false."),
|
|
1254
|
+
updated_before: z.string().optional().describe("Return only iterations updated before the given datetime. Expected in ISO 8601 format (2019-03-15T08:00:00Z)."),
|
|
1255
|
+
updated_after: z.string().optional().describe("Return only iterations updated after the given datetime. Expected in ISO 8601 format (2019-03-15T08:00:00Z)."),
|
|
1256
|
+
}).merge(PaginationOptionsSchema);
|