GitLab CI lets you run Claude Code inside your pipelines so merges, issues, and review comments can trigger real code changes. You add one job to .gitlab-ci.yml, store a masked API key, and mention @claude to get working merge requests. This guide walks through setup, triggers, authentication, and the key differences from GitHub Actions.

GitLab CI: What You’ll Learn
GitLab CI is the continuous integration engine built into GitLab, and pairing it with Claude Code turns routine pipeline jobs into AI-assisted development. You will learn how to configure a Claude job, manage authentication across providers, and trigger runs from merge requests or comments. By the end, you can wire GitLab CI into your team workflow with confidence.
Why Run Claude Code in GitLab CI?
Claude Code in GitLab CI brings AI directly into the place where your code already lives. Instead of copying snippets into a chat window, you describe what you need right inside an issue or merge request, and Claude proposes a complete change set for review. GitLab CI makes this possible without leaving your existing toolchain.
The GitLab CI integration is event-driven. GitLab listens for triggers you choose, such as a comment mentioning @claude, and spins up an isolated job on your own runner. Claude reads the thread context, inspects your repository, follows the conventions in your CLAUDE.md file, and writes changes to a branch. Every modification flows through a merge request so your branch protection and approval rules still apply.
This means reviewers see the same diff interface they always have. The only difference is that Claude drafted the code. You keep full control over what merges, and Claude never bypasses your GitLab CI governance.
Core Capabilities
The integration supports several high-value workflows that reduce manual toil:
- Create merge requests from issues: Describe a feature in an issue comment, and Claude writes the implementation and opens an MR.
- Implement review feedback: Mention Claude in an MR discussion to ask for a concrete code change, and it updates the branch.
- Fix bugs fast: Point Claude at a failing test or error, and it locates and patches the problem.
- Analyze regressions: Claude can review recent changes and propose optimizations for performance dips.
How the GitLab CI Integration Works
Understanding the GitLab CI architecture helps you troubleshoot and scale. The integration has three layers that work together on every run.
First, event-driven orchestration means GitLab listens for your chosen triggers. When a qualifying event fires, such as a merge request event or a web-triggered pipeline, the job collects context from the thread and repository, builds a prompt, and launches Claude Code in headless mode. You can learn more about non-interactive invocation in the headless mode guide.
Second, provider abstraction lets you pick the backend that fits your environment. You can use the Claude API directly, Amazon Bedrock with IAM-based access, or Google Cloud’s Agent Platform with Workload Identity Federation. This flexibility matters for data residency and enterprise procurement.
Third, sandboxed execution ensures each job runs in a container with strict network and filesystem rules. Claude enforces workspace-scoped permissions, and all changes flow back through a merge request. Your runners, your rules.
Claude Code for GitLab CI is currently in beta and is maintained by GitLab. For support, see the GitLab issue tracker.
Setting Up Your .gitlab-ci.yml
The fastest path to a working GitLab CI integration is a minimal job. You need two things: a masked CI/CD variable holding your API key, and a Claude job definition in your pipeline file. The official Claude Code GitLab CI documentation provides the canonical reference.
Start by adding the variable. In your GitLab project, navigate to Settings, then CI/CD, then Variables. Add a variable named ANTHROPIC_API_KEY, mark it as masked, and protect it if your runners are protected. This keeps the key out of logs and limits it to protected branches.
Next, add the Claude job to your .gitlab-ci.yml. The official documentation provides a baseline you can adapt:
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
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"
--debugLet us break down what each piece does. The stages block defines a dedicated ai stage so Claude jobs do not block your build or test stages. The image uses node:24-alpine3.21 because Claude Code runs on Node.js. The rules section controls when the job fires, here matching manual web runs and merge request events.
The GIT_STRATEGY: fetch variable tells GitLab to fetch the repository without a full clone, which is faster. The before_script installs the tools Claude needs, then runs the official install script from claude.ai/install.sh. The script block optionally starts a GitLab MCP server, then invokes Claude with a prompt, permission mode, and allowed tools.
The Claude Invocation Explained
The claude command in the script block uses several flags worth understanding:
-ppasses a prompt string. IfAI_FLOW_INPUTis set by your trigger, it uses that; otherwise it falls back to a default review prompt.--permission-mode acceptEditstells Claude to accept file edits automatically, which is necessary in a non-interactive pipeline.--allowedToolsrestricts Claude to specific tools: Bash, Read, Edit, Write, and the GitLab MCP tools prefixed withmcp__gitlab.--debugadds verbose output to the job logs for troubleshooting.
Triggering Claude Jobs
Triggers determine when Claude runs in GitLab CI. The rules block in your job definition is where you configure this, and GitLab exposes several pipeline sources you can match against.
The two most common sources are web and merge_request_event. The web source fires when someone manually runs the pipeline from the GitLab UI, which is perfect for testing. The merge_request_event source fires when a merge request is created or updated, which is ideal for automated review.
For mention-driven triggers, where a comment containing @claude launches a job, you need an additional layer. GitLab does not natively start a pipeline from a comment alone. You set up a project webhook for comment events that calls an event listener, and the listener invokes the pipeline trigger API with variables like AI_FLOW_INPUT and AI_FLOW_CONTEXT carrying the comment text and context.
# Example: scheduled trigger
claude-scheduled:
stage: ai
image: node:24-alpine3.21
rules:
- if: '$CI_PIPELINE_SOURCE == "schedule"'
before_script:
- apk add --no-cache git curl bash
- curl -fsSL https://claude.ai/install.sh | bash
script:
- >
claude
-p "Review open MRs and summarize risk for each"
--permission-mode acceptEdits
--allowedTools "Bash Read Write mcp__gitlab"Scheduled triggers use the schedule source and are useful for periodic tasks like summarizing open merge requests or checking for stale branches. You configure them in CI/CD then Schedules in the GitLab UI.
Authentication and API Key Management
Security in GitLab CI pipelines comes down to how you store and expose credentials. The golden rule is simple: never commit API keys or cloud credentials to your repository. Always use GitLab CI/CD variables.
For the Claude API, the GitLab CI setup is straightforward. You store ANTHROPIC_API_KEY as a masked variable, and Claude Code reads it from the environment automatically. Masked variables are hidden in job logs, and protected variables are only available on protected branches or tags, adding a second layer of control.
For GitLab API operations, Claude needs to write comments and open merge requests. By default, it uses the CI_JOB_TOKEN that GitLab injects into every job. If you need broader permissions, create a Project Access Token with api scope and store it as GITLAB_ACCESS_TOKEN, also masked. The token gives Claude the rights to interact with your project programmatically.
Provider Authentication
For enterprise setups, you can avoid long-lived keys entirely. Amazon Bedrock uses OIDC identity federation: GitLab acts as an identity provider in AWS IAM, and your job assumes a role at runtime using a short-lived web identity token. You store AWS_ROLE_TO_ASSUME and AWS_REGION as variables, and the job exchanges the token for temporary credentials.
Google Cloud’s Agent Platform uses Workload Identity Federation. You store GCP_WORKLOAD_IDENTITY_PROVIDER and GCP_SERVICE_ACCOUNT, and the job impersonates the service account without downloading any keys. This approach is more secure than static credentials and aligns with zero-trust principles.
For a deeper look at how Claude Code runs in automated environments without human interaction, see the headless mode automation guide.
Amazon Bedrock and Google Cloud Providers
Running Claude on your own cloud infrastructure gives you control over data residency and uses existing cloud commitments. The GitLab integration supports both Amazon Bedrock and Google Cloud’s Agent Platform with first-class job templates.
For Amazon Bedrock, the job installs the AWS CLI, writes the GitLab OIDC token to a file, and calls aws sts assume-role-with-web-identity to get temporary credentials. These are exported as AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, and AWS_SESSION_TOKEN. Claude then uses Bedrock as its backend. Model IDs on Bedrock include region-specific prefixes, such as us.anthropic.claude-sonnet-4-6.
For Google Cloud’s Agent Platform, the job uses gcloud auth login with a credential file describing an external account. This file references your Workload Identity Provider and service account impersonation URL. No service account keys are stored anywhere. You set CLOUD_ML_REGION to your desired region, such as us-east5.
Both providers let you pick regional endpoints to reduce latency and meet data-sovereignty requirements while using existing cloud agreements.
Differences from GitHub Actions
If you have used Claude Code with GitHub Actions, you will notice several structural differences when moving to GitLab CI. The concepts map closely, but the GitLab CI syntax and tooling diverge in important ways.
The pipeline file is the first difference. GitHub Actions uses YAML files in .github/workflows/ with on: triggers and jobs: definitions. GitLab CI uses a single .gitlab-ci.yml at the repository root with stages: and rules: blocks. The trigger model is also different: GitHub uses event types like push and pull_request, while GitLab uses pipeline sources like web and merge_request_event.
Secret management differs too. GitHub stores secrets in repository or environment settings and injects them via ${{ secrets.NAME }} syntax. GitLab stores them as CI/CD variables, masked and optionally protected, and injects them directly as environment variables. Both approaches keep secrets out of logs, but GitLab variables are simpler to reference in shell scripts.
Runner infrastructure is another distinction. GitHub Actions provides hosted runners by default, while GitLab CI runs on your own runners or shared runners provided by GitLab. This means you control the compute environment, network egress, and caching more directly with GitLab. For team-scale deployments, the enterprise setup guide covers broader considerations.
Finally, the mention-driven trigger works differently. In GitHub, a comment on a pull request can trigger a workflow via the issue_comment event. In GitLab, comment triggers require a webhook and an external listener that calls the pipeline trigger API. This is an extra setup step but gives you full control over how mentions are processed.
Common Parameters and Variables
Claude Code in GitLab CI accepts several parameters that let you fine-tune behavior. Understanding these GitLab CI parameters helps you control cost and quality.
The prompt parameter, passed via -p, is the instruction Claude follows. You can also use prompt_file to load instructions from a file in your repository, which is useful for long or reusable prompts. The max_turns parameter limits the number of back-and-forth iterations Claude performs, preventing runaway runs. The timeout_minutes parameter caps total execution time.
For provider configuration, ANTHROPIC_API_KEY is required for the Claude API. For Bedrock, you set AWS_REGION and role variables. For Google Cloud, you set region and WIF variables. Exact flags may vary by version of the Claude Code package, so running claude --help in your job is the authoritative reference.
Customizing Claude’s Behavior
You guide Claude in two primary ways. First, a CLAUDE.md file at the repository root defines coding standards, review criteria, and project-specific rules. Claude reads this file during every run and follows your conventions when proposing changes. Keep it focused and concise for best results.
Second, custom prompts let you pass task-specific instructions per job. You can define different jobs for different tasks, such as one job for code review and another for implementation. This separation keeps prompts short and targeted, which reduces token usage and improves output quality. For more on building repeatable workflows, see the workflows and automation guide.
A Worked Example
Imagine your team tracks a bug in the user dashboard component using GitLab CI. A developer opens an issue describing a TypeError that appears when the dashboard loads on certain accounts. Instead of debugging manually, they leave a comment: @claude fix the TypeError in the user dashboard component.
Here is what happens next. The comment event fires a webhook to your listener, which calls the pipeline trigger API with AI_FLOW_INPUT set to the comment text and AI_FLOW_CONTEXT set to the issue identifier. GitLab starts the Claude job on your runner.
The job container boots with node:24-alpine3.21, installs git and curl, and runs the Claude install script. Claude Code starts in headless mode with the prompt from AI_FLOW_INPUT. It reads CLAUDE.md to understand your coding standards, then explores the repository to find the dashboard component.
Claude identifies the TypeError, writes a fix using the Edit tool, and commits the change to a new branch. It opens a merge request with a description explaining the root cause and the fix. The mcp__gitlab tools handle the MR creation and any follow-up comments.
Your team reviews the MR like any other. A reviewer notices the fix handles the edge case but suggests a more defensive approach. They comment on the MR, and Claude picks up the feedback in a follow-up run, updates the code, and pushes the change. The merge request is approved and merged, all without a developer opening a local editor.
This example shows the full GitLab CI loop: event to trigger to job to MR to review to merge. The developer spent seconds writing a comment, and Claude handled the rest within your existing governance. That is the promise of GitLab CI with Claude Code.
GitLab CI: Common Mistakes to Avoid
Even with a clear setup, a few pitfalls trip up teams adopting Claude in their pipelines. Here are the most frequent ones and how to sidestep them.
- Forgetting to mask the API key: If you add
ANTHROPIC_API_KEYwithout checking the masked flag, it can appear in job logs. Always mark it masked and protect it if your runners are protected. - Using
/claudeinstead of@claude: Mention triggers require the at sign. A slash command will not fire your webhook listener, and the job will never start. - Skipping the
CLAUDE.mdfile: Without project conventions, Claude guesses at your standards. A conciseCLAUDE.mddramatically improves output quality and reduces iterations. - Not limiting
max_turnsor timeouts: A complex task can run for many turns, consuming tokens and runner minutes. Set sensible limits to avoid runaway costs on every job.

GitLab CI: Best Practices
Follow these GitLab CI practices to keep your integration secure, cost-effective, and maintainable as your team scales.
- Use OIDC or WIF over static keys: For Bedrock and Google Cloud, prefer identity federation. It eliminates long-lived secrets and aligns with zero-trust security models.
- Keep
CLAUDE.mdfocused: A bloated instructions file burns tokens on every run. Include only coding standards, review criteria, and project-specific rules that Claude must follow. - Provide clear issue and MR descriptions: The richer the context, the fewer iterations Claude needs. A vague prompt leads to back-and-forth that costs time and tokens.
- Set job timeouts and turn limits: Configure
timeout_minutesandmax_turnson every job so a stuck run does not consume your runner budget. - Review Claude’s MRs like any other: Treat AI-generated code with the same scrutiny as human contributions. Branch protection and approval rules apply, so use them.

GitLab CI: Frequently Asked Questions
Is the GitLab CI integration production-ready?
It is currently in beta and maintained by GitLab. Features may evolve. For enterprise use, test thoroughly and monitor the GitLab issue tracker for updates.
Do I need a separate Claude license?
You need an ANTHROPIC_API_KEY from Anthropic, or access via Amazon Bedrock or Google Cloud’s Agent Platform. Each interaction consumes tokens based on prompt and response size.
Can Claude open merge requests automatically?
Yes. With mcp__gitlab tools enabled and a valid CI_JOB_TOKEN or access token, Claude creates branches and opens MRs. All changes still go through your review process.
How do I trigger Claude from a comment?
Set up a project webhook for comment events that calls an event listener. The listener invokes the pipeline trigger API with AI_FLOW_INPUT carrying the comment text containing @claude.
What is the difference from GitHub Actions?
GitLab CI uses .gitlab-ci.yml with rules and CI/CD variables, while GitHub Actions uses workflow files with on triggers and secrets. GitLab CI runs on your own runners with different trigger mechanics.
These questions cover the most common setup concerns. If you hit an issue not listed here, check the troubleshooting section of the official documentation.
GitLab CI brings Claude Code directly into your pipelines, turning comments and merge requests into working code changes. With the right triggers, masked credentials, and a focused CLAUDE.md, your team can automate reviews, fixes, and feature drafts while keeping full governance. Start with a minimal job, verify your variables, and scale from there.
Continue Learning
- Headless Mode and CI Automation — how Claude runs non-interactively in pipelines and scripts
- Workflows and Automation — building repeatable Claude Code workflows for your team
- Enterprise and Team Setup — scaling Claude Code across teams and providers