list_repo_labels: limit/page parameters not exposed — hard cap at 50 labels causes silent duplicate creation #289

Open
opened 2026-06-26 10:53:15 +00:00 by goern · 0 comments
goern commented 2026-06-26 10:53:15 +00:00 (Migrated from codeberg.org)

Summary

list_repo_labels does not expose the Forgejo REST API's limit and page query parameters. Calls are silently capped at 50 labels regardless of any limit value passed in the tool arguments.

Steps to reproduce

  1. Create a repository with more than 50 labels (e.g. 57).
  2. Call list_repo_labels with limit: 1000.
  3. Observe: only the first 50 labels are returned. No error, no pagination cursor, no indication that results were truncated.
forgejo-mcp --cli list_repo_labels --args '{"owner":"machdenstaat","repo":"lage","limit":1000}' --output=json \
  | jq '.[0].text | fromjson | .Result | length'
# → 50   (not 57)

Impact

Any consumer that builds a name→ID map from list_repo_labels and then conditionally creates-or-updates labels will silently create duplicate labels for every label beyond position 50. The label name appears absent from the map, so create_repo_label is called even though the label already exists — and Forgejo's POST /repos/{owner}/{repo}/labels is not idempotent.

Observed in practice: running castra init-labels (a label-upsert tool) three times on a 57-label repo produced 35 duplicate labels that had to be manually deleted.

Underlying Forgejo API

GET /repos/{owner}/{repo}/labels supports limit (1–50) and page (1-based) query parameters. Pagination is fully supported server-side; the MCP tool just doesn't expose it.

Proposed fix

Add limit (integer, default 20, max 50) and page (integer, default 1) to the list_repo_labels tool schema, forwarding them directly to the Forgejo API. Consumers can then paginate by incrementing page until the response length is less than limit.

Workaround

Until this is fixed, bypass list_repo_labels and call the REST API directly with curl:

page=1; combined="[]"
while true; do
  batch="$(curl -sf -H "Authorization: token $TOKEN" \
    "$FORGEJO_URL/api/v1/repos/$OWNER/$REPO/labels?limit=50&page=$page")"
  count="$(jq 'length' <<<"$batch")"
  combined="$(jq -n --argjson a "$combined" --argjson b "$batch" '$a + $b')"
  [[ "$count" -lt 50 ]] && break
  ((page++))
done
echo "$combined"
## Summary `list_repo_labels` does not expose the Forgejo REST API's `limit` and `page` query parameters. Calls are silently capped at 50 labels regardless of any `limit` value passed in the tool arguments. ## Steps to reproduce 1. Create a repository with more than 50 labels (e.g. 57). 2. Call `list_repo_labels` with `limit: 1000`. 3. Observe: only the first 50 labels are returned. No error, no pagination cursor, no indication that results were truncated. ```bash forgejo-mcp --cli list_repo_labels --args '{"owner":"machdenstaat","repo":"lage","limit":1000}' --output=json \ | jq '.[0].text | fromjson | .Result | length' # → 50 (not 57) ``` ## Impact Any consumer that builds a name→ID map from `list_repo_labels` and then conditionally creates-or-updates labels will **silently create duplicate labels** for every label beyond position 50. The label name appears absent from the map, so `create_repo_label` is called even though the label already exists — and Forgejo's `POST /repos/{owner}/{repo}/labels` is not idempotent. Observed in practice: running `castra init-labels` (a label-upsert tool) three times on a 57-label repo produced **35 duplicate labels** that had to be manually deleted. ## Underlying Forgejo API `GET /repos/{owner}/{repo}/labels` supports `limit` (1–50) and `page` (1-based) query parameters. Pagination is fully supported server-side; the MCP tool just doesn't expose it. ## Proposed fix Add `limit` (integer, default 20, max 50) and `page` (integer, default 1) to the `list_repo_labels` tool schema, forwarding them directly to the Forgejo API. Consumers can then paginate by incrementing `page` until the response length is less than `limit`. ## Workaround Until this is fixed, bypass `list_repo_labels` and call the REST API directly with `curl`: ```bash page=1; combined="[]" while true; do batch="$(curl -sf -H "Authorization: token $TOKEN" \ "$FORGEJO_URL/api/v1/repos/$OWNER/$REPO/labels?limit=50&page=$page")" count="$(jq 'length' <<<"$batch")" combined="$(jq -n --argjson a "$combined" --argjson b "$batch" '$a + $b')" [[ "$count" -lt 50 ]] && break ((page++)) done echo "$combined" ```
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
agentic-forges/forgejo-mcp#289
No description provided.