Skip to main content
Glama
AyaanKhan0111

linkedin-discovery-mcp

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 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.

Related MCP server: LinkedIn MCP Server

Quick start

npm install
npm run build

Then follow 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.

Available Tools

2 tools
get_search_quota_statusA

Reports how much of today's self-imposed DuckDuckGo request budget has been used and how much remains. Check this before large search batches so you don't burn budget you need later in the day.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden. It discloses that the budget is self-imposed and resets daily ('today's'), and implies a non-destructive read. It doesn't detail output format or potential side effects, but for a status check, the key behaviors are covered.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two sentences, front-loaded with the primary action and outcome, followed by a practical usage tip. No wasted words or redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-parameter, no-output-schema tool, the description fully conveys what it reports (usage and remaining) and when to use it (before large batches). The complexity is low, and the description leaves no major gaps.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool has zero parameters, so the schema already exhaustively covers all inputs. The description adds no parameter meaning, but with no parameters present, this is appropriate. Baseline of 4 is warranted.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses the specific verb 'Reports' and clearly identifies the resource: today's self-imposed DuckDuckGo request budget. It distinguishes itself from the sibling tool search_linkedin_profiles by indicating this is a monitoring/status tool rather than a search tool.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says to check before large search batches, providing clear context on when to use. It doesn't mention when not to use or alternative tools, but the context is sufficient for a simple status tool with no direct alternatives.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_linkedin_profilesA

Discover public LinkedIn profiles matching the given criteria, via DuckDuckGo's public search (site:linkedin.com/in). Does NOT log into or scrape LinkedIn directly, so it carries no LinkedIn account risk. Returns ranked candidates with name/headline/company/location best-effort parsed from search snippets, plus a match_score and matched_signals showing why each candidate ranked where it did. Data is shallow (no full work history, no contact info) — treat results as a shortlist to verify manually, not verified enriched profiles. DuckDuckGo's LinkedIn index is smaller than Google's, so narrow criteria can come back with few or zero results — broaden them if that happens. Paced by a self-imposed daily request budget to stay polite to DuckDuckGo.

ParametersJSON Schema
NameRequiredDescriptionDefault
skillsNoSkills/technologies, e.g. ["Kotlin", "Go"]
companyNoTarget company name
industryNoIndustry keyword
locationNoLocation text, e.g. "Berlin" or "Greater New York City Area"
free_textNoAny additional raw search text to append to the query
seniorityNoSeniority term, e.g. "Senior", "Lead", "Director"
max_resultsNoMax candidates to return (default 20, hard cap 50 per call to protect the daily request budget)
exclude_termsNoTerms that disqualify a result if present, e.g. ["Intern", "Recruiter"]
role_keywordsYesJob titles/roles to match, e.g. ["Backend Engineer", "Software Engineer"]

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It transparently explains the mechanism (DuckDuckGo search, not direct scraping), the no-account-risk aspect, the shallow data depth, the return structure (match_score, matched_signals), and the self-imposed daily request budget. This goes well beyond a simple search description.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is moderately long but every sentence contributes value, covering purpose, limitations, and request budget. It is front-loaded with the primary function and does not waste words. The length is justified by the tool's complexity and the absence of annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool has 9 parameters, no output schema, and no annotations, the description provides a thorough context: return shape (name/headline/company/location, match_score, matched_signals), data limitations, search engine caveats, and advice on result counts. It is sufficiently complete for an agent to decide and invoke the tool appropriately.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The schema provides 100% description coverage for all 9 parameters, so the baseline is 3. The description does not add significant meaning beyond the schema, though it does provide context for max_results via the daily request budget and mentions the ranked output quality.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool discovers public LinkedIn profiles via DuckDuckGo's public search, using a specific verb and resource. It also distinguishes itself from sibling tools by explicitly noting it does not log into or scrape LinkedIn directly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides clear context on when to use the tool (discovering public LinkedIn profiles) and when not to rely on it (needs verified enriched profiles or full work history). It also advises broadening criteria if few results are returned. However, it does not explicitly name an alternative tool, only suggests manual verification.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 2 tool updatesv0.1.0
    • First observedget_search_quota_status
    • First observedsearch_linkedin_profiles

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

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    Not graded
    maintenance
    Enables direct access to LinkedIn through natural conversation, allowing users to search for people, jobs, companies, and groups, as well as view profiles using their existing Chrome browser session.
    11 npm
    -
  • A
    license
    A
    quality
    F
    maintenance
    Enables searching and scraping of LinkedIn for structured data on people, companies, and job listings. It allows AI clients to retrieve detailed profiles, experience, and activity sections using browser automation.
    7
    185
    MIT
  • A
    license
    Not graded
    quality
    F
    maintenance
    Enables LLMs to search for LinkedIn profiles and retrieve detailed profile information via the LinkedIn API, supporting secure OAuth2 authentication.
    85 npm
    52
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables natural language interaction with LinkedIn, including profile retrieval, job searching, messaging, and post engagement.
    3
    Apache 2.0