Skip to main content
Glama
AyaanKhan0111

linkedin-discovery-mcp

README.md
# linkedin-discovery-mcp

An MCP (Model Context Protocol) server that discovers public LinkedIn profiles matching
natural-language criteria — e.g. *"senior backend engineers in Berlin who know Kotlin,
not interns"* — and returns a ranked shortlist with match reasoning.

It works entirely through **public search snippets** (via DuckDuckGo). It never logs
into LinkedIn, never automates a LinkedIn session, and never touches any LinkedIn
account — so there's no LinkedIn ban risk. The trade-off is shallow data (name,
best-effort headline/company/location, profile URL — no full work history, no contact
info) and dependence on an unofficial, unauthenticated search backend that can rate-limit
or block bursty traffic.

See **[SETUP.md](./SETUP.md)** for install steps, MCP client configuration (Claude
Desktop, Claude Code, Antigravity), and known limitations — including a real rate-limit
caveat worth reading before assuming this scales to high daily volume.

## How it works

1. An MCP client (Claude, etc.) parses your prompt into structured criteria
   (`role_keywords`, `skills`, `location`, `company`, `seniority`, `exclude_terms`, ...)
   and calls the `search_linkedin_profiles` tool.
2. `src/searchProfiles.ts` builds a `site:linkedin.com/in` query and fetches paginated
   results from DuckDuckGo (`src/duckduckgo.ts`), with a polite delay between pages and
   local caching to avoid redundant fetches.
3. `src/parse.ts` filters out non-profile URLs, parses name/headline/company/location
   from the snippet text, scores each candidate against your criteria, and ranks them.
4. Results are returned as structured JSON, along with a self-imposed daily
   request-budget status (`get_search_quota_status`) so usage stays predictable.

## Quick start

```bash
npm install
npm run build
```

Then follow [SETUP.md](./SETUP.md) to connect it to your MCP client.

## Project layout

```
src/
  config.ts          # env-driven config (request pacing, cache, budget)
  duckduckgo.ts       # DuckDuckGo HTML search fetch + parse
  quota.ts            # self-imposed daily request budget, persisted to disk
  cache.ts            # local result cache (avoids re-fetching identical searches)
  parse.ts            # snippet parsing + relevance scoring
  searchProfiles.ts    # orchestrates search -> filter -> rank
  types.ts            # shared types
  index.ts            # MCP server entry point (stdio transport, tool definitions)
```

## Limitations (read before relying on this)

- Discovery only, not enrichment: no emails, phone numbers, or full profiles.
- DuckDuckGo's LinkedIn index is smaller and staler than Google's.
- DuckDuckGo will rate-limit/block bursty traffic — see the rate-limit section in
  SETUP.md for what was actually observed during testing and how to work around it.
- Currently stdio-only, so it plugs into Claude Desktop, Claude Code, and Antigravity,
  but **not** ChatGPT or any client that requires a remote HTTP MCP server.

TDQS

A4.4/5.0

Scored across 2 tools

Disambiguation5/5

The two tools have clearly distinct purposes: one performs profile searches, the other reports quota status. There is no overlap or ambiguity between them.

Naming Consistency5/5

Both tools follow the verb_noun snake_case pattern (search_linkedin_profiles, get_search_quota_status). The naming is consistent and predictable.

Tool Count3/5

With only 2 tools, the server is on the thin side. The narrow scope (search + quota) makes it reasonable, but it feels minimal for a discovery-focused server.

Completeness3/5

The core search capability is present, but there are notable gaps: no way to fetch a specific profile's details, no explicit pagination, and no advanced filters beyond search criteria. The quota tool is a helpful addition but doesn't round out the surface.

Maintenance

ActivitySlowing
ResponsivenessNo issues