Repository navigation
Add a no-login reactivation page for blocked calls, A/B vs pricing - #1574
Merged
Merged
Conversation
When an ended trial blocks a tool call, half of the workspaces now get a link to /reactivate/<token> instead of the pricing page. The token (AES-GCM, 30 days, key from ENCRYPTION_KEY) names the workspace; the page shows its plans and opens Stripe Checkout for it without a sign-in, and the paid licence binds through the unclaimed-licence sweep. The arm is recorded on trial_expired_call_blocked and the checkout source is mcp_reactivate.
…sign-in The page picks its language among the website's seven (amcp_locale cookie, then the browser), names the AI client whose call was blocked (else the first one the workspace connected) and shows only that client's directory, adds the live workspace and monthly tool-call numbers with the sign-up page's badges, and offers Sign in / Open your workspace in the header.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When an ended Cloud trial blocks a tool call, the AI client shows a link to reactivate the workspace. Today that link is the public pricing page: an anonymous checkout with an extra plan-choice step. This PR adds a no-login reactivation page and A/B-tests it against the pricing page, 50/50 per workspace.
https://cloud.anythingmcp.com/reactivate/<token>.ENCRYPTION_KEY(HKDF, infoanythingmcp/reactivate-link/v1). It holds only the workspace id, the calling user id and an expiry, encrypted, and no address. Holding it lets you see the workspace name and its plans, and pay for that workspace. Nothing else.?paid=1) it polls until the workspace is active.copy.ts. It follows theamcp_localecookie, then the browser's languages, else English.metadata.clientontrial_expired_call_blocked), else the first client the workspace connected, else "your AI". Only that client's directory listing is shown; both are shown when the client is unknown./api/public/stats, plus the sign-up page's badges (EU hosting, GDPR · DPA, AES-256-GCM, open source) and a "Works with" row./login?redirect=/), or "Open your workspace" when a session exists.organizationId, and the unclaimed-licence sweep binds it in about 2–3 minutes. The sweep runs every minute and binds licences that are at least 2 minutes old.Changes
Backend:
license/reactivation-token.ts: create and read the token.license/reactivation.controller.ts:GET /api/license/reactivate/:tokenreturns state, workspace name, trial end, AI client and usage.POST /api/license/reactivate/:token/checkouttakes{plan, billingPeriod}and returns{url}.mcp_reactivate.license-checkout.ts:reactivationLinkVariant(sha256reactivate-link-v1:<org>, 50/50) andtrialReactivationLink.mcp_reactivateadded toCHECKOUT_SOURCES.dynamic-mcp-tools.ts: uses the arm's link.trial_expired_call_blockedrecordsmetadata.variant.reactivate_page_viewed, at most once per workspace per UTC day.EmailVerifiedGuardallowlist:/api/license/reactivate/.license-wall.service.ts:connectedClient()extracted.Frontend:
app/reactivate/[token]page and layout (no-referrer, noindex).proxy.ts,auth-context,license-wallandonboarding-redirect.app/reactivate/[token]/copy.ts. The dashboard has three UI languages; this page is reached from a chat, so it follows the website's seven. It has its own plan chooser, because the dashboard'sPlanPickeris English only.reactivationAPI client;mcp_reactivateadded tocheckout-source.ts.How to read the test
For each arm, divide the purchases by the number of blocked workspaces. Count the blocked workspaces from
trial_expired_call_blockedgrouped bymetadata.variant. Count the purchases from Stripe checkouts withcheckout_sourcemcp_reactivate(page arm) ormcp_blocked(pricing arm).Deployment modes
Type
Testing
Commands (worktree from origin/main after
npm ciandprisma generate):packages/backend:npx jest --maxWorkers=4 src/license src/mcp-server src/auth/email-verified src/audit/product-event: 63 suites passed, 2 skipped; 1,056 tests passed, 5 skipped.npx tsc --noEmit -p tsconfig.json: clean.npx eslinton the changed files (no--fix): clean.packages/frontend:npx tsc --noEmit -p tsconfig.json: clean.npx eslinton the new page, copy, layout, proxy and spec: clean.npx playwright test tests/e2e/reactivate-link.spec.ts tests/e2e/card-trial.spec.ts tests/e2e/auth.spec.ts tests/e2e/i18n.spec.ts: 112 passed.reactivate-link.spec.tscovers the signed-out view and checkout, the header sign-in, Claude / ChatGPT / unknown-client wording and directories, the six non-English browser languages, Team preselection, an expired link, and polling after payment.How the paid licence reaches the workspace, checked in the site code (anythingmcp-website main):
checkout/startcopies the intent'sorganizationIdinto the Stripe session metadata.organizationId./api/license/unclaimedlists active Cloud licences without aninstanceIdonce they are 2 minutes old.organizationIdto that workspace.No site change is needed. The pricing-page and wall checkouts are unchanged. Still to confirm on the first real purchase from the page arm: the binder's log line.
Checklist