Subscription linking overview
Subscribers should never hit the paywall. We support two transports for
proving "this MCP install belongs to one of our paying subscribers" — pick
whichever fits your stack.
Both feed the same SubscriptionLink table and end up stamping
tier="subscriber" on the install's OAuth tokens. The meter check in
get_article early-returns for subscriber-tier requests — PAYWALL articles
serve normally, no MeterEvent written.
Where readers see it
Two entry points in the UI:
- At install time — the consent screen at
/authorizeshows an
"Already a subscriber? Connect my subscription" button above the
free-tier email form. - At paywall trip — the
paywalledpayload includes asubscriberLinkUrl
so the agent renders an "Already a subscriber? Link your account →"
secondary CTA inline in chat.
Both buttons hit /api/oauth/start-subscription-link, which mints an
installToken, persists a SubscriptionLink row, and 302s the reader to
your subscriptionConnectUrl.
The two transports
- Flip-Pay cookie — zero publisher dev work, requires the
vanity host CNAME. - HMAC webhook — for publishers not on Flip-Pay; ~1
afternoon of dev time on your side.
Cancellation
Cancellation signals (Flip-Pay JWT flips to non-subscriber, webhook
status="cancelled") downgrade existing tokens in place. No need to wait
for token expiry.
Adding another vendor
Want to support Memberful, Pico, Piano, WordPress paid memberships, or
something else? The pattern is: add a nullable Publisher.<vendor>Audience
field, a verifier under lib/oauth/, and a branch in
/api/oauth/connect-mcp that picks the right verifier based on which
field is set. The SubscriptionLink flow is vendor-agnostic — ping us
and we'll add it.