ai newsMi., 4. Nov.
EilmeldungOpenAI acquires Pierre Computer Company to make Git keep up with AI coding agents

A Feed for Tiny Tools: Following, Updating and Trusting AI-Built Web Apps

The problem: tiny tools have no RSS AI coding assistants have made small, single-purpose web tools almost free to build. A JSON differ, an image resizer or a token counter now takes one prompt and a few minutes, so people like Simon Willison publish dozens of them on a single page. The trouble star

dev.toMittwoch 18:13 · 04.11.5 Min. Lesezeit
Bild: dev.to

AI coding assistants have made small, single-purpose web tools almost free to build. A JSON differ, an image resizer or a token counter now takes one prompt and a few minutes, so people like Simon Willison publish dozens of them on a single page.

The trouble starts after publishing. In his April 2026 post Syndicating vibes, Matt Webb asks a set of plain questions nobody has answered yet:

Blogs had this problem twenty years ago, and RSS fixed it. Tools have no equivalent. Matt sketches the answer as an RSS-style feed of tools, each item with an Install button. I wanted to see how much of that one person could build in a weekend.

tool_feed.py is a single Python script that turns any tools index page into a subscribable, change-tracked feed. You point it at a page, and it writes two files: feed.json, a standard JSON Feed anyone can subscribe to, and state.json, which remembers what it saw last time.

python tool_feed.py https://tools.simonwillison.net --title "Simon's tools" Enter fullscreen mode Exit fullscreen mode Run it daily on a schedule and the feed stays current. The rest of this post walks through how each stage works.

The script finds the tool list by looking for the element with the largest group of similar children that each contain a link. No site-specific rules are needed for a typical tools page.

It parses the page into a tree and gives every element a signature: its tag plus its sorted CSS classes, like li.tool. Then it walks the tree children-first, so each element already knows whether anything below it contains a link. For every parent, it groups the linked children by signature and scores the parent by its biggest group.

Navigation menus are the main trap, because they are also lists of links. Anything inside nav, header or footer is skipped, so the real list wins even when the menu has more links. The whole pass touches each element once, so it costs O(N) in the size of the page and takes milliseconds.

A tool counts as updated only when its own page changes in a meaningful way. The index page rarely changes when a tool is edited, so the script fetches every tool page and fingerprints it.

Conditional requests first. Each fetch sends the ETag and Last-Modified values from the previous run. If the server answers 304 Not Modified, the tool is skipped without downloading anything. Most days, most tools cost one tiny request.

Strip the noise. Pages contain things that change on every load: HTML comments, nonce attributes on scripts, embedded timestamps. Hashing those would report an update every single day. So the script removes them and collapses whitespace before going further.

Hash what remains. The cleaned page goes through SHA-256. If the hash matches the stored one, nothing changed. If it differs, the tool gets a new version (the first 12 characters of the hash) and a changelog entry with the date.

The result is two kinds of change: listing changes from the index (a tool added or removed) and content changes from each tool page (a tool updated).

An update gets flagged needs_review when the page starts talking to a domain it never talked to before. That is the cheapest strong signal I could find for Matt's malicious-update worry.

For every version, the script collects the set of external hosts the page touches: <script src>, <link href>, <img src>, <iframe src>, <form action>, plus any fetch('https://…') call inside a script. Then it takes a set difference:

new_domains = domains(new version) − domains(old version) Enter fullscreen mode Exit fullscreen mode If new_domains is not empty, the update is flagged and the new hosts are listed. A tool that quietly starts sending data to evil.io cannot slip through as a routine edit.

A second, weaker signal also triggers review: the page size changing by more than 50% in one update. A complete rewrite is not necessarily bad, but it deserves a look before you trust it.

The first time a tool is seen, its domains become the baseline and nothing is flagged.

The output is a plain JSON Feed 1.1, so any feed reader that supports JSON Feed can already subscribe to it. Everything tool-specific lives under one extension key, _tool_feed, which the spec allows and ordinary readers ignore.

{ "id": "https://t.dev/tokens", "url": "https://t.dev/tokens/", "title": "Tokens", "content_text": "Count tokens", "date_modified": "2026-11-04T16:20:00+00:00", "_tool_feed": { "version": "9f2c41ab07de", "review": "needs_review", "domains": [ "evil.io" ], "changelog": [ { "kind": "updated", "at": "2026-11-04T16:20:00+00:00", "new_domains": [ "evil.io" ], "review": "needs_review" }, { "kind": "added", "at": "2026-11-03T16:20:00+00:00", "review": "ok" } ] } } Enter fullscreen mode Exit fullscreen mode Field What it answers version Which exact copy of the tool am I running? review Is the latest update safe to accept without looking? domains Who does this tool talk to? changelog What changed, and when? Newest first, last 20 kept. A reader app only has to compare the version it installed with the one in the feed to know an update exists, and read review to know whether to ask first.

I wanted the code to read like the design, without comments explaining it. A few Python features did most of that work.

The Fetcher protocol paid off immediately. To test the script without the network, I passed in a fake fetcher that returns hand-written pages, then ran it twice:

This is a first version, and it has clear gaps:

Next I plan to run the script daily with GitHub Actions and serve feed.json from GitHub Pages, so there is a live feed anyone can subscribe to.

The code is on GitHub at Talal-Ali/tool-feed. If you publish small tools, I'd like to know whether this format would work for you, and what you would change.

Quelle: dev.to (dev.to). Original öffnen