Help us improve
Share bugs, ideas, or general feedback.
GitLab discussion operations via API. ALWAYS use this skill when user wants to: (1) view threaded discussions on MRs/issues, (2) create new discussion threads, (3) reply to discussions, (4) resolve/unresolve discussions.
npx claudepluginhub grandcamel/gitlab-assistant-skills --plugin gitlab-assistant-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/gitlab-assistant-skills:gitlab-discussionThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Threaded discussion management for GitLab using `glab api` raw endpoint calls.
Manages GitLab merge requests via glab: create from commits, list/view/checkout, merge with auto-handling, block MRs, handle reviews/discussions/stacks.
Follows up on GitHub/GitLab PR/MR review threads: classifies unresolved/replied/resolved/silent states, checks commit coverage for fixes, drafts replies. Use for checking feedback responses or thread resolutions.
Fetches and filters PR review comments, extracts outside-diff-range feedback from review bodies, and resolves threads with proper attribution. Useful when addressing CodeRabbit, Cursor, or human reviewer feedback.
Share bugs, ideas, or general feedback.
Threaded discussion management for GitLab using glab api raw endpoint calls.
| Operation | Command Pattern | Risk |
|---|---|---|
| List MR discussions | glab api projects/:id/merge_requests/:iid/discussions | - |
| List issue discussions | glab api projects/:id/issues/:iid/discussions | - |
| Get discussion | glab api projects/:id/merge_requests/:iid/discussions/:id | - |
| Create discussion | glab api projects/:id/merge_requests/:iid/discussions -X POST -f ... | ⚠️ |
| Reply to discussion | glab api projects/:id/.../discussions/:id/notes -X POST -f ... | ⚠️ |
| Resolve discussion | glab api projects/:id/.../discussions/:id -X PUT -f resolved=true | ⚠️ |
| Delete note | glab api projects/:id/.../discussions/:id/notes/:nid -X DELETE | ⚠️⚠️ |
Risk Legend: - Safe | ⚠️ Caution | ⚠️⚠️ Warning | ⚠️⚠️⚠️ Danger
ALWAYS use when:
NEVER use when:
glab mr note or glab issue note)notes scope)Required Token Scopes: api
Permissions:
# List all discussions on MR
glab api projects/123/merge_requests/1/discussions --method GET
# With pagination
glab api projects/123/merge_requests/1/discussions --paginate
# Using project path
glab api "projects/$(echo 'mygroup/myproject' | jq -Rr @uri)/merge_requests/1/discussions"
# List all discussions on issue
glab api projects/123/issues/42/discussions --method GET
# With pagination
glab api projects/123/issues/42/discussions --paginate
# Get MR discussion by ID
glab api projects/123/merge_requests/1/discussions/abc123 --method GET
# Get issue discussion by ID
glab api projects/123/issues/42/discussions/def456 --method GET
# Create general discussion
glab api projects/123/merge_requests/1/discussions --method POST \
-f body="This looks good overall, but I have some suggestions."
# Create discussion on specific line (diff note)
glab api projects/123/merge_requests/1/discussions --method POST \
-f body="This could be simplified using a helper function." \
-f position[base_sha]="abc123" \
-f position[head_sha]="def456" \
-f position[start_sha]="abc123" \
-f position[position_type]="text" \
-f position[new_path]="src/app.py" \
-f position[new_line]=42
# Create discussion on old line (removed code)
glab api projects/123/merge_requests/1/discussions --method POST \
-f body="Why was this removed?" \
-f position[base_sha]="abc123" \
-f position[head_sha]="def456" \
-f position[start_sha]="abc123" \
-f position[position_type]="text" \
-f position[old_path]="src/old.py" \
-f position[old_line]=15
# Create suggestion
glab api projects/123/merge_requests/1/discussions --method POST \
-f body='```suggestion
def improved_function():
return "better implementation"
```'
# Create discussion
glab api projects/123/issues/42/discussions --method POST \
-f body="I think we should reconsider this approach."
# Reply to MR discussion
glab api projects/123/merge_requests/1/discussions/abc123/notes --method POST \
-f body="Good point, I'll fix this."
# Reply to issue discussion
glab api projects/123/issues/42/discussions/def456/notes --method POST \
-f body="I agree with the above."
# Resolve MR discussion
glab api projects/123/merge_requests/1/discussions/abc123 --method PUT \
-f resolved=true
# Unresolve MR discussion
glab api projects/123/merge_requests/1/discussions/abc123 --method PUT \
-f resolved=false
# Update note in discussion
glab api projects/123/merge_requests/1/discussions/abc123/notes/789 --method PUT \
-f body="Updated comment text"
# Delete note from discussion
glab api projects/123/merge_requests/1/discussions/abc123/notes/789 --method DELETE
For line-specific comments on MRs, you need to provide position information:
| Field | Required | Description |
|---|---|---|
base_sha | Yes | SHA of the base commit (target branch) |
head_sha | Yes | SHA of the head commit (source branch) |
start_sha | Yes | SHA of the start commit |
position_type | Yes | text for code, image for images |
new_path | For new/modified | Path in new version |
new_line | For new/modified | Line number in new version |
old_path | For deleted | Path in old version |
old_line | For deleted | Line number in old version |
# Get MR details to find SHAs
mr_info=$(glab api projects/123/merge_requests/1)
base_sha=$(echo "$mr_info" | jq -r '.diff_refs.base_sha')
head_sha=$(echo "$mr_info" | jq -r '.diff_refs.head_sha')
start_sha=$(echo "$mr_info" | jq -r '.diff_refs.start_sha')
echo "Base: $base_sha"
echo "Head: $head_sha"
echo "Start: $start_sha"
project_id=123
mr_iid=1
# Get diff refs
mr_info=$(glab api projects/$project_id/merge_requests/$mr_iid)
base_sha=$(echo "$mr_info" | jq -r '.diff_refs.base_sha')
head_sha=$(echo "$mr_info" | jq -r '.diff_refs.head_sha')
start_sha=$(echo "$mr_info" | jq -r '.diff_refs.start_sha')
# Add comment on line 42 of new file
glab api projects/$project_id/merge_requests/$mr_iid/discussions --method POST \
-f body="Consider adding error handling here." \
-f position[base_sha]="$base_sha" \
-f position[head_sha]="$head_sha" \
-f position[start_sha]="$start_sha" \
-f position[position_type]="text" \
-f position[new_path]="src/handler.py" \
-f position[new_line]=42
# Get all unresolved discussions
glab api projects/123/merge_requests/1/discussions --paginate | \
jq -r '.[] | select(.notes[0].resolvable == true and .notes[0].resolved == false) | .id' | \
while read discussion_id; do
echo "Resolving: $discussion_id"
glab api projects/123/merge_requests/1/discussions/$discussion_id --method PUT \
-f resolved=true
done
# Show unresolved discussions with content
glab api projects/123/merge_requests/1/discussions --paginate | \
jq -r '.[] | select(.notes[0].resolvable == true and .notes[0].resolved == false) | "[\(.id)] \(.notes[0].author.username): \(.notes[0].body | split("\n")[0])"'
project_id=123
mr_iid=1
mr_info=$(glab api projects/$project_id/merge_requests/$mr_iid)
base_sha=$(echo "$mr_info" | jq -r '.diff_refs.base_sha')
head_sha=$(echo "$mr_info" | jq -r '.diff_refs.head_sha')
start_sha=$(echo "$mr_info" | jq -r '.diff_refs.start_sha')
# Create suggestion (multi-line needs proper escaping)
glab api projects/$project_id/merge_requests/$mr_iid/discussions --method POST \
-f body='```suggestion
const result = await fetchData();
return result.data;
```' \
-f position[base_sha]="$base_sha" \
-f position[head_sha]="$head_sha" \
-f position[start_sha]="$start_sha" \
-f position[position_type]="text" \
-f position[new_path]="src/api.js" \
-f position[new_line]=25
# Count discussions by state
glab api projects/123/merge_requests/1/discussions --paginate | \
jq '{
total: length,
resolved: [.[] | select(.notes[0].resolved == true)] | length,
unresolved: [.[] | select(.notes[0].resolvable == true and .notes[0].resolved == false)] | length
}'
| Issue | Cause | Solution |
|---|---|---|
| 400 Bad Request | Missing position fields | Include all required position fields |
| 404 Discussion not found | Invalid discussion ID | Check discussion exists |
| Cannot resolve | Not resolvable or not authorized | Check note type and permissions |
| Position invalid | Wrong SHAs or line numbers | Get fresh diff_refs from MR |
| Note empty | Body not set | Check -f body=... parameter |