Skip to content
Merged
42 changes: 40 additions & 2 deletions .well-known/mcp/server-card.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"serverInfo": {
"name": "io.github.zereight/gitlab-mcp",
"version": "2.2.3"
"version": "2.2.4"
},
"authentication": {
"required": true,
Expand Down Expand Up @@ -10827,9 +10827,47 @@
]
}
},
{
"name": "gitlab_api_request",
"description": "DANGER: bypasses group and project restrictions, tool allowlists (GITLAB_TOOLS and GITLAB_DENIED_TOOLS_REGEX on other tools), and individual tool safety checks. The full token scope is exposed. Send one GitLab REST call under /api/v4. Readonly mode allows GET only, and modify mode rejects DELETE. Enable it only by listing api in GITLAB_TOOLSETS; all, discover_tools, and GITLAB_TOOLS do not. Prompt injection can drive this tool, so operators who rely on group, project, or tool restrictions must not enable it. GITLAB_ALLOWED_PROJECT_IDS is enforced only for /projects/:id paths; other endpoints are not constrained.",
"inputSchema": {
"type": "object",
"properties": {
"method": {
"description": "HTTP method. Defaults to GET. Non-GET requires a permission mode that allows writes. DELETE is rejected in modify mode.",
"type": "string",
"enum": [
"GET",
"POST",
"PUT",
"PATCH",
"DELETE"
]
},
"path": {
"type": "string",
"minLength": 1,
"description": "Path relative to /api/v4, such as projects/1 or /projects/1/issues. Absolute URLs are rejected."
},
"query": {
"description": "Query string parameters. Arrays are repeated as separate keys.",
"type": "object",
"propertyNames": {
"type": "string"
}
},
"body": {
"description": "JSON request body for POST, PUT, PATCH, and DELETE. Rejected on GET."
}
},
"required": [
"path"
]
}
},
{
"name": "discover_tools",
"description": "Discover and activate additional tool categories for this session. Available categories: core, merge_requests, issues, repositories, branches, projects, labels, ci, groups, pipelines, milestones, wiki, releases, tags, snippets, users, workitems, webhooks, search, variables, dependency_proxy, vulnerabilities, orbit. Already-active categories are listed in the response. Use this when a needed opt-in category is not currently exposed; omit `category` to inspect available categories, then call it with a category to activate that group for the current session. It changes only the session's tool registry, returns the active-tool summary, and does not change GitLab data.",
"description": "Discover and activate additional tool categories for this session. Available categories: core, merge_requests, issues, repositories, branches, projects, labels, ci, groups, pipelines, milestones, wiki, releases, tags, snippets, users, workitems, webhooks, search, variables, dependency_proxy, vulnerabilities, orbit. Already-active categories are listed in the response. Explicit-only toolsets are omitted; list them in GITLAB_TOOLSETS. Use this when a needed opt-in category is not currently exposed; omit `category` to inspect available categories, then call it with a category to activate that group for the current session. It changes only the session's tool registry, returns the active-tool summary, and does not change GitLab data.",
"inputSchema": {
"type": "object",
"properties": {
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Generated by [`auto-changelog`](https://github.com/CookPete/auto-changelog).
##### Added

- Protected tag tools in the `tags` toolset: `list_protected_tags`, `get_protected_tag`, `protect_tag`, and `unprotect_tag` ([#802](https://github.com/zereight/gitlab-mcp/issues/802)). `protect_tag` and `unprotect_tag` are writes (`readonly` hides them). `unprotect_tag` is also blocked in `modify`, matching `unprotect_branch`.
- Explicit opt-in `api` toolset with `gitlab_api_request` for one GitLab REST call under `/api/v4`. Not enabled by `GITLAB_TOOLSETS=all`, `discover_tools`, or `GITLAB_TOOLS`. Readonly allows GET only; modify rejects DELETE ([#804](https://github.com/zereight/gitlab-mcp/issues/804))
- Opt-in `snippets` toolset: `list_snippets`, `get_snippet`, `create_snippet`, `update_snippet`, and `delete_snippet` for personal and project snippets ([#730](https://github.com/zereight/gitlab-mcp/pull/730))
- Standalone `zereight-mcp-gitlab auth` device-flow command for SSO / headless OAuth ([#591](https://github.com/zereight/gitlab-mcp/issues/591))
- `create_webhook`, `update_webhook`, and `delete_webhook` for project and group hooks ([#713](https://github.com/zereight/gitlab-mcp/issues/713))
Expand Down
10 changes: 7 additions & 3 deletions README.ko.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ PAT, OAuth, 읽기 전용 모드, 동적 API URL, 원격 인증을 지원하며

### 왜 이 GitLab MCP를 사용하나요?

- **274개 도구: toolset 272개 + `execute_graphql` + `discover_tools`** — 작은 toolset으로 시작하고, 런타임에 카테고리 활성화
- **275개 도구: toolset 273개 + `execute_graphql` + `discover_tools`** — 작은 toolset으로 시작하고, 런타임에 카테고리 활성화
- **MR 2단계 리뷰** — `list_merge_request_changed_files` → 배치 `get_merge_request_file_diff`
- **Agent Skill 내장** — `skills/gitlab-mcp/` 워크플로우 가이드
- **유연한 인증** — Personal Access Token, 로컬 OAuth2 브라우저 플로우, MCP OAuth 프록시, 요청별 원격 인증
Expand All @@ -50,7 +50,7 @@ PAT, OAuth, 읽기 전용 모드, 동적 API URL, 원격 인증을 지원하며
| | @zereight/mcp-gitlab | GitLab MCP A (커뮤니티 CQRS형) | GitLab 공식 MCP 서버 |
| --------------- | ---------------------------------------------------------------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| **적합한 경우** | AI 에이전트 워크플로우 | 엔터프라이즈 멀티 인스턴스 / 그룹형 도구 | GitLab에 내장, 별도 설치 없음 |
| **도구 모델** | 274개 도구: toolset 272개 + `execute_graphql` + `discover_tools` | ~50–60개 `browse_*` / `manage_*` 그룹 도구 | HTTP 헤더로 고르는 toolset |
| **도구 모델** | 275개 도구: toolset 273개 + `execute_graphql` + `discover_tools` | ~50–60개 `browse_*` / `manage_*` 그룹 도구 | HTTP 헤더로 고르는 toolset |
| **MR 리뷰** | 2단계 배치 diff | 서버마다 다름 | `get_merge_request`에 diffs |
| **Node.js** | >=18.17 | 보통 >=24 | stdio는 `mcp-remote`, Node.js 20+ |
| **라이선스** | MIT | 서버마다 다름 | GitLab의 일부 |
Expand Down Expand Up @@ -162,7 +162,7 @@ command = lib.getExe inputs.gitlab-mcp.packages.${system}.default;
- `--api-url` - GitLab API URL (`GITLAB_API_URL` 대체)
- `--read-only=true` - Deprecated (removed in next major (v3.0.0)); `--permission-mode=readonly`를 사용 (`GITLAB_READ_ONLY_MODE` 대체)
- `--permission-mode` - 권한 수준: `readonly`, `modify`(삭제/중단 도구 비활성), `full` (`GITLAB_PERMISSION_MODE` 대체, 기본값 `full`)
- `--toolsets=all` - 지정한 툴셋 활성화 (`GITLAB_TOOLSETS` 대체, 미설정 시 lean `core` 기본값 사용)
- `--toolsets=all` - 지정한 툴셋 활성화. 명시적 `api` 툴셋은 빠짐 (`GITLAB_TOOLSETS` 대체, 미설정 시 lean `core` 기본값 사용). `gitlab_api_request`는 `--toolsets=api`
- `--tools=list_issues` - 개별 도구 추가 (`GITLAB_TOOLS` 대체)
- `--use-wiki=true` - Deprecated (removed in next major (v3.0.0)); `--toolsets=core,wiki`를 사용 (`USE_GITLAB_WIKI` 대체)
- `--use-milestone=true` - Deprecated (removed in next major (v3.0.0)); `--toolsets=core,milestones`를 사용 (`USE_MILESTONE` 대체)
Expand Down Expand Up @@ -202,6 +202,10 @@ CLI 인자는 환경 변수보다 우선합니다.
> [Tools Reference](./docs/tools/index.md#feature-toggles)와
> [Environment Variables](./docs/configuration/environment-variables.md)를 참고하세요.

> [!CAUTION]
> `gitlab_api_request`(`api` 툴셋)는 `GITLAB_ALLOWED_GROUPS`와 그 밖의 그룹 제한, 프로젝트 허용 목록, 도구 단위 제한(`GITLAB_TOOLS`, 다른 도구에 걸린 `GITLAB_DENIED_TOOLS_REGEX`), 개별 도구 안전 검사를 우회합니다. 토큰 권한 범위 전체가 노출됩니다. 프롬프트 인젝션이 이 도구를 호출할 수 있습니다. 이런 제한에 의존하는 운영자는 켜면 안 됩니다.
> `GITLAB_TOOLSETS`에 `api`를 직접 적을 때만 켜집니다 (`GITLAB_TOOLSETS=all`, `discover_tools`, `GITLAB_TOOLS`, 레거시 `USE_*`, `GITLAB_TOOL_PROFILE`로는 안 됩니다). `GITLAB_ALLOWED_PROJECT_IDS`는 `/projects/:id` 경로만 검사합니다. `/search`, `/users`, `/groups/:id`, `/runners` 같은 엔드포인트는 제한되지 않습니다. `GITLAB_PROJECT_ID`와 OAuth 그룹 허용 목록은 이 도구가 검사하지 않습니다.

- sse

변수 이름만 넘기세요. Docker 클라이언트는 export한 `GITLAB_PERSONAL_ACCESS_TOKEN` 값을 컨테이너로 복사합니다.
Expand Down
13 changes: 9 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ Supports PAT, OAuth, read-only mode, dynamic API URLs, and remote authorization

### Why use this GitLab MCP?

- **274 tools: 272 in toolsets + `execute_graphql` + `discover_tools`** — start with a small toolset; activate more at runtime without CQRS-style grouping
- **275 tools: 273 in toolsets + `execute_graphql` + `discover_tools`** — start with a small toolset; activate more at runtime without CQRS-style grouping
- **MR 2-step review** — `list_merge_request_changed_files` → batched `get_merge_request_file_diff`
- **Agent Skill built in** — workflow guidance in `skills/gitlab-mcp/`
- **Flexible auth** — Personal Access Token, local OAuth2 browser flow, MCP OAuth proxy, and per-request remote authorization
Expand All @@ -55,7 +55,7 @@ Supports PAT, OAuth, read-only mode, dynamic API URLs, and remote authorization
| | @zereight/mcp-gitlab | GitLab MCP A (community CQRS-style) | GitLab official MCP server |
| -------------- | ----------------------------------------------------------------- | -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| **Best for** | AI agent workflows | Enterprise multi-instance / grouped tools | Built into GitLab, no separate install |
| **Tool model** | 274 tools: 272 in toolsets + `execute_graphql` + `discover_tools` | ~50–60 grouped `browse_*` / `manage_*` tools | Toolsets chosen with an HTTP header |
| **Tool model** | 275 tools: 273 in toolsets + `execute_graphql` + `discover_tools` | ~50–60 grouped `browse_*` / `manage_*` tools | Toolsets chosen with an HTTP header |
| **MR review** | 2-step batched diff | Varies | `get_merge_request` with diffs |
| **Node.js** | >=18.17 | Often >=24 | Node.js 20+ for stdio via `mcp-remote` |
| **License** | MIT | Varies | Part of GitLab |
Expand Down Expand Up @@ -167,7 +167,7 @@ Some MCP clients (like GitHub Copilot CLI) have issues with environment variable
- `--api-url` - GitLab API URL (replaces `GITLAB_API_URL`)
- `--read-only=true` - Deprecated (removed in next major (v3.0.0)); use `--permission-mode=readonly` instead (replaces `GITLAB_READ_ONLY_MODE`)
- `--permission-mode` - Permission level: `readonly`, `modify` (no delete or teardown tools), or `full` (replaces `GITLAB_PERMISSION_MODE`, default `full`)
- `--toolsets=all` - Enable named toolsets (replaces `GITLAB_TOOLSETS`; unset uses the lean `core` default)
- `--toolsets=all` - Enable named toolsets except the explicit-only `api` toolset (replaces `GITLAB_TOOLSETS`; unset uses the lean `core` default). `gitlab_api_request` needs `--toolsets=api`
- `--tools=list_issues` - Add individual tools (replaces `GITLAB_TOOLS`)
- `--use-wiki=true` - Deprecated (removed in next major (v3.0.0)); use `--toolsets=core,wiki` instead (replaces `USE_GITLAB_WIKI`)
- `--use-milestone=true` - Deprecated (removed in next major (v3.0.0)); use `--toolsets=core,milestones` instead (replaces `USE_MILESTONE`)
Expand Down Expand Up @@ -208,6 +208,10 @@ The same binary is also a `gh`-style GitLab CLI (`tool <name>` or curated forms
> See [Tools Reference](./docs/tools/index.md#feature-toggles) and
> [Environment Variables](./docs/configuration/environment-variables.md).

> [!CAUTION]
> `gitlab_api_request` (toolset `api`) bypasses `GITLAB_ALLOWED_GROUPS` and other group restrictions, project allowlists, tool-level restrictions (`GITLAB_TOOLS`, `GITLAB_DENIED_TOOLS_REGEX` on other tools), and individual tool safety checks. The full token permission scope is exposed. Prompt injection can drive this tool. Operators who rely on these restrictions must NOT enable it.
> Enable it only by listing `api` in `GITLAB_TOOLSETS` (`GITLAB_TOOLSETS=all`, `discover_tools`, `GITLAB_TOOLS`, legacy `USE_*` flags, and `GITLAB_TOOL_PROFILE` do not). `GITLAB_ALLOWED_PROJECT_IDS` is checked only for `/projects/:id` paths. Endpoints such as `/search`, `/users`, `/groups/:id`, and `/runners` are not constrained. `GITLAB_PROJECT_ID` and OAuth group allowlists are not enforced.

- sse

Pass the variable name only. The Docker client copies the exported `GITLAB_PERSONAL_ACCESS_TOKEN` into the container.
Expand Down Expand Up @@ -918,7 +922,8 @@ Register the skill directory in your AI client to get optimal tool usage guidanc
271. `delete_snippet` - Delete a snippet
272. `list_project_runners` - List runners available to a project (type, status, paused, tag_list). Omits registration and authentication tokens.
273. `get_runner` - Get a runner's tag_list, run_untagged, locked, and access_level. When a project allowlist is active, the runner must be available to an allowed project. Omits registration and authentication tokens.
274. `discover_tools` - Discover and activate additional tool categories for this session. Available categories: core, merge_requests, issues, repositories, branches, projects, labels, ci, groups, pipelines, milestones, wiki, releases, tags, snippets, users, workitems, webhooks, search, variables, dependency_proxy, vulnerabilities, orbit. Already-active categories are listed in the response.
274. `gitlab_api_request` - Send one GitLab REST call under /api/v4. Enabled only when GITLAB_TOOLSETS lists api. Readonly allows GET; modify rejects DELETE.
275. `discover_tools` - Discover and activate additional tool categories for this session. Available categories: core, merge_requests, issues, repositories, branches, projects, labels, ci, groups, pipelines, milestones, wiki, releases, tags, snippets, users, workitems, webhooks, search, variables, dependency_proxy, vulnerabilities, orbit. Already-active categories are listed in the response.

<!-- TOOLS-END -->

Expand Down
Loading
Loading