@zereight/mcp-gitlab 2.3.6-next.131 → 2.3.6-next.132

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
@@ -306,7 +306,7 @@ MCP 서버가 직접 로컬 브라우저 callback을 받을 때만 `GITLAB_OAUTH
306
306
  | 환경 변수 | 필수 | 설명 |
307
307
  | ----------------------------- | ---- | ------------------------------------------------------------------------------------------------------------------------------- |
308
308
  | `GITLAB_MCP_OAUTH` | 예 | 활성화하려면 `true` |
309
- | `GITLAB_API_URL` | 예 | GitLab API base URL. URL에 자격 증명(`user:pass@`)을 넣지 마세요. 넣어도 무시됩니다. |
309
+ | `GITLAB_API_URL` | 예 | GitLab API base URL. URL에 자격 증명(`user:pass@`)을 넣지 마세요. 넣어도 무시됩니다. 비밀번호의 쉼표는 반드시 `%2C`로 적어야 합니다. |
310
310
  | `GITLAB_OAUTH_APP_ID` | 예 | GitLab OAuth Application ID |
311
311
  | `MCP_SERVER_URL` | 예 | 이 MCP 서버의 공개 HTTPS URL |
312
312
  | `STREAMABLE_HTTP` | 예 | 반드시 `true` |
@@ -574,7 +574,7 @@ node build/index.js
574
574
  | `GITLAB_MCP_OAUTH` | 예 | 활성화하려면 `true` |
575
575
  | `GITLAB_OAUTH_APP_ID` | 예 | 사전 등록 GitLab OAuth 애플리케이션의 client ID |
576
576
  | `MCP_SERVER_URL` | 예 | MCP 서버의 공개 HTTPS URL |
577
- | `GITLAB_API_URL` | 예 | GitLab 인스턴스 API URL(예: `https://gitlab.com/api/v4`). URL에 자격 증명(`user:pass@`)을 넣지 마세요. 넣어도 무시됩니다. |
577
+ | `GITLAB_API_URL` | 예 | GitLab 인스턴스 API URL(예: `https://gitlab.com/api/v4`). URL에 자격 증명(`user:pass@`)을 넣지 마세요. 넣어도 무시됩니다. 비밀번호의 쉼표는 반드시 `%2C`로 적어야 합니다. |
578
578
  | `STREAMABLE_HTTP` | 예 | 반드시 `true`(SSE 미지원) |
579
579
  | `GITLAB_OAUTH_SCOPES` | 아니오 | 요청할 GitLab scope 목록(쉼표 구분). 기본값은 `api`이며, 유효 permission mode가 `readonly`일 때 `read_api`입니다. 사전 등록 애플리케이션에 해당 scope가 설정되어 있어야 합니다. |
580
580
  | `OAUTH_REGISTER_RATE_LIMIT_PER_HOUR` | 아니오 | Dynamic Client Registration(`POST /register`)의 클라이언트 IP당 rolling 한도. 기본 `20`/시간, 범위 `1`–`1000`. IDE 창 여러 개 등으로 등록이 막히면 올리세요. GitLab API 한도와 무관합니다. |
package/README.md CHANGED
@@ -328,7 +328,7 @@ exchanging credentials with GitLab on behalf of the client.
328
328
  | Environment Variable | Required | Description |
329
329
  | ----------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------- |
330
330
  | `GITLAB_MCP_OAUTH` | ✅ | Set to `true` to enable |
331
- | `GITLAB_API_URL` | ✅ | GitLab API base URL. Do not embed credentials (`user:pass@`) in the URL; they are ignored. |
331
+ | `GITLAB_API_URL` | ✅ | GitLab API base URL. Do not embed credentials (`user:pass@`) in the URL; they are ignored. A comma in a password must be written as `%2C`. |
332
332
  | `GITLAB_OAUTH_APP_ID` | ✅ | GitLab OAuth Application ID |
333
333
  | `MCP_SERVER_URL` | ✅ | Public HTTPS URL of this MCP server |
334
334
  | `STREAMABLE_HTTP` | ✅ | Must be `true` |
@@ -616,7 +616,7 @@ No `headers` field is needed — Claude.ai obtains the token via OAuth automatic
616
616
  | `GITLAB_MCP_OAUTH` | Yes | Set to `true` to enable |
617
617
  | `GITLAB_OAUTH_APP_ID` | Yes | Client ID of the pre-registered GitLab OAuth application |
618
618
  | `MCP_SERVER_URL` | Yes | Public HTTPS URL of your MCP server; also allowed for `/mcp` Host/Origin checks |
619
- | `GITLAB_API_URL` | Yes | Your GitLab instance API URL (e.g. `https://gitlab.com/api/v4`). Do not embed credentials (`user:pass@`) in the URL; they are ignored. |
619
+ | `GITLAB_API_URL` | Yes | Your GitLab instance API URL (e.g. `https://gitlab.com/api/v4`). Do not embed credentials (`user:pass@`) in the URL; they are ignored. A comma in a password must be written as `%2C`. |
620
620
  | `STREAMABLE_HTTP` | Yes | Must be `true` (SSE is not supported) |
621
621
  | `GITLAB_OAUTH_SCOPES` | No | Comma-separated GitLab scopes to request (e.g. `api,read_user`). Defaults to `api` (or `read_api` when the effective permission mode is `readonly`). The pre-registered application must be configured with at least these scopes. |
622
622
  | `OAUTH_REGISTER_RATE_LIMIT_PER_HOUR` | No | Per-IP rolling limit for Dynamic Client Registration (`POST /register`). Default `20`/hour; range `1`–`1000`. Raise when clients (e.g. multiple IDE windows) hit registration throttling. Not a GitLab API limit. |
package/README.pt-BR.md CHANGED
@@ -306,7 +306,7 @@ Use `GITLAB_OAUTH_REDIRECT_URI` somente quando o próprio servidor MCP receber o
306
306
  | Variável de ambiente | Obrigatória | Descrição |
307
307
  | ----------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
308
308
  | `GITLAB_MCP_OAUTH` | sim | Defina como `true` para habilitar |
309
- | `GITLAB_API_URL` | sim | URL base da API do GitLab. Não inclua credenciais (`user:pass@`) na URL; elas são ignoradas. |
309
+ | `GITLAB_API_URL` | sim | URL base da API do GitLab. Não inclua credenciais (`user:pass@`) na URL; elas são ignoradas. Uma vírgula na senha deve ser escrita como `%2C`. |
310
310
  | `GITLAB_OAUTH_APP_ID` | sim | Application ID do OAuth do GitLab |
311
311
  | `MCP_SERVER_URL` | sim | URL HTTPS pública deste servidor MCP |
312
312
  | `STREAMABLE_HTTP` | sim | Deve ser `true` |
@@ -574,7 +574,7 @@ Não é necessário definir `headers`. O Claude.ai obtém o token via OAuth.
574
574
  | `GITLAB_MCP_OAUTH` | sim | Defina como `true` para habilitar |
575
575
  | `GITLAB_OAUTH_APP_ID` | sim | Client ID do aplicativo OAuth do GitLab previamente registrado |
576
576
  | `MCP_SERVER_URL` | sim | URL HTTPS pública do servidor MCP |
577
- | `GITLAB_API_URL` | sim | URL da API da instância GitLab (por exemplo, `https://gitlab.com/api/v4`). Não inclua credenciais (`user:pass@`) na URL; elas são ignoradas. |
577
+ | `GITLAB_API_URL` | sim | URL da API da instância GitLab (por exemplo, `https://gitlab.com/api/v4`). Não inclua credenciais (`user:pass@`) na URL; elas são ignoradas. Uma vírgula na senha deve ser escrita como `%2C`. |
578
578
  | `STREAMABLE_HTTP` | sim | Deve ser `true` (SSE não é suportado) |
579
579
  | `GITLAB_OAUTH_SCOPES` | não | Scopes do GitLab a solicitar, separados por vírgula. O padrão é `api`, ou `read_api` quando o permission mode efetivo é `readonly`. O aplicativo previamente registrado deve ter pelo menos esses scopes configurados. |
580
580
  | `OAUTH_REGISTER_RATE_LIMIT_PER_HOUR` | não | Limite rolling de Dynamic Client Registration (`POST /register`) por IP do cliente. Padrão `20`/hora, intervalo `1`–`1000`. Aumente se múltiplas janelas de IDE estiverem atingindo o limite. Não está relacionado aos limites da API do GitLab. |
package/README.zh-CN.md CHANGED
@@ -305,7 +305,7 @@ OpenCode、MCPJam、Claude.ai 等远程 MCP 客户端可能会在授权时发送
305
305
  | 环境变量 | 必需 | 说明 |
306
306
  | ----------------------------- | ---- | ----------------------------------------------------------------------------------------------------------- |
307
307
  | `GITLAB_MCP_OAUTH` | 是 | 设置为 `true` 以启用 |
308
- | `GITLAB_API_URL` | 是 | GitLab API base URL。不要在 URL 中嵌入凭据(`user:pass@`),嵌入的凭据会被忽略。 |
308
+ | `GITLAB_API_URL` | 是 | GitLab API base URL。不要在 URL 中嵌入凭据(`user:pass@`),嵌入的凭据会被忽略。密码中的逗号必须写成 `%2C`。 |
309
309
  | `GITLAB_OAUTH_APP_ID` | 是 | GitLab OAuth Application ID |
310
310
  | `MCP_SERVER_URL` | 是 | 此 MCP 服务器的公开 HTTPS URL |
311
311
  | `STREAMABLE_HTTP` | 是 | 必须为 `true` |
@@ -573,7 +573,7 @@ node build/index.js
573
573
  | `GITLAB_MCP_OAUTH` | 是 | 设置为 `true` 以启用 |
574
574
  | `GITLAB_OAUTH_APP_ID` | 是 | 预先注册的 GitLab OAuth 应用 client ID |
575
575
  | `MCP_SERVER_URL` | 是 | MCP 服务器的公开 HTTPS URL |
576
- | `GITLAB_API_URL` | 是 | GitLab 实例 API URL(例如 `https://gitlab.com/api/v4`)。不要在 URL 中嵌入凭据(`user:pass@`),嵌入的凭据会被忽略。 |
576
+ | `GITLAB_API_URL` | 是 | GitLab 实例 API URL(例如 `https://gitlab.com/api/v4`)。不要在 URL 中嵌入凭据(`user:pass@`),嵌入的凭据会被忽略。密码中的逗号必须写成 `%2C`。 |
577
577
  | `STREAMABLE_HTTP` | 是 | 必须为 `true`(不支持 SSE) |
578
578
  | `GITLAB_OAUTH_SCOPES` | 否 | 要请求的 GitLab scopes,以逗号分隔。默认值为 `api`;有效 permission mode 为 `readonly` 时为 `read_api`。预注册应用必须配置至少这些 scopes。 |
579
579
  | `OAUTH_REGISTER_RATE_LIMIT_PER_HOUR` | 否 | Dynamic Client Registration(`POST /register`)的每客户端 IP rolling 限制。默认 `20`/小时,范围 `1`–`1000`。多个 IDE 窗口等导致注册被限流时可调高。与 GitLab API 限额无关。 |
package/build/index.js CHANGED
@@ -94,7 +94,7 @@ import { listMcpResources, listMcpResourceTemplates, readMcpResource, } from "./
94
94
  import { getMcpPrompt, listMcpPrompts } from "./server/mcp-prompts.js";
95
95
  import { isInitializationRequestBody, isUnauthenticatedDiscoveryRequestBody, readAcceptHeader, readMcpSessionIdHeader, redactSessionIdForLog, } from "./server/request-helpers.js";
96
96
  export { readMcpSessionIdHeader } from "./server/request-helpers.js";
97
- import { apiUrlUserinfoWarning, commaSplitHint, configuredApiUrlErrors, encodeGitLabPath, encodeGitLabPathSegment, invalidListEntryError, isCleartextRemoteUrl, normalizeGitLabApiUrl, parseConfiguredGitLabApiUrls, } from "./utils/url.js";
97
+ import { apiUrlHostnameForLog, apiUrlUserinfoWarning, commaSplitHint, configuredApiUrlErrors, encodeGitLabPath, encodeGitLabPathSegment, invalidListEntryError, isCleartextRemoteUrl, normalizeGitLabApiUrl, parseConfiguredGitLabApiUrls, } from "./utils/url.js";
98
98
  import { estimateMergeCommitCount, filterDiffsByPatterns, openSafeOutputWriteStream, resolveDownloadRoot, readSafeExistingFile, summarizeWebhookEvents, } from "./utils/helpers.js";
99
99
  import { graphqlQueryContainsWriteOperation, graphqlQueryContainsDeleteOperation, } from "./utils/graphql-query.js";
100
100
  import { resolveNestedWikiUpdateTitle } from "./utils/wiki-title.js";
@@ -12958,7 +12958,9 @@ function initOAuthClient() {
12958
12958
  return;
12959
12959
  }
12960
12960
  if (isCleartextRemoteUrl(GITLAB_API_URL)) {
12961
- throw new Error(`Refusing to send OAuth tokens over cleartext HTTP to ${redactUrlSecretsInText(GITLAB_API_URL)}. ` +
12961
+ throw new Error(
12962
+ // The host name only: a port can hold the start of a password (see apiUrlHostnameForLog).
12963
+ `Refusing to send OAuth tokens over cleartext HTTP to http://${apiUrlHostnameForLog(GITLAB_API_URL)}. ` +
12962
12964
  "Use an https:// GITLAB_API_URL (http:// is only allowed for localhost).");
12963
12965
  }
12964
12966
  oauthClient = createGitLabOAuthClient(GITLAB_API_URL.replace(/\/api\/v4$/, ""));
@@ -12998,8 +13000,9 @@ async function runServer() {
12998
13000
  }
12999
13001
  });
13000
13002
  }
13001
- logger.info(`Configured GitLab API URLs: ${GITLAB_API_URLS.map(redactUrlSecretsInText).join(", ")}`);
13002
- logger.info(`Default GitLab API URL: ${redactUrlSecretsInText(GITLAB_API_URL)}`);
13003
+ // Host names only. GITLAB_API_URL is GITLAB_API_URLS[0], so it is logged the same way.
13004
+ logger.info(`Configured GitLab API URLs: ${GITLAB_API_URLS.map(apiUrlHostnameForLog).join(", ")}`);
13005
+ logger.info(`Default GitLab API URL: ${apiUrlHostnameForLog(GITLAB_API_URL)}`);
13003
13006
  if (GITLAB_OAUTH_ALLOWED_GROUPS) {
13004
13007
  logger.info(`Group access control enabled for: ${GITLAB_OAUTH_ALLOWED_GROUPS.join(", ")}`);
13005
13008
  }
@@ -108,6 +108,25 @@ export function parseConfiguredGitLabApiUrls(value) {
108
108
  hadUserinfo: entries.some(entry => entry.hadUserinfo),
109
109
  };
110
110
  }
111
+ /**
112
+ * The host name of a configured API URL, for the startup log. A password with a
113
+ * literal comma can be split into two URLs, and "http://alice:12" then reads
114
+ * the start of the password as a port, which text redaction keeps. The port,
115
+ * userinfo, path, and query are left out. An IPv6 host keeps its brackets.
116
+ * An "@" after the host means the host can be part of a password
117
+ * ("http://sec/ret@host" from "alice:12,http://sec/ret@host"), so it is not shown.
118
+ */
119
+ export function apiUrlHostnameForLog(url) {
120
+ let parsed;
121
+ try {
122
+ parsed = new URL(url);
123
+ }
124
+ catch {
125
+ return "<invalid>";
126
+ }
127
+ const atAfterHost = parsed.pathname.includes("@") || parsed.search.includes("@") || parsed.hash.includes("@");
128
+ return parsed.hostname.length === 0 || atAfterHost ? "<invalid>" : parsed.hostname;
129
+ }
111
130
  const LOOPBACK_HOSTNAMES = new Set(["localhost", "127.0.0.1", "[::1]"]);
112
131
  /**
113
132
  * True when the URL is plain `http://` to a non-loopback host, i.e. credentials sent
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zereight/mcp-gitlab",
3
- "version": "2.3.6-next.131",
3
+ "version": "2.3.6-next.132",
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": [