Skip to main content
Glama
moonie0201

ats-jobs-mcp

by moonie0201
README.md
# ats-jobs-mcp

An MCP server that answers **"what is this company hiring for, right now"** by reading
the company's own applicant-tracking system board API at call time — Greenhouse, Lever,
Ashby, Recruitee, Rippling or Personio. Not an index that was crawled last night.

No HTML scraping, no headless browser, no proxies. Every request goes to an endpoint the
vendor publishes for exactly this purpose.

## Install

Requires [uv](https://docs.astral.sh/uv/) and a free
[Apify](https://console.apify.com/settings/integrations) token. Runs are billed to
**your** Apify account — see [Pricing](#pricing).

```json
{
  "mcpServers": {
    "ats-jobs": {
      "command": "uvx",
      "args": ["--from", "git+https://github.com/moonie0201/ats-jobs-mcp", "ats-jobs-mcp"],
      "env": { "APIFY_TOKEN": "apify_api_..." }
    }
  }
}
```

| Client | Where that JSON goes |
|---|---|
| Claude Desktop | `~/Library/Application Support/Claude/claude_desktop_config.json` (macOS) · `%APPDATA%\Claude\claude_desktop_config.json` (Windows) |
| Cursor | `~/.cursor/mcp.json`, or `.cursor/mcp.json` in a project |
| Claude Code | `claude mcp add ats-jobs --env APIFY_TOKEN=apify_api_... -- uvx --from git+https://github.com/moonie0201/ats-jobs-mcp ats-jobs-mcp` |

## Tools

| Tool | What it does | Cost |
|---|---|---|
| `search_jobs(companies, title_contains?, remote_only?, max_jobs?)` | Live job rows for the given companies. `companies` are `provider:slug` pairs (`lever:palantir`) or career-site URLs. Returns title, company, location, remote flag, structured salary, employment type, url, postedAt. | **paid**, see below |
| `resolve_company(url_or_name)` | Maps a company name or career-site URL to the `provider:slug` pair `search_jobs` wants. | free |
| `list_supported_ats()` | The six providers and the slug form each expects. | free |

Filters are applied **before** billing, so a narrow query is cheap rather than a big
response you post-filter. `max_jobs` is a hard spend cap.

## Pricing

`search_jobs` starts a run of the paid Apify Actor
[`acotr_moonie/ats-jobs-scraper`](https://apify.com/acotr_moonie/ats-jobs-scraper) at
**$0.002 per delivered job row**, billed by Apify to the account behind your own
`APIFY_TOKEN`. This server is a thin client: it never proxies your calls, never sees your
token or your results, and no run is ever paid for on your behalf. The default
`max_jobs=50` caps a single call at about **$0.10**.

`resolve_company` and `list_supported_ats` cost nothing and start no run.

## What it will not do

- **Salary is parsed, never inferred.** Each salary carries a `source` field saying
  whether the number came from a structured provider field or a regex over prose.
- **No contact fields are emitted**, and contact details in ad bodies are redacted by
  default.
- **Where a value cannot be determined the field is `null`.** Nothing is guessed.
- `resolve_company` searches a **partial** directory — 1,804 rows, 1,444 of them verified
  live at last probe. A name that does not resolve is not proof the company has no board;
  pass the career-site URL instead.

## How it works

`resolve_company` reads the CC-BY
[ats-directory](https://github.com/moonie0201/ats-directory) over jsDelivr and caches it
under `~/.cache/ats-jobs-mcp/` for 24 hours. `search_jobs` calls the Apify Actor's
`run-sync-get-dataset-items` endpoint with your token.

## Links

- Actor source, MIT: <https://github.com/moonie0201/ats-jobs>
- Company directory, CC-BY: <https://github.com/moonie0201/ats-directory>
- Privacy policy: <https://github.com/moonie0201/ats-jobs/blob/main/PRIVACY.md>
- Takedown policy: <https://github.com/moonie0201/ats-jobs/blob/main/TAKEDOWN.md>

## Development

```bash
uv venv && uv pip install -e ".[dev]"
python -m pytest tests -q       # offline: builds the server, lists tools
python -m ats_jobs_mcp --list-tools
```

## Disclosure

I built this, and the Actor behind `search_jobs` is paid. The adapter code and the
company directory are open and free to use without it.

MIT licensed.

TDQS

A4.4/5.0

Scored across 3 tools

Disambiguation5/5

Each tool has a distinct responsibility: searching live jobs, listing supported ATS integrations, and resolving company names/URLs to provider-slug pairs. There is no overlap or ambiguity between them.

Naming Consistency5/5

All three tools use a consistent snake_case verb-first pattern: search_jobs, list_supported_ats, resolve_company. The naming clearly signals action and object.

Tool Count5/5

Three tools is an appropriate size for this server's focused purpose. Each tool is necessary and contributes a distinct step in the workflow from company name to actual job postings.

Completeness5/5

The tool set covers the full intended workflow: discover supported ATS platforms, resolve a company to the expected identifier, then search live job postings. No obvious missing operations or dead ends are apparent for the stated purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues