The Mine Works
← All posts
use-case July 17, 2026 · 11 min read

Sourcing Without a Recruiter Seat: 8 Tools, One Claude Agent, Under $1 a Role

A LinkedIn Recruiter seat costs thousands a year and still leaves you sending InMails nobody answers. Here is the full sourcing flow — longlist by real requirements, enrich, read the push and pull signals, see who you are bidding against, and reach a real address — run from Claude via MCP for about 84 cents a role.

Try the scraper

The actor referenced in this article. Pay only for results delivered.

View the scraper →

Every recruiter I know has had roughly this week.

Monday: you get the req. Tuesday: you run the same Boolean string you have run for four years, get 300 profiles, and pick 30 that look plausible from the headline. Wednesday: you send 30 InMails. By Friday you have four replies, three of which are “not looking, thanks.”

And somewhere in that week you paid — or your company paid — for a Recruiter seat. Recruiter Corporate runs in the thousands per year, roughly ten thousand for a single seat depending on your contract. For that money you got a better search box and a message quota.

Here is the thing the search box cannot tell you: which of those 30 people is actually going to move. And here is the thing the message quota guarantees: your note looks exactly like the nineteen others in their inbox, because it is the same note.

That is not an outreach problem. That is a data problem. So let’s treat it like one.

This post is the complete sourcing flow I would run for one role tomorrow. Eight tools, one Claude conversation, about eighty-four cents. No code.

The setup (two minutes, once)

The Mine Works MCP server puts our scrapers inside Claude as native tools. Claude calls them itself and reasons over the results in the same conversation — you never export a CSV and re-import it somewhere.

Open ~/.claude.json (or Claude Desktop → Settings → Developer → Edit Config) and add:

{
  "mcpServers": {
    "themineworks": {
      "url": "https://the-mine-works-mcp.hatchable.site/api/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_APIFY_TOKEN"
      }
    }
  }
}

Grab your token from Apify → Account → Integrations. Restart Claude. Runs bill to your own Apify account at pay-per-result rates — there is no subscription on our end.

One thing to be clear about before we start: every LinkedIn tool below reads public, Google-indexed pages only. No login, no cookies, no credentials, no seat. It is the logged-out view, at speed.

Now the flow.

Step 1: Longlist by the requirements, not by the headline

The manual version: you write a Boolean string, LinkedIn hands you a list sorted by its own idea of relevance, and you eyeball headlines. “Senior Engineer” tells you nothing about whether they have shipped the thing your hiring manager actually needs shipped. So you open 60 profiles in 60 tabs and start skimming.

Skip the tabs. LinkedIn Candidate Finder takes the requirements as structured filters and returns a longlist.

Prompt: Use find_linkedin_candidates with roleTitle “Senior Backend Engineer”, skills [“Go”, “Kubernetes”, “distributed systems”], location “Berlin”, minYears 5, maxYears 12, maxResults 100. Give me the full list.

Note what that is doing that a headline search does not: minYears and maxYears are a band, not a floor. Half of sourcing waste is people who are too senior for the comp band, and the headline never says so.

targetCompanies is the other lever worth knowing. If your hiring manager says “someone from a company that has actually operated this at scale,” name those companies and stop guessing.

Cost: $0.003 per candidate. 100 candidates is thirty cents.

Step 2: Enrich the shortlist on facts, not vibes

The manual version: you open each profile, scroll, and build a mental model you will forget by the third one. Then you make the shortlist call from that mush.

Pick the 20 you actually care about and get the real record.

Prompt: Use get_linkedin_profiles on these 20 profile URLs. I want full experience history, education, and skills. Then rank them against this job description — be harsh. For each one, tell me the strongest evidence they can do this job, and the one thing that worries me.

Two things fall out of the real history that the headline hides. Tenure rhythm: someone who has moved every 26 months and is at month 30 is a different prospect from someone four years into a company they helped build. And trajectory: the person whose last two moves were sideways is listening. The person who just got promoted six months ago is not.

You are not guessing at either of those any more. Claude read all twenty.

Cost: $0.004 per profile. Twenty profiles is eight cents.

Step 3: Is their employer a push or a pull?

This is the step that changes your pitch, and almost nobody does it.

The manual version: you don’t. You send the same message to someone at a company that raised a Series C last month and someone at a company that has been quietly flat since 2023.

Those are completely different conversations.

Prompt: Use get_linkedin_company for the 10 companies these candidates work at. Then search_crunchbase for each one — total funding, last round, and date. Flag any company whose last raise was more than 30 months ago.

A company that raised last month is a pull — the person is probably locked in with fresh equity and a mandate. Your pitch has to beat momentum, and often it can’t. Deprioritise.

A company that hasn’t raised in three years, with headcount flat or shrinking, is a push. That person has done the runway maths themselves. They are not waiting for a better message; they are waiting for a reason. You have one.

You can pass plain names to get_linkedin_company["stripe", "datadog"] — or full LinkedIn company URLs. Either works.

Note: Crunchbase is a browser-based scrape and takes longer than a single request can wait. The tool hands back a run_id and Claude collects it with get_run_results a few seconds later. That is expected, not an error.

Cost: $0.004 per company (LinkedIn) + $0.0133 (Crunchbase). For ten companies: about seventeen cents.

Step 4: Find out who you are bidding against

The manual version: you find out what the market pays when your candidate declines at offer stage and tells you they took something 20% higher.

Your competitors publish their hand. It is called a careers page.

Prompt: Use scrape_ats_jobs on these 5 competitors, platform “auto”: their ATS slugs are [slug1], [slug2], [slug3], [slug4], [slug5]. Pull every open role, then filter to anything in the same family as my req. For each match, extract the comp band if published, the seniority framing, and what they emphasise about the team.

ATS Jobs reads Greenhouse, Lever, Ashby and Workday boards directly, with the full job description attached. That description is the pitch your candidate is being read, verbatim, by four other recruiters this week.

Three things you get for a tenth of a cent per job:

  • The comp band, where it is posted — which is increasingly everywhere, by law.
  • The seniority ladder, which tells you whether your “Senior” is their “Staff.” That mismatch kills more offers than money does.
  • Their pitch. If every competitor board leads with “remote-first,” and yours doesn’t, you know exactly which objection is coming.

Cost: $0.001 per job. Five boards at ~40 roles each is 200 jobs — twenty cents.

Step 5: Find the one true thing to say

The manual version: “I came across your profile and was impressed by your background.” Everyone knows what that sentence means. It means you did not read anything.

Prompt: Use search_linkedin_posts for each shortlisted candidate’s name, and separately for their company name plus terms like “hiring”, “shipped”, “migration”, “on-call”. maxResults 20. Summarise what each person has actually been talking about publicly in the last few months.

This is the difference between “I saw your profile” and “you wrote last month about the on-call rotation being the thing you’d fix if you could — that’s the first thing this team is fixing.”

One is a template. The other is a reason to reply. Both take you the same amount of time now.

If the search comes back empty for someone, that is a finding too — a candidate with no public footprint is not going to be moved by a clever hook. Go straight and short with them instead.

Cost: $0.003 per post. Twenty posts is six cents.

Step 6: Reach an address that exists

The manual version: guess the pattern, send it, and never learn that it bounced because the bounce went to a mailbox you don’t check.

Prompt: Use find_website_contacts on these 10 company domains. Then run verify_emails on everything it returns — I only want addresses that pass MX and SMTP.

Website Contact Finder crawls the homepage, contact, about and team pages and pulls emails, phones and social profiles. Email Verifier then tells you which are real, which are role-based (careers@, info@ — a queue, not a person), and which are catch-alls that will accept anything and deliver nothing.

Sending to a dead address is worse than not sending — it costs you the same effort and teaches you nothing.

Cost: $0.001 per domain, $0.001 per email verified.

Step 7: Now write the message

Claude now has, in one conversation: the candidate’s real experience history, their tenure rhythm, whether their employer is a push or a pull, what four competitors are offering for the same profile, what this person has said publicly this quarter, and a verified address.

Prompt: Write outreach to [name] about the [role]. Their employer hasn’t raised since [date] — do not say that, but let it inform the framing. Reference their post about [topic] only if it is genuinely relevant; if it is a stretch, drop it. Address the comp gap against [competitor] head-on. Under 120 words. No flattery, no “impressive background,” no “reaching out.”

The reason this gets replies is not that an AI wrote it. It is that every claim in it is grounded in something real you pulled four minutes ago. It is specific because it can be specific.

Step 8: Make it standing

The whole flow is a prompt, which means it can be a recurring one.

Prompt: Re-run find_linkedin_candidates for this role. Show me only people who weren’t in last month’s longlist. Re-check the 10 employers — flag anyone whose company has had layoffs, a flat headcount quarter, or crossed 30 months since their last raise.

Push signals have a shelf life. The person who was locked in six months ago may not be now. Run this monthly on your evergreen reqs and you are talking to people in the window where they are actually listening.

What it actually costs

Real per-result prices, for a full sourcing pass on one role:

StepToolRateVolumeCost
Longlistfind_linkedin_candidates$0.003/candidate100$0.30
Enrich shortlistget_linkedin_profiles$0.004/profile20$0.08
Employer factsget_linkedin_company$0.004/company10$0.04
Funding signalsearch_crunchbase$0.0133/company10$0.13
Competitor boardsscrape_ats_jobs$0.001/job200 jobs$0.20
What they care aboutsearch_linkedin_posts$0.003/post20$0.06
Contactsfind_website_contacts$0.001/domain10$0.01
Verifyverify_emails$0.001/email20$0.02
Total$0.84

Eighty-four cents a role. You pay per result delivered — a search that returns nothing costs nothing.

For scale: a Recruiter Corporate seat is in the thousands per year, roughly ten thousand depending on contract. At eighty-four cents a role, that is a lot of reqs. I am not going to pretend the comparison is clean — the seat also gives you InMail delivery, ATS integrations, and a pipeline UI, and this gives you none of those. What it gives you is the research layer the seat never had.

The honest part

This does not send anything. There is no InMail here, no sequencer, no auto-send. You still write the message and you still hit send, and that is deliberate.

It also will not make a bad req fillable. If the comp band is 30% under market — and Step 4 will tell you that in about a minute — no amount of research fixes it. What it does is tell you on Tuesday instead of at offer stage in week six.

And it will not tell you whether someone is actually open to moving. Nothing will. Push signals are probability, not fact. A person at a company that hasn’t raised in three years might be perfectly happy. You are shortening the odds, not eliminating them.

On the ethics, briefly and plainly: this reads public pages. It is the same research a good recruiter does by hand — public profile, public company page, public job board, public post — done in minutes instead of an afternoon. The line has not moved. Use it to have a better-informed conversation with a person, not to accumulate things about them you would be embarrassed to mention on the call. If you would not say “I read your post about on-call” out loud, don’t use it.

What this removes is the part that was never the real work: not knowing which of 100 profiles to care about, and having nothing true to say to the twenty you do. Those are lookup problems. They have always been lookup problems. Until recently there was no reasonable way to do the lookups, so the industry substituted volume instead.

Now there is, and it costs less than a coffee.


Tools used: LinkedIn Candidate Finder · LinkedIn Profile Scraper · LinkedIn Company Details · Crunchbase · ATS Jobs · LinkedIn Post Search · Website Contact Finder · Email Verifier

All of them are available as one MCP endpoint.

Related Actor

Explore the scraper referenced in this article — see inputs, outputs, and pricing, then run it on Apify.

Frequently asked questions

Do I need a LinkedIn Recruiter seat for any of this? +

No. Every LinkedIn tool here reads public, Google-indexed pages — the same pages any logged-out visitor sees. No login, no cookies, no account credentials, no seat. What you lose is InMail delivery inside LinkedIn. What you gain is the research that makes an email worth opening in the first place.

What does sourcing one role actually cost? +

A full pass — 100 candidates longlisted, 20 profiles enriched, 10 employers checked for funding and headcount signals, 5 competitor ATS boards read, 20 post searches, 10 domains crawled and 20 addresses verified — comes to about $0.84 at current per-result rates. You pay per result delivered, and nothing for a search that returns nothing.

Isn't this just scraping people? +

It reads what a recruiter already reads by hand: public profiles, public company pages, public job boards, public posts. The difference is speed, not access. The ethical line is the same one it has always been — use it to have a better-informed conversation with someone, not to build a dossier on them.

Why would this beat higher InMail volume? +

Because volume is what everyone else is already doing, and the candidate can tell. Twenty other recruiters hit the same profile this month with the same template. The constraint is not how many people you can message — it is knowing which of them is actually open to moving, and having one specific true thing to say to them.

Does Crunchbase really take that long to return? +

Yes, and that is expected. It is a browser-based scrape, so it hands back a run_id immediately and Claude collects the results with get_run_results a few seconds later. You will see it do this by itself — it is not an error.