---
name: peopleseek-career-research
description: Answers career and labour-market research questions from the PeopleSeek Talent index (free MCP server at https://jobs.peopleseek.ai/mcp or REST at https://jobs.peopleseek.ai/api/v1): advertised compensation for a role, place and arrangement via compare_compensation (one currency, one period, a minimum sample, null below it); occupation exploration through the ESCO/ISCO hierarchy (list_occupations, search_occupations); where openings and remote-eligible openings are (list_countries counts); and the skills employers list for a role, read from job skills arrays. Use it when a user asks what a role pays, how pay differs between countries or remote and on-site, which countries have the most openings for a role or accept remote applicants from theirs, what jobs exist in a field, or which skills to learn. Always states that figures are advertised pay from disclosed postings, not accepted offers. Not for finding specific jobs (peopleseek-jobs) or applying (peopleseek-job-application).
metadata:
  version: 1.1.0
---

# PeopleSeek Career Research

The index is a sample of advertised postings from permitted sources, with the
employer's own words normalised and nothing estimated. Research answers built on it are
honest only when they carry the sample's limits with them: where it comes from, how big
it is, and what was excluded. This skill is about producing that kind of answer.
Interfaces, connection snippets and the parameter table are those of the
`peopleseek-jobs` skill; they are not repeated here.

## 1. Compensation: "what does a <role> pay in <place>?"

Use `compare_compensation` (MCP) or `GET /compensation` (REST). It takes every
`search_jobs` filter plus `min_sample`, and returns a `CompensationSummary` or `null`.
Rules the server applies, which the answer must carry:

- Only postings with a **disclosed** salary count. Undisclosed ones are reported in
  `excludedUndisclosed`, never estimated.
- Only **one currency and one period** count per summary. Pass `currency` and
  `compensation_period` explicitly (`EUR` + `year`, `USD` + `hour`); postings in other
  currencies or periods are reported in `excludedOtherCurrencyOrPeriod`, never converted.
- Below `min_sample` qualifying postings the result is `null`: say "too few disclosed
  salaries to report" and show the count you can get from a plain `search_jobs` with the
  same filters, rather than any number.
- Statistics are over the midpoint of each range (`medianMidpoint`, `p25Midpoint`,
  `p75Midpoint`), plus `minOfMins` and `maxOfMaxes`. `jobs` lists the contributing
  postings, each with source attribution and canonical link: show at least the count
  and offer the list.

Procedure, examples and the caveat wording:
[references/compensation.md](references/compensation.md).

**Always caveat**: "advertised ranges from N disclosed postings in the PeopleSeek index,
<currency> per <period>; X postings did not state pay and Y were in another currency or
period; advertised pay is not accepted pay and the index does not cover every employer".

Comparisons (remote vs on-site, Germany vs Austria, senior vs mid) are two or more
summaries with one filter changed and the same currency, period and `min_sample`. Never
compare summaries in different currencies.

## 2. Occupations: "what jobs exist in <field>?" / "what is this role called?"

- `search_occupations` resolves a word or synonym to ESCO occupations and ISCO groups
  with a `confidence`; ESCO alternative labels are searched, so "DevOps", "Site
  Reliability Engineer" and "systems administrator" each resolve.
- `list_occupations` walks the ISCO-08 hierarchy: major (1 digit) → sub-major (2) →
  minor (3) → unit (4) → ESCO occupations, each with `activeJobs`. Use `kind` and
  `parent_id`.
- `GET /occupations/{id}` (REST only) gives one node with `ancestors`, `children` and
  `activeJobs`.
- `occupation_id` in `search_jobs` with an ISCO group (`isco:25`) matches every
  occupation beneath it; use it to size a field, then narrow.

Procedure and examples: [references/occupations.md](references/occupations.md).

## 3. Geography: "where are the openings?" / "which countries accept remote applicants from mine?"

- `list_countries` returns every country with `activeJobs` (jobs located there) and
  `remoteEligibleJobs` (remote jobs whose eligibility is worldwide or lists the country).
  Sort client-side; say which column you sorted by.
- For a role within a country, run `search_jobs` with `occupation_id` (or `q`) and
  `country` and read `total`; for "remote and open to applicants in X", use
  `work_arrangement=remote` + `eligible_country=X`.
- Counts are live database counts over the index's sources. A country with few jobs
  may simply have few indexed sources; say so.

Procedure and examples: [references/geography.md](references/geography.md).

## 4. Skills: "what should I learn for <role>?"

Each job carries `skills` (strings as the source listed them) and `qualifications`.
Fetch a page or more of postings for the role (`search_jobs`, `limit` 100), tally the
`skills` strings case-insensitively, and report the most frequent with the sample size.
Say that the list reflects what the sampled employers wrote, that many postings list no
skills (`skills` is empty), and that it is not a curriculum. Related roles come from
`find_similar_jobs` on a representative posting and from the occupation's siblings in the
hierarchy.

## 5. Rules that never bend

- Never present a number the server did not return; no conversions, no extrapolation,
  no "typical" ranges from memory.
- Every figure is labelled "advertised" and carries sample size, exclusions, currency
  and period.
- A `null` summary is reported as insufficient data, not as "no pay information exists".
- Jobs cited as evidence are shown with company, source attribution and canonical link.
- Say what the index covers: the sources listed by its health endpoint and coverage
  page. It is not every job on the internet.
- Occupation labels are ESCO/ISCO resolutions, not the employer's wording; quote the
  posting's `title` when the wording matters.
