@zereight/mcp-gitlab 2.3.1 → 2.3.2

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.ko.md CHANGED
@@ -138,7 +138,13 @@ command = lib.getExe inputs.gitlab-mcp.packages.${system}.default;
138
138
 
139
139
  예시는 기존 `mcp-gitlab`보다 충돌 가능성이 낮은 `zereight-mcp-gitlab` 별칭을 사용합니다. MCP 클라이언트가 찾지 못하면 `which zereight-mcp-gitlab`의 절대 경로를 사용하세요.
140
140
 
141
- 전역 설치를 쓰지 않으려면 `npx -y @zereight/mcp-gitlab@2.3.0`처럼 직전 안정 버전(문서가 권장하는 버전)으로 고정하세요. 항상 최신 버전을 원하면 `npx -y @zereight/mcp-gitlab@latest`를 사용하세요. 새 버전이 나오면 서버가 시작 시 stderr로 알려줍니다(`GITLAB_DISABLE_VERSION_CHECK=true`로 비활성화 가능).
141
+ 전역 설치를 쓰지 않으려면 `npx -y @zereight/mcp-gitlab@2.3.1`처럼 직전 안정 버전(문서가 권장하는 버전)으로 고정하세요. 항상 최신 버전을 원하면 `npx -y @zereight/mcp-gitlab@latest`를 사용하세요. 새 버전이 나오면 서버가 시작 시 stderr로 알려줍니다(`GITLAB_DISABLE_VERSION_CHECK=true`로 비활성화 가능).
142
+
143
+ #### Claude Desktop 원클릭 설치(MCP Bundle)
144
+
145
+ v2.3.1 이후의 GitHub 릴리스마다 `gitlab-mcp.mcpb` [MCP Bundle](https://github.com/modelcontextprotocol/mcpb)이 첨부됩니다. [최신 번들](https://github.com/zereight/gitlab-mcp/releases/latest/download/gitlab-mcp.mcpb)을 내려받아 Claude Desktop으로 열거나 **Settings → Extensions**에 끌어다 놓으세요. Claude Desktop이 Personal Access Token을 입력받아 민감 정보로 저장하고, `GITLAB_API_URL`, `GITLAB_PERMISSION_MODE`, `GITLAB_TOOLSETS`, `GITLAB_MASKING_ENABLED`를 설정할 수 있게 합니다. Node.js나 npm을 따로 설치할 필요가 없습니다.
146
+
147
+ 소스에서 번들을 만들려면 `npm run pack:mcpb`를 실행하세요(`gitlab-mcp.mcpb` 생성).
142
148
 
143
149
  #### CLI 인자 사용하기(환경 변수 문제가 있는 클라이언트용)
144
150
 
package/README.md CHANGED
@@ -143,7 +143,13 @@ The store path is pinned by your lock file; update it with `nix flake update git
143
143
 
144
144
  The examples use `zereight-mcp-gitlab`, a less collision-prone alias for the legacy `mcp-gitlab` binary. If your MCP client cannot find it, use the absolute path from `which zereight-mcp-gitlab`.
145
145
 
146
- No global install? Pin `npx` to the previous stable release (the version these docs recommend), for example `npx -y @zereight/mcp-gitlab@2.3.0`. If you always want the newest release, use `npx -y @zereight/mcp-gitlab@latest` instead. The server prints a notice to stderr on startup when a newer version is available (disable with `GITLAB_DISABLE_VERSION_CHECK=true`).
146
+ No global install? Pin `npx` to the previous stable release (the version these docs recommend), for example `npx -y @zereight/mcp-gitlab@2.3.1`. If you always want the newest release, use `npx -y @zereight/mcp-gitlab@latest` instead. The server prints a notice to stderr on startup when a newer version is available (disable with `GITLAB_DISABLE_VERSION_CHECK=true`).
147
+
148
+ #### Claude Desktop one-click install (MCP Bundle)
149
+
150
+ Every GitHub release after v2.3.1 ships a `gitlab-mcp.mcpb` [MCP Bundle](https://github.com/modelcontextprotocol/mcpb). Download the [latest bundle](https://github.com/zereight/gitlab-mcp/releases/latest/download/gitlab-mcp.mcpb) and open it with Claude Desktop (or drag it into **Settings → Extensions**). Claude Desktop asks for your Personal Access Token (stored as a sensitive value) and lets you set `GITLAB_API_URL`, `GITLAB_PERMISSION_MODE`, `GITLAB_TOOLSETS`, and `GITLAB_MASKING_ENABLED`. No separate Node.js or npm install is needed.
151
+
152
+ To build the bundle from source, run `npm run pack:mcpb` (writes `gitlab-mcp.mcpb`).
147
153
 
148
154
  #### Using CLI Arguments (for clients with env var issues)
149
155
 
package/README.pt-BR.md CHANGED
@@ -138,7 +138,13 @@ O caminho no store é fixado pelo seu lock file; atualize-o com `nix flake updat
138
138
 
139
139
  Os exemplos usam `zereight-mcp-gitlab`, um alias com menor chance de conflito que o binário legado `mcp-gitlab`. Se o seu cliente MCP não o encontrar, use o caminho absoluto retornado por `which zereight-mcp-gitlab`.
140
140
 
141
- Não quer instalar globalmente? Fixe o `npx` na versão estável anterior (a versão recomendada por esta documentação), por exemplo `npx -y @zereight/mcp-gitlab@2.3.0`. Se quiser sempre a versão mais recente, use `npx -y @zereight/mcp-gitlab@latest`. O servidor exibe um aviso no stderr durante a inicialização quando existe uma versão mais nova disponível (desative com `GITLAB_DISABLE_VERSION_CHECK=true`).
141
+ Não quer instalar globalmente? Fixe o `npx` na versão estável anterior (a versão recomendada por esta documentação), por exemplo `npx -y @zereight/mcp-gitlab@2.3.1`. Se quiser sempre a versão mais recente, use `npx -y @zereight/mcp-gitlab@latest`. O servidor exibe um aviso no stderr durante a inicialização quando existe uma versão mais nova disponível (desative com `GITLAB_DISABLE_VERSION_CHECK=true`).
142
+
143
+ #### Instalação com um clique no Claude Desktop (MCP Bundle)
144
+
145
+ Cada release no GitHub posterior à v2.3.1 inclui um [MCP Bundle](https://github.com/modelcontextprotocol/mcpb) `gitlab-mcp.mcpb`. Baixe o [bundle mais recente](https://github.com/zereight/gitlab-mcp/releases/latest/download/gitlab-mcp.mcpb) e abra-o com o Claude Desktop (ou arraste-o para **Settings → Extensions**). O Claude Desktop pede seu Personal Access Token (armazenado como valor sensível) e permite definir `GITLAB_API_URL`, `GITLAB_PERMISSION_MODE`, `GITLAB_TOOLSETS` e `GITLAB_MASKING_ENABLED`. Não é preciso instalar Node.js ou npm separadamente.
146
+
147
+ Para gerar o bundle a partir do código-fonte, execute `npm run pack:mcpb` (gera `gitlab-mcp.mcpb`).
142
148
 
143
149
  #### Usando argumentos de CLI (para clientes com problemas com variáveis de ambiente)
144
150
 
package/README.zh-CN.md CHANGED
@@ -138,7 +138,13 @@ command = lib.getExe inputs.gitlab-mcp.packages.${system}.default;
138
138
 
139
139
  示例使用 `zereight-mcp-gitlab`,这是比旧的 `mcp-gitlab` 更不容易冲突的别名。如果 MCP 客户端找不到它,请使用 `which zereight-mcp-gitlab` 输出的绝对路径。
140
140
 
141
- 如果不想全局安装,请将 `npx` 固定到上一个稳定版本(即文档推荐的版本),例如 `npx -y @zereight/mcp-gitlab@2.3.0`。如果始终想使用最新版本,请改用 `npx -y @zereight/mcp-gitlab@latest`。有新版本发布时,服务器会在启动时通过 stderr 提示(可用 `GITLAB_DISABLE_VERSION_CHECK=true` 关闭)。
141
+ 如果不想全局安装,请将 `npx` 固定到上一个稳定版本(即文档推荐的版本),例如 `npx -y @zereight/mcp-gitlab@2.3.1`。如果始终想使用最新版本,请改用 `npx -y @zereight/mcp-gitlab@latest`。有新版本发布时,服务器会在启动时通过 stderr 提示(可用 `GITLAB_DISABLE_VERSION_CHECK=true` 关闭)。
142
+
143
+ #### Claude Desktop 一键安装(MCP Bundle)
144
+
145
+ v2.3.1 之后的每个 GitHub Release 都附带 `gitlab-mcp.mcpb` [MCP Bundle](https://github.com/modelcontextprotocol/mcpb)。下载[最新的 bundle](https://github.com/zereight/gitlab-mcp/releases/latest/download/gitlab-mcp.mcpb),用 Claude Desktop 打开(或拖到 **Settings → Extensions** 中)。Claude Desktop 会要求输入 Personal Access Token(作为敏感值保存),并可设置 `GITLAB_API_URL`、`GITLAB_PERMISSION_MODE`、`GITLAB_TOOLSETS` 和 `GITLAB_MASKING_ENABLED`。无需另外安装 Node.js 或 npm。
146
+
147
+ 如需从源码构建 bundle,运行 `npm run pack:mcpb`(生成 `gitlab-mcp.mcpb`)。
142
148
 
143
149
  #### 使用 CLI 参数(适用于环境变量有问题的客户端)
144
150
 
package/build/index.js CHANGED
@@ -109,6 +109,7 @@ import { buildBulkPublishDraftNotesBody, needsGitLab19_2BulkPublish, } from "./u
109
109
  import { appendFilterParam, appendFilterParams, cleanMutuallyExclusiveIdUsernameOptions, dropBlankArrayEntries, isBlankFilterValue, LIST_MERGE_REQUESTS_ID_USERNAME_PAIRS, sanitizeToolArguments, } from "./utils/tool-args.js";
110
110
  import { applyJmespathToToolResult, getJmespathSyntaxError, JMESPATH_TOOL_ARGUMENT, JMESPATH_TOOL_ARGUMENT_DESCRIPTION, omitJmespathArgument, readJmespathExpression, } from "./utils/jmespath-tool-result.js";
111
111
  import { parseSearchReplaceBlocks, applySearchReplace, applyUnifiedDiff, } from "./utils/patch-helper.js";
112
+ import { zodSchemaFor } from "./utils/schema.js";
112
113
  import { GitLabClientPool } from "./gitlab-client-pool.js";
113
114
  import { advertisesReadOnly, allTools, readOnlyTools, destructiveTools, deleteTools, parseEnabledToolsets, parseIndividualTools, buildFeatureFlagOverrides, isToolInEnabledToolset, findSmallestToolsetForTool, isExplicitOnlyToolsetId, isExplicitToolsetOnlyTool, isToolsetFullyActive, listDiscoverableCategories, TOOLSET_DEFINITIONS, DISCOVERABLE_TOOLSET_IDS, } from "./tools/registry.js";
114
115
  import { executeGitLabApiRequestAsync, GitLabApiRequestHttpError, GitLabApiRequestInputError, } from "./tools/gitlab-api-request.js";
@@ -8764,12 +8765,19 @@ async function handleToolCall(params) {
8764
8765
  }
8765
8766
  case "rebase_merge_request": {
8766
8767
  const { project_id, merge_request_iid, skip_ci, wait, timeout_seconds, poll_interval_seconds, } = RebaseMergeRequestSchema.parse(params.arguments);
8767
- const enqueued = await rebaseMergeRequest(project_id, merge_request_iid, skip_ci);
8768
8768
  if (!wait) {
8769
+ const enqueued = await rebaseMergeRequest(project_id, merge_request_iid, skip_ci);
8769
8770
  return { content: [{ type: "text", text: JSON.stringify(enqueued) }] };
8770
8771
  }
8772
+ const { mergeRequest: previous } = await getMergeRequestRebaseStatus(project_id, merge_request_iid);
8773
+ await rebaseMergeRequest(project_id, merge_request_iid, skip_ci);
8771
8774
  const { mergeRequest } = await waitForStatus(signal => getMergeRequestRebaseStatus(project_id, merge_request_iid, signal), TERMINAL_REBASE_STATUSES, timeout_seconds, poll_interval_seconds);
8772
- return { content: [{ type: "text", text: JSON.stringify(mergeRequest) }] };
8775
+ const rebaseResult = {
8776
+ ...mergeRequest,
8777
+ previous_sha: previous.sha,
8778
+ head_changed: mergeRequest.sha !== previous.sha,
8779
+ };
8780
+ return { content: [{ type: "text", text: JSON.stringify(rebaseResult) }] };
8773
8781
  }
8774
8782
  case "get_merge_request_approval_state": {
8775
8783
  const args = GetMergeRequestApprovalStateSchema.parse(params.arguments);
@@ -11328,9 +11336,17 @@ async function handleToolCall(params) {
11328
11336
  // Sensitive fields are also covered by REDACT_PATHS if arguments are logged elsewhere.
11329
11337
  logger.debug({ tool: params.name }, "Tool call failed");
11330
11338
  if (error instanceof z.ZodError) {
11331
- throw new Error(`Invalid arguments: ${error.issues
11332
- .map(e => `${e.path.join(".")}: ${e.message}`)
11333
- .join(", ")}`);
11339
+ const detail = error.issues
11340
+ .map(e => (e.path.length > 0 ? `${e.path.join(".")}: ${e.message}` : e.message))
11341
+ .join("; ");
11342
+ // Response schemas throw ZodError too. If the arguments pass the tool's own
11343
+ // schema, the failure came from parsing a GitLab response.
11344
+ const argsSchema = zodSchemaFor(allTools.find(tool => tool.name === params.name)?.inputSchema);
11345
+ if (argsSchema?.safeParse(params.arguments).success) {
11346
+ throw new Error(`Unexpected GitLab response for ${params.name}: ${detail}`);
11347
+ }
11348
+ // ToolInputError is returned as an isError tool result, so the model can fix and retry.
11349
+ throw new ToolInputError(`Invalid arguments for ${params.name}: ${detail}`);
11334
11350
  }
11335
11351
  throw error;
11336
11352
  }
@@ -2,7 +2,7 @@ const TOOL_GUIDANCE = {
2
2
  merge_merge_request: "Use this only after checking the merge request approval, conflict, and pipeline state; use `approve_merge_request` to approve rather than merge. The operation changes repository state and may squash commits, schedule auto-merge, or delete the source branch, so it requires merge permission and returns GitLab's merge result or a mergeability error. Pass `sha` from `get_merge_request` (`sha` or `diff_refs.head_sha`); GitLab 19.2+ groups may reject merges without it.",
3
3
  approve_merge_request: "Use this to record an approval on an existing merge request; it does not merge the request or change its source branch. The operation changes review state, may require re-authentication or approval permission, and returns the updated approval result or a permission/state error.",
4
4
  unapprove_merge_request: "Use this to remove the current user's approval from an existing merge request; use `merge_merge_request` only when you intend to merge. The operation changes review state and requires approval permission, and GitLab returns the updated result or an error when the request or approval is unavailable.",
5
- rebase_merge_request: "Use this when the source branch is behind its target branch; use `get_merge_request_conflicts` to inspect conflicts and `merge_merge_request` to merge. The operation rewrites the source branch history with a force push and requires permission to push to that branch. With `wait` true (default), it polls until the rebase ends and returns the merge request: GitLab reports a failed rebase in `merge_error`, but that field can also keep a message from an earlier attempt, so compare `sha` with its value before the rebase. If the rebase still runs after `timeout_seconds`, it returns a timeout error while GitLab continues the rebase. With `wait` false, it returns GitLab's enqueue response (`rebase_in_progress` true) at once. Set `skip_ci` to skip the CI pipeline for the rebased branch.",
5
+ rebase_merge_request: "Use this when the source branch is behind its target branch; use `get_merge_request_conflicts` to inspect conflicts and `merge_merge_request` to merge. The operation rewrites the source branch history with a force push and requires permission to push to that branch. With `wait` true (default), it polls until the rebase ends and returns the merge request plus `previous_sha` (its `sha` before the rebase) and `head_changed`. `head_changed: false` means that the head did not move; `merge_error` gives the reason when GitLab sends one. `merge_error` can keep a message from an earlier attempt, so it alone does not prove that this attempt failed. If the rebase still runs after `timeout_seconds`, it returns a timeout error while GitLab continues the rebase. With `wait` false, it returns GitLab's enqueue response (`rebase_in_progress` true) at once. Set `skip_ci` to skip the CI pipeline for the rebased branch.",
6
6
  get_merge_request_approval_state: "Use this to inspect approval rules and approvers before deciding whether a merge request can be merged; use `approve_merge_request` to change approval state. It is read-only and returns the approval-state response, while missing requests, unsupported GitLab versions, and permission failures are reported as errors.",
7
7
  get_merge_request_conflicts: "Use this to inspect merge conflicts before attempting `merge_merge_request`; it reports conflicts and does not resolve them. It is read-only, requires access to the project and merge request, and returns GitLab's conflict data or an error when the request cannot be evaluated.",
8
8
  list_merge_request_pipelines: "Use this to inspect pipelines associated with one merge request; use `list_pipelines` for project-wide pipeline filtering. It is read-only and paginated, requires project access, and returns pipeline records or GitLab errors for invalid identifiers, missing resources, or rate limits.",
@@ -1,4 +1,10 @@
1
1
  import { z } from "zod";
2
+ // JSON Schema produced by toJSONSchema -> the Zod schema it came from.
3
+ const zodSchemaByJsonSchema = new WeakMap();
4
+ /**
5
+ * Returns the Zod schema a toJSONSchema() result was built from, if any.
6
+ */
7
+ export const zodSchemaFor = (jsonSchema) => jsonSchema && typeof jsonSchema === "object" ? zodSchemaByJsonSchema.get(jsonSchema) : undefined;
2
8
  /**
3
9
  * Convert a Zod schema to JSON Schema, fixing nullable/optional fields
4
10
  * so they are not marked as required, and extracting required fields from the Zod schema.
@@ -154,5 +160,6 @@ export const toJSONSchema = (schema) => {
154
160
  }
155
161
  }
156
162
  }
163
+ zodSchemaByJsonSchema.set(fixedSchema, schema);
157
164
  return fixedSchema;
158
165
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zereight/mcp-gitlab",
3
- "version": "2.3.1",
3
+ "version": "2.3.2",
4
4
  "mcpName": "io.github.zereight/gitlab-mcp",
5
5
  "description": "GitLab MCP server for projects, merge requests, issues, pipelines, wiki, releases, and more",
6
6
  "keywords": [
@@ -69,6 +69,7 @@
69
69
  "lint:fix": "eslint . --fix",
70
70
  "release": "bash scripts/release.sh",
71
71
  "release:mcp-registry": "bash scripts/publish_mcp_registry.sh",
72
+ "pack:mcpb": "npm run build && bash scripts/pack-mcpb.sh",
72
73
  "format": "prettier --write \"**/*.{js,ts,json,md}\"",
73
74
  "format:check": "prettier --check \"**/*.{js,ts,json,md}\""
74
75
  },