Skip to main content
Glama
Yadukrishnan117

72bpm-leadgen-mcp-server

README.md
# 72BPM Lead-Gen MCP Server

An MCP server that turns discovery → enrichment → scoring → outreach into
callable tools, scoped to 72BPM's four practice areas:

- **SaaS Product Development**
- **E-mobility (EV) Applications & Infrastructure**
- **IoT Platforms**
- **AI Agent Creation**

## Why no LinkedIn API/scraper?

LinkedIn's Terms of Service prohibit automated scraping, and LinkedIn
actively detects and blocks it — both technically (rate limits, IP bans) and
legally. Rather than build something that breaks on day one and creates
legal exposure, this server:

- Crawls **companies' own public websites** directly (careers pages, blog
  posts, about pages) — fully fair game, standard practice.
- Uses a **real search engine (Brave Search API)** to read back publicly
  indexed snippets — including of LinkedIn company/people pages — the same
  way a human researcher googling `site:linkedin.com/company acme` would.
  This is a search-engine query, not a scrape of linkedin.com itself.
- Reads **public job postings** the same way.

If your team later gets access to LinkedIn's official Talent/Sales
Navigator API (via their Partner Program) or a compliant data provider,
swap `src/services/searchProvider.ts` — every tool depends only on that
one file's `webSearch()` function.

## Tools

| Tool | Purpose |
|---|---|
| `leadgen_discover_companies` | Search-based candidate discovery for one category + region |
| `leadgen_enrich_company` | Crawl a company's site + indexed LinkedIn/job signal, matched against all 4 categories |
| `leadgen_score_lead` | Weighted 0-100 fit score + tier (hot/warm/cold) + confidence for one category |
| `leadgen_find_contact` | Search-based candidate engineering contact (CTO/VP Eng/etc.) — **unverified**, always double-check before outreach |
| `leadgen_generate_pitch` | Drafts 2 outreach email variants using the value-lead framework |
| `leadgen_save_lead` / `leadgen_list_leads` / `leadgen_update_lead` | Simple pipeline tracking (JSON file by default) |

Typical workflow: `discover` → `enrich` → `score` → `find_contact` →
`generate_pitch` → `save_lead`, then `update_lead` as deals progress.

## Setup

```bash
npm install
cp .env.example .env
# edit .env and set BRAVE_API_KEY (free tier: https://brave.com/search/api/)
npm run build
```

### Run locally (stdio) — for Claude Desktop / Claude Code

```bash
npm start
```

Add to your Claude Desktop / Claude Code MCP config:

```json
{
  "mcpServers": {
    "72bpm-leadgen": {
      "command": "node",
      "args": ["/absolute/path/to/72bpm-leadgen-mcp-server/dist/index.js"],
      "env": {
        "BRAVE_API_KEY": "your-key-here"
      }
    }
  }
}
```

### Run as a hosted server (streamable HTTP) — for team-wide access

```bash
TRANSPORT=http PORT=3000 npm start
# or: npm run start:http
```

Exposes `POST /mcp` (the MCP endpoint) and `GET /health`. Point your
team's MCP clients at `https://your-host/mcp`. Deploy behind your normal
reverse proxy/TLS termination — this server does not handle auth itself,
so put it behind your existing auth layer if exposing it beyond your VPN.

## Customizing the ICP signals

`src/constants.ts` holds the weighted signal dictionary per category
(`ICP_SIGNALS`). These are the phrases the scoring engine looks for and how
many points each is worth. Tune them as you learn what actually converts —
e.g. if "battery swapping" mentions never turn into real deals, drop its
weight; if a new signal phrase keeps showing up in your best deals, add it.

Tier thresholds (`tierFromScore`) and confidence thresholds
(`confidenceFromSourceCount`) live in the same file.

## Customizing outreach voice

`src/tools/pitch.ts` has one `AUTHORITY_LINES` entry per category — the
"parallel domain authority" sentence 72BPM's pitches lean on. Edit these to
match your team's actual case studies as they accumulate; specific,
verifiable claims outperform generic ones.

## Known limitations (by design, not oversights)

- **No paid enrichment APIs** (Apollo/Clearbit/Crunchbase/BuiltWith) —
  you said you don't have those yet. The signal quality here is real but
  bounded by what's publicly crawlable. If you add API keys later, this is
  the natural next upgrade — add a new `services/` client and feed its text
  into `matchSignals()` alongside the site crawl.
- **Contact finding is unverified** — `leadgen_find_contact` parses search
  snippet text, which is sometimes ambiguous. It's a research shortcut, not
  a verified contact database. Always confirm before sending outreach.
- **Pipeline storage is a JSON file** — fine for one person or a small team
  running the stdio server locally. For the hosted HTTP deployment with
  multiple concurrent users, swap `src/services/storage.ts` for a real
  database (Postgres/SQLite) — every other tool only depends on the four
  functions that file exports.
- **Brave Search rate limits** apply — the free tier is fine for exploration
  but will need a paid tier for high-volume prospecting.

## Project structure

```
src/
├── index.ts              # Entry point, dual transport (stdio/HTTP)
├── constants.ts           # ICP signal weights, category labels, thresholds
├── types.ts                # Shared TypeScript types
├── services/
│   ├── searchProvider.ts   # Brave Search API wrapper (swap for another provider here)
│   ├── webCrawler.ts        # Company-site crawler (robots.txt-aware)
│   ├── companyIntel.ts       # Combines crawl + search into cached text bundles
│   ├── scoring.ts             # Weighted signal matching + scoring
│   └── storage.ts              # JSON-file lead pipeline (swap for a DB for hosted use)
└── tools/
    ├── discover.ts
    ├── enrich.ts
    ├── score.ts
    ├── contact.ts
    ├── pitch.ts
    └── pipeline.ts
```

TDQS

A4.6/5.0

Scored across 8 tools

Disambiguation5/5

Each tool has a distinct phase in the lead-gen workflow: discover finds candidates, enrich profiles a company, score quantifies fit, find_contact locates people, generate_pitch writes emails, and save/list/update manage the pipeline. Even the similar enrich vs. score are clearly differentiated by multi-category vs. single-category output.

Naming Consistency5/5

All tools follow the exact pattern leadgen_<verb>_<noun> with clear, consistent verbs (discover, enrich, score, find, generate, save, list, update). The prefix unifies the namespace and the verb_noun structure makes each tool's purpose predictable.

Tool Count5/5

8 tools is well-scoped for a specialized lead-generation workflow. Each tool covers a necessary step without redundancy or bloat, and the count is within the ideal range for a focused MCP server.

Completeness4/5

The lifecycle is nearly complete: discovery, enrichment, scoring, contact finding, pitch generation, and pipeline CRUD (save/list/update). The only notable gap is the absence of a delete/archive tool for leads, though the status field can handle disqualification, so agents can work around this.

Maintenance

ActivitySlowing
ResponsivenessNo issues