gitlab-issue-to-mr
Create an automation that implements GitLab issues when a configurable trigger label is applied.
Skill by OpenHands
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/openhands-gitlab-issue-to-mr
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
- Runs as
- Python package
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/gitlab-issue-to-mr
What's inside
- Skill name
gitlab-issue-to-mr- Description
- Create an automation that implements GitLab issues when a configurable trigger label is applied. Polls one or more projects deterministically, clones the default branch, starts one OpenHands conversation per label event, then commits, pushes, and opens the merge request itself.
- License
- MIT
- Instructions
- 440 lines in SKILL.md · view on GitHub
Before installing
- Ships executable scripts
- Instructions call the network
Files (8)
- .claude-plugin
- .codex-plugin
- plugin.json · .plugin/
- README.md
- SKILL.md
- issue-to-mr-setup.md · commands/
- state-schema.md · references/
- main.py · scripts/
SKILL.md (first lines)
# GitLab Issue to MR Automation
Create a cron automation that watches one or more GitLab projects for issues
with a trigger label, starts an OpenHands conversation once per label event with
the project's default branch already checked out, and opens a merge request with
whatever the agent produced.
The automation script is deterministic: issue discovery, label-event tracking,
state persistence, the clone, the branch, the commit, the push, the merge
request, the issue comments, and the clone's removal are all handled in Python.
The LLM is invoked only to write the code.
The agent is told **which** issue to implement, not what it says. It fetches the
description, the discussion, and whatever they link to itself, so nothing in the
prompt goes stale between dispatch and the moment the agent reads it.
That needs read access, so the conversation is handed one secret, `GITLAB_TOKEN`.
`AGENT_SECRET_NAMES` stays an allow-list: the rest of the deployment's secret
store is not reachable from a conversation whose instructions came from an issue.
On OpenHands Cloud and Enterprise the conversation runs with the user's own
settings instead: the connected GitLab integration's token, or the tools of the
connected GitLab MCP server.
The deployment's MCP servers are forwarded whole, matching `github-pr-reviewer`,
so a connected GitLab server gives the agent typed tools rather than curl. What
those servers reach is reachable from an issue-authored prompt, so connect only
servers that may be driven by untrusted text.
The agent also finishes the job: it commits, pushes its branch, and opens the
merge request, so the merge request appears when the agent stops rather than on
the next poll. The script does not trust that it happened - when the conversation
ends it asks GitLab whether the merge request exists, and opens it itself when it
does not. `origin` still carries no credential, so every GitLab command the agent
runs has to name `GITLAB_TOKEN`; the SDK only puts a secret in the environment of
a command that mentions it, and masks it in the output.
---
## Prerequisites
### GitLab access
On OpenHands Cloud and Enterprise, no secret is needed. A connected GitLab MCP
server (Settings -> MCP) is used directly, by the poller and by the conversations
it starts; a connected GitLab integration (Settings -> Integrations, connected by
signing in with GitLab) serves both with its token. With only the MCP server, the conversation commits through its
tools and reads a private project through them rather than cloning it.
Calling GitLab MCP directly needs GitLab 19.4 or later, where the branch,
commit, repository and work item tools this uses first appear. A token works with
any GitLab, so whenever there is one - the token of the user's GitLab sign-in or
connected integration, or a `GITLAB_TOKEN` secret - the poller and its
conversations use it rather than the MCP server. On an older GitLab, sign in with
GitLab or connect it under Settings -> Integrations; a `GITLAB_TOKEN` secret is
only needed when neither is possible.
On a local Agent Canvas, or when neither is connected, verify that the following
secret is set in **OpenHands Settings -> Secrets**:
| Secret name | Token type | Minimum requirements |
|---|---|---|
| `GITLAB_TOKEN` | Personal access token | `api` scope, and at least the **Developer** role on every watched project |
| `GITLAB_TOKEN` | Project or group access token | `api` scope, role **Developer** or above |
The `api` scope is what GitLab grants read and write on issues, notes, branches,
and merge requests through one scope; `read_api` polls happily and then fails at
the point of pushing. Developer is the lowest role that can push a branch and
open a merge request.
Two things the role does not cover, and which fail the push rather than the poll:
- **Protected branches.** The default branch is usually protected, but the
automation never pushes to it. Protect the branch prefix as well and the push
is rejected; leave `openhands/issue-*` unprotected.
- **CI/CD files.** An issue asking for a pipeline change makes the agent touch
`.gitlab-ci.yml`. That needs no extra scope, but a project with a protected
CI/CD configuration path rejects the push.
When several projects are monitored, the token must cover all of them.
Check with:
```bash
curl -s "https://gitlab.com/api/v4/user" \
-H "PRIVATE-TOKEN: $GITLAB_TOKEN" \
| python3 -c "import json,sys; d=json.load(sys.stdin); print(d.get('username') or d.get('message'))"
```
If the token is missing or invalid, inform the user and stop.
---
## Setup Workflow
Follow these steps in order.
### Step 1 - Verify GitLab access
On OpenHands Cloud and Enterprise, read `GET ${OPENHANDS_HOST}/api/v1/settings`
first. `gitlab` in `provider_tokens_set` means the user signed in with GitLab or
connected the integration, and its token is used, with any GitLab version: skip the
token check and go to Step 2. Otherwise, an entry in `agent_settings.mcp_config`
whose `url` is the instance's `/api/v4/mcp` means the poller uses that server: put
its key in `gitlab_mcp_server`, or leave it out and the run finds the server itself.
Call its `get_mcp_server_version` tool, and on 19.4 or later skip the token check
and go to Step 2. Calling GitLab MCP directly needs 19.4 or later, so on an older
GitLab tell the user that and ask them to sign in with GitLab or connect it under
Settings -> Integrations. Only if they can do neither, ask for a `GITLAB_TOKEN`
secret and run the token check below.
Otherwise run the `curl` check above, against the user's instance if it is not
`gitlab.com`.
- If absent: *"GITLAB_TOKEN is not set. Please add it in OpenHands Settings ->
Secrets."* Stop.
- If the API returns `{"message": "401 Unauthorized"}`: tell the user the token
is invalid and ask them to update it. Stop.
### Step 2 - Collect the GitLab API URLFrom OpenHands/extensions, MIT.
More from OpenHands/extensions
- 0.721score
deno
OpenHands
If the project uses deno, use this skill.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
discord
OpenHands
Build and automate Discord integrations (bots, webhooks, slash commands, and REST API workflows).
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
code-simplifier
OpenHands
Simplifies and refines code for clarity, consistency, and maintainability while preserving all functionality.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
datadog
OpenHands
Query and analyze Datadog logs, metrics, APM traces, and monitors using the Datadog API.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
add-skill
OpenHands
Import an existing skill from a GitHub repository URL into the current workspace.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
add-javadoc
OpenHands
Add comprehensive JavaDoc documentation to Java classes and methods.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
runtime-api-configs
OpenHands
Manage warm sandbox pools on OpenHands Enterprise by driving the runtime-api admin endpoints (list, save, delete warm runtime configurations) from a Python CLI.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
agent-creator
OpenHands
Create file-based sub-agents as Markdown files following the OpenHands SDK format.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
openhands
OpenHands
Unified OpenHands plugin — bundles the OpenHands Cloud CLI, Cloud REST API (openhands-api), Automations (openhands-automation), and Software Agent SDK…
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
agent-readiness-report
OpenHands
Evaluate how well a codebase supports autonomous AI-assisted development.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
release-notes
OpenHands
Generate consistent, well-structured release notes from git history.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
github
OpenHands
Interact with GitHub repositories, pull requests, issues, and workflows using the GITHUB_TOKEN environment variable and GitHub CLI.
SkillAFreshness: A★ 173Claude Code +9
Signals
- Stars
- 173
- Forks
- 118
- Open issues
- 84
- Last commit (this folder)
- Oct 12, 2026 (17 days ago)
- Last release
- Oct 23, 2026 (7 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/OpenHands/extensions
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from OpenHands
- 0.721score
release-notes
OpenHands
Generate consistent, well-structured release notes from git history.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
add-javadoc
OpenHands
Add comprehensive JavaDoc documentation to Java classes and methods.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
agent-readiness-report
OpenHands
Evaluate how well a codebase supports autonomous AI-assisted development.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
openhands
OpenHands
Unified OpenHands plugin — bundles the OpenHands Cloud CLI, Cloud REST API (openhands-api), Automations (openhands-automation), and Software Agent SDK…
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
runtime-api-configs
OpenHands
Manage warm sandbox pools on OpenHands Enterprise by driving the runtime-api admin endpoints (list, save, delete warm runtime configurations) from a Python CLI.
SkillAFreshness: A★ 173Claude Code +9 - 0.721score
add-skill
OpenHands
Import an existing skill from a GitHub repository URL into the current workspace.
SkillAFreshness: A★ 173Claude Code +9
Cite this page
gitlab-issue-to-mr skill. Agent Mart. https://agentmart.dev/skills/openhands-gitlab-issue-to-mr (last updated 2026-10-24)