feat: add issue & comment attachment tools (closes #106) #109

Merged
goern merged 0 commits from feature/issue-attachments into main 2026-05-02 10:06:55 +00:00
goern commented 2026-04-26 11:11:29 +00:00 (Migrated from codeberg.org)

Summary

Closes #106 — attachments uploaded via the Forgejo web UI were invisible to MCP clients because GET /issues/{index} does not embed them and forgejo-sdk/v3 has no issue/comment attachment methods.

  • Adds 12 new MCP tools (list/get/download/create/edit/delete × issue + comment), all callable via the existing --cli mode
  • Adds pkg/forgejo/rawhttp.go — a single raw-HTTP helper (DoJSON, DoJSONList, DoMultipart, DoRaw) that all attachment handlers go through; no net/http imports in the handler package
  • Download design (per the discussion on #106 with @heathen711):
    • Files < 1 MiB: returned inline as BlobResourceContents (MCP-protocol-native binary) + metadata JSON
    • Files ≥ 1 MiB: metadata + browser_download_url only; caller fetches with Authorization: token <TOKEN> — verified live against the Codeberg API (Open Question #2 from the spec, now resolved)
    • browser_download_url always included regardless of size

What was verified live

All API contract points from docs/plans/issue-attachments.md Part 1 were verified against a live Codeberg test issue before writing any Go code:

  • Multipart field name: attachment
  • PATCH body: {"name": "..."}
  • DELETE returns 204 ✓
  • Authorization: token works on browser_download_url ✓ (Open Question #2 resolved positively)
  • Full lifecycle (create → list → get → download → edit → delete → list-empty) run end-to-end against Codeberg

Test plan

  • go test ./... passes (includes unit tests for rawhttp helper and all 12 handlers with httptest mock servers)
  • go test -race ./pkg/forgejo/... ./operation/attachment/... passes
  • make build passes
  • Live: ./forgejo-mcp --cli list_issue_attachments --args '{"owner":"goern","repo":"forgejo-mcp","index":106}' returns attachment metadata on an issue with uploads
  • Live: download_issue_attachment on a small file returns BlobResourceContents whose base64 decodes to the original bytes
  • Live: download_issue_attachment on a file ≥ 1 MiB returns metadata + URL, no blob
## Summary Closes #106 — attachments uploaded via the Forgejo web UI were invisible to MCP clients because `GET /issues/{index}` does not embed them and `forgejo-sdk/v3` has no issue/comment attachment methods. - Adds **12 new MCP tools** (list/get/download/create/edit/delete × issue + comment), all callable via the existing `--cli` mode - Adds `pkg/forgejo/rawhttp.go` — a single raw-HTTP helper (`DoJSON`, `DoJSONList`, `DoMultipart`, `DoRaw`) that all attachment handlers go through; no `net/http` imports in the handler package - **Download design** (per the discussion on #106 with @heathen711): - Files < 1 MiB: returned inline as `BlobResourceContents` (MCP-protocol-native binary) + metadata JSON - Files ≥ 1 MiB: metadata + `browser_download_url` only; caller fetches with `Authorization: token <TOKEN>` — verified live against the Codeberg API (Open Question #2 from the spec, now resolved) - `browser_download_url` always included regardless of size ## What was verified live All API contract points from `docs/plans/issue-attachments.md` Part 1 were verified against a live Codeberg test issue before writing any Go code: - Multipart field name: `attachment` ✓ - `PATCH` body: `{"name": "..."}` ✓ - `DELETE` returns 204 ✓ - `Authorization: token` works on `browser_download_url` ✓ (Open Question #2 resolved positively) - Full lifecycle (create → list → get → download → edit → delete → list-empty) run end-to-end against Codeberg ## Test plan - [ ] `go test ./...` passes (includes unit tests for rawhttp helper and all 12 handlers with httptest mock servers) - [ ] `go test -race ./pkg/forgejo/... ./operation/attachment/...` passes - [ ] `make build` passes - [ ] Live: `./forgejo-mcp --cli list_issue_attachments --args '{"owner":"goern","repo":"forgejo-mcp","index":106}'` returns attachment metadata on an issue with uploads - [ ] Live: `download_issue_attachment` on a small file returns `BlobResourceContents` whose base64 decodes to the original bytes - [ ] Live: `download_issue_attachment` on a file ≥ 1 MiB returns metadata + URL, no blob
Sign in to join this conversation.
No reviewers
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!109
No description provided.