forgejo-mcp/openspec/specs/list-milestones-labels/spec.md
Christoph Görn 7eb8a34234
docs: 📝 archive 5 delivered openspec changes, track 2 unimplemented
Sweep: assessed all 7 active openspec changes against the codebase.
Five had landed implementations (bounded-text, org-label, org-management,
code-review-skill, list-milestones-labels) — archived under
openspec/changes/archive/2026-05-12-* and their deltas folded into
openspec/specs/. Two remain unimplemented: add-releases-support
(operation/release/ missing despite proposal PR #129) and
forgejo-action-code-review (.forgejo/workflows/claude-code-review.yml
missing despite spec deltas).

Beads: reopened forgejo-mcp-0ep (releases impl) with notes on actual
status; created forgejo-mcp-673 for the action workflow impl.
2026-05-12 15:38:15 +02:00

4.7 KiB

list-milestones-labels Specification

Purpose

TBD - created by archiving change list-milestones-labels. Update Purpose after archive.

Requirements

Requirement: List repository milestones

The system SHALL expose a list_repo_milestones MCP tool that returns all milestones for a given repository. The tool SHALL accept owner and repo as required string parameters. The tool SHALL accept page (number, required, default 1, min 1) and limit (number, required, default 100, min 1) parameters for pagination. The tool SHALL accept an optional state string parameter with values open, closed, or all (default: open). The tool SHALL call the Forgejo SDK ListRepoMilestones method and return a JSON array where each element contains at minimum id (numeric), title (string), description (string), state (string), open_issues (number), and closed_issues (number).

Scenario: List open milestones

  • WHEN the tool is called with owner="org", repo="project", page=1, limit=100
  • THEN the system returns a JSON array of open milestones each with id, title, description, state, open_issues, closed_issues

Scenario: List all milestones including closed

  • WHEN the tool is called with state="all"
  • THEN the system returns milestones in all states (open and closed)

Scenario: List milestones for repo with none defined

  • WHEN the tool is called on a repo that has no milestones
  • THEN the system returns an empty JSON array

Scenario: Paginated results

  • WHEN the tool is called with page=2, limit=10
  • THEN the system returns the second page of up to 10 milestones

Scenario: Repository does not exist

  • WHEN the tool is called with a non-existent owner/repo combination
  • THEN the SDK returns an error and the tool propagates it to the caller

Requirement: List repository labels

The system SHALL expose a list_repo_labels MCP tool that returns labels usable on issues in a given repository. The tool SHALL accept owner and repo as required string parameters. The tool SHALL accept page (number, required, default 1, min 1) and limit (number, required, default 100, min 1) parameters for pagination. The tool SHALL accept an optional include_org_labels boolean parameter (default true).

When include_org_labels is true and the owner corresponds to an organization, the tool SHALL also fetch /orgs/{owner}/labels via pkg/forgejo.DoJSONList and merge the returned labels into the response. Each label in the response SHALL carry a scope field of either "repo" or "org" so callers can disambiguate ID spaces. Each element SHALL contain at minimum id (numeric), name (string), color (string, hex), description (string), and scope (string).

When include_org_labels is false, the tool SHALL return only repo-scoped labels, each tagged scope: "repo".

If the org-labels fetch returns 404 (owner is not an org, or org has no labels), the tool SHALL omit org labels without raising an error.

Scenario: List labels for org-owned repo with merge enabled

  • WHEN the tool is called with owner="codeberg-org", repo="project", page=1, limit=100 (include_org_labels defaults to true)
  • THEN the system returns a JSON array containing both repo labels (each with scope: "repo") and org labels (each with scope: "org")

Scenario: List labels for user-owned repo

  • WHEN the tool is called with owner="alice", repo="project" where alice is a user, not an org
  • THEN the system returns repo labels only, each with scope: "repo"; the org-labels fetch returns 404 and is silently treated as empty

Scenario: Disable org-label merge

  • WHEN the tool is called with include_org_labels=false on an org-owned repo
  • THEN the system returns repo labels only, each with scope: "repo", even though the owner is an org

Scenario: List labels for repo with none defined

  • WHEN the tool is called on a repo with no repo labels and the owner is a user (or include_org_labels=false)
  • THEN the system returns an empty JSON array

Scenario: Paginated results

  • WHEN the tool is called with page=2, limit=10
  • THEN the system returns the second page of up to 10 labels in each scope, merged

Scenario: Repository does not exist

  • WHEN the tool is called with a non-existent owner/repo combination
  • THEN the SDK returns an error from the repo-labels fetch and the tool propagates it to the caller

Scenario: Org-labels fetch authentication failure

  • WHEN the tool is called with include_org_labels=true and the org-labels fetch returns 401 or 403
  • THEN the tool returns an error wrapping forgejo.ErrUnauthorized (does not silently drop org labels on auth failure)