feat(notifications): implement complete notification API #86
No reviewers
Labels
No labels
Compat/Breaking
Kind/Bug
Kind/Documentation
Kind/Enhancement
Kind/Feature
Kind/OpenSpec
Kind/Security
Kind/Testing
Priority/Critical
Priority/High
Priority/Low
Priority/Medium
RFC - Request For Comments
Reviewed/Confirmed
Reviewed/Duplicate
Reviewed/Invalid
Reviewed/Won't Fix
Status/Abandoned
Status/Blocked
Status/Need More Info
hermes-attempted
hermes-needs-clarification
hermes-ready
hermes-review
hermes-wip
human-required
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set
Reference
agentic-forges/forgejo-mcp!86
Loading…
Reference in a new issue
No description provided.
Delete branch "refs/pull/86/head"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #85
The Need
Currently, the
forgejo-mcpserver exposes thecheck_notificationstool, which is excellent for passively polling unread notifications. However, for fully autonomous agents that rely heavily on the MCP server to interact with Forgejo, merely reading notifications is insufficient. Without write access to the notification API, agents eventually get stuck or require manual GUI intervention to acknowledge notifications.The Solution
This PR expands the
User/Notificationstoolset inforgejo-mcpto expose the full Forgejo SDK notification suite, allowing 100% headless notification management.Implemented Tools
get_notification_thread(Fetches a single thread by ID)mark_notification_read(Marks a specific thread as read)mark_all_notifications_read(Global acknowledgment)list_repo_notifications(Filters notifications scoped to a specific repository)mark_repo_notifications_read(Marks all notifications in a specific repository as read)Implementation Details
log.LogMCPToolStart/LogMCPToolCompleteandforgejo.LogAPICallpatterns.mockNotificationServerinnotification_test.gohas been expanded to test all HTTP endpoints and correctly handle empty JSON responses forPUTandPATCH.README.mdhas been updated with the new tools, and aShowboatdemo (demos/notifications-management.md) is provided.Great work @byteflavour — the implementation is clean, well-structured, and consistent with the existing codebase patterns. A few findings below, two of which I would ask you to address before merging.
✅ What looks good
log.WithMCPContext,LogMCPToolStart,LogMCPToolComplete,LogMCPToolError)respbeforeresp.StatusCode— this fixes the pre-existing bug documented in the race test suiteowner/reporequired-param validation is explicit and returns a proper error, not just a silent zero-valueidvalidation inGetNotificationThreadFnandMarkNotificationReadFnreturns a clear error messagecheck_notifications) have test coverage🔴 Must fix (requesting changes)
1. Demo uses a hardcoded fake token
demos/notifications-management.mdbash blocks contain:Even though this is not a real credential, the project recently went through a P0 token-scrub on PR #83. Consistent practice — and the project standard — is to reference
$CODEBERG_TOKEN(or$FORGEJO_ACCESS_TOKEN) as a shell variable, never inline any string in that position.Suggested fix for both exec blocks:
2. Silent time-parse failures in
since/beforeIn
CheckNotificationsFnandListRepoNotificationsFn, invalid RFC3339 strings forsince/beforeare silently swallowed:The caller gets no feedback that their filter was ignored. The existing
ListIssueCommentsFn(inoperation/issue/issue.go) returns a proper error for the same case:Please apply the same pattern here.
🟡 Suggestions (non-blocking)
3. Race test
minimalArgsnot updatedtest/race/race_test.go→minimalArgs()has no cases for the 5 new tools. The tools that needid(get_notification_thread,mark_notification_read) will silently use the default args map (which lacksid) — meaning the race test exercises the error path rather than the happy path for those tools.Suggested addition:
4.
MarkNotificationReadFndiscards the returned threadThe SDK returns the updated
*Notificationobject. Returning it (asto.TextResult(thread)) would let the caller confirm what was marked read, consistent with how other mutating tools return the modified resource.Overall this is a solid, well-tested PR that completes the notification surface area. The two 🔴 items are small fixes — happy to approve once they're addressed.
this is nice @byteflavour good contribution and good work, thanks!!
Is a favour for me :) The tool worx great and actually it's funny to contribute here and work with the mcp. Also the workflow and response-time is great. Welcome to the a.i. century :)