Inspiration

A balance says what is in the account, not what that money is already promised to. Alex, our sample person, has $2,540 in PayPal and wants a $1,899 camera. The balance says yes. His month says no: $1,750 rent on Dec 1, a laptop still on PayPal Pay in 4 ($324.75 on Nov 20, Dec 4 and Dec 18), and his bills. If he buys today, he is below zero from Fri, Nov 20.

Nothing answers the question people have when they pay: which day can I afford this? Worth is for people who shop with PayPal, get paid monthly or by invoice, and often have a payment plan already running.

What it does

Worth turns "can I afford it?" into a date.

  • Safe to spend today. Alex sees $872.26, not $2,540: what is left after every bill until payday and his $300 cushion.
  • Check a purchase. For the Halden X5 (an invented brand), the answer is Wait until Tue, Dec 15. Buying today goes below the cushion from Thu, Nov 19 and is overdrawn from Fri, Nov 20, lowest −$726.74 on Mon, Nov 30. Waiting, the lowest point is $458.78 on Thu, Dec 31, still above the cushion.
  • Compare with PayPal Pay in 4. 4 × $474.75 still goes below the cushion on Sun, Nov 29. Worth compares Pay in 4 and never recommends it. PayPal's own Pay Later message sits beside it.
  • The balance chart draws one line per option against the cushion, shades red below it, and marks the days money comes in and goes out.
  • Save it for the day it fits. On Tue, Dec 15 Worth checks again ("Fresh check: this fits today") and Buy with PayPal opens PayPal's sandbox checkout. Worth captures only after you confirm.
  • Ask Worth. The guide is a chat on every screen. "Am I spending too much on coffee?" gets "Coffee: $94.50 over 15 payments…". "When do I get paid next?" gets "Mon, Nov 30: Salary, $3,900." Ask about the chart and the guide presses the option pills and points at the day. Ask about "a $600 TV this weekend", answer "Sunday" when it asks which day, and the comparison opens on Sun, Nov 15.
  • Connect PayPal. Sign in on PayPal's own page once. Worth reads your activity, proposes recurring payments and Pay in 4 plans to confirm, then stays connected: on a later visit it re-reads in the background, only adding new activity, plans and payments made. A PayPal CSV export is the fallback.
  • An MCP server lets any AI agent ask Worth before it pays.
  • An example shop in the repo keeps PayPal's button; the shopper swipes left on it to check with Worth first.

How we built it

One TypeScript app: React 19 and Vite, Express 5, Zod 4, Node 24's built-in SQLite, hosted on Render.

  • Engine. shared/finance.ts is pure TypeScript in integer cents. It projects the balance day by day for 60 days and searches 35 days for the earliest day that keeps the cushion. Every screen and the MCP server read it; a test locks Alex's story to the cent.
  • PayPal (sandbox). PayPal's hosted MCP server for Connect PayPal (OAuth 2.1 with PKCE, only list_transactions allowed), Orders v2, the JS SDK v6 button and popup, Pay Later messaging, find-eligible-methods, and signature-verified webhooks.
  • AI. Claude Sonnet 5.5 (Anthropic API) reads the question, calls read-only engine tools, chooses which engine facts to show and may add one sentence that names figures only through placeholders. The server checks that sentence and swaps in a template if it has a free number, contradicts the result or gives advice. Claude does no arithmetic and cannot pay.
  • Tests. 1,795 unit and integration tests and 64 Playwright end-to-end tests, with CI on every pull request.

Challenges we ran into

  • Reading a shopper's own activity. Log in with PayPal grants identity scopes only, and Transaction Search reads only the app owner's account. PayPal's hosted MCP server, with the user's own login, worked. The MCP SDK client failed on its tool schemas, so we wrote plain JSON-RPC.
  • Least privilege on a broad token. The consent screen also lists invoicing and more. Worth calls one tool and refuses every other name before any request.
  • Staying connected safely. Refresh tokens rotate, so Worth keeps only the newest, encrypted and bound to the session, one refresh at a time.
  • Honest sandbox data. Sandbox accounts can't hold backdated history, and the order and capture don't say whether Pay in 4 was chosen. The Connect flow is real; Alex's months of bills are sample data.

Accomplishments that we're proud of

  • A real PayPal sign-in that reads a shopper's own activity, read-only, one tool allowed, and stays connected.
  • Every figure agrees to the cent across Home, chat, chart, checkout and MCP.
  • An assistant that answers everyday questions and moves the chart without writing a number.

What we learned

  • Let the model choose and explain; let code compute. That split made the AI testable.
  • Check PayPal facts in the sandbox and the live docs before planning around them.

What's next for Worth

  • A reminder on the day a saved purchase fits.
  • The swipe as a drop-in snippet for real shops.
  • Testing with people who use Pay in 4 every month.

Worth is an independent project, not a PayPal product and not endorsed by PayPal. Sandbox only.

Built With

  • anthropic-api
  • channel3
  • claude
  • claude-sonnet
  • express.js
  • github-actions
  • model-context-protocol
  • node.js
  • oauth2-pkce
  • paypal
  • paypal-js-sdk-v6
  • paypal-mcp-server
  • paypal-messages
  • paypal-orders-v2
  • paypal-pay-later
  • paypal-webhooks
  • playwright
  • radix-ui
  • react
  • render
  • sqlite
  • typescript
  • vite
  • vitest
  • zod
Share this project:

Updates

Submission history