Repository navigation
Description
Slice 1 of #789 (EPIC: MCP server support). Startable now. It is independent of #788, because this is pipeline work that does not care how a caller authenticated.
This is the largest risk in the entire epic. It is not the tool code.
Why it blocks everything
IdempotencyMiddleware triggers on all of POST/PUT/PATCH/DELETE, /mcp is not exempt, and an authenticated MCP call resolves a tenant. With no Idempotency-Key header, the middleware returns 400. MCP Streamable HTTP sends everything as POST, initialize and tools/list included, and no MCP client knows this repo's header contract.
MCP does not function at all until /mcp is exempted. Keys do not merely collide. The first handshake gets a hard 400. This blocks even a read-only demo, which #770's original estimate did not account for.
Scope
- Exempt
/mcpby endpoint metadata (HandlesOwnIdempotencyAttribute), not a path literal, with a guard asserting the set of bearers is exactly{"/mcp"}. - Extract Make API write idempotency atomic across replicas #307's claim/execute/publish protocol into
IIdempotentUnit, keyed by an explicitIdempotencyScope(AccountId, OperationKey, CallerKey, RequestFingerprint)rather than the URL. - The middleware becomes the first adapter with
OperationKey = Sha256($"{Method}:{Path}"), byte-identical to today, including the/api/v1/meuser-scoping special case.
The rule that makes this safe
AtomicIdempotencyProtocolTests and the other #307 suites must pass UNEDITED. An edit to one of them in this PR means stop and review. It is not a fix. That is the entire mitigation for the risk this slice carries.
Run a local adversarial pass on the diff before the first push, per AGENTS.md. The #269 SingleAttemptExecution interaction, the #345 /error re-entry skip, and the steal-loss rollback path are each easy to preserve almost correctly.
Design
docs/plans/770-mcp-server/. Read 02-guards.md rows 17-24 before writing tests.
Note: if #788's OAuth work lands first and the write tool ends up routed through the existing HTTP endpoint over loopback, this extraction may be avoidable entirely. docs/plans/788-mcp-oauth/01-decision.md records that alternative. Price it before extracting.
Activity
mforce commentedon Oct 6, 2026
Closed as superseded in the 2026-10-06 re-evaluation. Nothing here is dropped; the work is split between two slices:
/mcpexemption moves to MCP slice 3: map /mcp, wire RBAC and tools/list filtering #806. It is a few lines and does nothing until/mcpis mapped.Verified on
mainat8cb14e67: the middleware still returns 400 for an/mcpPOST without a key, and no exemption or extracted protocol exists.