feat(requests): P2 — agent MCP tools for unified requests/inbox (RFC) #56
Reference in New Issue
Block a user
Delete Branch "feat/unified-requests-inbox-p2-mcp"
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?
Phase 2 — agent MCP tools for the unified requests/inbox subsystem
This is Phase 2 of the approved RFC. Phase 1 (workspace-server data model + REST endpoints) shipped in molecule-core PR #2525. This PR adds the agent-facing MCP tools in molecule-mcp-server that call those endpoints, mirroring the
approvals.tshouse pattern (every tool takesworkspace_id= the acting agent).The 7 tools (
src/tools/requests.ts) and the P1 endpoints they callcreate_requestPOST /workspaces/{id}/requestslist_inboxGET /workspaces/{id}/requests/inbox?status=check_requestsGET /workspaces/{id}/requests?status=(async pickup of responses to requests this agent RAISED)get_requestGET /workspaces/{id}/requests/{requestId}respond_requestPOST /workspaces/{id}/requests/{requestId}/respond(+POST .../messageswhen amessageis supplied)add_request_messagePOST /workspaces/{id}/requests/{requestId}/messagescancel_requestPOST /workspaces/{id}/requests/{requestId}/cancelrespond_requestsendsresponder_type=agent, responder_id=workspace_id;add_request_messagesendsauthor_type=agent, author_id=workspace_id.Contract correction vs the brief
The brief listed the action verbs as bare
/requests/{requestId}/...paths. In the real P1 router (workspace-server/internal/router/router.go) those bare paths are AdminAuth-gated (the canvas user). The agent-side verbs (get,respond,messages,cancel) are registered under the workspace-token-authwsAuthgroup/workspaces/:id/requests/.... Since all these tools act as an agent (workspace token), they correctly route through the/workspaces/{workspace_id}/...prefix — includingget_request, which therefore also takesworkspace_id(for auth scope) in addition torequest_id.Registration
registerRequestTools(srv)is wired into BOTH server modes (default surface + management), exactly likeregisterIssueTools. Handlers are re-exported fromsrc/index.ts.Untouched
Existing approval tools (
create_approval,decide_approval, …) are left fully intact against the old/approvalsendpoints. The formal shim/deprecation is a later phase (P5).Tests & count
src/__tests__/requests.test.ts(10 tests, fetch-mock): create task + approval, inbox vs check_requests, get, respond (+ thread-message variant), add_request_message, cancel, and an HTTP-error passthrough.toContainentries for all 7 tools.Verify
npm run build(tsc): clean.npx jest: 11 suites passed, 293 passed / 1 skipped.🤖 Generated with Claude Code
qa APPROVE (5-axis, 1st genuine lane — author devops-engineer≠me; CR-A security via cb15acea = 2nd). Correctness: P2 — new requests.ts (+271) implements the unified agent MCP request tools (create_request/list_inbox/check_requests/respond_request/get_request/add_request_message/cancel_request) routing to the workspace-server /requests endpoints. Robustness/Tests: 41 zod input-validation schemas (strong input hygiene — every tool param validated) + a 188-line test asserting the endpoint routing + payloads. Security/AUTHZ (privileged-surface axis): the tools FORWARD to server-side /requests endpoints — the server is the authz authority, same boundary as the #57 approval shims. respond_request sends responder_type='agent', responder_id=p.workspace_id (the agent's OWN claimed identity); a client-supplied workspace_id/recipient_id is validated SERVER-SIDE against the authenticated token (an agent can't respond for a workspace its token isn't authorized for). No tool-layer forge/bypass — the tool has no authority, it just POSTs validated input. 0 dangerous patterns (zero eval/exec/child_process). Content-sec: clean (0 IPs/creds/coords). Performance: n/a. Readability: clear zod schemas. NON-BLOCKING server-side note (same as #57, pre-existing): confirm /requests + /respond validate the client workspace_id/recipient_id against the token, not trust them blindly — workspace-server concern, not introduced here. Gate green, mergeable. Approving — privileged tool surface forwards to server-validated endpoints with strong zod input validation; integrity is server-side-bounded.
Security 5-axis — APPROVE (head
e688aa30ed). feat(requests): P2 — agent MCP tools for the unified requests/inbox (+484: src/tools/requests.ts + index + tests). 1st security lane; author devops-engineer != me./workspaces/{workspace_id}/requests/...(the canvas verbs are AdminAuth-gated, not reachable with a workspace token).workspace_idas the acting-workspace param andresponder_id=workspace_id. The authorization that the acting workspace == the request's recipient/requester is enforced SERVER-SIDE — which is exactly the gap I flagged on core#2525 (RC 10416: Respond/AddMessage/Cancel don't bind the authenticated :id to the participant → self-approval/cross-respond). mcp#56 is the CLIENT for those same endpoints, so these tools make that gap directly reachable by an agent (e.g. respond_request{action:approved} on its own request) IF the server isn't fixed.→ HARD merge-ordering flag: mcp#56 must NOT ship before core#2525's server-side participant-binding fix lands. They're a pair (MCP client + server handlers); #2525's RC naturally gates this. The client itself is correct — the enforcement belongs server-side — so APPROVE the client, but its safety is contingent on #2525.
workspace_id/request_idformat check in the tools as defense-in-depth (path-interpolated; stays on PLATFORM_URL host + server-validated, so low-risk, but belt-and-suspenders).Gate GREEN. APPROVE (client sound) — gated on core#2525's authz fix before merge. CR-B 2nd lane → 2-distinct.