{
  "markdown": "# Small Business Intelligence\n\nA free, open source [MCP](https://modelcontextprotocol.io) server that teaches\nany AI how to research a small business — and, more usefully, **where the public\nrecords actually are**.\n\n**Nine of its tools ship methodology, not data.** Each returns a rigorously\nstructured framework — a research procedure, an output schema, a quality rubric,\nthe traps — and the calling model executes the research itself, with its own\ntools and its own keys. Those nine call nothing at all.\n\n**Two ship the records.** `twin_cities_datasets` and `twin_cities_records` answer\nfrom joined public records for the seven-county Minneapolis-St. Paul metro —\nparcels and lot lines, recorded sale prices, owners, rental licences,\ncontamination files, business counts by trade, census tracts. Ask about one\naddress and they answer about that address. They call\n[brickandmortar.dev/api/export](https://brickandmortar.dev/api/export), which we\nrun; no tool here calls any third party. Every answer is a true row count, at\nmost six example rows, and a link to the complete file — never a file inline.\nSee [`/privacy`](#privacy) for exactly what those two transmit and what is kept.\n\nThat split is deliberate and dated: the server was built on \"no remote calls to\nour servers\" (2026-08-16), which rested on a thesis retired the next day — *the\njoin is the moat, and the data ships*. Confirmed 2026-08-20; the nine are\nuntouched.\n\nLive endpoint: **`https://brickandmortar.dev/mcp`**\nNo auth, no account, no key. Add it as a custom connector and ask.\n\n## Why this exists\n\nA capable model already knows how to reason about a small business. What it\ndoes not know is the operational trivia that lives in nobody's training data:\n\n- that a county's parcel geometry arrives in **survey feet in Kansas and metres\n  in Minnesota**, so a hard-coded threshold silently triples;\n- that Esri's `Touches` predicate returns **zero touching parcels** rather than\n  an error, so adjacency quietly becomes \"this parcel touches nothing\";\n- that **Kansas never records a sale price at all**, so an hour spent looking\n  for one is an hour spent looking for something that does not exist;\n- that Google's Places API returns **at most five reviews, relevance-ranked**,\n  so a sentiment trend computed from them is a real-looking number from a\n  sample somebody else chose;\n- that County Business Patterns **suppresses small cells**, so reading one as\n  zero turns a thin market into an empty one.\n\nEvery one of those produces a *plausible wrong answer* rather than a failure.\nThat is the whole problem with public data, and it is what this server is for.\n\nThe frameworks are the reasoning. [`src/tools/sources.ts`](./src/tools/sources.ts)\nis the map — where each record lives, how to reach it, and the specific way it\nlies. Every access pattern and trap in it was measured live against the agency's\nown endpoint while building a real two-metro property and review corpus, not\nrecalled from training data.\n\n## The tools\n\nStart with `data_source_atlas`. It is the one that changes what the rest are worth.\n\n| Tool | What it does |\n|---|---|\n| **`data_source_atlas`** | **Given a real question and a place, returns a source-first research plan: which public record settles it, how to reach it, and what the public record cannot answer at all.** Handles the jurisdictional fork (does this state even record sale prices?) before anything else. |\n| `business_teardown` | Full structured teardown of one named business — presence, review signal, competitive position, pricing posture, visibility gaps, prioritized evidence-cited recommendations. |\n| `competitor_landscape` | Maps the local competitive set: true competitors vs. adjacent players, positioning matrix, saturation signals — corroborated against an administrative establishment count, not just map results. |\n| `review_intelligence` | Mines public reviews: complaint taxonomy, theme extraction, sentiment trajectory, red flags for buyers. Rates, never raw counts. |\n| `local_visibility_audit` | Local search presence audit: map-pack factors, listing consistency, category selection, site fundamentals — a scored checklist. |\n| `pricing_benchmark` | A defensible local pricing comparison, including how to normalize across bundles and what to do when nobody publishes prices. |\n| `broker_diligence_prep` | Pre-diligence for brokers and buyers: SDE framing, multiple ranges, red-flag checklist, seller questions — plus the county's own record on the real property. |\n| `market_opportunity_scan` | Gap analysis for a category × metro: underserved demand vs. a spot that is empty for a reason. |\n| `compose_report` | Assembles prior tool outputs into one client-ready report, matched to the audience. |\n| `twin_cities_datasets` | What joined public records we publish for the seven-county Minneapolis–St. Paul metro: row counts, columns, the cuts available, the counties each actually covers. |\n| `twin_cities_records` | Asks those records a question — one property or the whole market. Returns the true matching row count, six example rows, and a link to the complete file. |\n| `request_a_feature` | **The only tool here that sends rather than answers.** Files a feature request, a data request or a correction to the person who builds this, when the server falls short of what the user wanted. |\n\n## What it will not do\n\nStated plainly, because the boundary is the design:\n\n- **No remote calls to us, from the nine framework tools.** Every endpoint they\n  name is reached by *your* model, directly, with your own keys. The two Twin\n  Cities tools do call us — that is how they hand over the records — and\n  `request_a_feature` posts the request you dictated to us and nowhere else.\n- **No data.** There is no corpus here, nothing cached, nothing to go stale.\n- **No account, no telemetry about you.** The only thing recorded is an\n  aggregate per-tool call counter with no identity attached. See\n  [PRIVACY.md](./PRIVACY.md).\n- **No claim to do financial diligence.** Revenue, margin, private lease terms\n  and the terms of a private sale are not public anywhere in the United States.\n  The tools say so rather than substituting a proxy.\n\n## Connect it\n\nAdd the endpoint as a custom connector in Claude, or any MCP-compatible client:\n\n```\nhttps://brickandmortar.dev/mcp\n```\n\nThen ask something real:\n\n> \"Where would I actually find what 1420 Grand Ave in Saint Paul last sold for?\"\n\n> \"I want to know if Wichita has room for another dog daycare — what should I pull?\"\n\n> \"Run a business_teardown on Mucci's Italian in Saint Paul, MN.\"\n\n## Run your own\n\n```bash\nnpm install\nnpm run typecheck    # tsc --noEmit\nnpm run dev          # wrangler dev — serves http://localhost:8787\n```\n\n`wrangler dev` runs against Miniflare's local KV simulation, so the usage ledger\nworks out of the box with no Cloudflare account needed.\n\n### Verify it\n\n```bash\n# list every tool\nnpx @modelcontextprotocol/inspector --cli --server-url http://localhost:8787/mcp \\\n  --method tools/list\n\n# call one\nnpx @modelcontextprotocol/inspector --cli --server-url http://localhost:8787/mcp \\\n  --method tools/call --tool-name data_source_atlas \\\n  --tool-arg question=\"what did this building last sell for\" \\\n  --tool-arg place=\"Wichita, KS\"\n```\n\nOr drop `--cli` for the interactive web UI (`npm run inspector`). Every tool\nshould list with an `outputSchema`, and a `tools/call` against each should return\n`structuredContent` matching it, with no `isError`. All of them list with\n`readOnlyHint: true` except `request_a_feature`, which sends a message and says\nso.\n\n### Deploy\n\n```bash\nwrangler login                              # or set CLOUDFLARE_API_TOKEN\nwrangler kv namespace create USAGE_LEDGER   # once — copy the id into wrangler.jsonc\nnpm run deploy\n```\n\nShips to the free `*.workers.dev` subdomain — no DNS work, no paid plan.\n\n## A note on context cost\n\n`tools/list` is ~43 KB (~10.8K tokens) and sits in the client's context for the\nwhole session whether or not a tool is ever called. Most of that is the shared\n`outputSchema` serialised once per tool. If you fork this and add tools, read the\ncomment at the top of [`src/tools/types.ts`](./src/tools/types.ts) first — every\n`.describe()` in that schema is paid for once per tool, forever.\n\n## Repo structure\n\n```\nsrc/\n├── index.ts        # Worker entry — routes /, /docs, /privacy, /mcp\n├── server.ts       # createServer(): builds McpServer; TOOL_NAMES is the one list\n├── env.ts          # Env (Worker bindings/vars) type\n├── middleware/     # identity resolution, KV usage ledger, policy, withPolicy seam\n├── oauth/          # OAuth 2.1 discovery handlers — written, not mounted\n├── tools/\n│   ├── sources.ts          # WHERE THE RECORDS ARE — parcel GIS, Census, state/local, reviews\n│   ├── federal_sources.ts  # BLS series construction + six measured traps\n│   └── *.ts                # one file per tool, sharing FrameworkPayload from types.ts\n└── pages/          # landing (/), docs (/docs), privacy (/privacy)\n```\n\nArchitecture and the SDK/transport decision: [ARCHITECTURE.md](./ARCHITECTURE.md).\n\n## Contributing\n\nThe most valuable contribution is **a measured trap**. If you pull a public\nsource and it lies to you in a way that returns a plausible number instead of an\nerror, that belongs in `sources.ts` — with how you measured it and when. Access\npatterns rot as agencies reorganise; a correction with a date on it is worth more\nthan a new framework.\n\nPlease don't add anything that makes the server call an external service. The\nno-outbound-calls property is what makes it free to run and safe to trust.\n\n## Who made this\n\nBuilt by [Brick & Mortar](https://brickandmortar.dev) — a small team in Saint\nPaul that maintains real local-market corpora (county parcel records, recorded\nsales, review panels, federal series) for its own products. The frameworks here\nare what we learned building those, including the traps that silently return a\nplausible wrong number.\n\nThis is a gift, not a funnel. It is not a demo of a paid product, there is\nnothing gated, and nothing here reports back to us.\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n",
  "bytes": 10114,
  "sha": "c8e1b9bfaa7e76b00591a8d2527334825ac2f7d39f4d7b2c3c8e7f3c22db6d61",
  "repo_slug": "2016judea/small-business-intelligence-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_2016judea_small_business_intel_0d0cb37b/readme"
}