Skip to content

Issue Management Examples

These step-by-step workflows cover issue management end to end: triaging open issues, assigning and labeling them, linking related and blocking issues, tracking milestone progress, holding discussions, and searching across projects. Each example pairs the prompt you type with the exact catalog action the server runs, written as domain.action → parameters: on the default dynamic surface that is the action you pass to gitlab_execute_action, and with GITLAB_MCP_TOOL_SURFACE=meta it is the action of the gitlab_<domain> meta-tool, so you can reuse the call directly.

The triage loop moves an issue from intake to resolution: view open issues, assign and label them, link related issues, track them in a milestone, and either close them or keep the discussion going. The diagram shows that cycle and where it loops back.

Yes

No

View Open
Issues

Assign &
Label

Link Related
Issues

Track in
Milestone

Resolved?

Close Issue

Add Comment
& Discuss

Prompt: “Show me all open issues in the backend project with label ‘bug’”

issue.list → project_id: "my-group/backend",
state: "opened", labels: ["bug"]

Returns: issue titles, authors, labels, milestones, assignees, and creation dates.

Prompt: “Assign issue #123 to johndoe and add labels ‘priority::high’ and ‘team::backend’”

issue.update → project_id: "my-group/backend",
issue_iid: 123, assignee_ids: [45], add_labels: ["priority::high", "team::backend"]

Prompt: “Show me all unassigned issues in the Sprint 15 milestone”

issue.list → project_id: "my-group/backend",
milestone: "Sprint 15", assignee_id: 0

Returns: issues without assignees that need attention before the sprint starts.

Prompt: “Close issue #456 with a comment explaining the fix”

issue.note_create → project_id: "my-group/backend",
issue_iid: 456, body: "Fixed in MR !89 — the timeout was caused by..."
issue.update → project_id: "my-group/backend",
issue_iid: 456, state_event: "close"

There is no dedicated “AI analysis” tool. AI-powered analysis happens when the assistant reads issues with issue.list or issue.get, reasons over their content, and then acts on the result — assigning, labeling, linking, or commenting with the actions below. For example, “Find the open bugs in backend, group them by likely root cause, and label the duplicates” chains a read action with the triage actions in this guide, all within one conversation.


Model relationships between issues so dependencies are explicit. Mark issues as related, record blocking relationships, and review every link attached to an issue.

Prompt: “Link issue #100 as related to issue #200 in the backend project”

issue.link_create → project_id: "my-group/backend",
issue_iid: 100, target_project_id: "my-group/backend", target_issue_iid: "200", link_type: "relates_to"

Prompt: “Mark issue #300 as blocking issue #400”

issue.link_create → project_id: "my-group/backend",
issue_iid: 300, target_project_id: "my-group/backend", target_issue_iid: "400", link_type: "blocks"

target_project_id is required even when both issues live in the same project, because a link may cross projects.

Prompt: “Show me all issues related to issue #100”

issue.link_list → project_id: "my-group/backend", issue_iid: 100

Returns: linked issues with relationship types (relates_to, blocks, is_blocked_by).

The three link types answer different questions, and choosing the wrong one hides a real dependency:

link_typeMeaningDirectionBlocks progress?
relates_toThe two issues are associated but neither gates the otherSymmetricNo
blocksThe source issue must be resolved before the target can startSource → targetYes
is_blocked_byThe inverse view of blocks, as seen from the target issueTarget → sourceYes

Creating a blocks link from #300 to #400 is what makes #400 report is_blocked_by #300 — you do not create both sides.


Organize and measure work with labels and milestones. Create scoped labels to categorize issues, and check a milestone’s progress to see how close a sprint is to completion.

Prompt: “Create a scoped label ‘priority::critical’ with red color in the backend project”

project.label_create → project_id: "my-group/backend",
name: "priority::critical", color: "#CC0000"

Prompt: “Show me the progress of milestone Sprint 15”

project.milestone_get → project_id: "my-group/backend", milestone_iid: 15

Returns: title, state, start date, due date, whether it has expired, and the milestone’s web URL; project.milestone_issues lists the issues still open in it.


Keep the conversation on the issue itself. Add a quick comment, open a threaded discussion for a deeper topic, or react with award emoji to acknowledge updates without adding noise.

Prompt: “Comment on issue #123: ‘Reproduced on staging — the error only occurs with concurrent requests’”

issue.note_create → project_id: "my-group/backend",
issue_iid: 123, body: "Reproduced on staging — the error only occurs with concurrent requests"

Prompt: “Create a discussion thread on issue #123 about the proposed architecture”

issue.discussion_create → project_id: "my-group/backend",
issue_iid: 123, body: "Let's discuss the proposed architecture for this feature..."

Prompt: “Add a thumbs-up reaction to issue #123”

issue.emoji_issue_create → project_id: "my-group/backend",
issue_iid: 123, name: "thumbsup"

Find issues beyond a single project. Search globally by keyword across every project you can access, or scope the search to one group to surface issues by label.

Prompt: “Search for issues mentioning ‘memory leak’ across all my projects”

search.issues → query: "memory leak"

Returns: matching issues across all accessible projects with titles, descriptions, and project paths.

Prompt: “Find all open issues with label ‘security’ in the platform group”

issue.list_group → group_id: "platform",
state: "opened", labels: ["security"]

Returns: security-related issues across all projects in the group.

On the default dynamic surface the assistant discovers the issue action and its schema first, then executes it, so every block above is the action of a gitlab_execute_action call. The two-step pattern is find, then execute:

gitlab_find_action → query: "open issues with a label"
gitlab_execute_action → action: "issue.list", params: { project_id: "my-group/backend", state: "opened", labels: ["bug"] }

Assigning, labeling and linking follow the same shape:

gitlab_execute_action → action: "issue.update", params: { project_id: "my-group/backend", issue_iid: 123, assignee_ids: [45], add_labels: ["priority::high", "team::backend"] }
gitlab_execute_action → action: "issue.link_create", params: { project_id: "my-group/backend", issue_iid: 300, target_project_id: "my-group/backend", target_issue_iid: "400", link_type: "blocks" }

With GITLAB_MCP_TOOL_SURFACE=meta the same calls go to the gitlab_issue meta-tool with action: list, action: update and action: link_create, each with the parameters nested under params.


Frequently asked questions

How do I triage GitLab issues with an AI assistant?

Ask your assistant to list the open issues you care about, then to assign, label, and link them. A typical triage loop is four calls: issue.list (filtered by state: opened and a labels array) to see the backlog, issue.update to set assignee_ids, add_labels, and milestone_id, issue.link_create (with target_project_id and target_issue_iid) to record dependencies, and issue.update again with state_event: close once resolved. On the default dynamic surface these are gitlab_execute_action actions, discoverable through gitlab_find_action; with GITLAB_MCP_TOOL_SURFACE=meta they are the gitlab_issue meta-tool's list, update, and link_create actions.

What is the difference between relates_to, blocks, and is_blocked_by?

They are the three link_type values accepted by issue.link_create (gitlab_issue with action: link_create on the meta surface). relates_to is a symmetric, non-blocking association — neither issue gates the other. blocks means the source issue must be resolved before the target can proceed. is_blocked_by is the inverse direction of the same relationship, so creating a blocks link from #300 to #400 is what makes #400 report is_blocked_by #300. Listing links with issue.link_list returns the relationship type alongside each linked issue.

Can an AI assistant close a GitLab issue for me?

Yes, but closing is a state change, so it follows the same safety rules as any other mutation. The call is issue.update with state_event: close (gitlab_issue, action: update, on the meta surface). If the deployment runs with GITLAB_MCP_READ_ONLY=true the action is not registered at all, and under GITLAB_MCP_SAFE_MODE=true the server returns a JSON preview of the change instead of applying it.

How do I search issues across several GitLab projects at once?

Use search.issues rather than issue.list (the gitlab_search and gitlab_issue meta-tools when GITLAB_MCP_TOOL_SURFACE=meta), because issue listing is scoped to one project or group. Search accepts an instance, group, or project scope, so search.issues with a group_id searches every project in that group in one call. Results come back with the project path on each hit, so an assistant can follow up with issue.get on whichever project owns the issue.