Back to Home

Developers

MCP Server

Radar Leads exposes a Model Context Protocol (MCP) server, so any MCP-compatible AI agent — Claude, ChatGPT, Cursor, Windsurf and others — can search 100M+ B2B contacts, reveal business emails and phone numbers, manage lead lists and export CSVs on your behalf.

View as Markdown

Requirements

MCP access is available on every account, including free accounts, so you can try it with your 5,000 free leads. ChatGPT and Claude connect by signing in to your account; other tools use an API key from the AI Agent page in your dashboard (up to five active keys, each revocable instantly). Free accounts can run up to 10 searches a minute (200 a day) through an agent; paid plans remove those limits.

Connecting

The server speaks streamable HTTP MCP at https://radarleads.io/api/mcp.

ChatGPT and Claude: add a custom connector with that address. You'll be asked to sign in to Radar Leads and allow access, with no key to copy. Connected apps are listed on the AI Agent page, where you can disconnect them at any time.

Other tools (Cursor, Windsurf, Claude Code...): authenticate with an API key as a bearer token. Add the following to your agent's MCP configuration:

mcpServers:
  radarleads:
    url: https://radarleads.io/api/mcp
    headers:
      Authorization: "Bearer YOUR_API_KEY"

Every request must carry Authorization: Bearer <your-api-key>. Requests without a valid key or sign-in are rejected with 401. Every call is scoped to your own organisation.

Tools

Searching is always free — you only spend credits when you reveal a lead, at 1 credit per newly revealed contact. Leads your organisation has already revealed are free forever.

search_leadsFree

Search the database and get a total count plus masked previews (names, titles and companies visible; emails and phones hidden). Supports cursor pagination via search_after. Use it to check volume before spending credits.

Arguments: filters, pageSize (1–100, default 25), search_after

reveal_leads1 credit per newly revealed lead

Starts a job that unlocks real contact details for the next N new leads matching your filters. No upper limit: large reveals run in the background on the server in chunks. Leads your organisation already owns are skipped and never charged. Returns a revealJobId immediately.

Arguments: filters (required), n (required, 1 or more), listId (optional)

check_reveal_statusFree

Reports progress and the result of a reveal job. While it returns "processing" (with revealed / requested counts), call it again after a short wait. Contact records are returned inline for reveals of up to 100 leads; export larger ones with export_leads.

Arguments: revealJobId (required)

list_lead_listsFree

Lists every saved lead list for your organisation with lead counts and IDs. Use the returned IDs with reveal_leads or export_leads.

Arguments: none

create_lead_listFree

Creates a new named lead list and returns its ID. List names must be unique within your organisation.

Arguments: name (required)

export_leadsFree (leads must already be revealed)

Starts a CSV export job for a list, or for all owned leads if no list is given. Supports exporting a range. Returns an exportJobId immediately.

Arguments: listId, listName, rangeFrom, rangeTo, customName

check_export_statusFree

Fetches the result of an export job. Returns a download URL once ready. Download URLs expire after 24 hours.

Arguments: exportJobId (required)

enrich_contactsFree

Starts enriching your own contacts: each needs a LinkedIn URL, an email, or a name with the company website. Up to 5,000 per call. Matching is free. Returns an enrichmentJobId immediately.

Arguments: contacts (required), name

check_enrichmentFree

Fetches an enrichment job: match counts and the credit cost for emails, phones or both; when finished, the enriched contacts, a CSV download link and the list they were saved to.

Arguments: enrichmentJobId (required)

reveal_enrichment1 credit per new contact

Reveals matched contacts with a new email (default), a new phone, or both. Contacts you already own are free.

Arguments: enrichmentJobId (required), want, limit, listId

get_creditsFree

Returns your current credit balance broken down by pool: plan credits, rollover credits and purchased extra credits, plus the total available.

Arguments: none

Asynchronous jobs

Both reveal_leads and export_leads start background jobs and return an ID immediately rather than blocking. Follow each with its matching status call — check_reveal_status or check_export_status. Those calls wait briefly server-side, so small jobs resolve on the first check. If one returns status: "processing", simply call it again.

There is no size limit on a reveal. Large reveals are processed on our servers in chunks, so they keep going even if your agent disconnects. Credits are charged chunk by chunk as leads are unlocked, never for leads you already own, and a reveal stops automatically (keeping everything unlocked so far) if your credits run out.

Rate limits

Per organisation, per minute: 60 searches, 30 job starts (reveal, export, enrich and creating lists) and 300 other calls (status checks, lists, credits). Over the limit, a call returns an error with error: "rate_limited" and retryAfterSeconds; wait that long and retry. Reveals and exports also run one at a time per organisation.

Filters

All filters are optional. Different filters are ANDed together; multiple values within one filter are ORed. Field names must match exactly — unrecognised names are ignored silently.

Person

personTitleIncludesstring[]Job title keywords to include. Words within one string are ANDed; multiple strings are ORed.
personTitleExcludesstring[]Job title keywords to exclude.
seniority{ anyOf: string[] }c_suite, vp, director, manager, senior, entry, owner, intern, partner
functionIncludes{ anyOf: string[] }engineering, sales, marketing, finance, operations, human_resources, information_technology, business_development, support, education, consulting
personFirstName / personLastNamestringPartial name match.
personCountry / personState / personCity{ anyOf: string[] }Where the person is physically based.

Company

companyCountry / companyState / companyCity{ anyOf: string[] }Where the company is headquartered. Usually the better choice for B2B targeting.
companyNamestringCompany name partial match.
companyDomainstring[]Company domains without www, e.g. ["stripe.com"].
companyDomainMatchMode"strict" | "contains"Default "strict" (exact domain). "contains" matches substrings.
companySize{ anyOf: string[] }1-10, 11-50, 51-200, 201-500, 501-1000, 1001-5000, 5001-10000, 10001+
companyEmployeeMin / companyEmployeeMaxnumberPrecise headcount range instead of buckets.
companyIndustry{ anyOf: string[] }Industry, using the exact names from the Radar Leads industry filter, e.g. "Computer Software", "Financial Services".
companyKeywordstring[]Keywords matched against name, description and specialties.
companyKeywordMode"broad" | "exact"Default "broad" (all words, any order). "exact" matches the phrase in order.
companySpecialties{ anyOf: string[] }Specialty tags, e.g. "CRM".
technologies{ anyOf: string[] }Tech stack in use, e.g. "Salesforce", "HubSpot".
fundingStage{ anyOf: string[] }seed, series_a, series_b, series_c, series_d, ipo, acquired, bootstrap
annualRevenue / totalFunding{ anyOf: string[] }lt_1m, 1m_10m, 10m_50m, 50m_200m, 200m_1b, gt_1b

Contact availability

hasEmail / hasPhone / hasLinkedinbooleanOnly return leads that have that contact method on file.

Match modes

roleMatchMode"all" | "any"Default "all". Combines personTitleIncludes + seniority + functionIncludes.
companyMatchMode"all" | "any"Default "any". Combines companyName + companyIndustry.

Example filter object

VPs of Sales at US software companies with 51–500 employees and an email on file:

{
  "personTitleIncludes": ["VP of Sales", "VP Sales", "Head of Sales"],
  "seniority": { "anyOf": ["vp"] },
  "companyCountry": { "anyOf": ["United States"] },
  "companySize": { "anyOf": ["51-200", "201-500"] },
  "companyIndustry": { "anyOf": ["Computer Software"] },
  "hasEmail": true
}

Zero results

When a search returns no matches, the response includes a _diagnosis object explaining why. It reports which single filter is most responsible, how many results you would get if it were removed, and whether the filters are merely narrow or actually contradictory — so your agent can suggest a fix rather than simply reporting failure.

Support

Questions about the MCP server or your integration: [email protected]