Some MCP clients (like GitHub Copilot CLI) don't pass environment variables reliably. For those clients, configure the server with CLI arguments instead.
CLI arguments take precedence over environment variables.
Install the server once:
brew tap zereight/gitlab-mcp https://github.com/zereight/gitlab-mcp
brew install zereight/gitlab-mcp/zereight-mcp-gitlabOr with npm:
npm install -g @zereight/mcp-gitlabNo global install? Pin npx to the previous stable release and keep the server flags after it, for example npx -y @zereight/mcp-gitlab@2.2.2 --token=.... Use @zereight/mcp-gitlab@latest if you always want the newest release.
{
"mcpServers": {
"gitlab": {
"command": "zereight-mcp-gitlab",
"args": ["--token=YOUR_GITLAB_TOKEN", "--api-url=https://gitlab.com/api/v4"],
"tools": ["*"]
}
}
}| Argument | Equivalent env var | Description |
|---|---|---|
--token |
GITLAB_PERSONAL_ACCESS_TOKEN |
GitLab Personal Access Token. |
--api-url |
GITLAB_API_URL |
GitLab API URL (e.g., https://gitlab.com/api/v4). |
--read-only=true |
GITLAB_READ_ONLY_MODE |
Deprecated (removed in next major (v3.0.0)); use --permission-mode=readonly instead. |
--permission-mode |
GITLAB_PERMISSION_MODE |
readonly, modify (no delete or teardown tools), or full. |
--toolsets=all |
GITLAB_TOOLSETS |
Enable named toolsets. Unset uses lean core. |
--tools=list_issues |
GITLAB_TOOLS |
Add individual tools on top of enabled toolsets. |
--use-wiki=true |
USE_GITLAB_WIKI |
Deprecated (removed in next major (v3.0.0)); use --toolsets=core,wiki or GITLAB_TOOLSETS=core,wiki instead. |
--use-milestone=true |
USE_MILESTONE |
Deprecated (removed in next major (v3.0.0)); use --toolsets=core,milestones or GITLAB_TOOLSETS=core,milestones instead. |
--use-pipeline=true |
USE_PIPELINE |
Deprecated (removed in next major (v3.0.0)); use --toolsets=core,pipelines or GITLAB_TOOLSETS=core,pipelines, and --tools=validate_ci_lint,validate_project_ci_lint or GITLAB_TOOLS=validate_ci_lint,validate_project_ci_lint. Append those tools to an existing list instead of replacing it. |
--disable-version-check=true |
GITLAB_DISABLE_VERSION_CHECK |
Disable the startup new-version notice. |
--masking-enabled=true |
GITLAB_MASKING_ENABLED |
Enable text-response masking. |
--masking-config |
GITLAB_MASKING_CONFIG |
Path to a masking configuration file. |
--masking-policy-file |
GITLAB_MASKING_POLICY_FILE |
Path to a protected managed-policy file. |
--masking-workspace-dir |
GITLAB_MASKING_WORKSPACE_DIR |
Directory used to resolve masking files. |
--compact-results=true |
GITLAB_MCP_COMPACT_RESULTS |
Truncate oversized MCP tool replies and attach a CLI command for the full payload. Off by default. |
--compact-result-chars |
GITLAB_MCP_COMPACT_RESULT_CHARS |
Size threshold in characters before a reply is compacted (default 4000). |
--compact-tools |
GITLAB_MCP_COMPACT_TOOLS |
Comma-separated tool names to compact when oversized, without enabling global compact mode. |
--tool-profile |
GITLAB_TOOL_PROFILE |
full (default) or slim. slim is ignored when --toolsets / GITLAB_TOOLSETS is set. |
Deprecation notice:
--read-only=true/GITLAB_READ_ONLY_MODE,--use-wiki=true/USE_GITLAB_WIKI,--use-milestone=true/USE_MILESTONE, and--use-pipeline=true/USE_PIPELINEare kept for backward compatibility but are deprecated (removed in next major (v3.0.0)). Use--permission-mode=readonly(orGITLAB_PERMISSION_MODE=readonly),--toolsets=core,wiki(orGITLAB_TOOLSETS=core,wiki),--toolsets=core,milestones(orGITLAB_TOOLSETS=core,milestones), and--toolsets=core,pipelines(orGITLAB_TOOLSETS=core,pipelines) plus--tools=validate_ci_lint,validate_project_ci_lint(orGITLAB_TOOLS=validate_ci_lint,validate_project_ci_lint). If you already setGITLAB_TOOLSETSor--toolsets, append the toolset to your existing list instead of replacing it. IfGITLAB_TOOLSor--toolsis already set, appendvalidate_ci_lint,validate_project_ci_lintinstead of replacing that list.
Subcommands are not MCP server flags. They run and exit without starting the MCP server.
The CLI is the full-payload path. MCP replies stay in the chat; this binary prints the complete tool result on stdout so a human can read lists, diffs, and job logs without stuffing them into the model context.
Leave MCP compact off unless you want that split. With
GITLAB_MCP_COMPACT_RESULTS=true (or --compact-results), an oversized MCP
tool reply becomes a short preview plus a zereight-mcp-gitlab tool … command.
Run that command in a terminal for the untruncated payload. Human CLI itself is
never compacted.
Every command maps to an existing registry tool — no new GitLab API surface.
You do not need an MCP client for this. For credentials (PAT or auth) see
CLI without MCP.
zereight-mcp-gitlab tool list_issues --project-id 123 --state opened
zereight-mcp-gitlab mr list --project-id 123 --state opened
zereight-mcp-gitlab issue view --project-id 123 --issue-iid 9
zereight-mcp-gitlab user whoami| Layer | Form | Default output |
|---|---|---|
| Generic | tool <tool-name> [options] |
JSON |
| Curated | <group> <action> [options] |
table |
- Flags are kebab-case schema keys (
project_id→--project-id). Number and boolean fields are converted from the schema type (--limit 10,--push-events false). Nested objects and arrays use--args-json '{...}'. - Curated shorts:
--mr-iid,--issue-iid,--branch,--source,--target. - Destructive tools (
delete_*,merge_merge_request,push_files, …) require--yes. Without it the command prints what it would do and exits2. - Human CLI uses the same exposure filters as MCP:
GITLAB_TOOLSETS/GITLAB_TOOLS/ legacy wiki-milestone-pipeline flags,GITLAB_DENIED_TOOLS_REGEX, andGITLAB_TOOL_POLICY_HIDDEN.GITLAB_TOOL_POLICY_APPROVEtools also need--yes. --permission-mode=readonlyrefuses writes with exit2before any network call.- Space-separated booleans keep their value (
--read-only falsestays off). Bare--read-onlystill means on. Do not write--use-oauth mrexpectingmrto be the flag value. - Exit codes:
0success,1API/auth/runtime failure,2usage or refused write. - Human tables go to stdout; diagnostics go to stderr so
... --output json | jqstays clean.
zereight-mcp-gitlab --help
zereight-mcp-gitlab mr --help
zereight-mcp-gitlab tool get_merge_request --helpSee Human CLI Design for the command catalog and phase list.
Run GitLab's OAuth Device Authorization Grant (GitLab 17.9+; 17.2–17.8 need
oauth2_device_grant_flow) and store a token at ~/.gitlab-mcp-token.json
(or GITLAB_OAUTH_TOKEN_PATH). This complements the existing localhost
callback flow; it does not replace it.
zereight-mcp-gitlab auth --client-id YOUR_APP_ID
zereight-mcp-gitlab auth --client-id YOUR_APP_ID --api-url https://gitlab.example.com/api/v4
zereight-mcp-gitlab auth --help| Argument | Equivalent env var | Description |
|---|---|---|
--client-id |
GITLAB_OAUTH_CLIENT_ID |
GitLab OAuth application ID. |
--api-url |
GITLAB_API_URL |
GitLab API URL; /api/v4 is stripped to origin. |
--token-path |
GITLAB_OAUTH_TOKEN_PATH |
Token file path. |
After auth succeeds, start the MCP server (or run the human CLI)
with GITLAB_USE_OAUTH=true and the same client ID. If you use --token-path, set GITLAB_OAUTH_TOKEN_PATH to the
same path when you start the MCP server or run the human CLI. See OAuth2 Authentication Setup Guide.
For the full list of configuration options, see Environment Variables.