recall · slot 05 · shipped
Tell me when something
I own is recalled.
And how sure you are.
Recalls are published. Nobody reads them, because they are published as a firehose about everyone's belongings. This keeps a list of the things you actually own and checks it against four public registers.
HIGH Something scanned off the box
Tickit Sensory Blocks Set of 16
The toy could rupture and the filling of the inside could come
out. The sand inside contains asbestos (measured value up to
1.92% by weight). Asbestos could cause cancer.
exact: barcode 5060138820289 matches exactly · Fri, 25/09
HIGH The stomach tablets
Shortage: Pantoprazol-Micro Labs 40 mg
Expected to last until 28.10.2026. Flagged as relevant to
hospital supply.
exact: PZN 10516704 matches exactly · Mon, 28/09
Sources
source checked result
── ────────── ─────── ────────── ──────────────────
ok safetygate 3 items 2 findings EU register only
ok bfarm 1 item 2 findings DE register only
ok endoflife 1 item 0 findings every jurisdiction
ok nhtsa 1 item 0 findings US register only
Absence of a notice is not proof a product is safe.
The situation
The notice for the thing in your kitchen was published. Nobody sent it to you.
A regulator puts out a notice, a manufacturer writes to whoever registered a warranty card in 2019, and the sand in your child's toy turns out to contain asbestos. You find out because someone mentions it.
| Register | Covers | Scope | Account |
|---|---|---|---|
| EU Safety Gatesafetygate | Consumer products, toys, appliances, electronics, vehicles | EU | none |
| BfArMbfarm | Medicine supply shortages, which is availability rather than safety | DE | none |
| NHTSAnhtsa | Vehicle safety campaigns | US | none |
| endoflife.dateendoflife | Software past its security support date | everywhere | none |
Safety Gate is the one that matters most in Europe. There is no documented
API, but there is a weekly report export in XML, which is better for this
purpose: a report reference is a stable cursor, so a refresh only fetches
weeks it has not seen, and a published week never changes so its cache never
expires. BfArM reports availability, not safety: a hit means a manufacturer
has declared a delivery shortage, so your pharmacy may not be able to fill a
repeat prescription. Every notice from that source carries that sentence with
it, because out of context shortage
is easily misheard as
unsafe
.
Running it
Tell it what you own, then check.
The local inventory is gitignored, which is where a list of your possessions belongs. It is a plain JS file, not a config format to learn.
git clone https://github.com/gledach/recall && cd recall
npm test # 98 tests, offline, about two seconds
cp config/inventory.default.mjs config/inventory.local.mjs
node bin/recall.mjs check # after listing what you own
No npm install. There is nothing to install, including its own
CSV and XML readers. Needs Node 22 or newer.
The command is gledach-recall. npm link puts that name
on your PATH. Nothing named recall is installed: npm already
publishes an unrelated package under that name.
Five kinds, each with the fields it needs
| Kind | Needs | Also accepts |
|---|---|---|
| appliance | make, model | barcode |
| device | make, model | barcode |
| vehicle | make, model, year | vin |
| software | product, as an endoflife.date slug | cycle |
| medicine | name | pzn, the 8 digits on the pack |
A missing required field is a startup error, not a skipped entry. An entry silently ignored looks exactly like an entry with nothing wrong, and it would be the one thing you cared about that never got checked.
Add the barcode. Everything else here is text matching: your spelling of a model number against a regulator's. A barcode is not matching at all, because the manufacturer printed those digits and the register reprinted them. Roughly half the EU alerts carry one, and every German shortage report carries a PZN. Only add digits you can read off the thing itself: a wrong barcode is worse than no barcode, because it will match something unrelated and be reported as certain.
How sure is it
It reports generously and grades honestly.
Two failure modes, and they are not symmetrical. Match loosely and every run reports a dozen unrelated things, people stop reading, then they miss the real one. Match tightly and the recall that mattered is never mentioned, which is worse and completely invisible.
| Grade | What it means |
|---|---|
| exact | A barcode, PZN or VIN matched, or the register matched it for us. |
| strong | Make and model both appear in the notice. |
| weak | A distinctive model number appears but the make does not. Check it yourself. Included by default. |
| mention | Only the make appears. Almost always noise, and hidden unless you ask for it. |
weak is shown by default, because missing a real recall is worse
than showing you something to dismiss. Nothing in the output ever says
you are affected
. It says what matched and how.
For agents
Five read-only tools, and read only on purpose.
It cannot add to your inventory and it cannot acknowledge a notice. Acknowledging is a person deciding they have dealt with something, and an assistant should not make that call on your behalf, so it stays a command you type.
npm run mcp
claude mcp add gledach-recall -- node /absolute/path/to/recall/mcp-server.mjs
check_inventory · list_inventory · notice_history
describe_sources · blind_spots
Every result carries its coverage and the confidence grade of each match,
because a model asked is my car recalled?
will otherwise turn
no notices found
into your car is fine
, which is a much stronger
claim than the data supports.
What it cannot see
Stated here, because this tool is dangerous precisely when it is trusted more than it deserves.
A source that is unreachable is reported as unreachable, never as clean.
Nothing found
and could not look
must never render the same
way, and that distinction is the single most important thing in the
codebase.
No UK, Swiss, Australian, Canadian or Japanese register. Not covered at all.
German vehicle recalls are not checked. That register sits behind a proof-of-work challenge. Vehicle coverage is US campaigns plus whatever the EU register happens to carry, which is not the same thing as German coverage.
Medicine coverage is German shortages only. There is no medicine safety register wired in.
Registers publish late. Days to weeks after a decision. A recall agreed this morning is not here.
Matching is text against text. A regulator who describes your product differently from how you wrote it down produces a low grade or nothing at all.
It checks your list, not your house. Anything you did not write down does not exist as far as this is concerned.
Tests: 98, offline, no network. A separate live suite answers a different question, namely whether the outside world still looks the way the parsers assume, and it is kept apart because a gate that fails when a public API has a bad afternoon teaches you to ignore the gate. The most dangerous bug this tool can have is a parser that returns zero records from a document full of them, because that is indistinguishable from good news. It has happened twice, which is why the live suite fails on a suspiciously empty result rather than reporting success.
This is not legal, medical or safety advice. If a notice concerns you, go to the register's own page and read the original. Data belongs to the European Commission, BfArM, NHTSA and endoflife.date respectively, and each source carries its own attribution.
Elsewhere on the shelf
Same author. Different shapes.
Each takes whatever shape suits it, from a single command to a dashboard. What they share is the promise rather than the plumbing: free, installable, and honest about what each one cannot see.
Slot 01 · live preview
signal
Ten watchers and one inbox on whichever market you name, scored and attributed, answerable by an agent over MCP.
Open the page →
Slot 03 · shipped
whenrun
Day-ahead power prices turned into the window your job should run in, then it starts the job there.
Open the page →
Slot 04 · shipped
phonehome
Which domains every device on your network contacts, and when one starts talking somewhere new.
Open the page →
Slot 06 · shipped
talk
Which API hosts your local coding agents connect to, and whether one of them is leaking sockets.
Open the page →
Slot 07 · shipped
snare
Remembers the hooks a coding agent runs at startup, and the editor tasks that run when a folder opens. Prints only when that set changes. It does not delete a hook.
Open the page →
Slot 08 · shipped
leash
Takes a snapshot before an agent session and another after, then shows what changed outside that repo: files, startup entries, services, packages and ports. It does not delete, kill or block anything.
Open the page →
Slot 02 · reference
signal-patterns
What is watchable, what it costs, and eight engineering decisions each extracted from a bug that shipped.
Open the page →