Feat/cep 8 update#44
Conversation
Add support for session-level payment interaction negotiation through the new `payment_interaction` tag, enabling clients to choose between `transparent` (default) and `explicit_gating` semantics for payment-gated invocations.
…gating Restructures the payment flow documentation to clearly distinguish between the default transparent notification-based lifecycle and the explicit gating lifecycle. Adds JSON-RPC error codes (-32042 Payment Required, -32043 Payment Pending) for explicit gating mode, defines authorization identity using RFC 8785 canonicalization, and clarifies that payment processing is a transport concern that MCP handlers may remain unaware of. Removes redundant sections and updates notification field references for consistency.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@ContextVM-org Really like where this is headed, the transparent vs explicit_gating split is clean and it's exactly what's needed for agent-driven payment flows. Just a small point; Step 10 says the server "consumes one authorization atomically" before forwarding to the handler. But what happens if the server successfully consumes the auth, calls the MCP handler, and then the response never makes it back to the client (maybe something like a relay drop)? From the client's perspective, they paid, retried, and got nothing. The authorization is gone. Their only option is to pay again for the same invocation. |
|
@1amKhush, thanks for your feedback. Yes, it effectively works that way. I think network conditions and other possible quirks are out of scope for this PR. I can’t think of an easy way to handle those cases without introducing some out‑of‑band interaction between the client and server, something like a channel for feedback or other communications. Do you have anything else in mind? |
|
@ContextVM-org the transparent vs. explicit_gating split is clean and it's the right shape for agent-driven payments. Two things:
Nit: after the reorg, "Discovery methods" / "Stateless operation" ended up nested under Payment Interaction Negotiation instead of PMI Discovery, looks like they got stranded when "PMI Discovery" was trimmed. Otherwise LGTM. |
@ContextVM-org Yeah fair point, I don't think it needs a full out-of-band channel either. What I had in mind is simpler than that, imo the components are actually already in the spec. The server already computes a canonical invocation identity (client pubkey + JCS hash of method/params) for authorization matching. After it consumes the authorization and gets the result back from the handler, it could just cache If the client retries with the same canonical identity and the server sees no unused authorization but does have a cached result for that identity, it returns the cached result instead of sending back a fresh |
…fective mode disclosure Updates CEP-8 payment interaction negotiation to clarify that clients request rather than advertise preferred semantics. Adds detailed "Effective mode disclosure and lifecycle negotiation" section specifying that servers must confirm the effective mode on their first direct response when clients request explicit_gating. Introduces JSON-RPC error format for rejecting unsupported payment interaction modes. Adds "Correlation, Authorization Identity, and Idempotency" section distinguishing transparent lifecycle (correlated by Nostr event id) from explicit gating lifecycle (correlated by canonical invocation identity derived from MCP method and params). Clarifies authorization claim/consumption semantics and prevents double-consumption.
|
@harsh04044 Thanks, both points make sense. I updated CEP-8 to make the effective payment lifecycle explicit during the first direct message exchange. For I also clarified the client side: a client that requested or requires explicit gating should treat an effective transparent response, lack of effective-mode disclosure, or receipt of transparent On the “same request” / idempotency point, I rewrote the section as
I also fixed the section nesting nit: |
|
@1amKhush Thanks, that replay-cache approach is a useful implementation strategy, but I intentionally did not add it to CEP-8 as standardized behavior, even as a MAY. Once the spec mentions result replay caches, clients may start expecting that behavior, and doing it correctly would likely require additional protocol surface: discovery/negotiation, TTL semantics, cache keys, streaming behavior, large or sensitive results, side-effect semantics, and replay eligibility. The updated text instead keeps CEP-8’s boundary narrower: explicit gating authorizes execution, not guaranteed result replay. The server must atomically claim or consume a matching paid authorization before forwarding the invocation to the underlying MCP handler, so the same authorization cannot cause concurrent double execution. If the invocation is executed and the response is lost due to transport loss, relay behavior, client disconnect, or similar delivery failure, CEP-8 does not require the server to replay the completed result. A later matching invocation with no unused authorization may be treated as unpaid and may receive a fresh That keeps the payment lifecycle interoperable without imposing result retention requirements or partially specifying a replay mechanism. |
|
@ContextVM-org this all looks great. the effective-mode disclosure (plus must-not-silently-fall-back and the -32602 path) closes the negotiation gap cleanly and splitting correlation by lifecycle makes "the same request" unambiguous. nice touch documenting the executed-but-undelivered case explicitly as policy-deferred - that also settles the earlier relay-drop thread. nit's fixed too. LGTM! |
|
@ContextVM-org That's a fair call. You're right that even a MAY would set an expectation. rest the latest changes make the CEP behavior unambiguous, LGTM 👍 |
Summary
This PR updates CEP-8 to introduce a new
explicit_gatingpayment lifecycle convention and clarify how it should be used alongside the existing transparent payment flow.Before this change, CEP-8 was centered on the notification-based payment flow. This PR adds a second, opt-in lifecycle for cases where payment requirements need to be surfaced directly to the client as part of the invocation result, instead of being handled transparently by transport or middleware.
What this PR adds
explicit_gatingas a new CEP-8 payment interaction modetransparentas the default and backward-compatible lifecyclepayment_interactiontag-32042Payment Required-32043Payment PendingWhy
The existing CEP-8 text did not clearly separate two different payment interaction models:
This PR makes that distinction explicit and documents the intended behavior of the new lifecycle so implementers can support agent-visible payment gates without ambiguity.
Compatibility
This change is additive:
explicit_gatingis opt-in and only applies when negotiated