-
-
The landing page. A text says it's Tom, PayPal holds Gran's £250, and Tom's Not me on his own phone releases it.
-
Was it you? Gran's phone shows £250 on hold at PayPal, and Tom's phone asks if he sent the text. A real sandbox hold.
-
A held £1.99 parcel payment. KERNEL opened the link as a desktop and as a UK phone at once, and only the phone got a card form.
-
Channel3 prices hold a £4.99 skillet that real shops sell from £15.99 (left), and a live Channel3 price watch (right).
-
Watchtower on AG Studio. "What did Leo spend on games?" built this chart in 17.4 s, with 14 tool calls and 0 money actions.
-
Agent lab: a scripted test agent obeys a hidden line and calls create_refund. Spotter freezes it and PayPal voids the hold.
Gran gets a text from a new number. It says it's Tom and asks for £250. She forwards it to Spotter. PayPal holds the £250, and instead of asking Gran "are you sure?", Spotter asks the real Tom on his own phone if he sent it. He taps Not me, the hold gets cancelled at PayPal, and nothing was paid. Nobody even needed the PIN.
A scammer can talk Gran past a warning. They can't answer on Tom's phone. That's basically the whole idea.
The name comes from the gym. A spotter doesn't lift the bar for you, they just stand there so it doesn't land on you.
Try it here: https://spotter-pay.vercel.app (no sign up, PayPal sandbox, fake money, the PIN is 2468)
What it does
Spotter sits between whoever is paying and PayPal. That can be Gran, Leo on a game chat, or an AI shopping agent.
Gran forwards a text or an email that asks for money. Leo right clicks a Discord message and picks Check with Spotter. An AI agent calls Spotter's tools, or PayPal's own Agent Toolkit tools pointed at Spotter.
Rules go first: an allowance, an "ask me first" amount, and payment methods that are never allowed. Then a Claude check that has to quote the exact words that worried it. Then real shop prices from Channel3.
Anything that needs a person becomes a PayPal authorisation. The money is reserved and nothing has left yet. Sam, the spotter, gets one card on Telegram, email or the dashboard: who, how much, one sentence on why, and Deny sits before Approve. Deny cancels the hold. Approve needs the PIN.
If the message claims to be from someone in the family, that person gets asked. Not me cancels the hold straight away. "Yes, it's me" doesn't pay anything by itself.
Friends and Family payments, gift cards, crypto or bank transfers that a stranger is pushing never go out. Spotter tells you how to pay with buyer protection instead, because a warning is just a popup a scammer talks you past.
AI shopping agents get the same rule. An agent can search, compare and ask to pay, but it can't approve its own payment. A hidden line on a shop page, a price no real shop charges, or the agent reaching for a refund tool, and it's stopped or frozen before any money moves.
How I built it
Next.js 16 and strict TypeScript on Vercel, Postgres on Neon (PGlite on my laptop). 1,992 tests, all passing, and 344 commits since the first one on 9 October.
PayPal is the only thing that holds or moves money.
Every checked payment is an Orders v2 AUTHORIZE order. Approve with the PIN captures it. Deny, Not me, a tripwire or a leaked agent key voids it. "Ask again tomorrow" reauthorizes it once, between day 4 and day 29. Every money call has its own PayPal-Request-Id, so a retry can't pay twice.
9 webhook events, each checked with PayPal's verify API on the raw bytes. A webhook never moves money. It only confirms what Spotter already did, and anything that doesn't match goes on the payment's timeline. There's Log in with PayPal for the spotter's account, and a daily job that settles anything stuck halfway through a capture or a void by asking PayPal what really happened.
Then the PayPal Agent Toolkit (@paypal/agent-toolkit 1.11.0). I put it behind a second MCP server that uses the toolkit's own tool names and schemas, so an agent built for the toolkit points at Spotter and doesn't have to change. One table maps all 47 tools for each kind of agent. A shopping agent gets offered 41 of them: 3 guarded, 3 passed through and 35 bait.
The AI bits:
The scam check runs on claude-opus-5-5 with a 20 second timeout and one retry. It treats every message as untrusted text and has to quote it, and code throws away any warning it can't find word for word in the message. Hidden text (invisible Unicode tags, fake delimiters, fake email wrappers) gets decoded and flagged. If Claude can't answer, a second key takes over, then gpt-5.4-mini with the same prompt and the same quote check, and anything the backup checked still waits for a person.
A case agent (Claude, 7 read only tools, 5 turns, 45 second cap) looks into every held payment. Every finding has to name the tool call it came from, or code drops it.
Watchtower is the family's board, built on AG Studio 3.0. My own agent, "spotter", has read only tools, places an empty tile and hands the chart to AG Studio's built in Widget and Data agents with delegate_to. Every agent runs on Claude through my own adapter, so the key stays on the server.
My adapter also switches on the approval surface AG Studio ships but doesn't pause on by itself yet. If any agent, mine or one of AG's built in ones, tries to change the board using words from a flagged payment, the call waits: Held for you, with Allow and Refuse on the tool card. The receipt under the board counts every AI action as authorised, allowed or refused.
Is the check any good? I ran it on 80 texts from a public dataset (Mishra and Soni, 2022, CC BY 4.0), 40 scams and 40 normal ones. 93% precision, 93% recall, so 37 of 40 scams caught, 3 normal texts flagged and 0 failed checks. The script, the whole dataset and every miss are in the repo (docs/eval.md).
KERNEL and Channel3 put real evidence on the card, and AG Grid keeps the history.
KERNEL opens every held link in a throwaway cloud browser, twice at the same moment: once as a desktop scanner and once as a phone on a UK mobile network. On the £1.99 parcel text the desktop got "Your parcel is on its way" and the phone got a card form. The same visit compares what a person can see with everything an agent reads, so a hidden instruction gets quoted on the card. The code Spotter runs on the page only reads, and the case file shows 0 clicks and 0 keys typed, straight from KERNEL's telemetry.
Channel3 prices are evidence that code adds to the flags before the decision runs. The shopping agent finds a cast iron skillet for £4.99. Without Channel3 that's a bargain under the allowance. With it, real UK shops list the same pan from £15.99 to £28.00, so it's held as a likely fake shop. Price tracking watches a real product and never buys anything.
AG Grid Community runs Activity: every payment in one table, filters per outcome, and the full case file in a drawer.
Timed on the live site with a fresh demo family:
The four tour scenarios take about 4 to 8 seconds each to get a verdict. Tom's Not me to "Your money is safe" is about a second. Approve with the PIN is about 2 seconds. In the agent lab, the hijacked agent was frozen and PayPal cancelled its hold about 5 seconds in, and PayPal's webhook confirmed it within about 15 seconds. In Watchtower, "What did Leo spend on games?" gives a new chart with the right £9.98 total in about 20 seconds, 14 tool calls, 0 money actions.
Design
The person deciding is usually someone's son or daughter on their phone, with Gran waiting. So the held card leads with one sentence, who and how much, and Deny before Approve. Everything else folds behind See the evidence.
axe with the WCAG 2.2 AA tags found 0 violations on 16 routes, at 390 and 1440 px, on the live site. No sideways scroll anywhere from 320 to 2560 px. Skip to main content is the first Tab stop, every stop has a visible focus ring, and results get announced to screen readers.
Gran has her own Watchtower view: big type, plain words, nothing to approve, in English or Polish.
Every example says it's an example. The £250 you start with says "Example, checked earlier", the sample month says Sample, and the agent lab says it's a scripted test agent. The shops and people are made up, and a test keeps real brand names out of the demo data.
Who it's for
UK Finance counted £576.4m lost in the UK in 2025 to scams where people were talked into sending the money themselves, up 19% on 2024. In the US the FTC reported $15.9bn lost to fraud in 2025, from 3 million reports. Friends and Family payments have no buyer protection.
So it's for older relatives getting "new number" texts, fake parcel fees and Friends and Family requests. Kids on game chats, where the cheap game credit scams are. And AI agents shopping with the PayPal Agent Toolkit, which has no spending limit or approval step of its own.
Nobody installs anything new. Gran forwards on Telegram or by email, her son gets the alert where he already is, and an agent keeps the toolkit it was written for. A small business gets the same Spotter with different words (approver, staff and agents) and two extra checks: a supplier invoice with changed bank details, and a buying agent going over budget.
What's actually new
Four decisions shaped everything else.
Ask the person the text pretends to be. This scam rests on one claim: "it's me, Tom". So Spotter takes that at its word and asks Tom on his own linked Telegram, never the number that texted. When a text only says "Hi Mum", it's claiming to be you, so you get asked on the held card.
Open the page the way her phone sees it. Scam kits show security scanners a harmless page and save the card form for real phones. So Spotter opens the link as both at the same moment and compares.
An agent's unused tools are tripwires. A shopping agent needs 6 of the 47 toolkit tools. Refunds and invoices have no honest use for a shopper, so instead of hiding them Spotter offers 35 of them as bait. An agent that reaches for create_refund is being steered by something, so it gets frozen and PayPal cancels its holds.
Real prices are evidence. A price way below every real shop is a fake shop sign, not a saving, and code hands that verdict to the AI as data so it can't decide otherwise.
Everything above can be tried on the live site in about 5 minutes with no account. The Try a payment page says which check each scenario shows, and the four tour buttons give the same result in any order. How it checked (/checks) shows each check's work on your own payments, plus all 47 toolkit tools and what Spotter does to each. The README has screen recordings of the live site and the timings above.
Challenges I ran into
The most annoying bug was a semicolon inside a SQL comment. PGlite on my laptop didn't care. Neon splits DDL on ";", so production broke and only production. A test now fails the build if a schema comment ever has one again.
Real Claude refused the agent lab's bait twice. Good for Claude, annoying for my demo. So the lab uses a scripted test agent that falls for it on purpose, and the page says so. Spotter doesn't rely on the model being careful anyway.
My Anthropic key ran out of credit in the middle of testing and Spotter held the payment anyway, which was a nice accidental proof that it fails closed. Then I built the failover so it doesn't have to.
Channel3 once priced a plain kettle like a designer one, and an Australian shop's converted price ended up in a UK going rate. Now there's one going rate per card: UK shops only for pounds, one price per shop, same department.
AG Studio picks chart colours by the order values first show up, not per value. So rows are sorted worst outcome first and the palette is built from the outcomes present, otherwise "Paid" could come out red. AG Studio 3.0 also doesn't redraw when the data changes, so live updates quietly remount the board.
My notes said the Agent Toolkit had 48 tools. It has 47. A test now checks my table against the installed package's own list.
What took me longest to see: the toolkit is built for sellers. Refunds, invoices, tracking and subscriptions act for the account that gets paid, which is exactly why a shopping agent reaching for them is such a loud signal.
What doesn't work yet
Spotter can't read texts or chat apps by itself, and honestly nothing should. People forward what asks them for money, and it can't stop someone paying directly in the PayPal app. For AI agents it's enforced, because the agent only has Spotter's tools.
Discord alerts to the spotter work in code, but I haven't seen a DM land yet. Discord only lets an app DM you if you share a server or you allow it in your settings.
In the sandbox, agent holds use a test card. Whether PayPal renews a card funded hold on day 4 is unproven, and the app never claims a renewal PayPal didn't return.
If PayPal's answer to a new hold never arrives and PayPal also forgets the request id, that hold only ends when PayPal expires it.
The Polish in Gran's view hasn't been checked by a native speaker yet.
npm audit reports high issues in the Agent Toolkit's own dependencies. Spotter only reads tool definitions and calls 10 methods, so none of the flagged code runs, but they're there.
And the AI check can be wrong. When it can't run or isn't sure, the payment waits for a person.
What I used
PayPal REST APIs (Orders v2, authorizations), Log in with PayPal, webhooks and the Agent Toolkit, all on the sandbox. Claude (Anthropic) for the scam check, the case agent, the photo price check and the Watchtower agents, with OpenAI gpt-5.4-mini as the backup for the scam check only. AG Studio for Watchtower and AG Grid Community for Activity. Channel3 for real shop prices, image search, photo checks and price tracking. KERNEL for the throwaway cloud browsers. Agentboxd for the [email protected] inbox, Neon and Vercel for hosting.
Built With
- ag-grid
- ag-studio
- agentboxd
- anthropic
- channel3
- claude
- discord
- kernel
- mcp
- neon
- next.js
- openai
- paypal
- paypal-agent-toolkit
- paypal-webhooks
- pglite
- postgresql
- react
- telegram
- typescript
- vercel
- vitest