DEV Community

Brage Mellesdal
Brage Mellesdal

Posted on

Payday Radar: predicting late invoices and "can I afford it?" with TabPFN-3.5

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

Payday Radar is a cash-flow radar for freelancers and tiny agencies. Give it your invoices and expenses as CSV and it:

  • predicts which open invoices will be paid late, and by how many days
  • forecasts the next 90 days of cash with P10 / P50 / P90 scenarios
  • flags unusual expenses and duplicate invoices
  • drafts the payment reminders (English or Norwegian)
  • answers "can I afford X?" from the pessimistic scenario instead of the average

Who would pay, and why: a freelancer with a few slow-paying clients. Their problem isn't bookkeeping, it's not seeing the cash crunch coming, and not wanting to upload client invoices to a random SaaS.

The same question gets two different answers depending on whether you look at the average or a bad month (synthetic data, TabPFN-3.5):

"Can I afford a 20,000 laptop in November?"
Mean forecast  ->  yes    (157,390 left after the purchase)
P10 scenario   ->  tight  (32,556 left, below the one-month cushion of 108,213)
Enter fullscreen mode Exit fullscreen mode

TabPFN-3.5 forecast with P10/P50/P90 and the P10-based answer

Honest status: it has only run on synthetic data, and no real user has tried it. The TabPFN-3.5 license is non-commercial, so I can't sell it on that model as it stands (see "Why Does Open Innovation Matter?"). Treat it as a prototype with a business model, not a finished product.

Demo

There is no hosted app, because the point is that your data stays on your machine. The whole demo runs offline in one command, with no account, token or GPU:

pip install -e ".[dev]"
python -m paydayradar --backend sklearn demo
Enter fullscreen mode Exit fullscreen mode

Here it is on the TabPFN-3.5 backend, called from a separate MCP client process. The client launches the server over stdio, calls the tools, and checks every output for leaked client names:

MCP client calling the TabPFN-backed tools

Same run, last tools and the leak check passing

Code

Payday Radar

ci

See late payments coming before they hurt. Payday Radar reads a freelancer's invoices and expenses (CSV), predicts which open invoices will be paid late, forecasts the next 90 days of cash with P10/P50/P90 scenarios, flags odd expenses and duplicate invoices, drafts the reminder emails and answers "can I afford X?". All prediction is done by TabPFN-3.5, and every capability is also exposed to any AI agent through an MCP server.

Built for the Hacktoberfest Open-Source AI Challenge (Week 2: Side Hustle), competing for the Best Use of TabPFN and Best Use of GitHub Copilot.

Demo video

Payday Radar demo video

All data in the video is synthetic. Note that TabPFN-3.5 is licensed for non-commercial use only.

TabPFN-3.5 forecast with P10/P50/P90 scenarios and a P10-based answer

What it does

Question How
Which open invoices will be paid late, and by how many days? TabPFN classifier + regressor on leak-free, numeric-only client-history features
What will my cash look like in
…

36 offline tests, CI on Python 3.10 and 3.12, MIT-licensed code, and a README with a "what is verified and what is not" table.

How I Built It

TabPFN-3.5 does all the prediction. It's a tabular foundation model: no tuning loop, you pass the history table and get predictions.

  1. Classification: will this invoice be late? Features are numeric client history (leak-free: only invoices paid before the reference date), amount, terms and month.
  2. Regression: how many days late, plus next month's income and expenses.
  3. Quantiles: the regressor predicts a distribution. I request quantiles (output_type="quantiles"), sample monthly income and expenses from them, and build balance paths. Percentiles of those paths give P10/P50/P90.
  4. Anomalies: predict the expected expense amount and flag large residuals. Duplicate invoices are caught by a plain rule.

A prediction agent with an MCP server. Five tools (risky_invoices, cashflow_forecast, can_afford, draft_reminder, anomalies) are one set of methods exposed two ways: to a local LLM through Ollama tool calling, and to any MCP client through a server (--redact swaps client and vendor names for aliases).

Three swappable backends behind one interface: hosted TabPFN-3.5, local TabPFN weights, and a scikit-learn fallback. The fallback is why tests and CI run offline with no token.

Does TabPFN actually help? Time-ordered split on synthetic invoices, 3 seeds:

Backend ROC-AUC ↑ Log-loss ↓ Brier ↓ Days-late MAE ↓
scikit-learn random forest 0.820 0.471 0.151 3.511
TabPFN-3.5 (hosted API) 0.861 0.416 0.130 3.277
Naive baselines 0.500 0.608 0.209 6.114

Benchmark table

What I'd claim: the probabilities are clearly better (log-loss and Brier), which matters because invoices are ranked by amount times P(late). What I wouldn't claim: the days-late gain is within one standard deviation, there are about 60 test invoices per seed, the data is synthetic, and the forest is untuned. A review also caught a flaw in my first benchmark (recent slow payers missing, and training labels not yet known at the cutoff); fixing it lowered the random forest's ROC-AUC by about 0.03.

Built with GitHub Copilot (Free plan). The coding agent and automatic PR review need a paid plan, so I didn't use them. I used Copilot CLI to draft four features on branches (privacy audit test, benchmark, MCP server, prediction intervals) and GitHub Actions for CI, a weekly report and Copilot's environment setup. A branch ruleset forced every change through a PR. The first scaffold and my reviews were done with Claude.

What worked: single-paragraph prompts pointing at an issue file and .github/copilot-instructions.md. For the MCP server, Copilot read the installed SDK source and used the current 2.x API instead of the renamed one I'd have written from memory.

What I had to catch:

  • Privacy test: Copilot's version checked model inputs after the pipeline finished. TabPFN accepts text columns, so a leaked client name wouldn't crash and wouldn't be caught. I moved the check to the moment frames reach the model.
  • Benchmark: the leakage above.
  • Environment: it couldn't run its own tests (pytest wasn't on its shell's PATH), so I ran them myself.

Two bugs that bit me: MCP clients start your server with a tiny environment, so TABPFN_TOKEN never arrived and every tool failed with a generic "Error executing tool". And every forecast month is a model call, so without clamping one months=60 request meant 120 hosted calls.

Why Does Open Innovation Matter?

What's open: the code (MIT), the open-source tabpfn package, downloadable TabPFN-3.5 weights (gated behind a license), and open protocols (MCP, Ollama's API).

What openness made possible:

  • Privacy by construction. The prediction model only ever sees numbers. A guard raises an error if a text column reaches it, and a test audits every frame at fit/predict time. That matters because TabPFN accepts text columns, so a leak wouldn't crash by itself. With local weights nothing leaves the machine after the one-time download. With the hosted API, the numeric tables go to Prior Labs' servers.
  • Swappable models. One interface, three backends. That is how I benchmarked them with identical code, and why CI needs no token.
  • An agent I can re-wire. The tools are plain methods behind MCP, so any client can drive them and I can change what the agent does without touching the models.

Where I won't overclaim:

  • I did not compare against a closed alternative head to head, so I can't say open "won".
  • Everything I ran went through the hosted TabPFN API. The local-weights backend and the Ollama invoice extraction are implemented (the parsers are unit-tested) but not yet run against a real model. The README says so.
  • The license limits the business case. The TabPFN-3.5 weights and API key are non-commercial. As summarised on the model card, that excludes commercial or production use, including client deliverables and internal commercial decisions. So I can't sell this on TabPFN-3.5 or run it on real business finances. The paths forward are a commercial license from Prior Labs, or a backend on permissively licensed weights (earlier TabPFN-2 weights, which I haven't tested). The scikit-learn backend works today but is a weaker model.

My Agent Session

I didn't save a DevRelay session. The agent work is documented in the repo instead: docs/BUILD_LOG.md lists who built what, what review found wrong in each Copilot draft, and has a screenshot per step. Here is Copilot CLI building the benchmark and the prediction intervals:

Copilot CLI on the benchmark task

Copilot CLI implementing prediction intervals

My First User

No real user yet. The TabPFN-3.5 license bars using it on someone's real finances, so a fair first test needs the scikit-learn backend on a freelancer's own CSV, which I haven't arranged. That is the next step.

Prize Categories

  • Best Use of TabPFN: TabPFN-3.5 for classification, regression, forecasting, quantile risk scenarios and anomaly detection, inside a prediction agent with an MCP server.

  • Best Use of GitHub Copilot: Copilot CLI drafted four features, and GitHub Actions automates CI, the weekly report and Copilot's environment setup. The coding agent and automatic Copilot PR review were not used (Free plan).

Top comments (0)