The ninth agent in our 30 agents series is Site to ICP: give it your URL and it reads your website the way a stranger would, then writes down what you actually sell and who buys it. Every other agent we have shipped produces something you can check. This one produces an argument, and that turned out to be the entire engineering problem.
An output you cannot run
A chart either plots the data or it does not. An MP3 either plays or it does not. A crash report either matches a stack trace or it does not. Every agent before this one produces an artefact with a truth condition attached, and when it is wrong you find out by looking.
“Series B fintechs in the Nordics, 40–200 employees, $4.2B TAM” has no truth condition. It is what any language model will tell you, instantly and fluently, when you ask who buys a product. Every noun in it is plausible. None of it came from the site.
That is worse than a wrong chart, and the reason is not that it is more often wrong. It is that it looks like research. It gets pasted into a board deck, and the person pasting it has no way to tell which half was read and which half was generated — because both halves are written in the same confident register.
Four rules, and one of them is the product
So most of this agent’s prompt is not about crawling. It is about making the seam visible.
Every line it writes is marked Stated: or Derived:. Stated means the site says it, and the sentence is quoted with the URL it came from. Derived means the agent concluded it, and it has to say what from — “three of five logos on /customers are logistics companies” is a finding; “they serve logistics” is a guess wearing a label. It may not write a number the site does not contain: no market sizes, no growth rates, no typical deal values. It has read one website.
None of that is new as an idea. It is the same discipline Meeting to Tasks uses when it records the line an issue came from, and the same one Maintainer uses when it marks its own diagnosis unconfirmed rather than asserting a cause. What is new is that here it is not a nicety. Without it there is no way to tell this agent apart from a confident guess with a file extension.
The fourth rule produced the most useful file, and we did not expect that. gaps.md is what your site does not say: no named buyer, no trigger, no proof, a pitch that changes between pages. It cannot be faked, because absence is not something a model can hallucinate its way into.
What it found in us
We tested it the only way that would have been honest, which was to point it at mume.ai before shipping it. It crawled twelve pages and wrote three files. From gaps.md:
No proof
There are no customer names, no logos, no testimonials, no case studies,
and no usage numbers anywhere in the 12 pages crawled. The only quantities
on the site describe the catalogue itself — "378 AI Models", "57 Providers",
"9 Agents" — not adoption, retention, or outcomes.And two more: the site never names a job title, a department or a company type, so it is impossible to tell whether the intended buyer is a consumer, an indie developer or a small-business operator. And it never states a trigger — nothing says what had just happened to someone right before they came looking.
Then it closed by saying that the profile it had just written was derived entirely from product shape rather than from any stated buyer description. Which is the correct thing to say, and not the thing a tool built to impress you would say.
All three are fair. We are going to fix them. The uncomfortable part is that we have read our own homepage several hundred times and none of us noticed.
The rubric is a program
The other half of the output is score.py — not a paragraph describing how you might weigh leads, but a file that reads a CSV and writes one back with a score and a reason for every row.
That distinction is why this belongs on a platform with a Linux sandbox rather than in a chat window. Advice about scoring cannot be argued with. A program can: you read the weights, you disagree with one, you change it and run it again next quarter against a different list. It is the same reason CSV Analyst writes PNGs to your workspace instead of describing charts.
The half we did not build
There is a shape of product this agent deliberately stops short of, and it is worth being direct about why.
The obvious next promise is “ask who to sell to and get a scored list of real companies in seconds”. We cannot do that. There is no web-search tool on this platform, and we checked the MCP registry for a company-data connector before assuming — nothing under leads, CRM, enrichment or prospecting, and nothing under search or scraping either. A list of real companies needs a real company database, which is a contract and a per-seat cost, not an afternoon.
We could have generated one anyway. Real-sounding company names are the easiest thing in the world for a language model to produce, and almost nobody would check the first ten. We are not going to, and the reason is narrow rather than principled: this is the one agent whose entire subject is claims about a market. An invented list here would poison the thing the other eight are built on.
So it scores the list you bring — a Sales Navigator export, an Apollo download, a CRM dump, a spreadsheet you keep by hand — and the rubric it writes is portable to whatever tool actually holds your data. The limits section on the agent’s page says all of this in the same words.
Two bugs, one of them in the agent
The first live run exposed a flaw we would not have predicted. Nine of its twelve fetches went into /docs, and it never reached /agents— the page about the product’s headline feature. Reference documentation is deeply linked and enormous, so a crawler that follows links naturally drowns in it. Nine pages of API reference tell you less about who buys a product than one customers page does.
The fix is a cap of two pages per section and an explicit order of preference, which is version 2 and what is live now. Worth noting that the bug was only visible because the agent keeps the pages it read in your workspace: the file list was the evidence.
The second bug was ours. The agent worked in every test we ran locally until the gateway had never heard of it — a flat 400 unknown_agent on the first message. Agent definitions are data, published to a snapshot document the gateway resolves against, and our own engineering notes claimed that only scheduled runs read it. That stopped being true months ago when run resolution moved server-side, and the note outlived the architecture it described. Every run reads the snapshot. Publishing is a step, not a formality.
Try it on your own site
Site to ICP is free to try and there is nothing to install. Paste a URL and read gaps.md first — it is the shortest file and the one most likely to tell you something you did not know about a page you wrote yourself.
Ask it to re-read weekly and it will compare against the pages it kept and rewrite only the sections that moved, which is what makes a positioning document something other than a snapshot of the day someone felt like writing one.