Server data from the Official MCP Registry
GitLab MCP Server with progressive disclosure - 2 meta-tools, 90% token reduction
GitLab MCP Server with progressive disclosure - 2 meta-tools, 90% token reduction
Valid MCP server (2 strong, 2 medium validity signals). No known CVEs in dependencies. Package registry verified. Imported from the Official MCP Registry. Trust signals: trusted author (5/5 approved).
6 files analyzed · 1 issue found
Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.
This plugin requests these system permissions. Most are normal for its category.
Set these up before or after installing:
Environment variable: GITLAB_PERSONAL_ACCESS_TOKEN
Environment variable: GITLAB_API_URL
Add this to your MCP configuration file:
{
"mcpServers": {
"io-github-detailobsessed-efficient-gitlab": {
"env": {
"GITLAB_API_URL": "your-gitlab-api-url-here",
"GITLAB_PERSONAL_ACCESS_TOKEN": "your-gitlab-personal-access-token-here"
},
"args": [
"-y",
"efficient-gitlab-mcp-server"
],
"command": "npx"
}
}
}From the project's GitHub README.
Token-Efficient GitLab Server Management — An enhanced fork of zereight/gitlab-mcp with progressive disclosure pattern for dramatic token savings.
This fork builds on zereight/gitlab-mcp with a redesigned architecture focused on token efficiency and maintainability. We regularly review upstream commits and port new features and bugfixes while keeping our own structure.
| Area | Upstream | This Fork |
|---|---|---|
| Architecture | Single index.ts (~10K lines) | Modular src/ with 15 tool modules |
| Tool Discovery | All 140+ tools exposed at once | SDK-native progressive disclosure (2 meta-tools) |
| Configuration | Flat individual exports | Typed ServerConfig interface with loadConfig() |
| Logging | console.log | Structured MCP protocol logger for agent observability |
| Runtime | Node.js + npm | Bun (faster builds, native TypeScript) |
| Linting | ESLint + Prettier | Strict Biome rules (noExplicitAny, noNonNullAssertion, cognitive complexity) |
| CI/CD | Basic | GitHub Actions (lint, build, test, semantic-release) |
| Pre-commit | None | prek hooks (typos, formatting, build verification) |
| Feature Flags | USE_PIPELINE, USE_MILESTONE, USE_GITLAB_WIKI required | None — all categories available via progressive disclosure |
enable()/disable() API so tools are registered but hidden until the LLM activates a category.src/tools/, making it easy to find, test, and extend individual tools without navigating a monolithic file.ServerConfig interface ensures all config values are validated at startup, with IDE autocompletion and compile-time safety.readOnlyHint annotations on all 146 tools to filter write operations.any types, no non-null assertions, enforced cognitive complexity limits.USE_PIPELINE, USE_MILESTONE, and USE_GITLAB_WIKI env vars to enable core tools. Progressive disclosure eliminates this — all 15 categories are registered but dormant until activated, so there's zero token cost and zero config overhead.We maintain main as a read-only mirror of upstream. New features and bugfixes from upstream are reviewed and ported into our architecture as needed — we don't blindly rebase, since the codebases have structurally diverged. If you're looking for a specific upstream feature, check our releases or open an issue.
Instead of exposing 140+ individual tools, this server exposes 2 meta-tools:
| Meta-Tool | Purpose |
|---|---|
list_categories | Discover available tool categories and their activation status |
activate_tools | Enable all tools in one or more categories |
| Approach | Tools Exposed | Approximate Token Cost |
|---|---|---|
| Traditional | 140+ tools | ~20,000+ tokens |
| Progressive Disclosure | 2 meta-tools | ~1,500 tokens |
~90% reduction in tool definition tokens!
1. LLM calls list_categories() → sees "merge-requests" category (20 tools, 0 active)
2. LLM calls activate_tools(categories: ["merge-requests"]) → 20 tools now appear in tool list
3. LLM calls create_merge_request({project_id: "123", title: "Fix bug", source_branch: "fix", target_branch: "main"})
All GitLab operations organized by category:
| Category | Description |
|---|---|
| repositories | Search, create, fork repos. Get files, push files, manage branches |
| merge-requests | Create, update, merge MRs. Discussions, threads, diffs |
| issues | Create, update, delete issues. Links, discussions |
| pipelines | List, create, retry, cancel pipelines. Job output |
| projects | Project details, members, labels |
| commits | List commits, get diffs |
| namespaces | List, get, verify namespaces |
| users | User details, search users, audit/project events, file uploads |
| search | Global, project, and group search across code, issues, MRs, commits |
| wiki | Wiki page management for projects and groups |
| milestones | Create, edit, delete milestones. Burndown events |
| releases | List, create, update, delete releases. Download assets |
| webhooks | List project webhooks and recent events |
| work-items | GraphQL work items: create, update, hierarchy, notes, incidents |
| graphql | Execute arbitrary GraphQL queries |
npx) or Bun 1.0+ (for bunx)api — Full access (create issues, merge MRs, manage pipelines, etc.)read_api — Read-only (server auto-detects and hides write tools)CI_JOB_TOKEN — automatically detected in GitLab CI pipelinesUse an api scope PAT to get all 146 tools across 15 categories:
Claude Code CLI:
# With npx (Node.js)
claude mcp add -s user gitlab \
-e GITLAB_PERSONAL_ACCESS_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx \
-e GITLAB_API_URL=https://gitlab.com \
-- npx efficient-gitlab-mcp-server@latest
# With bunx (Bun)
claude mcp add -s user gitlab \
-e GITLAB_PERSONAL_ACCESS_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx \
-e GITLAB_API_URL=https://gitlab.com \
-- bunx efficient-gitlab-mcp-server@latest
MCP client config (Claude Desktop, IDE extensions, etc.):
{
"mcpServers": {
"gitlab": {
"command": "npx",
"args": ["efficient-gitlab-mcp-server@latest"],
"env": {
"GITLAB_PERSONAL_ACCESS_TOKEN": "glpat-xxxxxxxxxxxxxxxxxxxx",
"GITLAB_API_URL": "https://gitlab.com"
}
}
}
}
Use a read_api scope PAT — the server auto-detects the limited scope and only exposes read tools. No extra config needed:
Claude Code CLI:
# With npx (Node.js)
claude mcp add -s user gitlab \
-e GITLAB_PERSONAL_ACCESS_TOKEN=glpat-your-read-only-token \
-e GITLAB_API_URL=https://gitlab.com \
-- npx efficient-gitlab-mcp-server@latest
# With bunx (Bun)
claude mcp add -s user gitlab \
-e GITLAB_PERSONAL_ACCESS_TOKEN=glpat-your-read-only-token \
-e GITLAB_API_URL=https://gitlab.com \
-- bunx efficient-gitlab-mcp-server@latest
Or force read-only mode explicitly (regardless of token scopes):
# With npx (Node.js)
claude mcp add -s user gitlab \
-e GITLAB_PERSONAL_ACCESS_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx \
-e GITLAB_API_URL=https://gitlab.com \
-e GITLAB_READ_ONLY_MODE=true \
-- npx efficient-gitlab-mcp-server@latest
# With bunx (Bun)
claude mcp add -s user gitlab \
-e GITLAB_PERSONAL_ACCESS_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx \
-e GITLAB_API_URL=https://gitlab.com \
-e GITLAB_READ_ONLY_MODE=true \
-- bunx efficient-gitlab-mcp-server@latest
For self-hosted GitLab, update GITLAB_API_URL to your instance URL.
git clone https://github.com/detailobsessed/efficient-gitlab-mcp.git
cd efficient-gitlab-mcp
bun install
bun run build
bun start
The server provides three layers of protection for users with limited-scope Personal Access Tokens:
1. Explicit read-only mode — Set GITLAB_READ_ONLY_MODE=true to restrict the server to read-only tools. Write tools won't appear in list_categories counts or be activated by activate_tools. This is controlled by the readOnlyHint annotation on every tool.
2. Automatic PAT scope detection — On startup, the server calls GitLab's GET /personal_access_tokens/self to inspect your token's scopes. If the token lacks the api scope (e.g., only has read_api), read-only mode is automatically enabled. No configuration needed — it just works.
3. Actionable 403 error messages — If a tool call hits a 403 Forbidden error, the error message includes specific guidance about which PAT scopes are needed, so the LLM can inform the user rather than retrying blindly.
# Explicit read-only mode
GITLAB_READ_ONLY_MODE=true
# Or just use a read_api token — auto-detected!
GITLAB_PERSONAL_ACCESS_TOKEN=glpat-your-read-only-token
The server supports MCP protocol logging for agent observability. When connected, LLM clients can receive structured log messages showing what the server is doing:
This helps agents understand server behavior and debug issues.
When using HTTP transport (STREAMABLE_HTTP=true), the server includes security features:
| Environment Variable | Default | Description |
|---|---|---|
HTTP_ALLOWED_HOSTS | localhost,127.0.0.1 | Comma-separated list of allowed Host headers |
HTTP_ALLOWED_ORIGINS | (any) | Comma-separated list of allowed Origin headers |
HTTP_ENABLE_DNS_REBINDING_PROTECTION | true | Enable DNS rebinding attack protection |
Example for production:
HTTP_ALLOWED_HOSTS=api.example.com,localhost \
HTTP_ALLOWED_ORIGINS=https://app.example.com \
STREAMABLE_HTTP=true \
bun start
# Run tests
bun test
# Run tests with coverage
bun test --coverage
# Lint and format
bun run check
# Build
bun run build
| Variable | Required | Default | Description |
|---|---|---|---|
GITLAB_PERSONAL_ACCESS_TOKEN | Yes* | - | GitLab personal access token (takes priority over CI_JOB_TOKEN) |
CI_JOB_TOKEN | No | - | GitLab CI job token (auto-detected in CI pipelines) |
GITLAB_API_URL | No | https://gitlab.com | GitLab instance URL |
GITLAB_PROJECT_ID | No | - | Default project ID when tools omit project_id |
GITLAB_ALLOWED_PROJECT_IDS | No | - | Restrict tools to these projects (comma-separated). With a single project, acts as default. With multiple, project_id is required per call |
GITLAB_READ_ONLY_MODE | No | false | Only expose read-only tools. Auto-detected from PAT scopes if not set |
GITLAB_IS_OLD | No | false | For older GitLab instances |
*PAT is recommended. CI_JOB_TOKEN is auto-detected in GitLab CI pipelines when no PAT is set. OAuth support is planned (see DET-44).
| Variable | Required | Default | Description |
|---|---|---|---|
STREAMABLE_HTTP | No | false | Enable HTTP transport |
SSE | No | false | Enable SSE transport |
PORT | No | 3002 | HTTP server port |
HOST | No | 127.0.0.1 | HTTP server host |
| Variable | Required | Default | Description |
|---|---|---|---|
LOG_LEVEL | No | info | debug, info, warn, error |
LOG_FORMAT | No | pretty | json, pretty |
HTTP_ALLOWED_HOSTS | No | localhost,127.0.0.1 | Allowed Host headers |
HTTP_ALLOWED_ORIGINS | No | (any) | Allowed Origin headers |
| Variable | Required | Default | Description |
|---|---|---|---|
REMOTE_AUTHORIZATION | No | false | Enable remote auth |
ENABLE_DYNAMIC_API_URL | No | false | Allow dynamic GitLab URLs |
SESSION_TIMEOUT_SECONDS | No | 3600 | Session timeout |
MAX_SESSIONS | No | 1000 | Maximum concurrent sessions |
MAX_REQUESTS_PER_MINUTE | No | 60 | Rate limit per session |
*Or use CI_JOB_TOKEN in GitLab CI pipelines. OAuth authentication is planned — see OAuth Setup Guide for the design.
.env files (gitignored)This project is a fork of zereight/gitlab-mcp. Thanks to the original author for the comprehensive GitLab API implementation.
MIT License — See LICENSE for details.
Be the first to review this server!
by Modelcontextprotocol · Developer Tools
Read, search, and manipulate Git repositories programmatically
by Toleno · Developer Tools
Toleno Network MCP Server — Manage your Toleno mining account with Claude AI using natural language.
by mcp-marketplace · Developer Tools
Create, build, and publish Python MCP servers to PyPI — conversationally.
by Microsoft · Content & Media
Convert files (PDF, Word, Excel, images, audio) to Markdown for LLM consumption
by mcp-marketplace · Developer Tools
Scaffold, build, and publish TypeScript MCP servers to npm — conversationally
by mcp-marketplace · Finance
Free stock data and market news for any MCP-compatible AI assistant.