# ATS Jobs

> Search ~1.4M open jobs from 24k company career boards: Greenhouse, Lever, Ashby, Workday and more

- name: io.github.eosphor/ats-jobs
- version: 1.0.2
- connection class: R1 (autonomous)
- trust: 96/100
- quality: 88/100 (good)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/io.github.eosphor%2Fats-jobs
- tools: https://api.protogrid.dev/v1/servers/io.github.eosphor%2Fats-jobs/tools

**An agent can connect on its own if it already holds `ATS_JOBS_TOKEN`.** Remote endpoint behind a static API key or header. The registry never sees the value; the agent fills the placeholder.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "ats-jobs": {
      "type": "http",
      "url": "https://melikhov.fr/mcp",
      "headers": {
        "Authorization": "Bearer ${ATS_JOBS_TOKEN}"
      }
    }
  }
}
```

Placeholders to fill: `${ATS_JOBS_TOKEN}`.

## Trust

- hygiene: 100
- liveness: 98
- freshness: 100
- provenance: 90
- drivers: +repository +namespace-matches-repo +website +reachable +uptime-95% +updated-5d-ago
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 88/100 (good)

### protocol: n/a (weight 25)

- n/a `protocol.modern`, `protocol.stateless`, `protocol.transport`, `protocol.list_ttl`: no remote answered a protocol handshake (not probed yet, unreachable, or local-only)

### authorization: 100 (weight 15)

- pass `auth.prm`: Protected Resource Metadata (RFC 9728) published
- pass `auth.as_metadata`: authorization server metadata reachable
- pass `auth.cimd`: Client ID Metadata Documents supported
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 81 (weight 30)

- pass `tools.descriptions`: every tool has a description
- warn `tools.description_length`: 1 tools have descriptions over 1,024 characters, which crowds the context
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 5 of 5 tools declare readOnlyHint or destructiveHint
- fail `tools.directory_hints`: no tool declares all four of readOnlyHint, destructiveHint, idempotentHint and openWorldHint; missing: search_all_jobs (destructiveHint, idempotentHint); search_jobs (destructiveHint, idempotentHint); search_jobs_multi (destructiveHint, idempotentHint); …
- pass `tools.token_cost`: about 1,232 tokens to load every tool
- pass `tools.api_dump`: tools are not a one-to-one API dump
- pass `tools.hidden_text`: no hidden text in tool names, descriptions, schemas or annotations

### stability: n/a (weight 15)

- n/a `stability.changes`, `stability.rug_pull`, `stability.new_links`: tool history recorded for 4 of the 7 days needed

### dependencies: n/a (weight 15)

- n/a `deps.known_vulns`, `deps.mcp_sdk_version`, `deps.resolvable`: no npm or PyPI package

- tools: 5, about 1,232 tokens to load them all
- tool set hash: 4c5a38bd90d27eb04d6e56bb6474163f
- badge: [![protogrid quality](https://protogrid.dev/badge/io.github.eosphor/ats-jobs.svg)](https://protogrid.dev/servers/io.github.eosphor/ats-jobs)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

_No tool definition changes recorded._

## Remotes

- https://melikhov.fr/mcp (streamable-http, auth api_key ${ATS_JOBS_TOKEN}, reachable true, uptime30d 0.94736844)
- https://ats-jobs.mcpize.run/mcp (streamable-http, auth oauth2, reachable true, uptime30d 0.9375)

## Packages

_none_

## Tools (5)

- `detect_company_ats`: Detect which ATS a company uses, without fetching its jobs.

Takes a website, domain or careers URL and returns the ATS vendor, handle
and how it was detected (URL pattern, careers page, or API probe). Useful to
confirm a company is supported before calling search_jobs.
- `list_supported_ats`: List the 10 supported ATS vendors and what each needs as input.
- `search_all_jobs`: Search open jobs across ~24,000 companies at once - no company list needed.

Reads a daily index of every live public board on Greenhouse, Lever, Ashby,
Workday, SmartRecruiters, Workable, Recruitee, Teamtailor, Breezy HR and Personio.
Jobs from the latest daily completed index (about 1.4 million records in the current build), at most 3 per company for variety. Results do not include descriptions. The index is a broad coverage snapshot, not an exhaustive real-time feed.

- keywords: comma-separated title terms, any may match, matched at word start
  ("engineer" matches "Engineering Manager"; "AI" does not match "maintain").
- exclude: comma-separated title terms to drop, e.g. "senior, intern".
- location: comma-separated substrings of the job location, e.g. "Berlin, Germany".
  "remote" also accepts remote roles.
- remote: true keeps only remote roles.
- posted_within_days: only jobs first published in the last N days.
- ats: limit to vendors, e.g. "greenhouse,ashby".
- company: substring of the company name.
- limit: 1-50 (default 20).

Returns title, company, location, remote, posted_at, url, ats, ats_handle and
`matched` (total matches). Use search_jobs(vendor=ats, handle=ats_handle) to get
live data and descriptions for one company.
- `search_jobs`: Search live job postings for one company.

Provide either `company` (website, domain or careers URL - the ATS is detected
automatically) or `vendor` + `handle` (e.g. vendor="greenhouse", handle="stripe").
Workday companies must use a careers URL, e.g.
https://nvidia.wd5.myworkdayjobs.com/NVIDIAExternalCareerSite.

Filters:
- keywords: space-separated terms, all must appear in title, department,
  location, company or description (AND match, case-insensitive).
- location: substring match on the job location, e.g. "Berlin" or "Paris".
- remote: true keeps only remote-friendly roles.
- posted_after: ISO date or datetime; returns only jobs posted on/after it.
  For only-new monitoring pass the previous response's `latest_posted_at`.

limit: 1-50 (default 20). include_descriptions adds a truncated description
(slower on Workday).

Returns job rows with title, company, location, remote, department,
employment_type, posted_at, url, ats, job_id, optional salary, plus
`latest_posted_at` to use as the next cursor.
- `search_jobs_multi`: Search several companies at once (up to 5), e.g. a target-account list.

Each company can be a website, domain or careers URL. Returns per-company
results plus a combined `jobs` list. `limit_per_company` is 1-20 (default 10).
Filters behave exactly like in search_jobs.
