Unified Jobs MCP Server
A zero-dependency Model Context Protocol server that gives an AI
agent one thing no single-source jobs tool does: a cross-source, deduplicated jobs feed. It
queries applicant-tracking systems, the LinkedIn public guest search, and the Hacker News
"Who is hiring?" thread, then collapses the same role seen on several sources into one canonical
record — with a sources[] array and a union of the richest salary, longest description, and
earliest post date. The agent gets a clean list instead of three overlapping ones plus a dedup
problem of its own.
- No API key, no account, no login. All data comes from keyless public endpoints.
- Zero dependencies. Hand-rolled spec-conformant JSON-RPC 2.0 over stdio — no SDK, no transitive
package tree in your agent's trust boundary. Installs and boots instantly under
npx.
- Public postings only. No member data, no PII beyond public job fields.
Install
Claude Desktop (claude_desktop_config.json) / Cursor / Cline / Continue:
Or run it directly:
Tools
search_unified_jobs
The cross-source feed. Pull one or more companies' ATS boards (companies[]), search LinkedIn
(keywords + location), and/or the current HN thread — in a single call — and get back one
deduplicated list. The same role on several sources merges into one record:
Every result set reports dedup stats: raw_source_hits, canonical_jobs, cross_source_merges,
collapsed, per_source_hits.
search_hn_hiring
Just the current month's Hacker News "Ask HN: Who is hiring?" thread, normalized into the same
schema. The monthly thread id is auto-discovered (it rotates on the 1st of every month) and each
free-text post header is parsed into structured fields. Optional query / remoteOnly filters.
list_sources
The source families, how to address ATS companies, and exactly how the cross-source dedup behaves.
No network call.
get_premium_access
The metered depth endpoints beyond the free reads above — a normalized cross-ATS compensation
layer and a per-company hiring-intent signal — served pay-per-call over x402
(USDC on Base, no account/API key; the caller's wallet pays the 402 inline, a few tenths of a cent
per call). Returns the base URL, each endpoint's path + price + what it adds, and the payment
handshake. No network call, no payment. Free preview first:
https://assetfactory-jobs-x402.sigrunner.workers.dev/jobs/preview?companies=stripe.com.
Sources
Every source is wrapped so a single source failing (e.g. LinkedIn's guest endpoint rate-limiting a
cloud IP) never fails the whole call — you get the sources that did return. The hosted metered
version adds Indeed and rotating residential proxies for volume.
How the dedup works
- Canonical key:
company | title | city, with legal suffixes stripped but seniority and role
qualifiers kept — so Backend - Infrastructure and Backend - Defense stay distinct.
- Merge: scalar fields are first-non-null in source-rank order; salary is taken whole from the
single richest source (kept internally consistent);
posted_at is the earliest; description is the
longest; sources[] accumulates every origin.
- Degrade open: a row with no derivable key is emitted as its own record with
merged: false —
never silently dropped.
Maintenance
A GitHub Actions smoke workflow runs a real MCP client handshake plus a live cross-source pull on
every push and daily. The ATS and HN families gate it; LinkedIn is advisory (cloud-IP rate limits).
A genuine upstream shape change fails the roundtrip and opens a tracking issue automatically — the
feed is kept working, not left to rot.
License
MIT © Grey Ridge Signals Group LLC