Install in Claude Code
Copygit clone --depth 1 https://github.com/MadsLorentzen/ai-job-search /tmp/freehire-search && cp -r /tmp/freehire-search/.agents/skills/freehire-search ~/.claude/skills/freehire-searchThen start a new Claude Code session; the skill loads automatically.
Definition
SKILL.md
# freehire Search Skill Search live job listings from the **[freehire.me](https://freehire.me)** job aggregator — an open-source IT job board that normalizes postings from ~50 ATS platforms across many countries into one schema. No authentication, no API key, and **zero runtime dependencies** — it runs with just `bun`. The market is chosen per query via facet flags (`--region`, `--country`), so the same skill works for a forker in any market out of the box. > This is a country-agnostic worked example of the repo's job-portal-skill pattern, > like `linkedin-search`. Unlike the HTML-scraping portals, it queries freehire's > public JSON API, so results are structured (skills, seniority, region facets) > rather than parsed from markup. ## ⚠️ Scope: tech-focused freehire's corpus already includes some non-tech postings (it crawls whole company career pages), **but its faceted filtering — skills, categories, and seniority dictionaries — is tuned tech-first today**, so this skill scopes its triggers to software / data / engineering / tech roles, where the filtering is strong. Non-tech coverage exists but is still maturing; don't rely on this skill for general (non-technical) job coverage yet. ## ℹ️ Hosted-service dependency (best-effort, no SLA) This skill depends on a third-party hosted service, freehire.me. Reads are **public and unauthenticated** — the same zero-signup bar as `linkedin-search`. **freehire.me is a personal project but actively maintained; it runs on a best-effort basis (no formal SLA).** If the API is unreachable, the CLI fails gracefully — a non-zero exit with a clear error message — so an outage degrades this source rather than breaking the surrounding workflow. **Self-hosting / swappable base URL.** The freehire backend is a separate MIT-licensed repo — [`strelov1/freehire`](https://github.com/strelov1/freehire) (Go + PostgreSQL + Meilisearch) — that stands up with one command via Docker Compose (`make up` → API on `:8080`, same `/api/v1/...` paths). The skill honors a base-URL env var, `FREEHIRE_API_URL` (default `https://freehire.me`), so pointing it at a local instance is a one-line change: ```bash FREEHIRE_API_URL=http://localhost:8080 bun run .agents/skills/freehire-search/cli/src/cli.ts search -q "go" ``` Caveat: standing up the *API* is light, but keeping a *full, continuously-fresh* mirror (millions of postings across ~50 platforms) is resource-heavy — a self-hoster would either crawl a scoped subset of sources or point the env var back at the hosted API. ## When to use this skill - Search for tech job openings by keyword, in a given region/country or remotely — each result comes back with its **full description**, no per-hit follow-up needed - Filter by seniority, category, skills, or recency (posted within N days) - Look one freehire posting up by its slug (including a closed one) ## Commands ### Search job listings ```bash bun run .agents/skills/freehire-search/cli/src/cli.ts search [-q "<keywords>"] [facet flags] ``` Key flags: - `--query <text>` / `-q <text>` — keyword search (title, skill, role). Full-text; optional. - `--jobage <days>` — posted within N days (maps to `posted_within_days`). - `--page <n>` — 1-indexed page. Default 1. - `--limit <n>` / `-n <n>` — results per page (API limit). Default 25. - `--format json|table|plain` — default `json`. - `--description-format markdown|text|html` — how each result's full description is rendered. Default `markdown`, which keeps the posting's headings and requirement lists intact. `json` output only. **Search results already carry the full description.** This skill queries freehire's agent search endpoint, which replaces the index's truncated preview with each posting's complete text, so a search of 20 roles is 1 request rather than 1 + 20. Do **not** loop `detail` over search hits to read their descriptions — reach for `detail` only to look one posting up by slug (e.g. from the tracker, or a posting already closed and therefore absent from search). Full descriptions are verbose: keep `--limit` modest, and pre-filter on title/company before reading bodies - or pass `--no-description` for a cheap discovery pass that keeps every other field and drops the bodies entirely (fetch a shortlisted job's body with `detail`, or re-run the search without the flag). Facet filters (values come from freehire's controlled vocabularies; comma-separate for OR within a facet): - `--region <codes>` — macro-region, e.g. `global`, `eu`, `us`, `apac`, `latam`, `cis`. `--region eu,us`. Use `none` to match jobs whose region could **not** be resolved (see "Partial data" below). - `--country <codes>` — ISO-3166 alpha-2, e.g. `--country DE,GB` - `--city <names>` — city name(s), e.g. `--city Berlin` - `--seniority <levels>` — `junior`, `middle`, `senior`, `staff`, `principal`, `lead`, … - `--category <cats>` — `backend`, `frontend`, `fullstack`, `devops`, `ml_ai`, `qa`, … - `--skill <names>` — canonical skill(s), e.g. `--skill go,kubernetes` - `--company <slug>` — company slug (from a result's `company_slug`) - `--remote <mode>` — `remote` | `hybrid` | `onsite` (`work_mode` facet) - `--facet <key=value>` — any other facet param (repeatable), e.g. `--facet salary_min=100000` > **Location is a facet, not free text.** Unlike `linkedin-search`'s `--location`, > freehire filters geography through the structured `--region`/`--country`/`--city` > facets. Discover the live values for a market at > [`/api/v1/jobs/facets`](https://freehire.me/api/v1/jobs/facets) (append `?q=<role>` > to scope it) — never invent facet values. ### Fetch full job detail ```bash bun run .agents/skills/freehire-search/cli/src/cli.ts detail <slug|url> [--format json|plain] ``` `slug` is the `id` from a `search` result (e.g. `golang-zensar-2bxu6dxm`). You may also pass a full `https://freehire.me/jobs/<slug>` URL. Returns the full (HTML-stripped) description, skills, region/country, and — when the posting is enriched — seniority, category, employm
More from this repository
jobbank-searchSkill
>
jobdanmark-searchSkill
>
jobindex-searchSkill
>
jobnet-searchSkill
>
linkedin-searchSkill
>
gemini-research-expertSubagent
Use this agent when the user needs to perform research tasks, gather information from external sources, or investigate topics that require web searches and synthesis of information.
job-application-assistantSkill
>
scrapeSkill
>