jobpipe
Polls configured Greenhouse public JSON boards to fetch and normalise job postings, deduplicating them before storage.
Used as an example Greenhouse board that was parsed in the live check, demonstrating job posting retrieval from Monzo's public board.
Used as an example Lever board that was parsed in the live check, demonstrating job posting retrieval from Palantir's public board.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@jobpipeFetch new UK jobs, check sponsorship, and show what passed the prefilter"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
jobpipe
An MCP server that lets Claude run a job-search pipeline, where the model's judgement is checked by code before it is allowed to count.
Claude does the one thing a model is good at here: reading a job description and judging fit. Everything else (sourcing, de-duplication, visa-sponsor checks, hard eligibility rules, storage, calibration) is plain, testable Python. And the model's scores are not trusted on faith: every score must quote the job description, and the server verifies the quote exists before the score counts.
It reads only public, unauthenticated sources. No LinkedIn scraping, no session cookies, no form submission.
Why this is interesting beyond job hunting
The pattern is general: use an LLM for judgement, and wrap it in deterministic controls that make the judgement auditable. It is the same idea I apply professionally when validating AI systems in financial services.
Control | How jobpipe implements it |
Narrow the model's job | Deterministic rules reject impossible postings first, so the model only scores plausible ones |
Ground every claim | Each rubric dimension needs a verbatim quote from the job description |
Verify, don't trust | The server checks each quote really appears in the text; fabricated evidence voids that dimension (scores 0, weight still counts) |
Allow honest "don't know" | A dimension can |
Measure it | You label postings by hand and get precision and recall per band |
Audit trail | Nothing is silently discarded; every rejection keeps its rule and evidence |
Related MCP server: job-search-mcp
How it works
flowchart LR
A["Greenhouse / Lever / Ashby<br/>public JSON boards"] --> B[Normalise + dedupe]
B --> C["UK sponsor register<br/>(GOV.UK CSV)"]
C --> D["Deterministic rules<br/>no model"]
D -->|REJECT, with reason| X[(kept for audit)]
D -->|PASS / REVIEW| E["Claude scores<br/>against rubric"]
E --> F{"Evidence check<br/>quote in JD?"}
F -->|no| G[dimension voided]
F -->|yes| H[score counts]
G --> I[Band: AUTO_DRAFT / REVIEW / REJECT]
H --> I
I --> J["Your labels → precision / recall"]The evidence check, concretely
The model returns, for each dimension, a score and a quote:
{"job_id": "greenhouse:examplecapital:123",
"dimensions": {
"quant_depth": {"score": 4, "abstain": false,
"evidence": "backtesting and benchmarking of pricing models"},
"...": "one entry per rubric dimension"}}record_assessment normalises typography and whitespace, then confirms the
quote occurs in the stored description (a 95% fuzzy floor tolerates curly
quotes and line breaks, nothing looser). If it does not, the dimension is voided
and the job cannot reach AUTO_DRAFT however high its total. Fabricating
evidence therefore lowers the score instead of being ignored. That is the
difference between a prompt that asks for citations and a system that enforces
them.
Live check (15 October 2026)
The parsers were run against three real public boards, one per ATS, using
examples/live_check.py:
Board | ATS | Postings parsed | Empty descriptions | Missing dates |
Monzo | Greenhouse | 68 | 0 | 0 |
Palantir | Lever | 315 | 0 | 0 |
Cohere | Ashby | 116 | 0 | 0 |
Total | 499 | 0 | 0 |
Deterministic pre-filter on those 499 (sponsor register not consulted in this check):
Verdict | Count |
REJECT (hard rule failed) | 216 |
REVIEW (soft rule failed) | 200 |
PASS | 83 |
The security-clearance rule fired 181 times (171 Palantir, 10 Cohere). Spot checks confirmed these were genuine clearance requirements, not keyword noise. So before a single token is spent, the model's workload drops from 499 postings to the 283 that are actually possible.
Tools exposed to Claude
Tool | Stage |
| Poll configured Greenhouse/Lever/Ashby boards, dedupe, store |
| Download the current GOV.UK register (24h cache) |
| Match employers → CONFIRMED / AMBIGUOUS / NOT_FOUND |
| Deterministic rules; rejects keep their reasons |
| Rubric text + JSON schema for scoring |
| Jobs that cleared the pre-filter |
| Validate evidence, compute band, store |
| Your own APPLY / MAYBE / NO, for calibration |
| Precision and recall against your labels |
| Current state |
| Outcome tracking |
Typical session:
refresh_sponsor_register
fetch_jobs
check_sponsorship (companies from the new jobs)
run_prefilter
next_to_score → get_rubric → score each → record_assessment
list_pipeline band=AUTO_DRAFTQuick start
git clone https://github.com/Jayaramgokul/jobpipe.git && cd jobpipe
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp config.example.yaml config.yaml # then list the boards you care about
python -m pytest tests/ -q # 30 offline tests
python examples/live_check.py # optional: hits three live boardsConnect it to Claude
Claude Code / Claude Desktop (local, stdio):
claude mcp add jobpipe -- /full/path/to/.venv/bin/python -m jobpipe.serveror in claude_desktop_config.json:
{
"mcpServers": {
"jobpipe": {
"command": "/full/path/to/.venv/bin/python",
"args": ["-m", "jobpipe.server"],
"env": {
"JOBPIPE_CONFIG": "/full/path/to/config.yaml",
"JOBPIPE_DATA": "/full/path/to/data"
}
}
}
}As a remote connector: set JOBPIPE_TRANSPORT=streamable-http and run it
behind a host that terminates TLS. A remote connector is reached from the
cloud, so localhost will not work. Local stdio is the better default, because
the pipeline data is personal.
Project layout
jobpipe/
ats.py fetch + normalise Greenhouse, Lever, Ashby; dedupe
sponsors.py GOV.UK sponsor register: download, cache, fuzzy match
prefilter.py deterministic HARD / SOFT rules with evidence snippets
rubric.py rubric, JSON schema, evidence verification, banding
store.py SQLite state, labels, calibration metrics
server.py MCP server exposing the 11 tools
tests/ 30 offline tests (fixtures, no network)
examples/ live smoke test against real boardsCalibrate before trusting it
The weights and thresholds shipped here are a starting guess, not a
measurement. Label 40 to 60 postings you have already judged by eye, then run
calibration_report. Read precision and recall separately because they cost
different things: a false positive wastes a tailoring cycle, a false negative
loses a job you wanted. If AUTO_DRAFT precision is below about 0.85, tighten
the weights or raise the threshold. If recall is below about 0.7, the threshold
is too high.
Limitations, stated plainly
Workday is not covered. It has no public JSON feed, which excludes most of the Big Four and most large banks. Use email alerts for those.
Company-name matching is genuinely hard. The register holds legal entity names; boards carry brand names. AMBIGUOUS is returned deliberately rather than guessing from the top fuzzy score.
Register freshness matters. Ratings change without notice. Force a refresh before acting on anything important.
Being on the register is not an offer of sponsorship. It means the employer can sponsor, not that it will for a given role.
Board slugs rot. Companies migrate ATS and old boards 404 quietly;
fetch_jobsreports these underboard_errors.The rubric is tuned to one profile (UK model risk and AI governance). The dimensions live in
rubric.pyand are meant to be edited.
Licence
MIT
This server cannot be deployed
Maintenance
Related MCP Connectors
AI job search MCP — fact-checked jobs, application tracker, alerts. ChatGPT, Claude, Cursor.
Job search across Greenhouse, Lever, Ashby, SmartRecruiters, Personio and Pinpoint, deduplicated.
HR and recruiting: score a job description, or generate a structured role profile. No API key.
Job search over employers' own hiring systems. Search with no key; a free key opens every read tool.
Related MCP Servers
- FlicenseNot gradedqualityCmaintenanceEnables running a job search with Claude Code: parses CV, discovers roles, fetches exact application fields, drafts non-trivial applications (positioning, not autofill), and renders an offline dashboard for review.-
- AlicenseNot gradedqualityCmaintenanceEnables searching and evaluating job postings from LinkedIn and freehire.me directly through Claude Desktop. Provides tools to search jobs, fetch full posting details, and assess candidate fit using eligibility scans and a scoring rubric.MIT
- FlicenseNot gradedqualityBmaintenanceEnables Claude Desktop to manage a job search end-to-end: find and score job listings, tailor resumes, generate application messages, and track application history, while leaving final external actions to the user.-
- AlicenseAqualityCmaintenanceEnables AI assistants to evaluate job postings under a UK visa constraint, including sponsor-licence checks with confidence grades, screening for seniority and hard requirements, and role searches that exclude recruitment agencies. It also tracks application history to help avoid duplicate applications.446 npmMIT