Review: Hook + MCP fix: GroupMe send_message requires name-based resolution + user approval
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Lineage — present ("Standalone incident-fix — no plan phase")
- [x] Repo — present (claude-custom + groupme-mcp, both correctly identified)
- [x] User Story — present, well-formed
- [x] Context — present, thorough incident writeup with timeline
- [x] File Targets — present, updated across both scope expansions to cover all 5 tools + server.py + hook + settings.json
- [x] Acceptance Criteria — present, consolidated in v2 expansion (9 criteria)
- [x] Test Expectations — present, hook tests restored in v2 expansion (3 hook test shapes + MCP tests)
- [x] Constraints — present, deploy ordering added in v2
- [x] Checklist — present
- [x] Related — present
File Targets
- [x]
hooks/block-groupme-send.sh— NEW. Pattern fileblock-mcp-merge.shverified at~/claude-custom/hooks/block-mcp-merge.sh(19 lines, clean jq-based PreToolUse hook) - [x]
settings.json— verified. PreToolUse section exists (lines 50-163). New matcher entry needed formcp__groupme__send_message|mcp__groupme__add_member|mcp__groupme__remove_member - [x]
src/groupme_mcp/tools/messages.py— verified.send_messagetakesgroup_idparam at line 14 - [x]
src/groupme_mcp/tools/members.py— verified.add_member(line 13),remove_member(line 50),list_members(line 65) all takegroup_id - [x]
src/groupme_mcp/tools/groups.py— verified.get_groupat line 42 takesgroup_id - [x]
src/groupme_mcp/server.py— verified. Shared helper_resolve_group()would go here. Currently hasget_client(),_error_response(),_ok()helpers - [x] Files NOT to touch:
groupme-sdk— confirmed, SDK keeps rawgroup_idinterface
Repo Placement
OK. Issue filed on
forgejo_admin/claude-custom which is the primary repo for the hook change. The second repo (forgejo_admin/groupme-mcp) is correctly identified for the MCP interface changes. Two PRs called for in checklist, matching two repos. Deploy ordering documented in v2 expansion (groupme-mcp first, then claude-custom).Dependencies
- Board item #357 is in
todocolumn onboard-pal-e-agency. No blocking dependencies found on the board. - Cross-repo dependency: groupme-mcp must deploy before claude-custom hook — documented in v2 expansion Constraints.
- SDK dependency: groupme-mcp consumes groupme-sdk via Forgejo PyPI. SDK interface unchanged — no SDK release needed.
Acceptance Criteria
All 9 consolidated criteria are agent-verifiable or appropriately documented as process constraints.
Blast Radius
- SDK list_groups pagination — ISSUE. The SDK's
list_groups(page=1, per_page=10)returns max 10 groups per call. The_resolve_group()helper must either paginate or call with a largerper_page. If the user belongs to more than 10 groups, resolution could silently miss the target group and return a false "no match" error. The scope says "MCP must call GroupMe API live" but does not address pagination strategy. - Existing groupme-mcp test suites will break. All 3 test files call tools with
group_id=. The scope says "tests updated" but the implementing agent should know these are full parameter interface rewrites, not just additions. - Hook tests have no home.
claude-customhas notests/directory. The scope describes piping mock JSON through the hook but doesn't specify where test scripts live or how they run. - create_group is the 6th tool in groups.py. Takes
namenotgroup_id, so correctly excluded. Not documented but non-blocking.
Recommendation
Two items need resolution before this ticket is READY:
- Document pagination strategy for
_resolve_group(). Add to Constraints: the helper must calllist_groups(per_page=100)or paginate to ensure all groups are searched. Without this, name resolution is silently incomplete for users with more than 10 groups. One line in Constraints is sufficient. - Specify hook test location. Add to Constraints or File Targets: where do hook bash tests live?
claude-customcurrently has notests/directory. The implementing agent needs a decision — newtests/directory, inline PR validation, or documented manual test commands.
Neither issue is a blocker — both are one-line additions to Constraints. Once addressed, this ticket is READY.