Fetches and analyzes GitLab merge request (MR) comments, metadata, and review feedback using authenticated API calls. Capabilities include fetching comment threads, retrieving reviewer feedback, filtering unresolved discussions, and generating MR activity reports. Use when the user asks about GitLab MR comments, code review discussions, review feedback, approval status, troubleshooting review delays, or needs to fetch merge request metadata via the GitLab API.
67
81%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Retrieve and analyze GitLab merge request comments and metadata using authenticated API calls.
Every GitLab MR comment fetch is a snapshot of a moving target, not a stable record. Comments get edited, resolved, and deleted between when a review happens and when it's analyzed, and the GitLab API returns 200 OK even when the payload inside is an error object — HTTP status alone does not mean "this data is valid." Treat every fetch as provisional: validate the shape of what came back before trusting it, and re-fetch rather than cache when the analysis is time-sensitive (an "unresolved discussion" report generated from an hour-old cache is actively misleading, not just stale).
The second load-bearing habit: System and Type are two independent axes, not one. System: true/false answers "who/what generated this" (bot vs human); Type: DiffNote/comment answers "where does this comment live" (inline on a diff line vs a general MR-level remark). A report that conflates them — e.g. treating all DiffNotes as human or all comments as automated — will misclassify real feedback.
.gitlab-ci.yml authoring — unrelated to the MR comments API this skill wrapsGITLAB_TOKEN or GITLAB_PAT with read_api scopecurl, jqFetches all comments from a GitLab merge request. Run it relative to this skill's own directory:
scripts/get_mr_comments.sh <merge_request_url>Example:
# Prerequisites assumed: GITLAB_TOKEN with read_api scope
scripts/get_mr_comments.sh "https://gitlab.com/your-group/your-project/-/merge_requests/123"Output Format:
---
Author: Name (@username)
Date: ISO8601 timestamp (UTC)
Type: DiffNote|comment
System: true|false
Comment body textSystem: true — automated/system-generated message; System: false — human commentType: DiffNote — inline code review comment; Type: comment — general MR commentExit Codes:
0: Success1: Invalid URL format, missing token, or API errorWhen to Examine Script Internals:
Read script source (scripts/get_mr_comments.sh, ~80 lines) when debugging unexpected output, extending for custom metadata, or understanding URL encoding. For basic usage, the examples above suffice.
See references/workflows-and-error-handling.md for the step-by-step review-summary and progress-tracking workflows, plus 401/404/200-with-error-body diagnosis.
WHY: PATs stored in source code are exposed in git history even after removal and create a permanent security risk — anyone with repo access, at any point in the future, can recover a token committed once.
❌ BAD:
GITLAB_TOKEN="glpat-xxxxxxxxxxxxxxxxxxxx" # inline in a script committed to version control✅ GOOD:
GITLAB_TOKEN="${GITLAB_TOKEN:?Set GITLAB_TOKEN with read_api scope}"Consequence: A leaked PAT grants read_api access to every project the token owner can see, not just the one repo it was committed to.
WHY: The API always paginates; requesting per_page=100 does not guarantee the result set fits on one page, and both under- and over-estimating the true count silently truncate downstream analysis.
❌ BAD:
curl "$API_URL/merge_requests?per_page=100" # assumes this is everything✅ GOOD:
page=1
while :; do
resp=$(curl -sD headers.txt "$API_URL/merge_requests?per_page=100&page=$page")
# process $resp
next=$(grep -i '^x-next-page:' headers.txt | tr -d '\r' | cut -d' ' -f2)
[ -z "$next" ] && break
page=$next
doneConsequence: Reports built on the first page only silently omit older or later comments/MRs, and nothing in the response signals that truncation happened — it looks like a complete, valid result.
WHY: The API enforces rate limits (typically 2000 req/min for REST); bulk operations without backoff must always check for 429 responses rather than assuming every request succeeds.
❌ BAD: firing parallel bulk API calls with no retry logic.
✅ GOOD: check for 429 status codes and implement exponential backoff, honoring the Retry-After header when the API provides one.
Consequence: A burst of unthrottled calls gets throttled mid-run, and any call that doesn't check its own status code silently treats a 429 error body as if it were real data.
v3 endpoint pathWHY: GitLab removed API v3 in GitLab 11.0; all integrations must use v4.
❌ BAD:
https://gitlab.example.com/api/v3/projects/✅ GOOD:
https://gitlab.example.com/api/v4/projects/Consequence: v3 endpoints return 404 or are silently redirected on current GitLab instances, producing confusing failures that look like an auth or URL problem rather than a versioning one.
System to exclude bot messages — it is independent of Type, so don't conflate the two axes (see Mindset)jq for JSON parsing; never grep on raw API JSON200 OK with an error body%2F for / in project paths)| Topic | Reference | When to Use |
|---|---|---|
| Step-by-step review-summary/progress-tracking workflows and 401/404/200-with-error-body diagnosis | Workflows and Error Handling | Building a report/monitoring script, or diagnosing a failed API call |
a1083f4
Also appears in
last in sync Aug 28, 2026
last in sync Aug 28, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.