{"id":49433511,"url":"https://github.com/jmrplens/gitlab-mcp-server","last_synced_at":"2026-05-22T07:15:24.772Z","repository":{"id":352837436,"uuid":"1208139072","full_name":"jmrplens/gitlab-mcp-server","owner":"jmrplens","description":"GitLab MCP server: 1006 self-managed / 1011 GitLab.com with Orbit; 32/47/48 meta-tools, 46 resources, 38 prompts, stdio/HTTP.","archived":false,"fork":false,"pushed_at":"2026-05-06T21:09:45.000Z","size":7306,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-06T21:25:51.534Z","etag":null,"topics":["ai-tools","gitlab","gitlab-api","go","llm","mcp","mcp-server","model-context-protocol"],"latest_commit_sha":null,"homepage":"https://jmrplens.github.io/gitlab-mcp-server/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jmrplens.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":"CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["jmrplens"]}},"created_at":"2026-04-11T21:48:02.000Z","updated_at":"2026-05-06T21:05:49.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/jmrplens/gitlab-mcp-server","commit_stats":null,"previous_names":["jmrplens/gitlab-mcp-server"],"tags_count":24,"template":false,"template_full_name":null,"purl":"pkg:github/jmrplens/gitlab-mcp-server","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmrplens%2Fgitlab-mcp-server","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmrplens%2Fgitlab-mcp-server/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmrplens%2Fgitlab-mcp-server/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmrplens%2Fgitlab-mcp-server/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jmrplens","download_url":"https://codeload.github.com/jmrplens/gitlab-mcp-server/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jmrplens%2Fgitlab-mcp-server/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32873248,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-10T13:40:02.631Z","status":"ssl_error","status_checked_at":"2026-05-10T13:40:02.145Z","response_time":54,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-tools","gitlab","gitlab-api","go","llm","mcp","mcp-server","model-context-protocol"],"created_at":"2026-04-29T15:00:51.305Z","updated_at":"2026-05-22T07:15:24.765Z","avatar_url":"https://github.com/jmrplens.png","language":"Go","funding_links":["https://github.com/sponsors/jmrplens"],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg alt=\"\" src=\"site/src/assets/banner-dark.svg\" width=\"840\"\u003e\n\u003c/p\u003e\n\n# GitLab MCP Server\n\n\u003cp align=\"center\"\u003e\n\n[![GitHub Release](https://img.shields.io/github/v/release/jmrplens/gitlab-mcp-server?style=flat\u0026logo=github\u0026label=Release)](https://github.com/jmrplens/gitlab-mcp-server/releases/latest)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n[![Go Report Card](https://goreportcard.com/badge/github.com/jmrplens/gitlab-mcp-server)](https://goreportcard.com/report/github.com/jmrplens/gitlab-mcp-server)\n[![Go Reference](https://pkg.go.dev/badge/github.com/jmrplens/gitlab-mcp-server/v2.svg)](https://pkg.go.dev/github.com/jmrplens/gitlab-mcp-server/v2)\n[![Glama MCP Score](https://glama.ai/mcp/servers/jmrplens/gitlab-mcp-server/badges/score.svg)](https://glama.ai/mcp/servers/jmrplens/gitlab-mcp-server)\n[![GitLab Mirror](https://img.shields.io/badge/GitLab-mirror-FC6D26?logo=gitlab\u0026logoColor=white)](https://gitlab.com/jmrp/gitlab-mcp-server)\n\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n\n[![Quality Gate](https://sonarcloud.io/api/project_badges/measure?project=jmrplens_gitlab-mcp-server\u0026metric=alert_status)](https://sonarcloud.io/summary/overall?id=jmrplens_gitlab-mcp-server)\n[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=jmrplens_gitlab-mcp-server\u0026metric=coverage)](https://sonarcloud.io/summary/overall?id=jmrplens_gitlab-mcp-server)\n![Platform](https://img.shields.io/badge/Windows%20%7C%20Linux%20%7C%20macOS-amd64%20%26%20arm64-lightgrey?style=flat\u0026logo=windows-terminal\u0026logoColor=white)\n\n\u003c/p\u003e\n\nA **Model Context Protocol (MCP) server** that exposes the entire GitLab API as MCP tools, resources, and prompts for AI assistants. Single static binary — zero dependencies.\n\n\u003e **Security first**: Continuously monitored on [SonarCloud](https://sonarcloud.io/summary/overall?id=jmrplens_gitlab-mcp-server) with quality gates, coverage, and security scanning. Supports read-only mode, safe mode (dry-run preview), and self-hosted GitLab with TLS verification.\n\u003e\n\u003e **Repository mirror**: GitHub is the canonical repository. A read-only mirror of the code and releases is available on [GitLab.com](https://gitlab.com/jmrp/gitlab-mcp-server) for discoverability; please open code contributions on GitHub.\n\n## Token Footprint\n\n\u003c!-- START TOKEN FOOTPRINT --\u003e\n\nMeasured with `go run ./cmd/gen_readme/` against the current base catalog. Totals estimate startup context visible to an MCP client: visible tool schemas plus shared resources and prompts, using the same byte/4 token heuristic as `cmd/audit_tokens`.\n\n**Default configuration**: with `TOOL_SURFACE` unset or `TOOL_SURFACE=dynamic`, `CAPABILITY_SURFACE=full`, `META_TOOLS` unset, `META_PARAM_SCHEMA=opaque`, and `GITLAB_ENTERPRISE` unset or `false`, the server uses the **dynamic find/execute surface**. Use `TOOL_SURFACE=meta` only when you explicitly want domain meta-tools; use `TOOL_SURFACE=individual` only when your client can handle the full tool catalog.\n\n| Configuration (`TOOL_SURFACE` / `CAPABILITY_SURFACE`) | Visible tools | Reachable actions | `META_PARAM_SCHEMA` | Tool schema tokens | Shared tokens | Total tokens |\n| ----------------------------------------------------- | ------------: | ----------------: | ------------------- | -----------------: | ------------: | -----------: |\n| `dynamic` / `full` (default)                          |             2 |               870 | n/a                 |              2,193 |        18,284 |       20,477 |\n| `dynamic` / `minimal`                                 |             2 |               870 | n/a                 |              2,193 |           740 |        2,933 |\n| `meta` / `full`                                       |            34 |               870 | `opaque`            |             66,405 |        18,284 |       84,689 |\n| `meta` / `minimal`                                    |            34 |               870 | `opaque`            |             66,405 |           740 |       67,145 |\n| `individual` / `full`                                 |           866 |               866 | n/a                 |            473,781 |        18,284 |      492,065 |\n\nRows use the base Community Edition catalog (`GITLAB_ENTERPRISE=false`). `META_PARAM_SCHEMA=opaque` affects only visible meta-tool input schemas; dynamic mode gets exact action schemas from `gitlab_find_action`, and every surface advertises `gitlab://tools` plus `gitlab://tools/{id}` for on-demand action browsing and input schemas. Individual mode already exposes one schema per tool.\n\n\u003c!-- END TOKEN FOOTPRINT --\u003e\n\n## Highlights\n\n- **1025 MCP tools** on self-managed Enterprise/Premium, or **1031 on GitLab.com Enterprise/Premium** with experimental Orbit Knowledge Graph support — broad GitLab REST API v4 + GraphQL coverage across 176 packages under `internal/tools`: projects, branches, tags, releases, merge requests, issues, pipelines, jobs, groups, users, wikis, environments, deployments, packages, container registry, runners, feature flags, CI/CD variables, security attributes, security categories, templates, admin settings, access tokens, deploy keys, Orbit, and more\n- **Default dynamic toolset** — exposes only `gitlab_find_action` and `gitlab_execute_tool` while keeping the same canonical GitLab action catalog. Optional domain meta-tools remain available with `TOOL_SURFACE=meta`: 33 base, 49 on self-managed Enterprise/Premium, or 50 on GitLab.com Enterprise/Premium\n- **AI model tool-use evaluation** — automated schema-only and Docker-backed runs against a populated GitLab CE instance measure tool/action selection, parameter shaping, recovery from GitLab errors, and destructive-action safety across Anthropic, Google, OpenAI, and Qwen. Published summaries appear in the managed evaluation block below; see [AI Model Evaluation Results](docs/testing/model-results.md)\n- **11 sampling actions** — LLM-assisted code review, issue analysis, pipeline failure diagnosis, security review, release notes, milestone reports, and more via `gitlab_analyze` meta-tool (MCP sampling capability)\n- **4 elicitation tools** — interactive creation wizards (issue, MR, release, project) with step-by-step user prompts\n- **46 MCP resources** in default dynamic/full mode — read-only data: user, groups, group members, group projects, projects, issues, pipelines, members, labels, milestones, branches, MRs, releases, tags, commits, file blobs, wiki pages, MR notes, MR discussions, single-entity templates (issue, MR, branch, tag, release, label, milestone, commit, wiki page, deployment, environment, job, board, snippet, deploy key, feature flag, group label, group milestone), the surface-aware `gitlab://tools` manifest and `gitlab://tools/{id}` detail template, workspace roots, and 5 workflow best-practice guides\n- **37 MCP prompts** — AI-optimized: code review, pipeline status, risk assessment, release notes, standup, workload, user stats, team management, cross-project dashboards, analytics, milestones, Git workflow quality, audit\n- **6 MCP capabilities** — logging, completions, roots, progress, sampling, elicitation\n- **50 tool icons** — base64-encoded SVG icons (`Sizes: [\"any\"]`) on all tools, resources, and prompts for visual identification in MCP clients\n- **Pagination** on all list endpoints with metadata (total items, pages, next/prev)\n- **Transports**: stdio (default for desktop AI) and HTTP (Streamable HTTP for remote clients)\n- **Cross-platform**: Windows, Linux \u0026 macOS, amd64 \u0026 arm64\n- **Self-hosted GitLab** with self-signed TLS certificate support\n\n## Example Prompts\n\nOnce connected, just talk to your AI assistant in natural language:\n\n\u003e \"List my GitLab projects\"\n\u003e \"Show me open merge requests in my-app\"\n\u003e \"Create a merge request from feature-login to main\"\n\u003e \"Review merge request !15 — is it safe to merge?\"\n\u003e \"List open issues assigned to me\"\n\u003e \"What's the pipeline status for project 42?\"\n\u003e \"Why did the last pipeline fail?\"\n\u003e \"Generate release notes from v1.0 to v2.0\"\n\nThe server handles the translation from natural language to GitLab API calls. You do not need to know project IDs, API endpoints, or JSON syntax — the AI assistant figures that out for you. See [Usage Examples](docs/examples/usage-examples.md) for more scenarios.\n\n## Quick Start\n\n### 1. Get the server\n\nDownload the latest binary for your platform from [GitHub Releases](https://github.com/jmrplens/gitlab-mcp-server/releases) and make it executable:\n\n```bash\nchmod +x gitlab-mcp-server-*  # Linux/macOS only\n```\n\nOr pull the published container image:\n\n```bash\ndocker pull ghcr.io/jmrplens/gitlab-mcp-server:latest\n```\n\n### 2. Configure GitLab access\n\n**Recommended**: Run the built-in setup wizard — it configures your GitLab connection and MCP client in one step:\n\n```bash\n./gitlab-mcp-server --setup\n```\n\n\u003e **Tip**: The wizard supports Web UI, Terminal UI, and plain CLI modes. On Windows, double-click the `.exe` to launch the wizard automatically.\n\nManual setup only needs a GitLab Personal Access Token with `api` scope:\n\n```env\nGITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx\n```\n\n`GITLAB_URL` defaults to `https://gitlab.com`; add it only when you connect to a self-managed GitLab instance.\n\n```env\nGITLAB_URL=https://gitlab.example.com\n```\n\n### 3. Connect your MCP client\n\nMost desktop clients use stdio: the client starts one local MCP server process and talks to it over stdin/stdout. Choose one of these runtime patterns.\n\n#### Native binary (stdio)\n\nVS Code and Cursor-style MCP configuration:\n\nAdd to `.vscode/mcp.json` in your workspace:\n\n```json\n{\n  \"servers\": {\n    \"gitlab\": {\n      \"type\": \"stdio\",\n      \"command\": \"/path/to/gitlab-mcp-server\",\n      \"env\": {\n        \"GITLAB_TOKEN\": \"glpat-xxxxxxxxxxxxxxxxxxxx\"\n      }\n    }\n  }\n}\n```\n\nClaude Desktop uses the same server command under `mcpServers`:\n\n```json\n{\n  \"mcpServers\": {\n    \"gitlab\": {\n      \"command\": \"/path/to/gitlab-mcp-server\",\n      \"env\": {\n        \"GITLAB_TOKEN\": \"glpat-xxxxxxxxxxxxxxxxxxxx\"\n      }\n    }\n  }\n}\n```\n\nFor client-specific paths, secure token prompts, HTTP OAuth, and extra IDEs, see [IDE Configuration](docs/ide-configuration.md).\n\n#### Docker launched by an IDE (stdio)\n\nIf an IDE starts Docker as the MCP server process, keep `docker run -i` and pass `--http=false` after the image name. Do not publish port 8080 in this mode.\n\n```json\n{\n  \"servers\": {\n    \"gitlab\": {\n      \"type\": \"stdio\",\n      \"command\": \"docker\",\n      \"args\": [\n        \"run\",\n        \"-i\",\n        \"--rm\",\n        \"-e\",\n        \"GITLAB_TOKEN\",\n        \"-e\",\n        \"GITLAB_URL\",\n        \"-e\",\n        \"GITLAB_SKIP_TLS_VERIFY\",\n        \"ghcr.io/jmrplens/gitlab-mcp-server:latest\",\n        \"--http=false\"\n      ],\n      \"env\": {\n        \"GITLAB_TOKEN\": \"glpat-xxxxxxxxxxxxxxxxxxxx\",\n        \"GITLAB_URL\": \"https://gitlab.com\",\n        \"GITLAB_SKIP_TLS_VERIFY\": \"false\"\n      }\n    }\n  }\n}\n```\n\n#### Docker or binary as an HTTP MCP server\n\nUse HTTP mode for shared, remote, or multi-user deployments. The Docker image\nstarts in HTTP mode by default, but the flags are shown explicitly here for\nclarity. These examples publish the container port on host loopback only;\n`--http-addr=0.0.0.0:8080` binds inside the container.\n\n```bash\n# Fixed GitLab instance for all clients\ndocker run -d --name gitlab-mcp-server -p 127.0.0.1:8080:8080 \\\n  ghcr.io/jmrplens/gitlab-mcp-server:latest \\\n  --http \\\n  --http-addr=0.0.0.0:8080 \\\n  --gitlab-url=https://gitlab.com\n\n# Multi-instance mode: clients send GITLAB-URL per request\ndocker run -d --name gitlab-mcp-server -p 127.0.0.1:8080:8080 \\\n  ghcr.io/jmrplens/gitlab-mcp-server:latest \\\n  --http \\\n  --http-addr=0.0.0.0:8080\n```\n\nHTTP clients authenticate each request with `PRIVATE-TOKEN` or `Authorization: Bearer`:\n\n```jsonc\n{\n  \"servers\": {\n    \"gitlab\": {\n      \"type\": \"http\",\n      \"url\": \"http://localhost:8080/mcp\",\n      \"headers\": {\n        \"PRIVATE-TOKEN\": \"glpat-xxxxxxxxxxxxxxxxxxxx\"\n      }\n    }\n  }\n}\n```\n\nIn multi-instance mode, clients must also send `GITLAB-URL`. See [HTTP Server Mode](docs/http-server-mode.md) for OAuth, reverse proxy, rate limit, and server-pool details.\n\n### 4. Verify\n\nOpen your AI client and try:\n\n\u003e _\"List my GitLab projects\"_\n\nSee the [Getting Started guide](https://jmrplens.github.io/gitlab-mcp-server/getting-started/) for detailed setup instructions.\n\n## Tool Modes\n\nThree registration modes, controlled by `TOOL_SURFACE`:\n\n| Mode                          | Tools                                                                              | Description                                                                                                                                                       |\n| ----------------------------- | ---------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **Dynamic Toolset** (default) | 2 visible tools                                                                    | Low-token find/execute surface over the canonical action catalog.                                                                                                 |\n| **Meta-Tools**                | 33 base GitLab/interactive tools; `gitlab_server` is a separate maintenance helper | Domain-grouped dispatchers with `action` parameter. Enable with `TOOL_SURFACE=meta`; see the full 33/49/50 catalog in [Meta-Tools Reference](docs/meta-tools.md). |\n| **Individual**                | 866 CE / 1025 self-managed enterprise / 1031 GitLab.com Enterprise                 | Every GitLab operation as a separate MCP tool.                                                                                                                    |\n\nFor dynamic experiments where resources and prompts dominate initial context, set `CAPABILITY_SURFACE=minimal` (stdio) or `--capability-surface=minimal` (HTTP). Minimal keeps `gitlab://workspace/roots` plus the surface-aware `gitlab://tools` manifest so dynamic, meta, and individual deployments can still read accepted call shapes. The default remains `full`.\n\nDynamic mode is now the default low-token find/execute surface; see [Dynamic Toolset](docs/dynamic-tools.md) for the field-aware ranking model, fuzzy fallback, response shapes, workflow diagrams, and migration guidance. Set `TOOL_SURFACE=meta` to use the consolidated domain meta-tool catalog.\n\nThe detailed meta-tool catalog now lives in [Meta-Tools Reference](docs/meta-tools.md), including action counts, Enterprise/Premium markers, and examples.\n\n## Compatibility\n\n| MCP Capability  | Support                                              |\n| --------------- | ---------------------------------------------------- |\n| **Tools**       | Up to 1031 individual / 33–50 meta                   |\n| **Resources**   | 46 (static + templates)                              |\n| **Prompts**     | 37 templates                                         |\n| **Completions** | Project, user, group, branch, tag                    |\n| **Logging**     | Structured (text/JSON) + MCP notifications           |\n| **Progress**    | Tool execution progress reporting                    |\n| **Sampling**    | 11 LLM-powered analysis actions via `gitlab_analyze` |\n| **Elicitation** | 4 interactive creation wizards                       |\n| **Roots**       | Workspace root tracking                              |\n\nTested with: VS Code + GitHub Copilot, Claude Desktop, Claude Code, Cursor, Windsurf, JetBrains IDEs, Zed, Kiro, Cline, Roo Code.\n\nSee the full [Compatibility Matrix](https://jmrplens.github.io/gitlab-mcp-server/compatibility/) for detailed client support.\n\n## AI Model Tool-Use Evaluation\n\nThe project includes an automated evaluator for model-facing MCP quality. It can\nrun schema-only checks against the tool catalog or execute validated model tool\ncalls through MCP against a Docker GitLab CE instance populated with fixtures.\nThe evaluator measures whether each model chooses the correct meta-tool and\naction, sends valid parameters, recovers from actionable GitLab errors, and\nrespects destructive-action safeguards.\n\n\u003c!-- START MODEL EVAL META SUMMARY --\u003e\nCurrent published result: **2026-05-18 Meta and Dynamic Docker full run**.\n\n| Provider  | Model                           | Compatibility | Tool accuracy |      Recovery | Docker live status          |\n| --------- | ------------------------------- | ------------- | ------------: | ------------: | --------------------------- |\n| Anthropic | `claude-haiku-4-5-20251001`     | Review        |        100.0% |    No repairs | 98.5% final across 264 ops  |\n| Google    | `gemini-3.1-flash-lite-preview` | Review        |         91.2% | 76.9% (10/13) | 97.8% final across 264 ops  |\n| OpenAI    | `gpt-5.4-nano`                  | OK            |        100.0% |  100.0% (2/2) | 100.0% final across 264 ops |\n| Qwen      | `qwen3.6-flash`                 | Review        |         97.0% |  100.0% (2/2) | 97.0% final across 264 ops  |\n\nThe published model-evaluation set covers 544 task attempts and 1056 expected MCP operations. Across the selected reports, models emitted 1043 tool calls over 1064 model requests, with 98.3% aggregate final success. See [AI Model Evaluation Results](docs/testing/model-results.md) for the detailed current matrix.\n\u003c!-- END MODEL EVAL META SUMMARY --\u003e\n\n\u003c!-- START MODEL EVAL DYNAMIC SUMMARY --\u003e\nCurrent published result: **Docker CE dynamic 20260522-005714**.\n\n| Provider  | Model                           | Compatibility | Tool accuracy |   Recovery | Docker live status          |\n| --------- | ------------------------------- | ------------- | ------------: | ---------: | --------------------------- |\n| Anthropic | `claude-haiku-4-5-20251001`     | OK            |        100.0% | No repairs | 100.0% final across 266 ops |\n| Google    | `gemini-3.1-flash-lite-preview` | OK            |        100.0% | No repairs | 100.0% final across 266 ops |\n| OpenAI    | `gpt-5.4-nano`                  | OK            |        100.0% | No repairs | 100.0% final across 266 ops |\n| Qwen      | `qwen3.6-flash`                 | OK            |        100.0% | No repairs | 100.0% final across 266 ops |\n\nThe published model-evaluation set covers 552 task attempts and 1064 expected MCP operations. Across the selected reports, models emitted 1097 tool calls over 1097 model requests, with 100.0% aggregate final success. See [AI Model Evaluation Results](docs/testing/model-results.md) for the detailed current matrix.\n\u003c!-- END MODEL EVAL DYNAMIC SUMMARY --\u003e\n\n## Documentation\n\nFull documentation is available at **[jmrplens.github.io/gitlab-mcp-server](https://jmrplens.github.io/gitlab-mcp-server/)**. Use this map when you need the source-of-truth reference for a specific area:\n\n| Document                                             | Description                                                                            |\n| ---------------------------------------------------- | -------------------------------------------------------------------------------------- |\n| [Getting Started](docs/getting-started.md)           | Download, setup wizard, per-client configuration                                       |\n| [IDE Configuration](docs/ide-configuration.md)       | Per-client stdio, HTTP legacy, and HTTP OAuth examples                                 |\n| [Configuration](docs/configuration.md)               | Environment variables, transport modes, TLS                                            |\n| [Environment Variables](docs/env-reference.md)       | Exhaustive environment variable table with defaults and examples                       |\n| [CLI Reference](docs/cli-reference.md)               | All command-line flags, exit codes, and runtime examples                               |\n| [HTTP Server Mode](docs/http-server-mode.md)         | Shared HTTP deployments, authentication, server pool isolation                         |\n| [Tools Reference](docs/tools/README.md)              | All individual tools with input/output schemas, including GitLab.com-only Orbit        |\n| [Meta-Tools](docs/meta-tools.md)                     | 33/49/50 domain meta-tools with action dispatching                                     |\n| [Dynamic Toolset](docs/dynamic-tools.md)             | 2-tool low-token mode with canonical action catalog, safety model, and examples        |\n| [Resources](docs/resources-reference.md)             | All 46 resources with URI templates                                                    |\n| [Prompts](docs/prompts-reference.md)                 | All 37 prompts with arguments and output format                                        |\n| [Auto-Update](docs/auto-update.md)                   | Self-update mechanism, modes, and release format                                       |\n| [Testing](docs/testing/README.md)                    | Unit, E2E, schema model evaluation, Docker model evaluation, and curated model results |\n| [Security](docs/security.md)                         | Security model, token scopes, input validation                                         |\n| [Architecture](docs/architecture.md)                 | System architecture, component design, data flow                                       |\n| [Development Guide](docs/development/development.md) | Building, testing, CI/CD, contributing                                                 |\n| [Troubleshooting](docs/troubleshooting.md)           | Common startup, token, TLS, transport, and tool-discovery issues                       |\n\n## Tech Stack\n\n| Component     | Technology                                       |\n| ------------- | ------------------------------------------------ |\n| Language      | Go 1.26+                                         |\n| MCP SDK       | `github.com/modelcontextprotocol/go-sdk` v1.6.0  |\n| GitLab Client | `gitlab.com/gitlab-org/api/client-go/v2` v2.29.0 |\n| Transport     | stdio (default), HTTP (Streamable HTTP)          |\n\n## Building from Source\n\n```bash\ngit clone https://github.com/jmrplens/gitlab-mcp-server.git\ncd gitlab-mcp-server\nmake build\n```\n\nSee the [Development Guide](docs/development/development.md) for cross-compilation and contributing guidelines.\n\n## Container Image\n\nThe published image is `ghcr.io/jmrplens/gitlab-mcp-server:latest`. Runtime examples live in [Quick Start](#quick-start) next to MCP client configuration, and Docker Compose/source-build details live in the [Development Guide](docs/development/development.md#docker).\n\n## FAQ\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eDoes it work with self-hosted GitLab?\u003c/strong\u003e\u003c/summary\u003e\n\nYes. Set `GITLAB_URL` to your instance URL. When `GITLAB_URL` is omitted, stdio mode uses `https://gitlab.com`. Self-signed TLS certificates are supported via `GITLAB_SKIP_TLS_VERIFY=true`.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eIs my data safe?\u003c/strong\u003e\u003c/summary\u003e\n\nThe server runs locally on your machine (stdio mode) or on your own infrastructure (HTTP mode). No data is sent to third parties — all API calls go directly to your GitLab instance. See \u003ca href=\"SECURITY.md\"\u003eSECURITY.md\u003c/a\u003e for details.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eCan I use it in read-only mode?\u003c/strong\u003e\u003c/summary\u003e\n\nYes. Set `GITLAB_READ_ONLY=true` to disable all mutating tools (create, update, delete). Only read operations will be available.\n\nAlternatively, set `GITLAB_SAFE_MODE=true` for a dry-run mode: mutating tools remain visible but return a structured JSON preview instead of executing. Useful for auditing, training, or reviewing what an AI assistant would do.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eWhat GitLab editions are supported?\u003c/strong\u003e\u003c/summary\u003e\n\nBoth Community Edition (CE) and Enterprise Edition (EE). Set `GITLAB_ENTERPRISE=true` in stdio mode to enable additional tools for Premium/Ultimate features (DORA metrics, vulnerabilities, compliance, etc.). In HTTP mode, `--enterprise` can force the Enterprise/Premium catalog, otherwise CE/EE is detected per token+URL pool entry when GitLab reports edition.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eHow does it handle rate limiting?\u003c/strong\u003e\u003c/summary\u003e\n\nThe server includes retry logic with backoff for GitLab API rate limits. Errors are classified as transient (retryable) or permanent, with actionable hints in error messages.\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eWhich AI clients are supported?\u003c/strong\u003e\u003c/summary\u003e\n\nAny MCP-compatible client: VS Code + GitHub Copilot, Claude Desktop, Cursor, Claude Code, Windsurf, JetBrains IDEs, Zed, Kiro, and others. The built-in setup wizard can auto-configure most clients.\n\u003c/details\u003e\n\n## Contributing\n\nSee [CONTRIBUTING.md](CONTRIBUTING.md) for development guidelines, branch naming, commit conventions, and pull request process.\n\n## Security\n\nSee [SECURITY.md](SECURITY.md) for the security policy and vulnerability reporting.\n\n## Code of Conduct\n\nSee [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md). This project follows the [Contributor Covenant v2.1](https://www.contributor-covenant.org/version/2/1/code_of_conduct/).\n\n## Unnecessary Statistics\n\nNumbers nobody asked for, but here they are anyway.\n\n\u003c!-- START STATS --\u003e\n\n### File counts\n\n| Category                 |     Files |       Lines |\n| ------------------------ | --------: | ----------: |\n| Source (`.go`, non-test) |       885 |     146,856 |\n| Unit tests (`_test.go`)  |       475 |     249,138 |\n| End-to-end tests         |       111 |      24,461 |\n| **Total**                | **1,471** | **420,455** |\n\n### Functions\n\n| Category                        |  Count |\n| ------------------------------- | -----: |\n| Source functions                |  6,221 |\n| — exported (public)             |  2,442 |\n| — unexported (private)          |  3,779 |\n| Unit test functions (`TestXxx`) | 10,145 |\n| Subtests (`t.Run(...)`)         |  2,210 |\n| End-to-end test functions       |    252 |\n\n### Ratios worth noting\n\n| Observation                        |                      Value |\n| ---------------------------------- | -------------------------: |\n| Test lines vs source lines         | 1.70× more tests than code |\n| Average source file length         |                 ~165 lines |\n| Average test file length           |                 ~524 lines |\n| Comment lines in source            |   11,883 (~8.1% of source) |\n| Test functions per source function |                       1.6× |\n\n### Code patterns\n\n| Pattern                            | Count |\n| ---------------------------------- | ----: |\n| `if err != nil` checks             | 6,040 |\n| `defer` statements                 |   768 |\n| `struct` types defined             | 2,282 |\n| `//nolint` suppressions            |    62 |\n| `TODO` / `FIXME` / `HACK` comments |     1 |\n\n### Project\n\n| Metric                         | Value |\n| ------------------------------ | ----: |\n| Go packages                    |   215 |\n| Direct dependencies (`go.mod`) |    11 |\n| Indirect dependencies          |    49 |\n| Git commits                    |   184 |\n| Unique contributors            |     2 |\n\n### Hall of fame\n\n| Record              | File                                                     |\n| ------------------- | -------------------------------------------------------- |\n| Longest source file | `internal/tools/dynamic/register.go` — 2,994 lines       |\n| Longest test file   | `internal/tools/projects/projects_test.go` — 7,080 lines |\n\n### Because why not\n\n| Fact                                 | Value                                                                                                |\n| ------------------------------------ | ---------------------------------------------------------------------------------------------------- |\n| Source code printed at 55 lines/page | ~2,670 pages of A4                                                                                   |\n| Source lines mentioning `\"gitlab\"`   | 8,573 (impossible to avoid)                                                                          |\n| Longest function name in source      | `assertDynamicCompatibilityPolicyOwnedByActionCompat` (51 chars)                                     |\n| Longest test function name           | `TestRequiredMissingAndUnknownParamNames_SchemaValidation_ReturnsSortedMissingAndUnknown` (87 chars) |\n\n\u003c!-- END STATS --\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmrplens%2Fgitlab-mcp-server","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjmrplens%2Fgitlab-mcp-server","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjmrplens%2Fgitlab-mcp-server/lists"}