Claude Code GitLab CI/CD Worktrees 2026

Claude Code and GitLab: CI/CD, Merge Request Worktrees, and Marketplaces (2026 Guide)

The Prompt Shelf ·

GitLab teams spent most of 2026 watching Claude Code’s GitHub-first feature list from the sidelines — worktrees that only parsed GitHub pull request URLs, plugin marketplaces that treated gitlab.com as just another generic git remote, no first-party CI job. That gap closed in a two-week stretch this August: v2.1.232 (August 13) added GitLab-aware plugin marketplaces and token redaction, and v2.1.233 (August 14) taught --worktree and the claude agents view to parse merge request URLs. Combined with the GitLab-maintained CI/CD integration that’s been in beta since earlier this year, Claude Code now has three separate, independently-shipped ways to work with a GitLab project — and they solve different problems.

This guide covers all three: the .gitlab-ci.yml job that responds to @claude mentions, --worktree support for merge request URLs, and the marketplace/security changes that came with it. If you only read one section, make it the comparison table — most of the confusion around this feature set comes from treating it as one integration instead of three.


Three Ways to Connect Claude Code to GitLab

GitLab CI/CD integration--worktree from an MR URLPlugin marketplaces on gitlab.com
What it doesRuns Claude Code inside a GitLab CI job, triggered by @claude mentionsBranches a local worktree from an existing merge requestHosts and installs plugins from a gitlab.com repository
Where Claude runsYour GitLab runner, in CIYour machine, interactivelyYour machine, interactively
ShippedBeta, maintained by GitLabv2.1.233 (Aug 14, 2026)v2.1.232 (Aug 13, 2026)
SetupAdd a job to .gitlab-ci.yml + a masked ANTHROPIC_API_KEY variableNothing — works out of the box on v2.1.233+Nothing — works out of the box on v2.1.232+
Typical use”Turn this issue into an MR” from a comment”Let me review and extend this MR locally”Distributing team plugins from a GitLab group

If you’re setting up Claude Code for a GitLab team for the first time, the CI/CD integration is the one that changes your workflow the most — it’s the closest GitLab-side equivalent to Claude Code’s GitHub Actions integration. The worktree and marketplace changes matter more once you’re already running Claude Code locally against GitLab-hosted repos and just want the same conveniences GitHub users have had for months.


Claude Code for GitLab CI/CD

This integration is maintained by GitLab, not Anthropic — it’s built on the Claude Code CLI and Agent SDK, and is currently in beta. It runs Claude inside isolated GitLab CI jobs and commits results back through merge requests, so every change still goes through your normal review process.

How it’s triggered

GitLab listens for whatever event you configure — most commonly a comment containing @claude on an issue, merge request, or review thread. The job pulls context from the thread and repository, builds a prompt from it, and runs claude non-interactively.

Minimal setup

Add one masked CI/CD variable (Settings → CI/CD → Variables):

ANTHROPIC_API_KEY   (masked, protected as needed)

Then add a job to .gitlab-ci.yml:

stages:
  - ai

claude:
  stage: ai
  image: node:24-alpine3.21
  rules:
    - if: '$CI_PIPELINE_SOURCE == "web"'
    - if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
  variables:
    GIT_STRATEGY: fetch
  before_script:
    - apk update
    - apk add --no-cache git curl bash
    - curl -fsSL https://claude.ai/install.sh | bash
    - export PATH="$HOME/.local/bin:$PATH"
  script:
    - /bin/gitlab-mcp-server || true
    - >
      claude
      -p "${AI_FLOW_INPUT:-'Review this MR and implement the requested changes'}"
      --permission-mode acceptEdits
      --allowedTools "Bash Read Edit Write mcp__gitlab"
      --debug

Test it by running the job manually from CI/CD → Pipelines, or trigger it from a merge request comment. For mention-driven triggers, you’ll need a webhook on “Comments (notes)” that calls the pipeline trigger API with variables like AI_FLOW_INPUT and AI_FLOW_CONTEXT when a comment contains @claude — the quick-setup job above doesn’t wire that webhook for you.

Provider choice: Claude API, Bedrock, or Google Cloud

For teams with data-residency or procurement requirements, the job can run against Amazon Bedrock or Google Cloud’s Agent Platform instead of the Claude API directly, using OIDC/Workload Identity Federation instead of stored keys:

# Amazon Bedrock — GitLab exchanges its OIDC token for temporary AWS credentials
claude-bedrock:
  stage: ai
  image: node:24-alpine3.21
  id_tokens:
    GITLAB_OIDC_TOKEN:
      aud: https://gitlab.example.com
  before_script:
    - apk add --no-cache bash curl jq git aws-cli
    - curl -fsSL https://claude.ai/install.sh | bash
    - export PATH="$HOME/.local/bin:$PATH"
    - export AWS_WEB_IDENTITY_TOKEN_FILE="/tmp/oidc_token"
    - printf "%s" "$GITLAB_OIDC_TOKEN" > "$AWS_WEB_IDENTITY_TOKEN_FILE"
    - >
      aws sts assume-role-with-web-identity
      --role-arn "$AWS_ROLE_TO_ASSUME"
      --role-session-name "gitlab-claude-$(date +%s)"
      --web-identity-token "file://$AWS_WEB_IDENTITY_TOKEN_FILE"
      --duration-seconds 3600 > /tmp/aws_creds.json
    - export AWS_ACCESS_KEY_ID="$(jq -r .Credentials.AccessKeyId /tmp/aws_creds.json)"
    - export AWS_SECRET_ACCESS_KEY="$(jq -r .Credentials.SecretAccessKey /tmp/aws_creds.json)"
    - export AWS_SESSION_TOKEN="$(jq -r .Credentials.SessionToken /tmp/aws_creds.json)"
  script:
    - >
      claude -p "${AI_FLOW_INPUT:-'Implement the requested changes and open an MR'}"
      --permission-mode acceptEdits --allowedTools "Bash Read Edit Write mcp__gitlab"
  variables:
    AWS_REGION: "us-west-2"
    CLAUDE_CODE_USE_BEDROCK: "1"

No AWS access keys ever get stored in a CI/CD variable — GitLab’s id_tokens block mints a short-lived OIDC token per job, and the role trust policy restricts it to your project and protected refs. The equivalent Google Cloud’s Agent Platform setup swaps AWS_ROLE_TO_ASSUME for Workload Identity Federation variables (GCP_WORKLOAD_IDENTITY_PROVIDER, GCP_SERVICE_ACCOUNT, GCP_PROJECT_ID) and sets CLAUDE_CODE_USE_VERTEX: "1" instead.

What Claude can do in the job

  • Turn an issue into a merge request: @claude implement this feature based on the issue description
  • Propose an approach in an MR discussion: @claude suggest a concrete way to cache this API call
  • Fix a reported bug: @claude fix the TypeError in the user dashboard component

Every one of these ends in a diff a human reviews and approves — the job’s mcp__gitlab tool opens or updates an MR, it doesn’t merge anything itself.

Costs and limits worth knowing before you turn this on

  • The job consumes GitLab runner minutes on top of your normal CI usage — check your plan’s runner billing.
  • API token usage scales with prompt and codebase size; set --max-turns and a job-level timeout: 30m to put a ceiling on both.
  • CLAUDE.md at the repository root is read on every run, so keep it focused — a bloated CLAUDE.md costs tokens on every single CI invocation, not just interactive sessions. See our token budget optimization guide if that file has grown unwieldy.
  • Never commit ANTHROPIC_API_KEY or cloud credentials to the repository. Use masked CI/CD variables, or OIDC/WIF where the provider supports it.

--worktree From a GitLab Merge Request

Separately from the CI/CD integration, Claude Code’s local --worktree flag — which isolates a session in its own git worktree so file edits never collide with your main checkout — learned to parse GitLab merge request URLs in v2.1.233.

claude --worktree "https://gitlab.com/group/project/-/merge_requests/42"

Claude Code reads only the 42 from that URL, then fetches from your repository’s origin remote using a host-specific path:

  • github.com → fetches pull/<number>/head
  • gitlab.com → fetches merge-requests/<number>/head
  • GitHub Enterprise, self-managed GitLab, or any other host → tries pull/<number>/head first, then falls back to merge-requests/<number>/head

The worktree lands at .claude/worktrees/pr-42, and the session shows up in claude agents labeled !42 — GitLab’s own notation for a merge request, distinct from the #42 GitHub notation Claude Code has used since worktree-from-PR support first shipped. Before v2.1.233, only #<number> and GitHub-style URLs were accepted; a GitLab URL pasted into --worktree on an older version silently failed to resolve.

You can also open one from the numeric shorthand, quoted so your shell doesn’t parse # as a comment start:

claude --worktree "#42"

That works identically whether origin points at GitHub or GitLab — Claude Code figures out which fetch path to use from the remote itself, not from how you typed the reference.

This is genuinely useful for review workflows: rather than checking out a colleague’s MR branch in your main working directory (and derailing whatever you were already doing there), you get an isolated worktree, ask Claude to walk the diff, extend it, or write missing tests, and clean it up when you’re done — same cleanup behavior as any other --worktree session: an unnamed session with no changes gets removed automatically on exit, a named one or one with uncommitted work prompts you first.


Plugin Marketplaces on gitlab.com

Also in this release window (v2.1.232, one day before the worktree change), plugin marketplaces gained the ability to clone a bare gitlab.com URL the same way they’ve long handled bare GitHub URLs — including nested subgroups, which GitLab supports and GitHub doesn’t.

Before this shipped, adding a GitLab-hosted marketplace required the full .git URL:

/plugin marketplace add https://gitlab.com/company/plugins.git

That still works. What’s new is that the bare form now resolves the same way a bare GitHub org/repo reference always has, including through nested GitLab subgroups (gitlab.com/company/team/plugins), so a marketplace catalog hosted on GitLab is no longer visibly second-class compared to one on GitHub. A marketplace.json catalog file works identically regardless of which host serves it — see our plugin marketplace guide if you haven’t set one up yet.

This matters more than it sounds for GitLab-only shops: before v2.1.232, distributing internal Claude Code plugins (custom subagents, slash commands, hooks) to a team meant either standing up a GitHub mirror just for plugin hosting, or accepting the friction of full git URLs everywhere a bare reference would otherwise work.


GitLab Token Redaction

The same release added GitLab-specific secret protection to Claude Code’s output redaction, extending coverage that already existed for gh and GitHub token formats.

Nine GitLab token family prefixes get masked on sight — replaced with a redacted placeholder wherever they’d otherwise appear in tool output or transcripts:

glrt-    gloas-   glptt-   glagent-  glimt-
glsoat-  glcbt-   glft-    glffct-

Two routable, higher-blast-radius prefixes get removed completely instead of masked:

glpat-   (personal access tokens)
gldt-    (deploy tokens)

The distinction is deliberate: a masked token still shows its prefix and length, which is fine for most of these token families since they’re scoped or short-lived. glpat- and gldt- are routable and long-lived enough that even a partially-visible redaction was judged too risky, so Claude Code drops them from output entirely rather than masking them.

Claude Code also now protects the glab CLI’s config store the same way it’s protected gh’s — so a session with Bash access can’t casually read your glab credentials out of its config file and echo them into a transcript, a class of accidental exposure that used to be specific to GitHub tooling.

None of this requires configuration. It’s automatic redaction behavior, the same category as the API key and cloud credential masking Claude Code has applied to Bash output for longer than GitLab support has existed.


Self-Managed GitLab: What Works, What Doesn’t

Featuregitlab.comSelf-managed GitLab
CI/CD integrationYesYes — it’s just a .gitlab-ci.yml job on your own runners
--worktree from MR URLYes, merge-requests/<n>/headYes, via fallback: tries pull/<n>/head first, then merge-requests/<n>/head
claude agents !N labelingYesYes, once the worktree resolves
Bare-URL plugin marketplaceYesNo — use the full git URL
Token redaction (glpat-, glrt-, etc.)YesYes — pattern-based, not host-specific

The practical takeaway for self-managed instances: everything works, but the convenience shortcuts (--worktree "#42" resolving cleanly, bare marketplace URLs) are tuned for gitlab.com specifically. On a self-managed host, expect one extra fetch attempt on worktree creation (harmless, just not instant) and use the full .git URL for marketplaces.


FAQ

Does Claude Code support GitLab the same way it supports GitHub?

Mostly, as of August 2026. The CI/CD integration mirrors GitHub Actions’ @claude-mention workflow, --worktree and claude agents now parse merge request URLs the same way they parse pull request URLs, and plugin marketplaces clone bare gitlab.com URLs. The one real gap: Claude Code Action’s automatic PR-review-on-every-PR mode has no direct GitLab equivalent yet — GitLab’s own AI code review tooling fills that role instead.

How do I start a Claude Code worktree from a GitLab merge request?

claude --worktree "https://gitlab.com/group/project/-/merge_requests/42", quoted so your shell doesn’t mangle it. Requires v2.1.233 or later; check with claude --version.

How does Claude Code redact GitLab tokens?

Nine prefixes (glrt-, gloas-, glptt-, glagent-, glimt-, glsoat-, glcbt-, glft-, glffct-) are masked. Two higher-risk prefixes (glpat-, gldt-) are removed from output entirely rather than masked.

Can I use a self-managed GitLab instance?

Yes for the CI/CD integration and --worktree (with a fallback fetch attempt). The bare-URL marketplace shortcut is gitlab.com-specific; use the full .git URL on a self-managed instance.

Does the GitLab CI/CD job run on Anthropic’s infrastructure?

No — it runs on your own GitLab runners, sandboxed, with your choice of the Claude API, Amazon Bedrock, or Google Cloud’s Agent Platform as the model provider.


Browse real-world CLAUDE.md and AGENTS.md configurations, including CI-focused examples, in our rules gallery.

Related Articles

Explore the collection

Browse all AI coding rules — CLAUDE.md, .cursorrules, AGENTS.md, and more.

Browse Rules