gitlab-agent-webhook turns GitLab webhooks into autonomous agent work.
Open a merge request and it can review. Mention @agent on an issue or MR note and it can pick up the task, resume context, and reply through GitLab. The service stays small on purpose: webhook in, job queued, agent spawned, results posted back.
GitLab teams should not need a custom UI or direct LLM API integration just to run coding agents against issues and merge requests. This project keeps the control plane simple:
- GitLab sends webhooks.
- This service validates, routes, and persists jobs.
- Agents run through local CLIs like
claude,codex, andgemini. - Agents use
glabfor GitLab-native interaction.
That means you can self-host the automation layer, choose your preferred agent backend, and keep the actual GitLab actions in the same place developers already work.
- Auto-reviews merge requests on open and update events
- Responds to issue and MR mentions like
@agent fix this flaky test - Supports agent selection from the mention prefix:
@agent codex ... - Tracks resumable agent sessions in SQLite
- Uses a queue + worker model so webhook responses stay fast
- Posts acknowledgements and status updates back to GitLab
Minimum tested version: GitLab 11.0. Best-effort support for older self-hosted instances.
| GitLab version | Notes |
|---|---|
| 11.0+ | Full support. assignees array introduced; older instances send a singular assignee which is normalized automatically. |
| 13.2+ | draft field available on MR payloads. Older instances omit it; the service defaults to false. |
| 16.0+ | DiffNote note type added. These are parsed and silently ignored (only issue and MR notes trigger agents). |
| Any | last_commit may be absent on empty MRs. The idempotency key falls back to "no-commit" so the job still enqueues. |
The setup-webhooks script auto-detects the instance version and omits the webhook name field when the instance is older than 16.9.
claudecodexgemini
Each backend is executed through its local CLI. The service does not call model APIs directly.
The flow is intentionally narrow:
- GitLab sends a webhook to
POST /webhook. - The payload is validated and routed into a job.
- A worker claims the job and spawns the selected agent CLI.
- The agent uses
glabto comment, react, inspect context, and push changes if asked. - Session state is stored so follow-up mentions can resume the same thread of work.
@agent fix the broken test@agent codex please investigate this regression@agent gemini summarize the failing pipeline and propose a fix
Only a leading selector token changes the agent. Mid-sentence names stay part of the prompt.
- Bun
- TypeScript
- Hono
- Drizzle ORM
- SQLite
glab
- Copy the environment template and set
BOT_USERNAME=agent. - Install the required CLIs you want to use:
claude,codex, and/orgemini. - Install dependencies.
- Run migrations.
- Start the server and point a GitLab webhook at
/webhook.
bun install
bun run db:migrate
bun run devRequired environment variables:
GITLAB_WEBHOOK_SECRETBOT_USERNAMEGITLAB_TOKENGITLAB_HOST
Optional environment variables include DEFAULT_AGENT, DATABASE_PATH, WORKER_CONCURRENCY, AGENT_TIMEOUT_MS, and agent CLI path overrides.
See .env.example.
The project follows strict TDD and a single verification gate:
bun test
bun run checkbun run check runs typecheck, lint, and test. No alternative verification path exists in this repo.
- OpenCode support
- Publish an npm package for
npx/bunxusage - Publish a Docker image