Cursor Cloud Agent (Pay Monthly)
The Pay Monthly settings page hosts a live Cursor Cloud Agent console that opens GitHub pull requests on your behalf. It's the bridge between the runtime price-detection agent (which only patches a merchant's live config) and the repository-level changes that need code review — repair-heuristic upgrades, new merchant onboarding, runtime SDK fixes, etc.
Where it lives
In the admin: Merchants → [merchant] → Pay Monthly Message Settings → Cursor Cloud Agent (last accordion on the page).
In the codebase:
| Layer | Path |
|---|---|
| SDK wrapper | cloud-run/price-selector-agent/lib/cursor-agent.js |
| Prompt templates | cloud-run/price-selector-agent/lib/prompt-templates.js |
| Express routes | cloud-run/price-selector-agent/index.js (/agent/*) |
| Admin console | admin/js/cursor-agent-console.js |
| Mount point | admin/js/views/pay-monthly-settings.js (_mountCursorAgentConsole) |
| Styling | admin/css/admin.css (.cac-*) |
How it works
- The admin clicks a template (e.g. Onboard new merchant) or types a free-form prompt and hits Send to Cursor →.
- The browser POSTs to
/agent/spawnon the price-selector-agent Cloud Run service, passing either atemplateId + contextor a rawprompt. - The service composes the final prompt (templates inject the active merchant
context + a standard preamble that forces a PR) and calls
Agent.create({ cloud: { repos, autoCreatePR: true }, ... })from@cursor/sdk. - The browser opens an
EventSourceto/agent/:agentId/runs/:runId/streamand renders assistant text, tool calls, thinking, and status frames as they arrive. - When the run finishes, the response includes
prUrl— a Review PR ↗ button surfaces it in the active-agent header. The admin reviews and merges on GitHub.
Templates
Defined in lib/prompt-templates.js. Add a new one by:
- Writing a
build(context)function that returns{ title, prompt, repos?, defaultBranchPrefix? }. - Registering it in the
TEMPLATESobject withrequiredContextlisting the keys the front-end should provide.
Current templates:
| ID | Target repo | Purpose |
|---|---|---|
selectorRepairEscalation | finmatch-shared | Escalate runtime repair failures to a code-level fix in the agent's heuristics. |
newMerchantOnboarding | finmatch-shared | Generate merchants.json profile + ecommerce_overrides skeleton + lender wiring. |
runtimeSdkTweak | finmatch-p | Patch detection / injection bugs in the runtime SDK. |
freeFormWithContext | finmatch-shared | Free-form prompt with merchant context auto-prepended. |
Troubleshooting: Pay Monthly product-page selectors vs calculator lenders
Admins sometimes ask whether product page price selectors are still working after changing Calculator lender settings (for example forgetting to enable Humm on the calculator). These are separate configuration paths:
-
Pay Monthly message (product page): Uses
financeFeaturesVisibility.payMonthlyMessage.productto pick one lender for the “or £X/month” message viagetPayMonthlyLender(pageType)in the runtime SDK. That does not read calculator toggles. -
Product page prices: Resolved from
merchantConfig.ecommerce_overrides.selectors(e.g.productSalePriceSelector,productNormalPriceSelector,productPriceContainer) indetectPrices()/getPriceSelectorsForPageType()— unrelated to which lenders are enabled on the calculator. -
Embedded / dynamic calculators: Use
financeFeaturesVisibility.calculator(embedded lenders list, dynamic per-page config, etc.), which is independent of Pay Monthly selectors.
So toggling calculator lenders affects who appears in calculators / related UI, not whether DOM selectors for prices resolve. If Pay Monthly messaging disappeared, check Pay Monthly lender wiring and eligibility (assigned products, limits) first; if prices are wrong or missing, check the Pay Monthly → Prices / selector configuration and console logs from price detection.
Configuring the API key
The Cloud Run service needs a Cursor API key (the long key_… string from
cursor.com/dashboard/integrations)
exposed as the CURSOR_API_KEY env var. Pick one of:
Option A — GitHub Actions secret (simplest). Add a single GitHub Actions
secret named CURSOR_API_KEY whose value is the long key itself. The deploy
workflow passes it through to Cloud Run as a plain env var.
Option B — GCP Secret Manager (the long key never touches GitHub).
- Create a secret in GCP Secret Manager (e.g.
cursor-api-key) and put the long key in as the secret value. - Add a GitHub Actions secret named
CURSOR_API_KEY_SECRET_REFwhose value is the reference, formatted as<secret-name>:latest(e.g.cursor-api-key:latest). - The deploy workflow detects the ref and passes it through with
gcloud run deploy --update-secrets CURSOR_API_KEY=<ref>.
If both are present, Option A wins (simpler beats more-secure when both
exist). Until at least one is set, /agent/* routes return
500 CURSOR_API_KEY is not configured. The runtime price-detection routes
(/run, /snapshot, etc.) keep working as before.
Default repository / branch
The wrapper defaults to opening PRs against
finmatch-shared (origin/finmatch-shared). Override per-template via the
repos field, or globally via these env vars:
CURSOR_DEFAULT_REPO_URL=https://github.com/your-org/finmatch-shared
CURSOR_DEFAULT_REPO_REF=finmatch-shared
CURSOR_RUNTIME_REPO_URL=https://github.com/your-org/finmatch-p
CURSOR_RUNTIME_REPO_REF=finmatch-p
CURSOR_DEFAULT_MODEL_ID=composer-2
The deploy workflow already wires CURSOR_DEFAULT_* to the Actions
github.repository_owner, so these are correct out of the box.
Reviewing a PR
- The active-agent card shows Review PR ↗ when the run finishes.
- Clicking opens the PR on GitHub. Review as normal.
- The agent itself is preserved in your team's Cursor workspace — click Open in Cursor ↗ to inspect the conversation transcript.
Sending a follow-up
Inside the active-agent card, the Send a follow-up to this agent… input
posts to /agent/:agentId/messages, resuming the same agent's conversation.
Use this for "also update the changelog" / "fix the lint error CI flagged"
style asks — the agent has full context of what it just did.
Re-attaching from history
The bottom of the console lists the 10 most recent cloud agents for your team. Click Re-attach on any row to load that agent's latest run into the active-agent card and resume the live stream (if still running) or view the terminal state.