All packs
    Claude Code
    Intermediate

    The Local Marketing OS

    the brain that runs local marketing

    Cover art for the The Local Marketing OS Build Pack
    About an hour for setup, then fourteen prompts over four or five evenings
    $0 beyond Claude Code with OpenRouter free models; $10 of credit when the Director's note goes to a real owner; VPS or Mac mini optional
    14 prompts
    v1.0.0
    next.js
    postgres
    docker
    claude-code
    openrouter
    ollama

    A self-hosted marketing department for one local service business: a Content Factory gated by a Brand Brain, a Speed-to-Lead responder that books at night, ads rebuilt weekly under your cap, a 90-day publishing gate, attribution where every number is a link, and one Director running it each morning.

    What you build

    PartWhat it isWhat it does
    EyesA Next.js ops-center dashboard, dark, dense, ledger-style numbersMarketing Director, Content Factory, Paid Demand, Speed-to-Lead, Radar, Local SEO, Publishing, Attribution, Brand Brain, Calendar. Four KPI cards per page, each with a plain-language subtitle.
    BrainClaude Code, then an LLM through OpenRouter or OllamaClaude builds it. The runtime model drafts content, extracts fields from a lead's message, and writes the morning note behind a fallback chain and a validator that rejects any claim not in the data.
    MemoryPostgres, about thirty tables, money in centsBrand Brain, pieces, leads, conversations, slots, campaigns, change orders, signals, keywords, reviews, publish queue, attribution events, runs, approvals. Five guards live in Postgres, not the UI.
    The gateA deterministic claims gate over every generated sentenceBanned phrases, prices, promises and credentials are held unless the exact claim is on the owner's approved list. The UI shows the sentence and the rule. The model cannot add a claim.
    Nervous systemOne intake door, one event bus, one socket pattern for the outside worldPOST /api/leads/submit takes every future channel in one shape. Ads, social, GBP and senders are sockets: CSV in, signed webhook out, nothing counts as done until the outside system confirms back.
    The human boundaryHold / Approve on everything that leaves the buildingOffers, prices, promises, budget changes above your cap and every post inside a channel's 90-day gate wait for a click. Speed-to-Lead replies only from approved templates. No auto-approve exists.

    Where this comes from

    Structure Webworks published "How a Local Business Runs Marketing With AI Agents": a marketing department for one home-services company where a Marketing Director sits over seven modules — a Content Factory, a Paid Demand Engine, a Speed-to-Lead responder, a Market Signal Radar, Local SEO & Listings, a Publishing Engine, and Attribution & Reporting — and stops at the gates. The link is in the files box. It is a good map. The part worth copying exactly is the set of gates: nothing publishes unapproved for the first ninety days on a channel, budget changes above the cap are held, and any sentence that sounds like a guarantee or a price waits for the owner.

    Their article says fourteen modules replaced three salaries and two retainers. Nobody here has measured that, so this pack does not repeat it, and the dashboard it builds has no "saved vs the old team" card. What it builds instead is the honest version of the same shape: deterministic code does the gathering, one LLM call writes the sentences, a validator throws out any line that cites a piece, a campaign or an amount that is not in the data, and the Brand Brain is a table in Postgres with a gate in front of it — not a paragraph in a prompt.

    What you build

    When it runs, it feels like a marketing manager who read every review, every lead and every campaign before you got in. The Content Factory writes the week from a brief and the Brand Brain; any sentence with a guarantee, a price or a credential the owner never approved is held, and the screen shows you the sentence. A form fills at 11:40 on a Sunday; Speed-to-Lead qualifies the job, the address, the timeline and the insurance using replies assembled only from templates you approved, and books a tentative inspection into a slot you opened. The moment someone asks "how much", it stops and hands off to you. The Paid Demand Engine proposes on Monday, monitors on Wednesday and proposes kills on Friday, with the arithmetic in every proposal, and Postgres refuses to approve anything that crosses your weekly cap.

    Then the Director runs six stages every morning and leaves a "Waiting on you" list with Hold and Approve on each line, and a note whose every number opens into the rows that made it. The one thing it deliberately does not do: publish, spend, or promise on its own. There is no setting for that, a script fails the build if a column named auto_approve ever appears, and the prompts tell Claude not to add one.

    Do you need this? Be honest first

    If you run a one-person trade and your marketing is a Google Business Profile you update when you remember, you do not need seven modules; you need to reply to your reviews. This is for the local service business — roofing, HVAC, plumbing, remodeling, cleaning, landscaping — with enough lead flow that nights and weekends are being lost, where ad spend is a number nobody can tie to a booked job, and where the owner is the only person who knows what the company is allowed to promise. It is also for the builder who wants to sell that business a system it owns instead of a retainer.

    You are building software that drafts marketing, not a licence to say anything. The approved-claims list starts nearly empty on purpose. What a platform allows and what advertising rules apply where you are is the business's call and its advisers' job. If you are not comfortable saying that to a client, close the tab.

    What you need

    Pick the machine first:

    OptionGood forRuntime model
    Any laptop — Windows with WSL, Mac, or Linux with OmarchyLearning and buildingOpenRouter free models
    A Mac mini with 64 GB or moreRunning it in the office with local AI; customer data never leavesOllama with qwen3:32b or llama3.3:70b
    A small VPSReachable from anywhere, awake at 11:40 on a SundayOpenRouter

    Every option needs Claude Code logged in (Pro, Max or Team), Docker, Node and git. The pack assumes none of them are installed: the setup guide starts at "open a terminal" (or install one — Windows Terminal, Tabby, PuTTY, Terminal.app, or Super + Return on Omarchy) and ends when claude, docker and node all answer. It covers the OpenRouter account (free models first, $10 of credit when the note goes to a real owner), Ollama on a 64 GB Mac, and a VPS if you go that way. No ad-platform keys, no social tokens, no Google Business Profile access: every outside platform is a socket in this lesson, and demo mode ships a fake one that confirms by itself. Nothing of the author's is in it; every credential is yours.

    The setup guide is one HTML file you open in a browser. Every command has a copy button, every step has a checkbox, and a progress bar at the top shows how far along you are. Your progress is saved in that browser.

    What is in the zip

    local-marketing-os/
      README.md               the document: what, why, hosting, the accounts, the folder map
      index.html              the clickable setup guide with all fourteen prompts (same as the browser link above)
      COSTS.md                every cost, with the date it was read
      CREDITS.md              where the idea comes from, the as-is notice, what was verified, terms
      paths/                  one README per platform: Windows WSL2, Mac Apple Silicon, Linux Omarchy
      prompts/                00-project-brief ... 13-tests-and-smoke
      assets/                 the cover art
    

    What was verified and what was not

    This pack is distributed as is, as a proof of concept. The setup guide was opened in a real browser and driven by a script on 2026-08-30: the three platform tabs, the progress bar, the checkboxes, the saved progress, and the copy buttons all work — including from a downloaded file, where the modern clipboard API silently fails and the guide falls back to the older method. The install commands are the current official ones for WSL, Homebrew, Docker, nvm, pacman and Claude Code as of that date; they were not executed end to end on three fresh machines for this release.

    The fourteen prompts were written against a reviewed design, read twice by a separate model session for contradictions and missing steps, and have not been run as a sequence. Every prompt ends with a "how you know it worked" check that you can see without reading code — Postgres refusing to approve a held sentence, the dispatcher sitting still on a gated channel, the engine refusing to spend past your cap. Prompt 13 makes Claude break the code on purpose to prove the tests can fail. If a prompt breaks on your machine, paste the full error into Claude Code and ask it to fix it, then post what broke and the platform in the community.

    Read the prompt before you run it

    Hand each prompt to Claude first and ask what it plans to build. Compare that to what the prompt says. A prompt costs a minute to fix. A wrong build costs an afternoon.

    More packs