Metadata-Version: 2.4
Name: local-leads-mcp
Version: 0.1.0
Summary: Find local businesses with no website (or a weak one) and verify them — OpenStreetMap discovery plus anti-false-positive website verification, in one MCP server. No API keys needed.
Project-URL: Homepage, https://github.com/Raffaele86/local-leads-mcp
Project-URL: Repository, https://github.com/Raffaele86/local-leads-mcp
Project-URL: Issues, https://github.com/Raffaele86/local-leads-mcp/issues
Author-email: Raffaele Nocera <info@raffaelenocera.com>
License-Expression: MIT
License-File: LICENSE
Keywords: ai-agents,claude,lead-generation,local-business,mcp,openstreetmap,prospecting
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Internet :: WWW/HTTP :: Indexing/Search
Requires-Python: >=3.10
Requires-Dist: httpx>=0.27.0
Requires-Dist: mcp>=1.2.0
Description-Content-Type: text/markdown

# local-leads-mcp

**Find local businesses that need a website — and prove it — from your AI agent.**

One MCP server that discovers local businesses via OpenStreetMap and then *verifies* them with the checks that separate a real lead list from a pile of false positives. Built for freelancers and agencies that use Claude, Cursor or any MCP client for prospecting.

**No API keys required** for the core workflow: discovery, website verification, email deliverability check and weak-site scoring all run on free, open infrastructure (Overpass, Nominatim, DNS-over-HTTPS, plain HTTP).

## Why this and not a maps scraper?

The hard part of local prospecting isn't getting a list of businesses — it's not embarrassing yourself. Lead lists built from raw map data are full of traps this server checks for explicitly:

- **"No website" that isn't.** OSM data can be stale; a missing `website` tag proves nothing. `verify_website` checks apex *and* www *and* redirects (an apex domain that doesn't resolve while the site lives happily on `www.` is a classic false "no website"), and `confirm_no_website` uses a web search as the final word.
- **A Facebook page is not a website.** Social profiles, booking aggregators (Fresha, TheFork, Treatwell…), directory listings and free subdomains (`*.wixsite.com`, `*.business.site`…) are classified as `not_own_site`, not as "has a website".
- **Emails that bounce.** `check_mx` predicts deliverability before you ever write to a lead (no MX = guaranteed bounce; PEC-only domains are flagged).
- **"The site is bad" needs evidence.** `score_website` returns citable issues (no HTTPS, no mobile viewport, missing title/meta/H1, no sitemap…), not vibes — optionally with Lighthouse scores via the PageSpeed API.

Every verdict ships with the raw checks that produced it, so your agent can show its work.

## Quickstart (60 seconds)

```json
{
  "mcpServers": {
    "local-leads": {
      "command": "uvx",
      "args": ["local-leads-mcp"]
    }
  }
}
```

That's it — no credentials. Then ask your agent things like:

> Find 20 restaurants in Turin with no website, verify each one, and give me a CSV of the confirmed ones with a phone number.

### Optional environment variables

| Variable | Enables |
|---|---|
| `BRAVE_API_KEY` | `confirm_no_website` via Brave Search API |
| `GOOGLE_CSE_API_KEY` + `GOOGLE_CSE_CX` | `confirm_no_website` via Google Programmable Search |
| `PAGESPEED_API_KEY` | Lighthouse scores inside `score_website` |

## Tools

### Discovery (OpenStreetMap — no key)
- `find_businesses(area, category, website_filter, phone_prefix, require_phone, limit)` — businesses in a city/district, filtered by website presence. ~35 friendly categories plus any raw OSM `key=value` tag.
- `list_categories()` — the category → OSM tag map.

### Verification (no key)
- `verify_website(domain_or_url)` — verdicts: `live_own_site`, `not_own_site`, `domain_exists_no_site`, `no_website_found`; includes per-URL evidence.
- `check_mx(domain)` — email deliverability pre-check via DNS-over-HTTPS.

### Qualification (no key; PageSpeed optional)
- `score_website(url)` — 0–100 weak-site score with named issues + CMS/tech detection (WordPress, Wix, Shopify, …).

### Confirmation (needs a search key)
- `confirm_no_website(business_name, city)` — the final word on "really no website?", classifying search results into own-site candidates vs listings/socials.

### Export
- `export_leads(leads_json, format)` — CSV, JSON or Markdown table.

## Ethics & fair use

- Data sources are public: OpenStreetMap (© OSM contributors, [ODbL](https://www.openstreetmap.org/copyright)), public DNS, and the businesses' own public pages.
- OSM requests are rate-limited locally (min 1 s between calls) and carry a descriptive User-Agent, per the [Nominatim](https://operations.osmfoundation.org/policies/nominatim/) and Overpass usage policies. For heavy workloads, run your own Overpass instance.
- This server **discovers and verifies** — it does not scrape personal emails and it does not send anything. How you contact a business is on you: follow your local rules (GDPR and friends).

## License

MIT.

---

Built by [Raffaele Nocera](https://raffaelenocera.com) — web consulting for local businesses. If this tool helps you win a client, I'd love to [hear about it](https://github.com/Raffaele86/local-leads-mcp/discussions).
