An open-source Python tool that finds engineers who list your framework as a skill and have their own recent code on GitHub, ranks who looks most hands-on, drafts a short note that mentions their work with the framework, and writes an Ashby-ready import file.
A skills list shows who read about a framework. Public code shows who uses it. This tool starts from the skill, keeps only people with their own non-fork repos pushed recently, and puts the ones whose repos are tagged with the framework first. Crustdata is the people data layer (API docs).
flowchart LR
A[Framework you need<br/>e.g. LangGraph] --> B[Crustdata API<br/>POST /person/search]
B --> C[Skill + own repos<br/>pushed recently, not forks]
C --> D[Code rules<br/>real skill, builds software]
D --> E[Hands-on score 0-10]
E --> F[Short note per person]
F --> G[ashby_import.csv + Slack digest]
- Search. Two
POST /person/searchcalls with the same base filter: the framework is a listed skill, and the person has a non-fork repo pushed since your cutoff. The first call adds "a repo tagged with the framework topic". The second does not. Tagged repos come first so they survive a small--max-results. - Filter. Search filters match any entry in a profile, so the tool re-checks each profile in code:
- the framework is really one of the listed skills (not a longer, different skill),
- something in the current titles or headline says they build software,
- recruiter, sales, trainer and student titles without an engineering signal are dropped.
- Score. A transparent 0-10 hands-on score: 2 for skill plus own recent code, +4 for a repo tagged with the framework, +2 if the framework appears in their headline, summary or job description, +1 if it sits in their top 10 skills, +1 for a senior title. Change the weights in
score(). - Note. With
--notes, Claude writes two sentences that open with their work with the framework. It is told not to invent repo names or numbers. Without Claude you get a plain template. - Export. The top N go to
out/ashby_import.csv(name, profile URL, title, company, score, evidence, note, source) for your recruiter to review and send from Ashby, plus an optional Slack digest.
Crustdata returns whether the repo match happened, not the repo list, so the note refers to "your public LangGraph code", never to a repo name it cannot see.
Requires Python 3.9+. No dependencies for the core tool.
git clone https://github.com/mhimed-crustdata/framework-engineer-sourcer
cd framework-engineer-sourcer
make setup # creates .env, then add your CRUSTDATA_API_KEY
make demo # runs the search and prints the summary, never posts to Slack
make run # same, and posts the digest to SLACK_WEBHOOK_URL
make test # unit tests, no networkPick another framework: python3 sourcer.py --framework "dbt" --role "Analytics Engineer" --country "United States".
All settings live in .env (copy from .env.example). Command-line flags override them.
| Variable | Default | What it does |
|---|---|---|
CRUSTDATA_API_KEY |
required | Your Crustdata API key. Read from the environment only |
FRAMEWORK |
LangGraph |
The skill to search for. Must match a skill on the profile |
FRAMEWORK_TOPIC |
framework, lowercased | GitHub topic that marks a repo as built with it |
ROLE_NAME |
engineering role |
Role name used in the note |
SINCE_DAYS |
180 |
Only count repos pushed in the last N days |
COUNTRY |
empty (worldwide) | Person location, e.g. United States |
SLACK_WEBHOOK_URL |
empty | Slack incoming webhook. Empty means no Slack post |
ANTHROPIC_API_KEY |
empty | Optional. With --notes, Claude writes the note |
ANTHROPIC_MODEL |
claude-opus-5-5 |
Model for the optional Claude step |
Useful flags: --dry-run, --all (include people already exported), --max-results N, --top N, --out DIR.
Files in out/ contain personal data and are git-ignored.
A real run on 2026-10-19 against the live API: framework LangGraph, own repos pushed in the last 180 days, worldwide, --max-results 100. No individuals are shown. Aggregated from out/candidates.json:
{
"profiles_scanned": 198,
"kept": 192,
"with_framework_repo": 97,
"framework_in_profile_text": 90,
"by_country": {"India": 90, "United States": 36, "Other (34 countries)": 66},
"score": {"9-10": 46, "7-8": 38, "5-6": 46, "2-4": 62}
}For scale, across the whole index: 35,254 profiles list the skill, 3,882 of those also have their own non-fork repo pushed in the window, and 201 have a repo tagged with the framework. Listing the skill alone leaves you with roughly nine in ten people who have no recent public code of their own.
The code rules were gentle on this query: 6 of 198 were dropped (no software-building title, or recruiter/trainer/student titles). The real filtering is the search itself.
What the Slack digest looks like (redacted):
:hammer_and_wrench: Framework Engineer Sourcer: 25 LangGraph engineers with public code
• [Name] (10/10) [Senior title] at [Company]: public LangGraph repo, LangGraph in profile text, skill #2 of 20 profile
_Hi [First name], I came across your public LangGraph code and thought of you for our [role]. Open to a short chat?_
…and 15 more in out/ashby_import.csv
- Start from the skill, not the repo. The skill gives you a clean, searchable set. Code evidence then narrows it.
- Ask for own code.
dev_platform_profiles.repos.is_fork = falseanddev_platform_profiles.repos.github_pushed_atsince your cutoff remove people whose only repos are forks or abandoned. - Use repo topics as the strong signal. A repo tagged with the framework is the closest filter to "builds with it".
- Re-check in code. Confirm the skill and the current role on the same profile before you trust a hit (
qualify()insourcer.py). - Rank with rules you can explain to a hiring manager. Then let the model write the note, not choose the list.
- Hand over to the ATS. The CSV columns map to an Ashby candidate import. A recruiter reviews and sends.
How do I source engineers from GitHub?
Search a people database for the framework as a skill, filter to people who have their own non-fork repos pushed recently, and rank by whether the repos are about the framework. This tool does that with one endpoint, POST /person/search, using the dev_platform_profiles.* filters.
Does it show me their repos? No. The search filters on repo activity, but the API returns the person's profile, not the repo list. Open the GitHub profile before you write to them, or keep the note general, as the template does.
Why do I need the code filters if the search already filters? Because skills and titles match loosely. The tool confirms the skill is the one you asked for and that the person builds software today.
Does it email anyone?
No. It writes a CSV and, if you set a webhook and drop --dry-run, a Slack digest. Sending stays with your recruiter in Ashby.
Is Claude required?
No. It is optional and off unless ANTHROPIC_API_KEY is set and you pass --notes.
Which Crustdata endpoint does it use?
POST /person/search on API version 2025-11-01.
sourcer.py # the workflow: search, qualify, score, note, export
crustdata_api.py # tiny Crustdata client (stdlib only)
notify.py # optional Slack + Claude
tests/ # unit tests, no network