Diátaxis type: Reference Audience: 👤🔧 All users Prerequisites: gitlab-mcp-server binary installed
Complete environment variable reference for gitlab-mcp-server stdio mode.
Settings this project defines are read as GITLAB_MCP_<NAME> from 2.8.0.
A stdio MCP server runs in whatever shell its client was started from, next to
every other tool that person uses. Names as generic as LOG_LEVEL, AUTH_MODE
or RATE_LIMIT_RPS may already be owned by something else there, and the
collision is silent: the server reads a value nobody gave it and behaves in a
way nobody configured.
The unprefixed spelling was removed in 3.1.0 and is read by nothing. One left set is named at startup, with the variable to rename it to.
The switches that already began with GITLAB_ were renamed as well, so that every variable of this server reads alike: GITLAB_TIER, GITLAB_READ_ONLY, GITLAB_SAFE_MODE, GITLAB_IGNORE_SCOPES and GITLAB_SKIP_TLS_VERIFY are now GITLAB_MCP_TIER, GITLAB_MCP_READ_ONLY, GITLAB_MCP_SAFE_MODE, GITLAB_MCP_IGNORE_SCOPES and GITLAB_MCP_SKIP_TLS_VERIFY, and YOLO_MODE is GITLAB_MCP_YOLO_MODE. The old spellings stopped working in 3.1.0. One left in the environment is reported at startup naming its replacement, and for GITLAB_READ_ONLY and GITLAB_SAFE_MODE the server refuses to start rather than serve writes on a deployment that asked to be read-only.
Two names are gone rather than renamed, both deprecated in 2.7.5 and removed in 3.0.0: META_TOOLS, whose replacement is GITLAB_MCP_TOOL_SURFACE, and GITLAB_ENTERPRISE, whose replacement is GITLAB_MCP_TIER.
Some names stay bare on purpose:
| Names | Why they were not renamed |
|---|---|
GITLAB_URL, GITLAB_TOKEN |
GitLab's own convention. Every existing configuration sets them, and they are the two most likely to be written into a client configuration from memory |
OTEL_* |
Owned by the OpenTelemetry specification. The exporters read those names themselves and would never see a prefixed spelling |
AUTOPILOT |
A convention other agent tooling sets, honored as an alias of GITLAB_MCP_YOLO_MODE and never warned about. The setting itself is ours and carries the prefix; its old spelling YOLO_MODE was removed in 3.1.0 |
MODELEVAL_* |
The model evaluation's own variables, set by make targets in this repository. They configure a test harness that cmd/server never links, so they never appear beside another tool's variables in a user's shell |
The tables below always give the name to set, so read the name rather than
deriving it. The renamed set is internal/config.PrefixedEnvNames(); a name
outside it is read verbatim.
| Variable | Description | Example |
|---|---|---|
GITLAB_TOKEN |
Personal Access Token with api scope |
glpat-xxxxxxxxxxxxxxxxxxxx |
| Variable | Default | Description |
|---|---|---|
GITLAB_URL |
https://gitlab.com |
GitLab instance base URL (must use http:// or https:// scheme). Set this for self-managed instances |
GITLAB_MCP_SKIP_TLS_VERIFY |
false |
Skip TLS certificate verification (true/false). Use for self-signed certs |
| Variable | Default | Description |
|---|---|---|
GITLAB_MCP_TOOL_SURFACE |
dynamic |
Canonical tool catalog selector: dynamic, meta, or individual. dynamic exposes find/execute |
GITLAB_MCP_CAPABILITY_SURFACE |
full |
Resource and prompt catalog selector: full keeps the complete catalog; minimal keeps the surface-aware gitlab://tools manifest and disables optional GitLab data resources, workflow guides, prompts, and resource subscriptions — resources/subscribe is only advertised on full. Dynamic describe/find still returns action schemas inline with minimal |
GITLAB_MCP_META_PARAM_SCHEMA |
opaque |
Meta-tool input-schema strategy: opaque (compact {action, params:any} envelope, default), compact (oneOf with property names + types only, 8.7x opaque size) or full (oneOf with full per-action JSON Schemas, 18.3x opaque size). Applies to visible meta-tool schemas in meta; has no practical effect on dynamic or individual tool schemas. Per-action call shapes and JSON Schemas are discoverable through gitlab://tools and gitlab://tools/{id} for every surface |
GITLAB_MCP_TIER |
(detected) | Licensing tier: free/ce, premium, or ultimate. When set, used verbatim with no license check. When unset, detected from the instance license (GET /license → plan), fallback free. In HTTP mode use --tier; when omitted the tier is detected per token+URL pool entry. Enterprise/Premium tools are gated when the resolved tier is Premium or Ultimate |
GITLAB_MCP_LOG_LEVEL |
info |
Logging verbosity: debug, info, warn, error. The --log-level flag sets the same variable and wins over it |
GITLAB_MCP_PPROF_ADDR |
(empty) | Serve Go's profiling handlers (net/http/pprof) on this address, on a listener of their own that starts before the transport and stops with the process. The host must be loopback (127.0.0.1:6060, [::1]:6060 or localhost:6060); any other host is refused at startup, since a heap profile is a copy of the process's memory and the handlers take no credential. Empty serves nothing. Both transports; the --pprof-addr flag sets the same variable. Used by cmd/bench_resources to profile the concurrency series |
GITLAB_MCP_ALLOW_PRIVATE_INSTANCES |
false |
Permit a private, loopback, CGNAT 100.64.0.0/10, link-local, unique-local or unspecified address as a destination this server's operator did not choose. Two destinations are not the operator's choice: an instance a caller named in the GITLAB-URL header under --allow-any-gitlab-url, and a redirect hop that left the configured instance's own host (which is how GitLab answers artifact, trace and package downloads when object storage is configured). An address --gitlab-url or GITLAB_URL named is exempt whatever it resolves to, so a GitLab on localhost, on 10.x or behind a VPN needs nothing set; and a redirect to a private address is allowed anyway when the configured instance itself resolves private. The cloud metadata addresses (169.254.169.254, 169.254.170.2, fd00:ec2::254, 100.100.100.200) are refused on every hop for every deployment and this does not permit them. Enforced at the dialer, after DNS resolution. Both transports; the --allow-private-instances flag sets the same variable. See ADR-0022 |
GITLAB_MCP_READ_ONLY |
false |
Read-only mode: mutating operations are removed per action, not per tool, so reads keep working on every surface — gitlab_issue survives with its read actions and gitlab_execute_action stays available (annotated read-only) for the reads it can route. On the individual surface, where one tool is one action, this is simply the removal of the mutating tools (true/false) |
GITLAB_MCP_SAFE_MODE |
false |
Safe mode: intercepts mutating operations per action and returns a preview card naming that action and echoing its arguments instead of executing, so issue.create previews while issue.list executes. If GITLAB_MCP_READ_ONLY=true, it takes precedence (true/false) |
GITLAB_MCP_EMBEDDED_RESOURCES |
true |
Embed the canonical gitlab:// MCP resource URI as an EmbeddedResource content block in the get results that carry one (twenty-two actions, listed in Output Format). Set to false to disable for clients that don't tolerate duplicate content blocks (true/false) |
GITLAB_MCP_EXCLUDE_TOOLS |
(empty) | Comma-separated list of tool names, group names or canonical action IDs to exclude (e.g. gitlab_admin,gitlab_runner). They are excluded from the tool surface and from the resources, subscriptions, prompts and argument completions that return the same objects, so the removal holds on every request path |
GITLAB_MCP_IGNORE_SCOPES |
false |
Skip PAT scope detection and register all tools regardless of token permissions (true/false) |
GITLAB_MCP_CLIENT_COMPAT |
auto |
Per-client response compatibility. On auto, a session identifying itself as OpenAI Codex gets the float priority in content and resource annotations rounded to 0 or 1 — the Codex builds bundled with ChatGPT.app reject a fractional value and mark the call as an unexpected response type. Every other field, and every other client, is delivered unchanged. Set off to disable the rewriting. Read from the process environment in both stdio and HTTP modes; the --client-compat flag sets the same variable. See Client Compatibility |
GITLAB_MCP_DESCRIPTION_SUBSTITUTIONS |
(empty) | Rewrite listed catalog text for strict MCP gateway validators: comma-separated old=new pairs applied in order to every listed description and title (backslash escapes \, \= \\). Covers tools on every surface (schema-embedded descriptions included), prompts, resources and resource templates; never names, URIs, pattern, const, enum values or tool-call payloads. A malformed value refuses startup; an active configuration is announced at WARN once. Both transports; the --description-substitutions flag sets the same variable. See Client Compatibility |
| Variable | Default | Description |
|---|---|---|
GITLAB_MCP_YOLO_MODE |
false |
Skip confirmation prompts for destructive actions (delete, force-push) |
AUTOPILOT |
false |
Same as GITLAB_MCP_YOLO_MODE — skip all confirmation prompts |
These are checked by the elicitation subsystem. When the MCP client supports elicitation, destructive tools ask for user confirmation unless one of these is true. A non-empty GITLAB_MCP_YOLO_MODE takes precedence over AUTOPILOT, and the --yolo-mode flag sets GITLAB_MCP_YOLO_MODE.
| Variable | Default | Description |
|---|---|---|
GITLAB_MCP_UPLOAD_MAX_FILE_SIZE |
2GB |
Maximum file size for upload and file-read tools. Supports human-friendly suffixes: KB, MB, GB (case-insensitive). Upper bound: 1 TB. Both transports; the --upload-max-file-size flag sets the same variable |
| Variable | Default | Description |
|---|---|---|
GITLAB_MCP_ALLOWED_IMPORT_DIRS |
(empty) | Additional OS path-list-separated directories allowed for file_path/file project and group import archives. The current working directory (unless it is the filesystem root or the user's home directory, which are dropped as implicit roots) and the OS temp directory are always allowed. Import archives must resolve inside an allowed directory after symlink resolution and must use the .tar.gz extension |
GITLAB_MCP_ALLOWED_UPLOAD_DIRS |
(empty) | Additional OS path-list-separated directories a tool may read a local file from (every file_path and directory_path input: uploads, secure files, avatars, package publish). The current working directory (unless it is the filesystem root or the user's home directory, which are dropped as implicit roots) and the OS temp directory are always allowed, and a path is resolved through symlinks first |
GITLAB_MCP_ALLOWED_DOWNLOAD_DIRS |
(empty) | Additional OS path-list-separated directories a tool may write a downloaded file into (output_path). Same syntax and same always-allowed roots. The destination is resolved twice, before its parent directories are created and again after, so the second check sees the directory being written to |
A server reached over HTTP refuses every caller-supplied local path whatever these say, since the caller has no files on the machine the server runs on. content_base64 is the remote form.
Off by default, in both transports. Telemetry goes to a collector the operator configures, never to the maintainer: the endpoint, credentials, sampling and batching come from the standard OTEL_EXPORTER_OTLP_* variables, which the exporters read themselves under their own names, and OTEL_SDK_DISABLED=true vetoes the export regardless of what is set here. Each of these has a flag of the same name except the key, which stays environment-only because process arguments are readable through /proc. See Telemetry.
| Variable | Default | Description |
|---|---|---|
GITLAB_MCP_TELEMETRY |
false |
Export OpenTelemetry traces, metrics and logs over OTLP. Flag --telemetry |
GITLAB_MCP_TELEMETRY_IDENTITY |
none |
How much telemetry records about who made a call: none records nobody, pseudonymous a per-process HMAC digest that correlates one caller's calls without naming them, full the GitLab user id and username. Identity never reaches a metric under any policy. Flag --telemetry-identity |
GITLAB_MCP_TELEMETRY_IDENTITY_KEY |
(empty) | Secret the pseudonymous policy derives its keys from (HKDF-SHA256). Empty generates one per process, so a digest identifies a caller within one process and nowhere else; set it when several replicas must agree or a distinct-user count has to survive a restart, and keep it away from wherever the telemetry lands. No flag on purpose |
GITLAB_MCP_TELEMETRY_IDENTITY_ROTATION |
(empty) | How long a generated pseudonymisation key lives, e.g. 24h; empty or 0 keeps it for the life of the process, 30 days is the ceiling. Ignored, with a warning at startup, when GITLAB_MCP_TELEMETRY_IDENTITY_KEY is set. Flag --telemetry-identity-rotation |
GITLAB_MCP_TELEMETRY_TOOL_NAME |
auto |
Whether gen_ai.tool.name is a metric dimension: auto keeps it on the dynamic and meta surfaces and drops it on individual, where about a thousand tools would exhaust the SDK's cardinality limit and collapse the long tail into one overflow bucket; on and off force it. Flag --telemetry-tool-name |
These apply whichever transport carries the call, so the tool surface makes no difference to them: GITLAB_MCP_ACTION_TIMEOUT bounds the action handler, GITLAB_MCP_STDIO_MAX_LINE_BYTES caps each stdio input message, and GITLAB_MCP_MAX_LISTEN_STREAMS caps the concurrent subscriptions/listen streams one credential may hold open.
| Variable | Default | Description |
|---|---|---|
GITLAB_MCP_ACTION_TIMEOUT |
65m |
Cancel an action still running after this long, in both transports; 0 disables it. Upper bound: 24h. Above the longest wait any action offers (a pipeline wait caps itself at 3600 s), so it ends a handler nobody else bounds, not a legitimate call. HTTP mode also has --action-timeout |
GITLAB_MCP_STDIO_MAX_LINE_BYTES |
4 MiB | Longest stdio message accepted, in bytes. A longer line is refused and answered, not buffered, so a client cannot grow the process by sending one. It matches the SDK's own default for an HTTP request body, so both transports refuse the same messages. Raise it only for a client that inlines large base64 payloads. A missing, unparseable or non-positive value warns and keeps the default |
GITLAB_MCP_MAX_LISTEN_STREAMS |
64 |
Concurrent subscriptions/listen streams one credential may hold open; 0 removes that ceiling and nothing else, so a credential holding one open is still counted as busy and is not idle-swept from the pool. A listen is a request the client leaves open, costing a blocked goroutine and a file descriptor each, and a real client opens a handful. A second ceiling of 512 per process is not configurable, because the per-credential one multiplies by however many tokens a caller holds. Both transports |
These variables configure the HTTP server pool. Each has a CLI flag counterpart, and the flag wins when it is passed explicitly — see HTTP Mode Equivalents below. In stdio mode they are parsed but unused, since stdio runs a single server with no pool, with one exception: the two rate-limit variables at the end of the table meter stdio's single server as well, where the limiter is off unless they turn it on.
| Variable | Default | Description |
|---|---|---|
GITLAB_MCP_MAX_HTTP_CLIENTS |
100 |
Maximum unique (token, GitLab URL) server entries kept in the pool; it bounds pooled entries, not sessions or concurrent requests. Upper bound: 10,000 |
GITLAB_MCP_SESSION_TIMEOUT |
30m |
Idle MCP session timeout; applies to --stateless=false only, since under the default stateless transport each POST's session ends with its response. Upper bound: 24h |
GITLAB_MCP_DRAIN_DELAY |
0 |
After SIGTERM, keep the listener open and answer /health with 503 draining for this long before closing it, so a balancer that polls /health removes the instance before the close. Upper bound: 5m. 0 closes at once. Set it to at least one probe interval |
GITLAB_MCP_POOL_IDLE_TIMEOUT |
1h |
Reclaim a pooled per-token-and-URL credential entry after this long unused; 0 keeps entries until the pool size bound evicts them. Upper bound: 24h. An entry with a live subscription is never idle by this measure |
GITLAB_MCP_SESSION_REVALIDATE_INTERVAL |
15m |
Token re-validation interval for pooled entries. 0 stops the periodic check, but an entry whose credential is older than 1h is still rebuilt, which re-runs the probe. Upper bound: 24h |
GITLAB_MCP_AUTH_MODE |
legacy |
Authentication mode: legacy (PRIVATE-TOKEN header passthrough) or oauth (RFC 9728 Bearer token verification via GitLab API) |
GITLAB_MCP_OAUTH_CACHE_TTL |
15m |
TTL for verified OAuth token identity cache. Range: 1m–2h |
GITLAB_MCP_OAUTH_CLIENT_UID |
(empty) | Comma-separated GitLab OAuth application uids whose tokens are admitted. Empty admits any credential the instance accepts; setting it refuses personal access tokens, which belong to no application. Flag --oauth-client-uid; see ADR-0019 |
GITLAB_MCP_PUBLIC_URL |
(empty) | Externally reachable origin of this deployment. Required with GITLAB_MCP_AUTH_MODE=oauth (RFC 9728 resource identifier); in legacy mode its origin seeds the trusted-origins list |
GITLAB_MCP_TRUSTED_ORIGINS |
(empty) | Comma-separated absolute origins (scheme://host[:port]) allowed to make cross-origin browser requests. * accepts any origin and disables the protection; empty adds none, though a configured GITLAB_MCP_PUBLIC_URL origin is trusted regardless |
GITLAB_MCP_RATE_LIMIT_RPS |
0 |
Per-credential rate limit, in requests/second, on every call that reaches GitLab (tools/call, resources/read, resources/subscribe, subscriptions/listen, prompts/get), plus tools/list on a bucket of its own refilled a tenth as fast: that one reaches no GitLab and spends the processor every tenant shares instead. Its burst is the configured one, undivided, so a fleet of clients on one credential can still all discover at once. 0 disables the limiter. The default is 0 in stdio and 10 in HTTP mode, where --rate-limit-rps overrides it. See Security — Rate Limiting Model |
GITLAB_MCP_RATE_LIMIT_BURST |
40 |
Token-bucket burst size when GITLAB_MCP_RATE_LIMIT_RPS > 0. Must be ≥ 1 |
Configuration is loaded by internal/config/ in this precedence order (higher wins):
- The process environment, which is what the MCP client passed to the server
- The file
GITLAB_MCP_ENV_FILEnames, when the process environment names one ~/.gitlab-mcp-server.envin the user's home directory
Note:
godotenvnever overwrites a variable that is already set, so an earlier step always wins over a later one.
A .env in the current working directory is not on that list. See The working directory is not a configuration source below.
| Variable | Default | Description |
|---|---|---|
GITLAB_MCP_ENV_FILE |
(empty) | Path of one dotenv file to load in addition to the home file; the --env-file flag sets the same thing and wins over it. Read from the process environment only, which is what makes it an opt-in: a file this server loads cannot nominate another, so the working-directory .env cannot name itself. Give an absolute path. A relative one is resolved against the working directory the client chose, which is the load this replaced under another name, so startup warns when it sees one |
A stdio server inherits its working directory from the MCP client, and every client that opens a workspace sets it to that workspace. Its contents therefore arrive with a cloned repository or an unpacked archive, chosen by whoever wrote them rather than by whoever runs the server.
The ./.env load used to come first, so two lines in a cloned repository could redirect your token to another host, turn off certificate verification so that redirection raised no error, and rewrite the tool descriptions the model reads. None of it needed a tool call or a model turn: the startup probe delivered the token. The variables that make it work are exactly the ones no MCP client sets, so they are always free for whichever file is read first.
A dotenv file now configures this server only when someone put it where the server looks (~/.gitlab-mcp-server.env) or named it (GITLAB_MCP_ENV_FILE). Being in the working directory is not a decision anyone made, which is the same conclusion Git's safe.directory, direnv's direnv allow and VS Code Workspace Trust reached.
A working-directory .env is still looked for, and reported at WARN with its absolute path and the names of the keys it wanted to set, so a repository-local file that stopped taking effect is a line in the startup log rather than an afternoon of debugging. Nothing in it reaches the environment.
# Required
GITLAB_TOKEN=glpat-xxxxxxxxxxxxxxxxxxxx
# Optional
GITLAB_MCP_SKIP_TLS_VERIFY=false
GITLAB_MCP_TOOL_SURFACE=dynamic
GITLAB_MCP_LOG_LEVEL=info
GITLAB_MCP_UPLOAD_MAX_FILE_SIZE=500MBWrite that to ~/.gitlab-mcp-server.env, or to any path you then name in GITLAB_MCP_ENV_FILE. For self-managed GitLab, add GITLAB_URL=https://gitlab.example.com.
Security: Never commit tokens or credentials. Whichever file holds the token, restrict it to its owner (
chmod 600on Unix).
In HTTP mode, configuration resolves in three layers, highest first:
- A CLI flag passed explicitly on the command line. Always wins.
- The environment variable, when the corresponding flag was not passed.
- The built-in default.
Passing a flag whose value happens to equal the default still counts as choosing it, so the environment cannot override it. See CLI Reference for the full flag list.
The rows marked (none) in the variable column are flags with no environment counterpart at all, the transport and listener flags in particular. A deployment that configures everything else through the environment must still pass those on the command line. The rows marked (none) in the flag column are the reverse: settings that exist only in the environment, because the flag would put a secret on a command line.
Nothing in this table is reachable from a request. Clients control only their GitLab token and the GITLAB-URL header, and what that header may do follows how many instances the deployment published: with none it selects the instance freely; with exactly one it is ignored and logged, because that instance is authoritative; with several it selects among them, and a value naming anything else is refused rather than quietly served the default. Every other configuration header is ignored and reported in the ignored_options log field. See Configuration Precedence.
| Environment Variable | CLI Flag | Notes |
|---|---|---|
GITLAB_MCP_ENV_FILE |
--env-file |
Dotenv file loaded besides ~/.gitlab-mcp-server.env; the flag wins over the variable. Both transports |
| (none) | --transport |
CLI-only; stdio, http or auto. Empty defers to --http, and auto reads file descriptor 0 (HTTP only when stdin is the null device) |
GITLAB_URL |
--gitlab-url |
Optional in stdio mode; defaults to https://gitlab.com. Required in HTTP mode unless --allow-any-gitlab-url is passed. When set in HTTP mode it fixes the GitLab instance; with the escape hatch and no instance, GITLAB-URL selects per request and a request without it is refused. A comma-separated value (or a repeated --gitlab-url) publishes several instances: GITLAB-URL is then required and selects among them, refusing anything else |
| (none) | --allow-any-gitlab-url |
CLI-only, and deliberately so: this is the flag that lets a caller choose the host this server sends their token to, so it belongs in the command line that started the process rather than in an environment nobody reads back. Start with no instance published and let GITLAB-URL name any host. For a single-user local deployment where the operator is the caller; it warns at startup and must not be used on a listener anyone else can reach |
GITLAB_TOKEN |
(none) | Not needed in HTTP mode — clients provide tokens per-request |
GITLAB_MCP_SKIP_TLS_VERIFY |
--skip-tls-verify |
|
GITLAB_MCP_TOOL_SURFACE |
--tool-surface |
Canonical selector: meta, individual, or dynamic |
GITLAB_MCP_CAPABILITY_SURFACE |
--capability-surface |
Explicit selector: full or minimal |
GITLAB_MCP_META_PARAM_SCHEMA |
--meta-param-schema |
|
GITLAB_MCP_MAX_HTTP_CLIENTS |
--max-http-clients |
|
GITLAB_MCP_SESSION_TIMEOUT |
--session-timeout |
|
| (none) | --http-idle-timeout |
CLI-only; HTTP server idle connection timeout. Default 0 disables idle closure so --session-timeout is the effective lifetime |
| (none) | --http-addr |
CLI-only; listen address. host:port binds TCP; a value containing a path separator binds a unix socket instead |
| (none) | --http-socket-mode |
CLI-only; octal permission mode for a unix socket named by --http-addr (default 0660) |
| (none) | --tls-cert, --tls-key |
CLI-only; PEM certificate and key that terminate HTTPS on the listener itself. Both or neither |
| (none) | --stateless |
CLI-only; sessionless streamable HTTP (default true). --stateless=false restores legacy stateful sessions |
| (none) | --json-response |
CLI-only; return application/json response bodies instead of text/event-stream |
| (none) | --max-request-body-bytes |
CLI-only; maximum streamable HTTP request body size in bytes; 0 uses the SDK default (4 MiB) |
GITLAB_MCP_ACTION_TIMEOUT |
--action-timeout |
Both transports; the flag is the HTTP spelling |
GITLAB_MCP_DRAIN_DELAY |
--drain-delay |
HTTP mode only: stdio has no listener to hold open |
GITLAB_MCP_POOL_IDLE_TIMEOUT |
--pool-idle-timeout |
|
GITLAB_MCP_SESSION_REVALIDATE_INTERVAL |
--revalidate-interval |
0 stops the periodic check; an entry whose credential is older than 1h is still rebuilt |
GITLAB_MCP_AUTH_MODE |
--auth-mode |
|
GITLAB_MCP_OAUTH_CLIENT_UID |
--oauth-client-uid |
Comma-separated GitLab OAuth application uids whose tokens are admitted; empty admits any credential the instance accepts |
| (none) | --resource-documentation |
CLI-only; https URL published as RFC 9728 resource_documentation. Empty publishes this project's HTTP server mode page |
| (none) | --resource-policy-uri |
CLI-only; https URL published as RFC 9728 resource_policy_uri. Empty omits the field |
| (none) | --resource-tos-uri |
CLI-only; https URL published as RFC 9728 resource_tos_uri. Empty omits the field |
GITLAB_MCP_OAUTH_CACHE_TTL |
--oauth-cache-ttl |
|
GITLAB_MCP_PUBLIC_URL |
--public-url |
|
GITLAB_MCP_RATE_LIMIT_RPS |
--rate-limit-rps |
|
GITLAB_MCP_RATE_LIMIT_BURST |
--rate-limit-burst |
|
| (none) | --trusted-proxies |
CLI-only; addresses or CIDR ranges of the proxies whose --trusted-proxy-header is believed, required with it |
| (none) | --trusted-proxy-header |
CLI-only; HTTP header with real client IP for rate limiting behind proxies, believed only from --trusted-proxies |
GITLAB_MCP_TRUSTED_ORIGINS |
--trusted-origins |
|
GITLAB_MCP_TIER |
--tier |
In HTTP mode, an explicit flag forces the tier; when omitted, the tier is detected from the instance license per token+URL pool entry (fallback free) |
GITLAB_MCP_READ_ONLY |
--read-only |
|
GITLAB_MCP_SAFE_MODE |
--safe-mode |
|
GITLAB_MCP_EMBEDDED_RESOURCES |
--embedded-resources |
|
GITLAB_MCP_EXCLUDE_TOOLS |
--exclude-tools |
Comma-separated list |
GITLAB_MCP_IGNORE_SCOPES |
--ignore-scopes |
|
GITLAB_MCP_LOG_LEVEL |
--log-level |
Both transports. The flag writes the variable, so the one reader stays |
GITLAB_MCP_CLIENT_COMPAT |
--client-compat |
Both transports; same mechanism |
GITLAB_MCP_UPLOAD_MAX_FILE_SIZE |
--upload-max-file-size |
Both transports; same mechanism |
GITLAB_MCP_YOLO_MODE |
--yolo-mode |
Both transports; same mechanism. AUTOPILOT has no flag and loses to a non-empty GITLAB_MCP_YOLO_MODE |
GITLAB_MCP_DESCRIPTION_SUBSTITUTIONS |
--description-substitutions |
Both transports; same mechanism |
GITLAB_MCP_PPROF_ADDR |
--pprof-addr |
Both transports; same mechanism. Loopback only |
GITLAB_MCP_ALLOW_PRIVATE_INSTANCES |
--allow-private-instances |
Both transports; same mechanism. Never permits a cloud metadata address |
GITLAB_MCP_TELEMETRY |
--telemetry |
Both transports |
GITLAB_MCP_TELEMETRY_IDENTITY |
--telemetry-identity |
Both transports |
GITLAB_MCP_TELEMETRY_IDENTITY_KEY |
(none) | Environment only, on purpose: process arguments are readable through /proc |
GITLAB_MCP_TELEMETRY_IDENTITY_ROTATION |
--telemetry-identity-rotation |
Both transports |
GITLAB_MCP_TELEMETRY_TOOL_NAME |
--telemetry-tool-name |
Both transports |
GITLAB_MCP_STDIO_MAX_LINE_BYTES |
(none) | stdio only; the HTTP counterpart of the same ceiling is --max-request-body-bytes |
GITLAB_MCP_MAX_LISTEN_STREAMS |
(none) | Both transports; environment only |
GITLAB_MCP_ALLOWED_UPLOAD_DIRS, GITLAB_MCP_ALLOWED_DOWNLOAD_DIRS, GITLAB_MCP_ALLOWED_IMPORT_DIRS |
(none) | stdio only; a server reached over HTTP refuses every caller-supplied local path whatever these say |
- CLI Reference — Command-line flags for HTTP mode
- Configuration — Client config and secure token management
- Dynamic Toolset — Low-token find/execute workflow and migration guidance
- Security — Token management best practices
- HTTP Server Mode — OAuth mode architecture and deployment
- OAuth App Setup — Creating GitLab OAuth applications