Add set_label, comment_on_issue, and create_repo MCP tools #6

Closed
opened 2026-03-13 20:07:23 +00:00 by forgejo_admin · 1 comment
Contributor

Lineage

plan-pal-e-agency → Phase 3 (Forgejo MCP completeness)

Repo

forgejo_admin/forgejo-mcp

User Story

As an agent following the label signaling protocol,
I want to set labels on Forgejo issues, comment on issues, and create repos via MCP tools,
So that the workflow state machine (agent-workflow) can operate without manual intervention.

Context

The agent-workflow SOP defines a label signaling protocol where Dev agents set status:in-progress, status:qa, and QA agents set status:approved or status:needs-fix on Forgejo issues. Currently forgejo-mcp has 17 tools but none for label management, issue commenting, or repo creation. The underlying forgejo-sdk already has all the methods — this issue is purely about adding MCP tool wrappers.

This is the #1 blocker for autonomous agent workflow.

File Targets

Files to modify:

  • src/forgejo_mcp/tools/workflows.py — Add 3 new tool functions following existing pattern (@mcp.tool() decorator, Annotated params, JSON return, _error_response())

Files to NOT touch:

  • src/forgejo_mcp/server.py — No changes needed, tool registration is automatic via decorators
  • src/forgejo_mcp/__init__.py — No changes needed

Acceptance Criteria

  • set_label(owner, repo, issue_number, labels) tool exists — accepts label names (not IDs), looks up IDs via issue_list_labels, calls issue_replace_labels or issue_add_label. Returns the current labels on the issue after the operation.
  • comment_on_issue(owner, repo, issue_number, body) tool exists — posts a comment on a Forgejo issue. Returns the comment ID and body.
  • create_repo(owner, repo_name, description, private) tool exists — creates a new repository. Returns repo name, URL, clone URL.
  • All three tools follow existing pattern: Annotated[type, Field(description=...)] params, JSON string return, _error_response() error handling
  • All three tools have clear docstrings (these become MCP tool descriptions)

Test Expectations

  • Integration test for set_label: create an issue, set a label by name, verify label is applied
  • Integration test for comment_on_issue: create an issue, post a comment, verify comment exists
  • Integration test for create_repo: create a repo, verify it exists, clean up (delete repo)
  • Run: pytest tests/ -v

Constraints

  • Follow existing tool pattern in workflows.py exactly — no new files, no new abstractions
  • set_label must accept label names not IDs (agents don't know label IDs). Look up via issue_list_labels(owner, repo) first
  • For set_label, support both "add" mode (append to existing) and "replace" mode (replace all labels). Default to "add" mode since the common case is adding status:in-progress alongside existing type:feature
  • Check forgejo-sdk source at ~/forgejo-sdk/src/forgejo_sdk/ for available methods: issue.py for labels/comments, repository.py for repo creation
  • pyproject.toml already has forgejo-sdk as dependency — no changes needed

Checklist

  • PR opened
  • Tests pass
  • No unrelated changes
  • project-pal-e-agency — project this affects
### Lineage `plan-pal-e-agency` → Phase 3 (Forgejo MCP completeness) ### Repo `forgejo_admin/forgejo-mcp` ### User Story As an agent following the label signaling protocol, I want to set labels on Forgejo issues, comment on issues, and create repos via MCP tools, So that the workflow state machine (agent-workflow) can operate without manual intervention. ### Context The agent-workflow SOP defines a label signaling protocol where Dev agents set `status:in-progress`, `status:qa`, and QA agents set `status:approved` or `status:needs-fix` on Forgejo issues. Currently forgejo-mcp has 17 tools but none for label management, issue commenting, or repo creation. The underlying forgejo-sdk already has all the methods — this issue is purely about adding MCP tool wrappers. This is the #1 blocker for autonomous agent workflow. ### File Targets Files to modify: - `src/forgejo_mcp/tools/workflows.py` — Add 3 new tool functions following existing pattern (`@mcp.tool()` decorator, `Annotated` params, JSON return, `_error_response()`) Files to NOT touch: - `src/forgejo_mcp/server.py` — No changes needed, tool registration is automatic via decorators - `src/forgejo_mcp/__init__.py` — No changes needed ### Acceptance Criteria - [ ] `set_label(owner, repo, issue_number, labels)` tool exists — accepts label **names** (not IDs), looks up IDs via `issue_list_labels`, calls `issue_replace_labels` or `issue_add_label`. Returns the current labels on the issue after the operation. - [ ] `comment_on_issue(owner, repo, issue_number, body)` tool exists — posts a comment on a Forgejo issue. Returns the comment ID and body. - [ ] `create_repo(owner, repo_name, description, private)` tool exists — creates a new repository. Returns repo name, URL, clone URL. - [ ] All three tools follow existing pattern: `Annotated[type, Field(description=...)]` params, JSON string return, `_error_response()` error handling - [ ] All three tools have clear docstrings (these become MCP tool descriptions) ### Test Expectations - [ ] Integration test for `set_label`: create an issue, set a label by name, verify label is applied - [ ] Integration test for `comment_on_issue`: create an issue, post a comment, verify comment exists - [ ] Integration test for `create_repo`: create a repo, verify it exists, clean up (delete repo) - Run: `pytest tests/ -v` ### Constraints - Follow existing tool pattern in `workflows.py` exactly — no new files, no new abstractions - `set_label` must accept label **names** not IDs (agents don't know label IDs). Look up via `issue_list_labels(owner, repo)` first - For `set_label`, support both "add" mode (append to existing) and "replace" mode (replace all labels). Default to "add" mode since the common case is adding `status:in-progress` alongside existing `type:feature` - Check forgejo-sdk source at `~/forgejo-sdk/src/forgejo_sdk/` for available methods: `issue.py` for labels/comments, `repository.py` for repo creation - `pyproject.toml` already has `forgejo-sdk` as dependency — no changes needed ### Checklist - [ ] PR opened - [ ] Tests pass - [ ] No unrelated changes ### Related - `project-pal-e-agency` — project this affects
Author
Contributor

PR #10 Review

BLOCKERS

None.

NITS

  1. set_label label limit: issue_list_labels is called with limit=100. If a repo exceeds 100 labels, some would silently fail to resolve. Consider paginating or raising the limit. Low-risk for now -- no repo in this platform is close to 100 labels.

  2. Test file naming: test_new_tools.py is generic. As more tools are added this name becomes meaningless. A name like test_label_comment_repo.py would age better.

  3. comment_on_issue overlaps with comment_on_pr: Both call issue_create_comment on the same Forgejo API endpoint (issues and PRs share IDs). Having both is intentional for agent discoverability, but worth documenting the equivalence so future maintainers do not think they are different.

  4. CI does not run pytest: The .woodpecker.yml pipeline only runs ruff check and ruff format --check. Integration tests require live Forgejo credentials so this is understandable, but worth noting that test correctness relies entirely on pre-merge local runs. This is a pre-existing gap, not introduced by this PR.

SOP COMPLIANCE

  • Branch named after issue (6-add-set-label-comment-on-issue-create-repo)
  • PR body follows template (Summary, Changes, Test Plan, Related)
  • Related references plan slug (plan-pal-e-agency)
  • Closes #6 in PR body
  • Tests exist (6 integration tests covering happy paths and error cases)
  • No secrets, .env files, or credentials committed
  • No scope creep (2 files changed, all within issue scope)
  • Commit message is descriptive
  • CI passes (pipeline #14 success)

Code Quality Notes

  • All three tools follow the established @mcp.tool() pattern with Annotated params, JSON return, and _error_response() error handling -- consistent with existing tools.
  • set_label resolves label names to IDs (good UX), validates mode and label existence with clear error messages, and returns current labels after the operation.
  • create_repo correctly handles both user and org ownership with a secure default (private=True).
  • Tests create disposable resources and clean up in finally blocks. Test assertions are specific and well-commented.
  • SDK method signatures verified against forgejo-sdk source -- all calls are correct.

VERDICT: APPROVED

## PR #10 Review ### BLOCKERS None. ### NITS 1. **`set_label` label limit**: `issue_list_labels` is called with `limit=100`. If a repo exceeds 100 labels, some would silently fail to resolve. Consider paginating or raising the limit. Low-risk for now -- no repo in this platform is close to 100 labels. 2. **Test file naming**: `test_new_tools.py` is generic. As more tools are added this name becomes meaningless. A name like `test_label_comment_repo.py` would age better. 3. **`comment_on_issue` overlaps with `comment_on_pr`**: Both call `issue_create_comment` on the same Forgejo API endpoint (issues and PRs share IDs). Having both is intentional for agent discoverability, but worth documenting the equivalence so future maintainers do not think they are different. 4. **CI does not run `pytest`**: The `.woodpecker.yml` pipeline only runs `ruff check` and `ruff format --check`. Integration tests require live Forgejo credentials so this is understandable, but worth noting that test correctness relies entirely on pre-merge local runs. This is a pre-existing gap, not introduced by this PR. ### SOP COMPLIANCE - [x] Branch named after issue (`6-add-set-label-comment-on-issue-create-repo`) - [x] PR body follows template (Summary, Changes, Test Plan, Related) - [x] Related references plan slug (`plan-pal-e-agency`) - [x] `Closes #6` in PR body - [x] Tests exist (6 integration tests covering happy paths and error cases) - [x] No secrets, .env files, or credentials committed - [x] No scope creep (2 files changed, all within issue scope) - [x] Commit message is descriptive - [x] CI passes (pipeline #14 success) ### Code Quality Notes - All three tools follow the established `@mcp.tool()` pattern with `Annotated` params, JSON return, and `_error_response()` error handling -- consistent with existing tools. - `set_label` resolves label names to IDs (good UX), validates mode and label existence with clear error messages, and returns current labels after the operation. - `create_repo` correctly handles both user and org ownership with a secure default (`private=True`). - Tests create disposable resources and clean up in `finally` blocks. Test assertions are specific and well-commented. - SDK method signatures verified against `forgejo-sdk` source -- all calls are correct. ### VERDICT: APPROVED
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
ldraney/forgejo-mcp#6
No description provided.