- Add docs/plans/issue-attachments.md: full spec for 12 new MCP tools covering CRUD for issue and comment attachments (closes #106) - Add docs/plans/reply-to-review-comment.md: spec for #98 - Track feature work in beads (forgejo-mcp-ydg) - Rename MCP config token var CODEBERG_ACCESS_TOKEN → CODEBERG_TOKEN - Remove redundant config.json example (superseded by .mcp.json)
5.4 KiB
Reply to Review Comment — Implementation Plan
Issue: #98
Branch: feature/reply-to-review-comment
Summary
Add a reply_to_review_comment MCP tool that posts a threaded reply to a specific inline review comment on a pull request. This enables AI-assisted code review workflows where the PR author responds directly to each inline reviewer comment.
Current State
- forgejo-mcp has 6 review tools in
operation/pull/review.go: create, submit, dismiss, delete reviews; create/delete review requests - forgejo-sdk v2.2.1 has
ListPullReviewComments(GET) but no method to POST a reply to a review comment - The Forgejo REST API supports this via:
with a JSON body containingPOST /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/commentsbodyand (undocumented in SDK) a mechanism to thread replies
Key Design Decision: SDK Gap
The forgejo-sdk does not expose a method for creating review comment replies. Two options:
Option A: Raw HTTP call via SDK client (recommended)
Use the SDK client's underlying HTTP transport to make a direct API call. The SDK's Client type is based on a standard HTTP client, so we can construct the request ourselves while reusing auth and base URL.
Pros: No upstream dependency, ships immediately Cons: Bypasses SDK validation; couples to raw API shape
Option B: Upstream SDK contribution
Contribute a CreatePullReviewCommentReply method to forgejo-sdk, then use it.
Pros: Clean, idiomatic Cons: Blocks on upstream review cycle (1-2 weeks minimum)
Recommendation: Start with Option A (raw HTTP) so the feature ships. File an upstream SDK issue in parallel. When the SDK adds native support, refactor to use it.
Target State
New Tool: reply_to_review_comment
| Parameter | Type | Required | Description |
|---|---|---|---|
owner |
string | yes | Repository owner |
repo |
string | yes | Repository name |
index |
number | yes | Pull request index |
review_id |
number | yes | Review ID |
comment_id |
number | yes | ID of the comment to reply to |
body |
string | yes | Reply body text |
Returns: The created PullReviewComment as JSON.
Forgejo API Call
POST /repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/comments
Content-Type: application/json
{
"body": "...",
"reply_to": <comment_id> // threads the reply under the original comment
}
Note
: The exact field name (
reply_tovsin_reply_to) must be verified against the Forgejo API spec or by inspecting the Forgejo source. The Gitea API usesin_reply_to.
Implementation Steps
Part 1: Verify API Contract
- Check the Forgejo API spec for
POST /repos/{owner}/{repo}/pulls/{index}/reviews/{id}/comments— confirm the request body schema and the field name for threading replies - Test manually with
curlagainst a live Forgejo instance to confirm behavior
Part 2: Implement the Tool
1. Add parameter descriptions in pkg/params/params.go
CommentID = "The ID of the review comment to reply to"
(ReviewID and ReviewBody already exist.)
2. Add tool definition and handler in operation/pull/review.go
const ReplyToReviewCommentToolName = "reply_to_review_comment"
var ReplyToReviewCommentTool = mcp.NewTool(
ReplyToReviewCommentToolName,
mcp.WithDescription("Reply to an inline review comment on a pull request"),
mcp.WithString("owner", mcp.Required(), mcp.Description(params.Owner)),
mcp.WithString("repo", mcp.Required(), mcp.Description(params.Repo)),
mcp.WithNumber("index", mcp.Required(), mcp.Description(params.PRIndex)),
mcp.WithNumber("review_id", mcp.Required(), mcp.Description(params.ReviewID)),
mcp.WithNumber("comment_id", mcp.Required(), mcp.Description(params.CommentID)),
mcp.WithString("body", mcp.Required(), mcp.Description(params.ReviewBody)),
)
3. Implement handler with raw HTTP call
Since the SDK lacks this method, the handler will need to make a direct HTTP POST. The implementation should:
- Construct the URL:
/repos/{owner}/{repo}/pulls/{index}/reviews/{review_id}/comments - Send JSON body:
{"body": "...", "in_reply_to": <comment_id>} - Parse the response as a
PullReviewComment - Use the SDK client's token and base URL for auth
The exact mechanism depends on what the SDK's Client type exposes. If it doesn't expose raw request methods, we may need a small helper in pkg/forgejo/ that wraps http.Client with the same auth config.
4. Register the tool
In RegisterReviewTools():
s.AddTool(ReplyToReviewCommentTool, ReplyToReviewCommentFn)
Part 3: Documentation
- Add the new tool to the review tools table in
README.md
Open Questions
- Exact API field name: Is it
reply_toorin_reply_to? Must verify against Forgejo API spec. - SDK raw HTTP access: Does the SDK client expose a way to make arbitrary authenticated requests, or do we need to build our own
http.Requestwith the token header? - Response shape: Does the POST return the created comment, or just a status? This determines the return value formatting.
Risk Assessment
- Low risk: The tool is additive — no existing behavior changes
- Medium risk: Raw HTTP call bypasses SDK versioning checks; if Forgejo API changes, this breaks silently. Mitigated by eventually moving to SDK method.