Metadata-Version: 2.4
Name: brasil-mcp-leads
Version: 0.3.0
Summary: MCP stdio client for the Brasil MCP Leads API. B2B lead generation (CNPJ + enrichment via scraping + LLM summaries) from your Claude Desktop / Claude Code. Bring-your-own LLM via MCP Sampling.
Project-URL: Homepage, https://github.com/brasil-mcp/leads
Project-URL: Repository, https://github.com/brasil-mcp/leads
Project-URL: Issues, https://github.com/brasil-mcp/leads/issues
Author: Brasil MCP
License: MIT
License-File: LICENSE
Keywords: b2b,brasil,client,cnpj,leads,lgpd,mcp
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Natural Language :: Portuguese (Brazilian)
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27
Requires-Dist: mcp>=1.0.0
Description-Content-Type: text/markdown

# brasil-mcp-leads

[![PyPI](https://img.shields.io/pypi/v/brasil-mcp-leads.svg)](https://pypi.org/project/brasil-mcp-leads/)
[![Python](https://img.shields.io/pypi/pyversions/brasil-mcp-leads.svg)](https://pypi.org/project/brasil-mcp-leads/)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![CI](https://github.com/brasil-mcp/leads/actions/workflows/ci.yml/badge.svg)](https://github.com/brasil-mcp/leads/actions/workflows/ci.yml)

**MCP stdio client for the Brasil MCP Leads B2B lead-generation API.**

> **Privacy-first lead gen.** Enrich Brazilian CNPJs (RFB base + opt-in site
> scrape + tier-1/2/3 LLM summaries) from your Claude Desktop / Claude Code,
> bring-your-own LLM via MCP Sampling, credit-billed, LGPD-compliant.

## Repo layout — this is a split repo

Two pieces, two licenses, one repo:

| Path | License | Purpose |
|---|---|---|
| [`src/brasil_mcp_leads/`](src/brasil_mcp_leads) | **MIT** | Published to PyPI as `brasil-mcp-leads`. MCP stdio client + `httpx` wrapper for the REST API. **What end users install.** |
| [`server/`](server) | **AGPL-3.0-or-later** | Operator-side code. FastAPI REST API + asyncpg + Asaas billing + site scraper + LLM fallback. **NOT published to PyPI** — self-hosters clone this repo and run from `server/`. See [server/README.md](server/README.md). |

This split happened in v0.3.0. Up to and including v0.2.0 the PyPI package
shipped the server. From v0.3.0 onward the PyPI package ships only the thin
HTTP client. See [CHANGELOG.md](CHANGELOG.md) for the migration story.

---

## Quickstart (client)

### 1. Install (or just `uvx` it)

```bash
uv tool install brasil-mcp-leads
# or run on demand:
uvx brasil-mcp-leads
```

### 2. Configure your MCP client

Claude Desktop (`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "brasil-mcp-leads": {
      "command": "uvx",
      "args": ["brasil-mcp-leads"],
      "env": {
        "BRASIL_MCP_LEADS_URL": "https://server.solidapps.tech/brasil-mcp/leads",
        "BRASIL_MCP_LEADS_KEY": "your-api-key-here"
      }
    }
  }
}
```

Claude Code (`.claude/settings.local.json` or via `claude mcp add`):

```bash
claude mcp add brasil-mcp-leads \
  --env BRASIL_MCP_LEADS_URL=https://server.solidapps.tech/brasil-mcp/leads \
  --env BRASIL_MCP_LEADS_KEY=your-api-key-here \
  -- uvx brasil-mcp-leads
```

### 3. Sign up via MCP (no key yet — v0.3.0+)

`BRASIL_MCP_LEADS_KEY` is OPTIONAL. The signup tools (`request_api_key` and
`check_signup_status`) and `health` work without a key. The lookup tools
(`lookup_lead` / `bulk_lookup_leads` / `sample_leads`) return a
`MISSING_API_KEY` envelope until a key is configured.

Typical first-run dialogue from inside Claude:

```
You: I want to get a Brasil MCP Leads key. Use the free plan.
Claude (calling request_api_key(email="me@example.com", plan="free")):
   Here's your API key: brmcpleads_xxx...
   CRITICAL: Store this api_key NOW — it will NOT be returned again.
   Add it as BRASIL_MCP_LEADS_KEY in your MCP client config and restart.
```

For paid plans (`hobby` / `starter` / `pro`) the tool returns an Asaas
`checkout_url` and a `polling_token`. Open the URL in your browser, pay
(Asaas hosts the card capture), then call `check_signup_status(polling_token)`
to retrieve the key (also emailed to you as backup).

After saving the key in your MCP client config (e.g.
`claude_desktop_config.json` → `env.BRASIL_MCP_LEADS_KEY`), restart the
client to enable the lookup tools.

## Environment variables

| Var | Required | Default | Description |
|---|---|---|---|
| `BRASIL_MCP_LEADS_URL` | yes | — | Base URL of the Leads REST API (no trailing path) |
| `BRASIL_MCP_LEADS_KEY` | optional (required only for lookup tools) | — | API key, sent as `Authorization: Bearer <key>`. Without it, `lookup_lead`/`bulk_lookup_leads`/`sample_leads` return `MISSING_API_KEY` envelopes; `health` and the signup tools (`request_api_key`, `check_signup_status`) still work, so the unconfigured client is exactly the path users follow to self-serve a key. |
| `BRASIL_MCP_LEADS_TIMEOUT` | no | `30` | HTTP timeout in seconds (leads queries are slow: scrape + summary) |

## Tools exposed (6)

### Signup (no API key required)

- **`request_api_key(email, plan="free", cpf_cnpj?)`** — start a self-service
  signup. Free → returns the API key inline (1 key per email lifetime).
  Paid (`hobby` / `starter` / `pro`) → returns an Asaas `checkout_url` +
  `polling_token`; pay, then poll `check_signup_status`.
- **`check_signup_status(polling_token)`** — poll the paid-flow signup. Returns
  `{status:'pending'}` while waiting on Asaas, `{status:'paid', api_key, plan,
  warning}` on first call after payment (STORE_KEY_NOW — the key is also
  emailed as a backup), or `{status:'delivered'}` on subsequent polls. 410
  `SIGNUP_EXPIRED` if the polling token has aged out.

### Lookup (requires `BRASIL_MCP_LEADS_KEY`)

- **`lookup_lead(cnpj, deliver?, website_url?)`** — single-CNPJ lookup.
  `deliver` controls base / scrape / summary tier; returns a `LeadResponse`
  envelope (empresa, endereco, cnae, contacts_base, contacts_scraped, summary,
  charged_credits, delivered_skus, credit_balance).
- **`bulk_lookup_leads(cnpjs, deliver?)`** — batch lookup (up to 1000 CNPJs).
  Partial failures contained per-item: each result is `{cnpj, result}` or
  `{cnpj, error}`. Use to enrich existing lists.
- **`sample_leads(n, filters?, deliver?, exclude_already_sold=True, randomize=True)`**
  — filter-based discovery (CNAE / UF / município / porte / capital social /
  data abertura / has_email / has_corporate_email / has_whatsapp_cached /
  has_summary_min_tier). Use to discover net-new CNPJs matching your ICP.
- **`health()`** — server version + DB ping. Public, no API key needed.

## Credits & pricing

| Plan | Price (BRL/month) | Credits | Overage cap |
|---|---|---|---|
| free | 0 | 50 lifetime | — |
| hobby | 50 | 100 | 2× monthly fee |
| starter | 125 | 500 | 2× monthly fee |
| pro | 187.50 | 1000 | 2× monthly fee |

- 1 credit per CNPJ delivered with base / base+scrape / base+scrape+summary
  via caller-LLM (MCP Sampling).
- 2 credits when the summary is sourced from our fallback LLM or the cache.
- Re-deliveries within the 30-day idempotency window are free.

## Error envelope

Network/HTTP failures become a JSON envelope so tool callers always see the
same shape:

```json
{ "error": { "code": "UPSTREAM_TIMEOUT", "message_pt": "...", "message_en": "..." } }
```

Codes added by this client:

- `UPSTREAM_TIMEOUT` — Leads server didn't respond within `BRASIL_MCP_LEADS_TIMEOUT`.
- `UPSTREAM_NETWORK` — connection refused, DNS failure, TLS handshake error.
- `UPSTREAM_BAD_RESPONSE` — Leads server returned non-JSON or unexpected shape.
- `MISSING_API_KEY` — `BRASIL_MCP_LEADS_KEY` not configured (query tools only).

All other codes come straight from the upstream Leads API:
`CNPJ_NOT_COVERED` (404), `OPT_OUT_BLOCKED` (451), `PAYMENT_REQUIRED` (402),
`QUOTA_EXHAUSTED` (429), `SUMMARY_UNAVAILABLE` (503), `MATCH_AUTH_ERROR` (500),
`MATCH_UNAVAILABLE` (503), `MISSING_TOKEN` / `INVALID_TOKEN` (401),
`RATE_LIMITED` (429).

## Privacy

- The only data that leaves your machine is the CNPJ + the `deliver` flags +
  (when `filters` are supplied) the ICP criteria. No PII inputs from your side.
- LGPD opt-out is propagated from the upstream Match base — opted-out CNPJs
  return `OPT_OUT_BLOCKED` with a 451 status.
- Your `BRASIL_MCP_LEADS_KEY` is sent only as the `Authorization: Bearer`
  header against `BRASIL_MCP_LEADS_URL`. Never logged.
- All HTTPS, no plaintext fallback.
- See the upstream
  [brasil-mcp-match privacy contract](https://github.com/brasil-mcp/match#privacy)
  for the underlying RF base posture.

## Self-hosting the server

If you want to run your own Leads deployment instead of consuming a hosted
one, see [server/README.md](server/README.md). The server is
AGPL-3.0-or-later; running a public-facing instance triggers the
source-availability obligation.

## License

This published package (`src/brasil_mcp_leads/`) is **MIT**. See [LICENSE](LICENSE).

The server side ([`server/`](server)) is **AGPL-3.0-or-later** — see
[server/LICENSE](server/LICENSE).

The MIT license on the client is intentional: it lets you embed the stdio
client in proprietary stacks while the AGPL server protects the operator-side
work from being relicensed downstream.

## Related

- [brasil-mcp/essentials](https://github.com/brasil-mcp/essentials) — Fase 1, MIT.
- [brasil-mcp/match](https://github.com/brasil-mcp/match) — Fase 2, privacy-preserving CNPJ verification.
