Pre-Black Friday: 20% off, for as long as you stayEARLYBFon Solo and AgencyEnds Nov 28Start free

How-to guide

How to Pull LinkedIn Profile Data With an MCP Server (Claude and REST)

A database call instead of a scraper. Size the list for free, then enrich by LinkedIn URL.

Get your free API key →Free to start. No credit card. 1,000 records to spend whenever you like.

TL;DR

  • You do not scrape LinkedIn. You ask a people database, over MCP or REST, for profiles you can match by LinkedIn URL, title or company.
  • It takes about 15 minutes. Counting is free. Each profile you enrich or search result you receive spends 1 LeadOcean record, so the walkthrough spends about 3.
  • LeadOcean returns profile and career data. It does not return LinkedIn posts, comments or reactions. If you need post data, you need a different tool.

Prerequisites

  • A LeadOcean account on the Free plan: 1,000 records for life, no card, 5 requests a second. Sign up here.
  • For the REST steps: an API key exported as $LEADOCEAN_API_KEY, and curl.
  • For the MCP steps: Claude Desktop, Claude Code or any client that supports remote MCP with OAuth. The server URL is https://api.leadocean.io/mcp. You sign in with OAuth and paste no key.

Step 1: Connect the MCP server

Add LeadOcean as a remote MCP server. In Claude Code:

bash
claude mcp add --transport http leadocean https://api.leadocean.io/mcp

Your client opens an OAuth sign-in. Approve it. The server exposes 13 tools. Seven cost nothing: leadocean_count_leads, leadocean_count_companies, leadocean_list_filters, leadocean_list_enum_values, leadocean_get_account, leadocean_get_export and leadocean_list_exports. search_leads, get_lead, find_phone, get_company, search_companies and export_leads spend records.

Step 2: Size the audience for free

Ask before you pull. A count never spends a record.

text
Use leadocean_count_leads: jobLevel VP, jobFunction "Sales & Business Development",
country CA. Do not fetch any people.

The tool call behind that prompt:

json
{
  "jobLevel": ["VP"],
  "jobFunction": ["Sales & Business Development"],
  "country": ["CA"],
  "facets": false
}

Enum values are exact strings. If a filter returns nothing, ask leadocean_list_enum_values for the right spelling before you guess.

Step 3: Pull the profiles

Now ask for a small page. This spends records, so keep the limit low while you test.

text
Use leadocean_search_leads with the same filters and limit 2.
Show name, title, company and LinkedIn URL.

The REST equivalent. The body is flat JSON and filters are arrays:

bash
curl -s https://api.leadocean.io/v1/people/search \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "jobLevel": ["VP"],
    "jobFunction": ["Sales & Business Development"],
    "country": ["CA"],
    "limit": 2
  }'

Search pages with cursor, at 1 to 100 rows a page. One search pages to 10,000 rows. Narrow the filters instead of walking further.

Step 4: Enrich one LinkedIn URL

You already have a profile URL and want the record behind it. Enrich takes exactly one of linkedin_url, email, phone or person_id.

bash
curl -s https://api.leadocean.io/v1/people/enrich \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "linkedin_url": "https://www.linkedin.com/in/jane-doe-example",
    "reveal_email": true
  }'

A person we hold nothing for returns 404 and costs nothing. Since October 2026 the response also carries career history under resume_data: past roles, educations, certifications and awards, each when held. Past employers have no company_id yet.

In Claude, say: "Use leadocean_get_lead on this LinkedIn URL and summarize the last three roles." That call costs 1 record if a profile is found and nothing if not.

Step 5: Add a phone number, only if you need it

Phones are a separate call: GET /v2/people/phone. A v2 contact call costs one record even when it finds nothing, so enrich first and ask for a phone only on the people who matter.

bash
curl -s "https://api.leadocean.io/v2/people/phone?linkedin_url=https%3A%2F%2Fwww.linkedin.com%2Fin%2Fjane-doe-example" \
  -H "x-api-key: $LEADOCEAN_API_KEY"

The endpoint takes one of linkedin_url, person_id or contact_id as a query parameter. It returns the numbers best first, each with phone and type, or found: false.

Step 6: Export the whole list

When the count looks right, export instead of paging. Exports take up to 50,000 rows a request and 500,000 a day. Bulk CSV export is not on Free, so this step needs Solo ($97 a month) or higher.

bash
curl -s https://api.leadocean.io/v1/exports \
  -H "x-api-key: $LEADOCEAN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": {
      "jobLevel": ["VP"],
      "jobFunction": ["Sales & Business Development"],
      "country": ["CA"]
    },
    "limit": 5000
  }'

The export body nests the search filters under filters, with limit beside them. Every row costs one record.

You can also do this from app.leadocean.io: the Exports page has a filter builder, a column picker and a price preview before you download the CSV.

What you get

This is the real output of the free count in Step 2, run on 2026-10-21:

json
{
  "total": 5574,
  "totalIsExact": true,
  "totalAll": 18800,
  "distinctCompanies": 3873,
  "credits": 0
}

Read it carefully. total counts people with a verified, catch-all-valid or catch-all email, the default. totalAll is the same filters with no email condition. The call spent 0 records.

The enrich response has this outline. Response shape from the API reference, with placeholder values:

json
{
  "success": true,
  "data": {
    "profile_data": { "profile_full_name": "Jane Doe" },
    "contact_data": {
      "has_email": true,
      "email_status": "verified",
      "contact_current_experiences": [ { "company_name": "Acme" } ]
    },
    "resume_data": { "experiences": [], "educations": [] }
  }
}

The current role sits in contact_current_experiences[]. Past roles sit in resume_data, each when held. Fetch api.leadocean.io/openapi.json once and map the fields you need.

Troubleshooting

ErrorCauseFix
401Missing or wrong x-api-key, or the MCP sign-in expiredRe-export $LEADOCEAN_API_KEY or re-run the OAuth sign-in
429Above the plan's rate limit (5 a second on Free, 200 on Agency)Wait for the Retry-After header, or slow the loop
402The 1,000 free records are spentMove to Solo or Agency; a 402 costs nothing
404 on enrichWe hold nothing for that personNothing to fix and nothing charged; try the email or person_id
Empty resultsAn enum value is misspelled, for example vp instead of VPLook it up with leadocean_list_enum_values
Export refusedOver 50,000 rows a request or 500,000 a day, or you are on FreeNarrow the filters, split the job, or upgrade

FAQ

Can LeadOcean scrape LinkedIn posts?

No. It does not return posts, comments or reactions. It returns profile, role, company and contact data from its own database.

Is this a scraper?

No. Nothing is fetched from LinkedIn when you call it. The dataset is refreshed monthly and each record carries its own fetched_at date.

How many records does the walkthrough spend?

About 3: two search results and one enrichment. Counts and filter lookups spend none.

Which LinkedIn lookups already have a recipe?

Going from a profile to an email is covered in LinkedIn to email over MCP. The reverse is email to LinkedIn over MCP.

Where do I compare scraper tools?

See the LinkedIn scraper roundup. For plans and pacing, see pricing.

Pull LinkedIn profile data without running a scraper

Free to start. No credit card. 1,000 records to spend whenever you like.

Get your free API key →