← All work
Agentic research · runs locallyRuns locally

MimicUser

You can read your own landing page a hundred times and never see what a stranger sees in ninety seconds. MimicUser gives a language model a persona, a budget and a real browser, points it at your live product, and reports what it concluded — with the agreement rate across sessions attached to every claim.

46 → 23
raw observations reduced to agreed findings
3 / 3
sessions that independently hit the top issue
~5 min
per autonomous session, unattended

What it is

Conventional user research is slow and expensive at the stage where it would change the most: before launch, when you have a page and a claim and no users. The usual substitute is asking a language model what it thinks of your copy, which produces agreeable, ungrounded text because the model never actually used the thing.

MimicUser closes that gap by making the model a user. A persona is constructed — background, goals, technical ability, price sensitivity, patience — and handed a real Chromium browser and a task. It navigates, reads, clicks, gets confused, forms opinions, and stops when it decides it has what it came for. Everything it saw and did is recorded as a session, then analysed into findings with severity, dimension, impact and a recommendation.

The finding that justified the tool

The clearest run so far was against the public site of a speech-recognition API startup, unaffiliated and unnamed here. Six sessions were dispatched across two audiences: a backend engineer evaluating speech-to-text vendors, and a CTO at a regional call centre.

All three call-centre sessions independently discovered the same thing, and it was not subtle: the accent the homepage used as its flagship differentiator was billed in a premium tier at roughly thirty times the headline rate advertised elsewhere on the site, with no explanation anywhere on the pricing page. Every cost projection a prospect built from the headline number was wrong, for exactly the workload the marketing was written to attract.

Two of the three also noticed that the subscription cards rendered their '/ month' and 'monthly credits' labels with no figures beside them — a broken page that a buyer reads as evasion. All three raised cloud-only deployment with no on-premise story as a blocker, and all three ended the same way: willing to trial the free tier, unwilling to commit budget.

  • "Wait, hold on — [the flagship accent] is priced separately as a 'Premium' specialist model … that's over 30x more expensive."
  • "The Starter/Scale/Business plan cards show '/ month' and 'monthly credits' but no actual dollar figures or credit amounts are displaying."
  • "I'm not pulling out a credit card today."

Turning agent runs into evidence

One agent session is an anecdote. A model will happily invent a grievance, and a single run gives you no way to tell invention from insight. The aggregation layer exists to make that distinction structural rather than editorial.

Findings from every session in a study are clustered by claim, and each surviving finding carries the number of independent sessions that reached it against the number that could have. A problem three of three sessions hit is reported very differently from one that a single session raised once, and findings that look like environmental noise are flagged as such rather than silently dropped. Severity spread across runs is kept too, so a disagreement stays visible instead of being averaged away.

In the study above that reduced forty-six raw observations to twenty-three agreed findings — and the two that mattered most were also the two with unanimous agreement.

Letting an agent drive a browser safely

An autonomous agent with a real browser pointed at a URL it chose is an SSRF engine. Left unguarded it can reach the cloud metadata service, the host, the private network and its own database — and the ordinary defence of validating the URL before navigating does not hold, because the browser resolves the name again after the check and an attacker who controls DNS can answer differently the second time.

So the policy is enforced on every request the browser makes rather than once per destination, and the verdict is deliberately not cached — caching is what made rebinding reliable. Refusals cover private and link-local ranges and the IPv6 routes back to them that get forgotten: IPv4-mapped, NAT64, 6to4, IPv4-compatible and Teredo. WebSockets are guarded separately because the browser routes them through a different API, and service workers are blocked outright.

Because the browser is still the one resolving names, the application-level policy is backed by a network-level one: a firewall rule set that permits the research network to reach the public internet and nothing else — not the metadata endpoint, not the host, not neighbouring containers.

Why it isn't a public demo

The stack is a Postgres database, a Redis broker, an API, a background worker and headless Chromium. That does not fit a free tier, and a public instance would also be a service that browses arbitrary URLs on a stranger's behalf — which is a liability, not a portfolio piece.

The design work for opening it up is done rather than hypothetical: visitors would supply their own model key, sealed at rest, and a public mode refuses operator-only routes outright instead of quietly falling back to the operator's own credentials when a visitor's key is missing. Failing closed there was a deliberate choice; the alternative bills the host for strangers' usage.

Built with

  • Python
  • FastAPI
  • Claude Agent SDK
  • Playwright
  • Dramatiq
  • PostgreSQL
  • Redis
  • Next.js

Not hosted: this needs Postgres, Redis, a worker and headless Chromium. Findings and quotes above are verbatim from a real study; the product evaluated is deliberately unnamed and identifying specifics are generalised.