Skip to main content

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:

LayerPath
SDK wrappercloud-run/price-selector-agent/lib/cursor-agent.js
Prompt templatescloud-run/price-selector-agent/lib/prompt-templates.js
Express routescloud-run/price-selector-agent/index.js (/agent/*)
Admin consoleadmin/js/cursor-agent-console.js
Mount pointadmin/js/views/pay-monthly-settings.js (_mountCursorAgentConsole)
Stylingadmin/css/admin.css (.cac-*)

How it works

  1. The admin clicks a template (e.g. Onboard new merchant) or types a free-form prompt and hits Send to Cursor →.
  2. The browser POSTs to /agent/spawn on the price-selector-agent Cloud Run service, passing either a templateId + context or a raw prompt.
  3. 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.
  4. The browser opens an EventSource to /agent/:agentId/runs/:runId/stream and renders assistant text, tool calls, thinking, and status frames as they arrive.
  5. 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:

  1. Writing a build(context) function that returns { title, prompt, repos?, defaultBranchPrefix? }.
  2. Registering it in the TEMPLATES object with requiredContext listing the keys the front-end should provide.

Current templates:

IDTarget repoPurpose
selectorRepairEscalationfinmatch-sharedEscalate runtime repair failures to a code-level fix in the agent's heuristics.
newMerchantOnboardingfinmatch-sharedGenerate merchants.json profile + ecommerce_overrides skeleton + lender wiring.
runtimeSdkTweakfinmatch-pPatch detection / injection bugs in the runtime SDK.
freeFormWithContextfinmatch-sharedFree-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.product to pick one lender for the “or £X/month” message via getPayMonthlyLender(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) in detectPrices() / 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).

  1. Create a secret in GCP Secret Manager (e.g. cursor-api-key) and put the long key in as the secret value.
  2. Add a GitHub Actions secret named CURSOR_API_KEY_SECRET_REF whose value is the reference, formatted as <secret-name>:latest (e.g. cursor-api-key:latest).
  3. 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

  1. The active-agent card shows Review PR ↗ when the run finishes.
  2. Clicking opens the PR on GitHub. Review as normal.
  3. 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.