@zereight/mcp-gitlab 1.0.51 → 1.0.53

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 CHANGED
@@ -26,8 +26,9 @@ When using with the Claude App, you need to set up your API key and URLs directl
26
26
  "GITLAB_PERSONAL_ACCESS_TOKEN": "your_gitlab_token",
27
27
  "GITLAB_API_URL": "your_gitlab_api_url",
28
28
  "GITLAB_READ_ONLY_MODE": "false",
29
- "USE_GITLAB_WIKI": "false",
30
- "USE_MILESTONE": "false"
29
+ "USE_GITLAB_WIKI": "false", // use wiki api?
30
+ "USE_MILESTONE": "false", // use milestone api?
31
+ "USE_PIPELINE": "false" // use pipeline api?
31
32
  }
32
33
  }
33
34
  }
@@ -55,6 +56,8 @@ When using with the Claude App, you need to set up your API key and URLs directl
55
56
  "USE_GITLAB_WIKI",
56
57
  "-e",
57
58
  "USE_MILESTONE",
59
+ "-e",
60
+ "USE_PIPELINE",
58
61
  "iwakitakuma/gitlab-mcp"
59
62
  ],
60
63
  "env": {
@@ -62,7 +65,8 @@ When using with the Claude App, you need to set up your API key and URLs directl
62
65
  "GITLAB_API_URL": "https://gitlab.com/api/v4", // Optional, for self-hosted GitLab
63
66
  "GITLAB_READ_ONLY_MODE": "false",
64
67
  "USE_GITLAB_WIKI": "true",
65
- "USE_MILESTONE": "true"
68
+ "USE_MILESTONE": "true",
69
+ "USE_PIPELINE": "true"
66
70
  }
67
71
  }
68
72
  }
@@ -82,6 +86,7 @@ $ sh scripts/image_push.sh docker_user_name
82
86
  - `GITLAB_READ_ONLY_MODE`: When set to 'true', restricts the server to only expose read-only operations. Useful for enhanced security or when write access is not needed. Also useful for using with Cursor and it's 40 tool limit.
83
87
  - `USE_GITLAB_WIKI`: When set to 'true', enables the wiki-related tools (list_wiki_pages, get_wiki_page, create_wiki_page, update_wiki_page, delete_wiki_page). By default, wiki features are disabled.
84
88
  - `USE_MILESTONE`: When set to 'true', enables the milestone-related tools (list_milestones, get_milestone, create_milestone, edit_milestone, delete_milestone, get_milestone_issue, get_milestone_merge_requests, promote_milestone, get_milestone_burndown_events). By default, milestone features are disabled.
89
+ - `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.
85
90
 
86
91
  ## Tools 🛠️
87
92
 
@@ -137,14 +142,17 @@ $ sh scripts/image_push.sh docker_user_name
137
142
  48. `list_pipeline_jobs` - List all jobs in a specific pipeline
138
143
  49. `get_pipeline_job` - Get details of a GitLab pipeline job number
139
144
  50. `get_pipeline_job_output` - Get the output/trace of a GitLab pipeline job number
140
- 51. `list_merge_requests` - List merge requests in a GitLab project with filtering options
141
- 52. `list_milestones` - List milestones in a GitLab project with filtering options
142
- 53. `get_milestone` - Get details of a specific milestone
143
- 54. `create_milestone` - Create a new milestone in a GitLab project
144
- 55. `edit_milestone ` - Edit an existing milestone in a GitLab project
145
- 56. `delete_milestone` - Delete a milestone from a GitLab project
146
- 57. `get_milestone_issue` - Get issues associated with a specific milestone
147
- 58. `get_milestone_merge_requests` - Get merge requests associated with a specific milestone
148
- 59. `promote_milestone` - Promote a milestone to the next stage
149
- 60. `get_milestone_burndown_events` - Get burndown events for a specific milestone
145
+ 51. `create_pipeline` - Create a new pipeline for a branch or tag
146
+ 52. `retry_pipeline` - Retry a failed or canceled pipeline
147
+ 53. `cancel_pipeline` - Cancel a running pipeline
148
+ 54. `list_merge_requests` - List merge requests in a GitLab project with filtering options
149
+ 55. `list_milestones` - List milestones in a GitLab project with filtering options
150
+ 56. `get_milestone` - Get details of a specific milestone
151
+ 57. `create_milestone` - Create a new milestone in a GitLab project
152
+ 58. `edit_milestone ` - Edit an existing milestone in a GitLab project
153
+ 59. `delete_milestone` - Delete a milestone from a GitLab project
154
+ 60. `get_milestone_issue` - Get issues associated with a specific milestone
155
+ 61. `get_milestone_merge_requests` - Get merge requests associated with a specific milestone
156
+ 62. `promote_milestone` - Promote a milestone to the next stage
157
+ 63. `get_milestone_burndown_events` - Get burndown events for a specific milestone
150
158
  <!-- TOOLS-END -->
package/build/index.js CHANGED
@@ -13,7 +13,7 @@ import { dirname } from "path";
13
13
  import fs from "fs";
14
14
  import path from "path";
15
15
  import { URL } from "url";
16
- import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, ListIssuesSchema, GetIssueSchema, UpdateIssueSchema, DeleteIssueSchema, GitLabIssueLinkSchema, GitLabIssueWithLinkDetailsSchema, ListIssueLinksSchema, ListIssueDiscussionsSchema, GetIssueLinkSchema, CreateIssueLinkSchema, DeleteIssueLinkSchema, ListNamespacesSchema, GetNamespaceSchema, VerifyNamespaceSchema, GetProjectSchema, ListProjectsSchema, ListLabelsSchema, GetLabelSchema, CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema, CreateNoteSchema, CreateMergeRequestThreadSchema, ListGroupProjectsSchema, ListWikiPagesSchema, GetWikiPageSchema, CreateWikiPageSchema, UpdateWikiPageSchema, DeleteWikiPageSchema, GitLabWikiPageSchema, GetRepositoryTreeSchema, GitLabTreeItemSchema, GitLabPipelineSchema, GetPipelineSchema, ListPipelinesSchema, ListPipelineJobsSchema,
16
+ import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabMergeRequestDiffSchema, GetMergeRequestSchema, GetMergeRequestDiffsSchema, UpdateMergeRequestSchema, ListIssuesSchema, GetIssueSchema, UpdateIssueSchema, DeleteIssueSchema, GitLabIssueLinkSchema, GitLabIssueWithLinkDetailsSchema, ListIssueLinksSchema, ListIssueDiscussionsSchema, GetIssueLinkSchema, CreateIssueLinkSchema, DeleteIssueLinkSchema, ListNamespacesSchema, GetNamespaceSchema, VerifyNamespaceSchema, GetProjectSchema, ListProjectsSchema, ListLabelsSchema, GetLabelSchema, CreateLabelSchema, UpdateLabelSchema, DeleteLabelSchema, CreateNoteSchema, CreateMergeRequestThreadSchema, ListGroupProjectsSchema, ListWikiPagesSchema, GetWikiPageSchema, CreateWikiPageSchema, UpdateWikiPageSchema, DeleteWikiPageSchema, GitLabWikiPageSchema, GetRepositoryTreeSchema, GitLabTreeItemSchema, GitLabPipelineSchema, GetPipelineSchema, ListPipelinesSchema, ListPipelineJobsSchema, CreatePipelineSchema, RetryPipelineSchema, CancelPipelineSchema,
17
17
  // pipeline job schemas
18
18
  GetPipelineJobOutputSchema, GitLabPipelineJobSchema,
19
19
  // Discussion Schemas
@@ -49,6 +49,7 @@ const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_PERSONAL_ACCESS_TOKEN;
49
49
  const GITLAB_READ_ONLY_MODE = process.env.GITLAB_READ_ONLY_MODE === "true";
50
50
  const USE_GITLAB_WIKI = process.env.USE_GITLAB_WIKI === "true";
51
51
  const USE_MILESTONE = process.env.USE_MILESTONE === "true";
52
+ const USE_PIPELINE = process.env.USE_PIPELINE === "true";
52
53
  // Add proxy configuration
53
54
  const HTTP_PROXY = process.env.HTTP_PROXY;
54
55
  const HTTPS_PROXY = process.env.HTTPS_PROXY;
@@ -339,6 +340,21 @@ const allTools = [
339
340
  description: "Get the output/trace of a GitLab pipeline job number",
340
341
  inputSchema: zodToJsonSchema(GetPipelineJobOutputSchema),
341
342
  },
343
+ {
344
+ name: "create_pipeline",
345
+ description: "Create a new pipeline for a branch or tag",
346
+ inputSchema: zodToJsonSchema(CreatePipelineSchema),
347
+ },
348
+ {
349
+ name: "retry_pipeline",
350
+ description: "Retry a failed or canceled pipeline",
351
+ inputSchema: zodToJsonSchema(RetryPipelineSchema),
352
+ },
353
+ {
354
+ name: "cancel_pipeline",
355
+ description: "Cancel a running pipeline",
356
+ inputSchema: zodToJsonSchema(CancelPipelineSchema),
357
+ },
342
358
  {
343
359
  name: "list_merge_requests",
344
360
  description: "List merge requests in a GitLab project with filtering options",
@@ -446,6 +462,17 @@ const milestoneToolNames = [
446
462
  "promote_milestone",
447
463
  "get_milestone_burndown_events",
448
464
  ];
465
+ // Define which tools are related to pipelines and can be toggled by USE_PIPELINE
466
+ const pipelineToolNames = [
467
+ "list_pipelines",
468
+ "get_pipeline",
469
+ "list_pipeline_jobs",
470
+ "get_pipeline_job",
471
+ "get_pipeline_job_output",
472
+ "create_pipeline",
473
+ "retry_pipeline",
474
+ "cancel_pipeline",
475
+ ];
449
476
  /**
450
477
  * Smart URL handling for GitLab API
451
478
  *
@@ -1857,6 +1884,69 @@ async function getPipelineJobOutput(projectId, jobId) {
1857
1884
  await handleGitLabError(response);
1858
1885
  return await response.text();
1859
1886
  }
1887
+ /**
1888
+ * Create a new pipeline
1889
+ *
1890
+ * @param {string} projectId - The ID or URL-encoded path of the project
1891
+ * @param {string} ref - The branch or tag to run the pipeline on
1892
+ * @param {Array} variables - Optional variables for the pipeline
1893
+ * @returns {Promise<GitLabPipeline>} The created pipeline
1894
+ */
1895
+ async function createPipeline(projectId, ref, variables) {
1896
+ projectId = decodeURIComponent(projectId); // Decode project ID
1897
+ const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/pipeline`);
1898
+ const body = { ref };
1899
+ if (variables && variables.length > 0) {
1900
+ body.variables = variables.reduce((acc, { key, value }) => {
1901
+ acc[key] = value;
1902
+ return acc;
1903
+ }, {});
1904
+ }
1905
+ const response = await fetch(url.toString(), {
1906
+ method: "POST",
1907
+ headers: DEFAULT_HEADERS,
1908
+ body: JSON.stringify(body),
1909
+ });
1910
+ await handleGitLabError(response);
1911
+ const data = await response.json();
1912
+ return GitLabPipelineSchema.parse(data);
1913
+ }
1914
+ /**
1915
+ * Retry a pipeline
1916
+ *
1917
+ * @param {string} projectId - The ID or URL-encoded path of the project
1918
+ * @param {number} pipelineId - The ID of the pipeline to retry
1919
+ * @returns {Promise<GitLabPipeline>} The retried pipeline
1920
+ */
1921
+ async function retryPipeline(projectId, pipelineId) {
1922
+ projectId = decodeURIComponent(projectId); // Decode project ID
1923
+ const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/retry`);
1924
+ const response = await fetch(url.toString(), {
1925
+ method: "POST",
1926
+ headers: DEFAULT_HEADERS,
1927
+ });
1928
+ await handleGitLabError(response);
1929
+ const data = await response.json();
1930
+ return GitLabPipelineSchema.parse(data);
1931
+ }
1932
+ /**
1933
+ * Cancel a pipeline
1934
+ *
1935
+ * @param {string} projectId - The ID or URL-encoded path of the project
1936
+ * @param {number} pipelineId - The ID of the pipeline to cancel
1937
+ * @returns {Promise<GitLabPipeline>} The canceled pipeline
1938
+ */
1939
+ async function cancelPipeline(projectId, pipelineId) {
1940
+ projectId = decodeURIComponent(projectId); // Decode project ID
1941
+ const url = new URL(`${GITLAB_API_URL}/projects/${encodeURIComponent(projectId)}/pipelines/${pipelineId}/cancel`);
1942
+ const response = await fetch(url.toString(), {
1943
+ method: "POST",
1944
+ headers: DEFAULT_HEADERS,
1945
+ });
1946
+ await handleGitLabError(response);
1947
+ const data = await response.json();
1948
+ return GitLabPipelineSchema.parse(data);
1949
+ }
1860
1950
  /**
1861
1951
  * Get the repository tree for a project
1862
1952
  * @param {string} projectId - The ID or URL-encoded path of the project
@@ -2064,9 +2154,13 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
2064
2154
  ? tools0
2065
2155
  : tools0.filter(tool => !wikiToolNames.includes(tool.name));
2066
2156
  // Toggle milestone tools by USE_MILESTONE flag
2067
- let tools = USE_MILESTONE
2157
+ const tools2 = USE_MILESTONE
2068
2158
  ? tools1
2069
2159
  : tools1.filter(tool => !milestoneToolNames.includes(tool.name));
2160
+ // Toggle pipeline tools by USE_PIPELINE flag
2161
+ let tools = USE_PIPELINE
2162
+ ? tools2
2163
+ : tools2.filter(tool => !pipelineToolNames.includes(tool.name));
2070
2164
  // <<< START: Gemini 호환성을 위해 $schema 제거 >>>
2071
2165
  tools = tools.map(tool => {
2072
2166
  // inputSchema가 존재하고 객체인지 확인
@@ -2561,6 +2655,42 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2561
2655
  ],
2562
2656
  };
2563
2657
  }
2658
+ case "create_pipeline": {
2659
+ const { project_id, ref, variables } = CreatePipelineSchema.parse(request.params.arguments);
2660
+ const pipeline = await createPipeline(project_id, ref, variables);
2661
+ return {
2662
+ content: [
2663
+ {
2664
+ type: "text",
2665
+ text: `Created pipeline #${pipeline.id} for ${ref}. Status: ${pipeline.status}\nWeb URL: ${pipeline.web_url}`,
2666
+ },
2667
+ ],
2668
+ };
2669
+ }
2670
+ case "retry_pipeline": {
2671
+ const { project_id, pipeline_id } = RetryPipelineSchema.parse(request.params.arguments);
2672
+ const pipeline = await retryPipeline(project_id, pipeline_id);
2673
+ return {
2674
+ content: [
2675
+ {
2676
+ type: "text",
2677
+ text: `Retried pipeline #${pipeline.id}. Status: ${pipeline.status}\nWeb URL: ${pipeline.web_url}`,
2678
+ },
2679
+ ],
2680
+ };
2681
+ }
2682
+ case "cancel_pipeline": {
2683
+ const { project_id, pipeline_id } = CancelPipelineSchema.parse(request.params.arguments);
2684
+ const pipeline = await cancelPipeline(project_id, pipeline_id);
2685
+ return {
2686
+ content: [
2687
+ {
2688
+ type: "text",
2689
+ text: `Canceled pipeline #${pipeline.id}. Status: ${pipeline.status}\nWeb URL: ${pipeline.web_url}`,
2690
+ },
2691
+ ],
2692
+ };
2693
+ }
2564
2694
  case "list_merge_requests": {
2565
2695
  const args = ListMergeRequestsSchema.parse(request.params.arguments);
2566
2696
  const mergeRequests = await listMergeRequests(args.project_id, args);
package/build/schemas.js CHANGED
@@ -150,6 +150,28 @@ export const ListPipelineJobsSchema = z.object({
150
150
  page: z.number().optional().describe("Page number for pagination"),
151
151
  per_page: z.number().optional().describe("Number of items per page (max 100)"),
152
152
  });
153
+ // Schema for creating a new pipeline
154
+ export const CreatePipelineSchema = z.object({
155
+ project_id: z.string().describe("Project ID or URL-encoded path"),
156
+ ref: z.string().describe("The branch or tag to run the pipeline on"),
157
+ variables: z
158
+ .array(z.object({
159
+ key: z.string().describe("The key of the variable"),
160
+ value: z.string().describe("The value of the variable"),
161
+ }))
162
+ .optional()
163
+ .describe("An array of variables to use for the pipeline"),
164
+ });
165
+ // Schema for retrying a pipeline
166
+ export const RetryPipelineSchema = z.object({
167
+ project_id: z.string().describe("Project ID or URL-encoded path"),
168
+ pipeline_id: z.number().describe("The ID of the pipeline to retry"),
169
+ });
170
+ // Schema for canceling a pipeline
171
+ export const CancelPipelineSchema = z.object({
172
+ project_id: z.string().describe("Project ID or URL-encoded path"),
173
+ pipeline_id: z.number().describe("The ID of the pipeline to cancel"),
174
+ });
153
175
  // Schema for the input parameters for pipeline job operations
154
176
  export const GetPipelineJobOutputSchema = z.object({
155
177
  project_id: z.string().describe("Project ID or URL-encoded path"),
@@ -550,21 +572,21 @@ export const GitLabDiscussionNoteSchema = z.object({
550
572
  old_path: z.string(),
551
573
  new_path: z.string(),
552
574
  position_type: z.enum(["text", "image", "file"]),
553
- old_line: z.number().nullable(),
554
- new_line: z.number().nullable(),
575
+ old_line: z.number().nullish(), // This is missing for image diffs
576
+ new_line: z.number().nullish(), // This is missing for image diffs
555
577
  line_range: z
556
578
  .object({
557
579
  start: z.object({
558
580
  line_code: z.string(),
559
581
  type: z.enum(["new", "old", "expanded"]),
560
- old_line: z.number().nullable(),
561
- new_line: z.number().nullable(),
582
+ old_line: z.number().nullish(), // This is missing for image diffs
583
+ new_line: z.number().nullish(), // This is missing for image diffs
562
584
  }),
563
585
  end: z.object({
564
586
  line_code: z.string(),
565
587
  type: z.enum(["new", "old", "expanded"]),
566
- old_line: z.number().nullable(),
567
- new_line: z.number().nullable(),
588
+ old_line: z.number().nullish(), // This is missing for image diffs
589
+ new_line: z.number().nullish(), // This is missing for image diffs
568
590
  }),
569
591
  })
570
592
  .nullable()
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zereight/mcp-gitlab",
3
- "version": "1.0.51",
3
+ "version": "1.0.53",
4
4
  "description": "MCP server for using the GitLab API",
5
5
  "license": "MIT",
6
6
  "author": "zereight",