DEV Community

Cover image for Localscout: an open-weight agent that audits a local business's website before it pitches them
Aditya Patkar
Aditya Patkar

Posted on

Localscout: an open-weight agent that audits a local business's website before it pitches them

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

Every freelance web developer knows the loop. You finish a project, and the next morning you are hunting for clients again: scrolling Google Maps, opening websites that take ten seconds to load, and sending messages that say "I can improve your website" to owners who have read that sentence fifty times. The pitch carries no proof, so it gets ignored.

Localscout flips the order: audit first, pitch second.

You type something like plumbers in Bhopal, and Localscout:

  1. Finds matching businesses from Google Maps results.
  2. Audits each website with real measurements: a mobile Lighthouse run (time to main content, layout shift, blocking time) plus plain HTTP checks for HTTPS, a mobile viewport tag, page title and description, and a tap-to-call link. Businesses with no website, or only a social page, are flagged too.
  3. Scores every lead. A slow site on a busy, well-reviewed business scores highest, because that owner has the most to gain.
  4. Drafts a short WhatsApp message in English, Hinglish, or Hindi that cites only what was measured, for example that the main content took 6.1 seconds to appear in a mobile speed test.
  5. Hands it to you. You read it, copy it or open WhatsApp with the text prefilled, send it yourself, and log what happened.

It never sends anything on its own. There is no send button in the code at all.

Who would pay? Freelance web developers and tiny agencies, especially in India, where WhatsApp is how you actually reach a plumber, a salon, or a clinic. The problem it solves for them is twofold: working out which of two hundred listings is worth a message, and arriving with evidence instead of a claim. [FILL IN: your pricing idea, for example a flat fee per batch of leads, or "I haven't priced it yet, but one hour of manual prospecting is the benchmark".]

Demo

Live: https://localscout-5cvy.onrender.com/

The free Render instance sleeps when idle, so the first load can take up to a minute.

Things to try: click "Explore with demo data", move your cursor across the pixel map (each square is a business, colored by opportunity score), open a lead to see the audit evidence behind its score, and compare the three message languages.

Code

Localscout

Find local businesses, audit their websites with real measurements, and draft honest outreach that you review and send by hand.

Localscout never sends anything. There is no send code path. It finds businesses measures what is actually wrong with their site, writes a short message that cites only those measurements, and hands it to you.

Everything runs on your machine.


Quickstart

Three commands. No API keys, no Chrome, no Ollama, no network.

pnpm install
pnpm dev
Enter fullscreen mode Exit fullscreen mode

Then open http://localhost:5173.

This is fixtures mode: discovery reads 35 recorded SerpApi responses from fixtures/serpapi/, auditing runs against local fixture sites, and drafting uses canned JSON. Everything is exercised except the three external services.

Run a batch from the terminal instead:

pnpm cli "plumbers" Bhopal --limit 20
Enter fullscreen mode Exit fullscreen mode

How it works

Browser (React)  --HTTP/SSE-->  API (127.0.0.1:8787)
                                      |
                               Mastra workflow
  discover -> dedupe -> audit (x N) -> score ->
…

How I Built It

What is open, and what isn't

Piece What it does Open?
Gemma (via Ollama or any OpenAI-compatible endpoint) Turns structured findings into a short message Open weights
Lighthouse Measures speed and mobile readiness Open source
Mastra Orchestrates the workflow Open source
SQLite Stores leads, audits, drafts, outreach log Open source
SerpApi Google Maps discovery Hosted service (the one closed part; responses are cached and the source is swappable)

The workflow. A Mastra workflow runs discover → dedupe → audit → score → draft → persist. Each step is a thin wrapper over a pure, tested function, so a framework quirk never traps the logic. One failing site never aborts a run: every external call returns a result marked ok, stale, or unavailable, and the UI says so instead of guessing.

Evidence before words. This is the decision I care about most. The model never reads a web page. Deterministic code produces the findings (for example "main content at 6.1 s, threshold 4.0 s"), and the model only turns that structured data into plain language. Then a grounding validator checks the draft: every number must match the audit evidence, it may not cite a finding that wasn't provided, and banned phrases like "guaranteed #1 ranking" are rejected. A bad draft gets one retry with the errors attached, and after that falls back to a deterministic template. A cold message with a made-up number is worse than no message.

Safety by construction. Websites come from search results, so the auditor treats them as untrusted: private and loopback addresses are blocked (including cloud metadata endpoints), redirects are re-checked, and page text never reaches the model. A contacted business or domain is never pitched twice.

A real hiccup. I planned to resolve the city to coordinates before searching. My SerpApi key is on the Free plan, and every geocoding engine returned "Unsupported search engine". The documented alternative, location plus z, worked and returned 20 real Bhopal plumber results. I built the map from the GPS coordinates each listing already carries, which turned out simpler and removed the need to know the city center at all.

The frontend. I modeled the look on the Hacktoberfest site itself: a teal canvas, coral buttons with hard offset shadows, and a pixel-grid map. Each business is a square colored by score, and a spotlight follows the cursor across the grid. The map is drawn on a canvas for smoothness, while the lead squares are real buttons so keyboard and screen-reader users get the same map.

Process. I wrote the build spec first (architecture, data model, scoring rules, design system, git workflow), then had a coding agent build it phase by phase. [FILL IN: anything that went differently from the spec, such as a Mastra API change or a Lighthouse quirk, and how you handled it.]

Deployment. Hosted on Render. [FILL IN: how it is deployed, for example a single web service serving the API and the built frontend.]

Why Does Open Innovation Matter?

It makes the unit economics work. Prospecting only pays if a lead costs almost nothing to process. With an open-weight model, drafting costs no per-token fee, so the only real cost per lead is the search itself. [FILL IN: your measured numbers from /api/metrics or the eval run, for example average audit time, average draft latency, and SerpApi calls per lead.]

It keeps a freelancer's pipeline theirs. A lead list, the notes on each business, and the outreach log are a solo freelancer's most valuable data. Localscout stores them in a local SQLite file, and drafting needs no third-party LLM, so none of it goes to a model provider.

It lets me fix the part generic models handle poorly. Romanized Hindi (Hinglish) written for a local shop owner is exactly where general-purpose models tend to sound stiff. Open weights mean I can swap models, evaluate them with the same fixtures, and fine-tune later without changing the product. The model sits behind a small provider interface, so moving between Ollama, another OpenAI-compatible endpoint, or a different Gemma size is a config change.

It makes the evidence checkable. Because the audit uses open-source Lighthouse, a business owner can run the same test and see the same number. That is a much stronger opener than "your site feels slow."

Prize Categories

  • Best Use of Render: the app is hosted on Render.
  • Best Use of SerpApi: live Google Maps discovery with a disk cache to protect the free-plan quota.
  • Best Use of Mastra: the discover-to-persist workflow runs on Mastra.
  • Best Use of Gemma: drafting runs on a Gemma model.

Top comments (0)