@zereight/mcp-gitlab 1.0.59 → 1.0.61

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/index.js CHANGED
@@ -16,7 +16,7 @@ import path from "path";
16
16
  import express from "express";
17
17
  // Add type imports for proxy agents
18
18
  import { Agent } from "http";
19
- import { Agent as HttpsAgent } from 'https';
19
+ import { Agent as HttpsAgent } from "https";
20
20
  import { URL } from "url";
21
21
  import { GitLabForkSchema, GitLabReferenceSchema, GitLabRepositorySchema, GitLabIssueSchema, GitLabMergeRequestSchema, GitLabContentSchema, GitLabCreateUpdateFileResponseSchema, GitLabSearchResponseSchema, GitLabTreeSchema, GitLabCommitSchema, GitLabNamespaceSchema, GitLabNamespaceExistsResponseSchema, GitLabProjectSchema, GitLabUserSchema, GitLabUsersResponseSchema, GetUsersSchema, CreateOrUpdateFileSchema, SearchRepositoriesSchema, CreateRepositorySchema, GetFileContentsSchema, PushFilesSchema, CreateIssueSchema, CreateMergeRequestSchema, ForkRepositorySchema, CreateBranchSchema, GitLabDiffSchema, 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,
22
22
  // pipeline job schemas
@@ -40,7 +40,7 @@ try {
40
40
  }
41
41
  }
42
42
  catch (error) {
43
- console.error("Warning: Could not read version from package.json:", error);
43
+ // Warning: Could not read version from package.json - silently continue
44
44
  }
45
45
  const server = new Server({
46
46
  name: "better-gitlab-mcp-server",
@@ -51,6 +51,7 @@ const server = new Server({
51
51
  },
52
52
  });
53
53
  const GITLAB_PERSONAL_ACCESS_TOKEN = process.env.GITLAB_PERSONAL_ACCESS_TOKEN;
54
+ const IS_OLD = process.env.GITLAB_IS_OLD === "true";
54
55
  const GITLAB_READ_ONLY_MODE = process.env.GITLAB_READ_ONLY_MODE === "true";
55
56
  const USE_GITLAB_WIKI = process.env.USE_GITLAB_WIKI === "true";
56
57
  const USE_MILESTONE = process.env.USE_MILESTONE === "true";
@@ -62,7 +63,7 @@ const HTTPS_PROXY = process.env.HTTPS_PROXY;
62
63
  const NODE_TLS_REJECT_UNAUTHORIZED = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
63
64
  const GITLAB_CA_CERT_PATH = process.env.GITLAB_CA_CERT_PATH;
64
65
  let sslOptions = undefined;
65
- if (NODE_TLS_REJECT_UNAUTHORIZED === '0') {
66
+ if (NODE_TLS_REJECT_UNAUTHORIZED === "0") {
66
67
  sslOptions = { rejectUnauthorized: false };
67
68
  }
68
69
  else if (GITLAB_CA_CERT_PATH) {
@@ -94,8 +95,13 @@ httpAgent = httpAgent || new Agent();
94
95
  const DEFAULT_HEADERS = {
95
96
  Accept: "application/json",
96
97
  "Content-Type": "application/json",
97
- Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
98
98
  };
99
+ if (IS_OLD) {
100
+ DEFAULT_HEADERS["Private-Token"] = `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`;
101
+ }
102
+ else {
103
+ DEFAULT_HEADERS["Authorization"] = `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`;
104
+ }
99
105
  // Create a default fetch configuration object that includes proxy agents if set
100
106
  const DEFAULT_FETCH_CONFIG = {
101
107
  headers: DEFAULT_HEADERS,
@@ -695,15 +701,16 @@ async function listIssues(projectId, options = {}) {
695
701
  // Add all query parameters
696
702
  Object.entries(options).forEach(([key, value]) => {
697
703
  if (value !== undefined) {
698
- if (key === "labels") {
704
+ const keys = ["labels", "assignee_username"];
705
+ if (keys.includes(key)) {
699
706
  if (Array.isArray(value)) {
700
707
  // Handle array of labels
701
708
  value.forEach(label => {
702
- url.searchParams.append("labels[]", label.toString());
709
+ url.searchParams.append(`${key}[]`, label.toString());
703
710
  });
704
711
  }
705
712
  else {
706
- url.searchParams.append("labels[]", value.toString());
713
+ url.searchParams.append(`${key}[]`, value.toString());
707
714
  }
708
715
  }
709
716
  else {
@@ -915,6 +922,8 @@ async function createMergeRequest(projectId, options) {
915
922
  labels: options.labels?.join(","),
916
923
  allow_collaboration: options.allow_collaboration,
917
924
  draft: options.draft,
925
+ remove_source_branch: options.remove_source_branch,
926
+ squash: options.squash,
918
927
  }),
919
928
  });
920
929
  if (response.status === 400) {
@@ -955,12 +964,20 @@ async function listDiscussions(projectId, resourceType, resourceIid, options = {
955
964
  const discussions = await response.json();
956
965
  // Extract pagination headers
957
966
  const pagination = {
958
- x_next_page: response.headers.get("x-next-page") ? parseInt(response.headers.get("x-next-page")) : null,
967
+ x_next_page: response.headers.get("x-next-page")
968
+ ? parseInt(response.headers.get("x-next-page"))
969
+ : null,
959
970
  x_page: response.headers.get("x-page") ? parseInt(response.headers.get("x-page")) : undefined,
960
- x_per_page: response.headers.get("x-per-page") ? parseInt(response.headers.get("x-per-page")) : undefined,
961
- x_prev_page: response.headers.get("x-prev-page") ? parseInt(response.headers.get("x-prev-page")) : null,
971
+ x_per_page: response.headers.get("x-per-page")
972
+ ? parseInt(response.headers.get("x-per-page"))
973
+ : undefined,
974
+ x_prev_page: response.headers.get("x-prev-page")
975
+ ? parseInt(response.headers.get("x-prev-page"))
976
+ : null,
962
977
  x_total: response.headers.get("x-total") ? parseInt(response.headers.get("x-total")) : null,
963
- x_total_pages: response.headers.get("x-total-pages") ? parseInt(response.headers.get("x-total-pages")) : null,
978
+ x_total_pages: response.headers.get("x-total-pages")
979
+ ? parseInt(response.headers.get("x-total-pages"))
980
+ : null,
964
981
  };
965
982
  return PaginatedDiscussionsResponseSchema.parse({
966
983
  items: discussions,
@@ -2048,11 +2065,17 @@ async function getRepositoryTree(options) {
2048
2065
  queryParams.append("page_token", options.page_token);
2049
2066
  if (options.pagination)
2050
2067
  queryParams.append("pagination", options.pagination);
2068
+ const headers = {
2069
+ "Content-Type": "application/json",
2070
+ };
2071
+ if (IS_OLD) {
2072
+ headers["Private-Token"] = `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`;
2073
+ }
2074
+ else {
2075
+ headers["Authorization"] = `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`;
2076
+ }
2051
2077
  const response = await fetch(`${GITLAB_API_URL}/projects/${encodeURIComponent(options.project_id)}/repository/tree?${queryParams.toString()}`, {
2052
- headers: {
2053
- Authorization: `Bearer ${GITLAB_PERSONAL_ACCESS_TOKEN}`,
2054
- "Content-Type": "application/json",
2055
- },
2078
+ headers,
2056
2079
  });
2057
2080
  if (response.status === 404) {
2058
2081
  throw new Error("Repository or path not found");
@@ -2290,9 +2313,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
2290
2313
  ? tools1
2291
2314
  : tools1.filter(tool => !milestoneToolNames.includes(tool.name));
2292
2315
  // Toggle pipeline tools by USE_PIPELINE flag
2293
- let tools = USE_PIPELINE
2294
- ? tools2
2295
- : tools2.filter(tool => !pipelineToolNames.includes(tool.name));
2316
+ let tools = USE_PIPELINE ? tools2 : tools2.filter(tool => !pipelineToolNames.includes(tool.name));
2296
2317
  // <<< START: Gemini 호환성을 위해 $schema 제거 >>>
2297
2318
  tools = tools.map(tool => {
2298
2319
  // inputSchema가 존재하고 객체인지 확인
@@ -2986,10 +3007,10 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
2986
3007
  */
2987
3008
  async function runServer() {
2988
3009
  try {
2989
- console.error("========================");
2990
- console.error(`GitLab MCP Server v${SERVER_VERSION}`);
2991
- console.error(`API URL: ${GITLAB_API_URL}`);
2992
- console.error("========================");
3010
+ // Server startup banner removed - inappropriate use of console.error for logging
3011
+ // Server version banner removed - inappropriate use of console.error for logging
3012
+ // API URL banner removed - inappropriate use of console.error for logging
3013
+ // Server startup banner removed - inappropriate use of console.error for logging
2993
3014
  if (!SSE) {
2994
3015
  const transport = new StdioServerTransport();
2995
3016
  await server.connect(transport);
@@ -3020,7 +3041,6 @@ async function runServer() {
3020
3041
  console.log(`Server is running on port ${PORT}`);
3021
3042
  });
3022
3043
  }
3023
- console.error("GitLab MCP Server running on stdio");
3024
3044
  }
3025
3045
  catch (error) {
3026
3046
  console.error("Error initializing server:", error);
package/build/schemas.js CHANGED
@@ -427,6 +427,8 @@ export const CreateMergeRequestOptionsSchema = z.object({
427
427
  labels: z.array(z.string()).optional(),
428
428
  allow_collaboration: z.boolean().optional(), // Changed from maintainer_can_modify to match GitLab API
429
429
  draft: z.boolean().optional(),
430
+ remove_source_branch: z.boolean().optional().describe("Flag indicating if a merge request should remove the source branch when merging."),
431
+ squash: z.boolean().optional().describe("If true, squash all commits into a single commit on merge.")
430
432
  });
431
433
  export const GitLabDiffSchema = z.object({
432
434
  old_path: z.string(),
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zereight/mcp-gitlab",
3
- "version": "1.0.59",
3
+ "version": "1.0.61",
4
4
  "description": "MCP server for using the GitLab API",
5
5
  "license": "MIT",
6
6
  "author": "zereight",
@@ -21,6 +21,7 @@
21
21
  "watch": "tsc --watch",
22
22
  "deploy": "npm publish --access public",
23
23
  "generate-tools": "npx ts-node scripts/generate-tools-readme.ts",
24
+ "changelog": "auto-changelog -p",
24
25
  "test": "node test/validate-api.js",
25
26
  "test:integration": "node test/validate-api.js",
26
27
  "lint": "eslint . --ext .ts",
@@ -48,6 +49,7 @@
48
49
  "prettier": "^3.4.2",
49
50
  "ts-node": "^10.9.2",
50
51
  "typescript": "^5.8.2",
51
- "zod": "^3.24.2"
52
+ "zod": "^3.24.2",
53
+ "auto-changelog": "^2.4.0"
52
54
  }
53
55
  }