Back to Browse

Ats Job Feed Recipes MCP Server

Developer ToolsLow Risk10.0MCP RegistryRemote
Free

Server data from the Official MCP Registry

Read job postings live from employer career sites across 10 applicant tracking systems.

About

Read job postings live from employer career sites across 10 applicant tracking systems.

Remote endpoints: streamable-http: https://mcp.apify.com/?tools=starbright_overlap/ats-job-feed

Security Report

10.0
Low Risk10.0Low Risk

Valid MCP server (1 strong, 0 medium validity signals). No known CVEs in dependencies. Imported from the Official MCP Registry.

Endpoint verified · Requires authentication · 1 issue found

Security scores are indicators to help you make informed decisions, not guarantees. Always review permissions before connecting any MCP server.

Permissions Required

This plugin requests these system permissions. Most are normal for its category.

env_vars

Check that this permission is expected for this type of plugin.

HTTP Network Access

Connects to external APIs or services over the internet.

file_system

Check that this permission is expected for this type of plugin.

What You'll Need

Set these up before or after installing:

APIFY_TOKENRequired

How to Connect

Remote Plugin

No local installation needed. Your AI client connects to the remote endpoint directly.

Add this to your MCP configuration to connect:

{
  "mcpServers": {
    "io-github-hwangbyeongseon-career-site-job-feed": {
      "url": "https://mcp.apify.com/?tools=starbright_overlap/ats-job-feed"
    }
  }
}

Documentation

View on GitHub

From the project's GitHub README.

ATS job feed recipes

AllMCPs Verified

Working code for pulling job postings straight out of company applicant tracking systems — Greenhouse, Lever, Workday, Ashby, Workable, SmartRecruiters, Breezy, Personio, Pinpoint and Rippling — and doing something useful with them.

Every script here runs as-is. Set APIFY_TOKEN and go.

export APIFY_TOKEN=...        # https://console.apify.com/settings/integrations
python python/new_jobs_to_csv.py

Why this exists

Each of these platforms publishes an open JSON endpoint that the company's own careers page reads — no key, no login, no scraping of rendered HTML. The awkward parts are everything around that:

  • Every platform has a different shape. Greenhouse nests offices and departments; Workday sends a POST and reports posting age as the string "Posted 30+ Days Ago"; SmartRecruiters caps a response at 100 rows whatever limit you pass; Breezy answers 403 for a board that does not exist, where everyone else uses 404.
  • Finding out who is on which platform is the actual work. There is no public directory of Greenhouse or Personio boards. The slug is in a careers URL somewhere, if you can find the careers URL.
  • Dates are unreliable. Three of these ten platforms publish no posting date at all, so any "posted in the last N days" filter has to decide what to do with rows whose age is unknown.

The scripts below use Apify Actors that have already dealt with all of that and return one row shape across every platform. You can equally point them at the raw endpoints — the notes at the bottom list them.

Recipes

FileWhat it does
javascript/watch-companies.mjsDiff a shortlist between runs — what opened, what closed
javascript/salary-data.mjsPostings that publish a pay range, normalised to an annual figure
python/one_company.pyEvery open role at one company, from its careers URL
python/new_jobs_to_csv.pyOnly postings that appeared since the last run, appended to CSV

These Actors bill per row delivered. Every script caps itself at a couple of hundred rows and reads MAX_ROWS if you want more, so running an example does not produce a surprise.

The row shape

Every recipe gets the same fields, whichever platform the job came from:

{
  "provider": "greenhouse",
  "company": "Databricks",
  "companySlug": "databricks",
  "jobId": "7845321",
  "title": "Staff Software Engineer",
  "location": "San Francisco, CA",
  "department": "Engineering",
  "employmentType": "Full-time",
  "remote": false,
  "postedAt": "2026-08-14T09:12:00.000Z",
  "applyUrl": "https://boards.greenhouse.io/databricks/jobs/7845321",
  "salary": null,
  "descriptionText": "...",
  "scrapedAt": "2026-08-19T11:02:41.883Z"
}

companySlug:jobId is stable while a posting is open, which is what makes the diffing recipes work.

What each platform actually publishes

Measured from live boards, not from vendor documentation. Useful before you build on any one of them:

FieldWorkdaySmartRecruitersGreenhouseWorkableLeverAshbyBreezyPersonioPinpointRippling
title, company, locationyesyesyesyesyesyesyesyesyesyes
applyUrlyesyesyesyesyesyesyesyesyesyes
postedAtpartialyesyesyesyesyesyesnonono
departmentnoyesyesyesyesyesyesyesyesyes
employmentTypeyesyesnoyesyesyesyesyesyesno
descriptionTextnonoyesyesyesyesnonoyesno
salarynononononoyesyesno37%no

Workday's partial is the "Posted 30+ Days Ago" problem: an exact age becomes a timestamp, a vague one stays null rather than being invented.

Raw endpoints

If you would rather call the platforms directly, these are the public endpoints. All of them answer without a key. Replace {company} with the board slug.

PlatformEndpoint
Greenhousehttps://boards-api.greenhouse.io/v1/boards/{company}/jobs?content=true
Leverhttps://api.lever.co/v0/postings/{company}?mode=json
Ashbyhttps://api.ashbyhq.com/posting-api/job-board/{company}?includeCompensation=true
SmartRecruitershttps://api.smartrecruiters.com/v1/companies/{company}/postings?limit=100&offset=0
Workablehttps://apply.workable.com/api/v1/widget/accounts/{company}?details=true
Breezyhttps://{company}.breezy.hr/json
Personiohttps://{company}.jobs.personio.de/search.json
Pinpointhttps://{company}.pinpointhq.com/postings.json
Ripplinghttps://api.rippling.com/platform/api/ats/v1/board/{company}/jobs
WorkdayPOST https://{tenant}.{cluster}.myworkdayjobs.com/wday/cxs/{tenant}/{site}/jobs

Two things that will bite you if you write your own client:

  • SmartRecruiters returns at most 100 postings per response regardless of limit. Page with offset, and take the real total from totalFound rather than counting rows.
  • Breezy returns 403, not 404, for a subdomain with no board on it. Treating that as rate limiting and backing off turns a half-hour job into a fourteen-hour one.

Licence

MIT. The Actors these scripts call are commercial and priced per row; the code here is not.

Reviews

No reviews yet

Be the first to review this server!

Ats Job Feed Recipes MCP Server - Read job postings live from employer career sites across 10 | MCP Marketplace