freehire-search について
freehire-searchは、複数のATSの求人情報を統一するfreehire.meで、技術職を検索するコマンドラインスキルです。構造化された勤務地・職種フィルターに対応し、検索結果に全文を含みます。
主な機能
- 01技術職求人の検索
- 02地域、国、都市、勤務形態での絞り込み
- 03経験レベル、カテゴリ、スキルでの絞り込み
- 04検索結果に求人全文を表示
- 05slugによる求人の参照
活用シーン
- 01EUのリモートReact求人を探す
- 02地域を指定してシニアバックエンド職を検索する
- 03保存済みまたは掲載終了した求人の詳細を読む
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ madslorentzen/ ai-job-search --skill freehire-searchインストール後、Claude Code で/freehire-searchを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
url-reference.mdcli/package.jsonREADME.mdtsconfig.jsoncli/src/cli.tshelpers.tscli/src/commands/detail.tssearch.tscli/tests/cli-flag-validation.test.tscommands.test.tshelpers.tsparsing.test.tsrequest-timeout.test.tsrequired-search-values.test.tsretry-backoff.test.ts詳細
freehire 検索スキル
freehire.me ジョブアグリゲーターから最新の求人情報を検索します — これはオープンソースの IT 求人ボードで、多くの国の約 50 の ATS プラットフォームからの求人を 1 つのスキーマに正規化します。認証も API キーも不要で、ランタイム依存関係はゼロ — bun だけで動作します。市場はクエリごとにファセットフラグ(--region、--country)で選択されるため、同じスキルが任意の市場のフォーカーにとってそのまま使えます。
これはリポジトリの job-portal-skill パターンの国に依存しない実例で、
linkedin-searchのようなものです。HTML をスクレイピングするポータルとは異なり、freehire の公開 JSON API にクエリを送るため、結果はマークアップから解析されるのではなく構造化されています(スキル、シニアリティ、リージョンファセット)。
⚠️ 範囲: テック中心
freehire のコーパスにはすでに一部の非テック求人が含まれています(企業のキャリアページ全体をクロールしているため)が、そのファセットフィルタリング — スキル、カテゴリ、シニアリティの辞書 — は現在テック優先で調整されているため、このスキルはトリガーをソフトウェア / データ / エンジニアリング / テック職に限定しており、そこではフィルタリングが強力です。非テックのカバレッジも存在しますがまだ成熟途上です。一般的な(非技術的な)求人のカバレッジについては、まだこのスキルに依存しないでください。
ℹ️ ホスト型サービスへの依存(ベストエフォート、SLA なし)
このスキルはサードパーティのホスト型サービスである freehire.me に依存しています。読み取りは公開されており認証不要 — linkedin-search と同じく登録不要のハードルです。
freehire.me は個人プロジェクトですが活発にメンテナンスされており、ベストエフォートで運用されています(正式な SLA はありません)。 API に到達できない場合、CLI は優雅に失敗します — 明確なエラーメッセージと共に非ゼロで終了するため、障害時はこのソースが機能低下するだけで、周囲のワークフローが壊れることはありません。
セルフホスト / 差し替え可能なベース URL。 freehire バックエンドは別の MIT ライセンスのリポジトリ — strelov1/freehire(Go + PostgreSQL + Meilisearch)— で、Docker Compose により 1 コマンドで立ち上がります(make up → API は :8080、同じ /api/v1/... パス)。このスキルはベース URL の環境変数 FREEHIRE_API_URL(デフォルト https://freehire.me)に対応しているため、ローカルインスタンスを指すのは 1 行の変更です:
FREEHIRE_API_URL=http://localhost:8080 bun run .agents/skills/freehire-search/cli/src/cli.ts search -q "go"
注意点: API の立ち上げは軽量ですが、完全で継続的に新鮮なミラー(約 50 のプラットフォームにまたがる数百万件の求人)を維持するのはリソースを大量に消費します — セルフホスターは、対象を絞ったソースのサブセットをクロールするか、環境変数をホスト型 API に戻して指すかのいずれかになります。
このスキルを使う場面
- キーワードで、指定したリージョン / 国またはリモートのテック求人を検索 — 各結果は完全な説明付きで返り、ヒットごとの追加取得は不要です
- シニアリティ、カテゴリ、スキル、または新しさ(N 日以内に投稿)でフィルタリング
- 1 件の freehire 求人をそのスラッグで参照(クローズされたものを含む)
コマンド
求人情報を検索する
bun run .agents/skills/freehire-search/cli/src/cli.ts search [-q "<keywords>"] [facet flags]
主なフラグ:
--query <text>/-q <text>— キーワード検索(タイトル、スキル、職種)。全文検索。任意。--jobage <days>— N 日以内に掲載されたもの(posted_within_daysに対応)。--page <n>— 1 始まりのページ番号。デフォルトは 1。--limit <n>/-n <n>— 1 ページあたりの結果数(API の上限)。デフォルトは 25。--format json|table|plain— デフォルトはjson。--description-format markdown|text|html— 各結果の詳細説明をどのように レンダリングするか。デフォルトはmarkdownで、求人情報の見出しや要件リストが そのまま保持されます。json出力のみ。
検索結果にはすでに詳細説明が含まれています。 このスキルは freehire の
エージェント検索エンドポイントにクエリを送ります。これはインデックスの切り詰められた
プレビューを各求人情報の完全なテキストで置き換えるため、20 件の職種の検索は
1 + 20 ではなく 1 リクエストで済みます。検索ヒットに対して detail をループさせて
説明を読むことは しないでください — detail を使うのは、スラッグで
1 件の求人情報を調べるときだけです(たとえばトラッカーから、またはすでに掲載が
終了して検索に出てこない求人など)。詳細説明は冗長です:
--limit は控えめに保ち、本文を読む前にタイトル/会社で事前に絞り込んでください -
または --no-description を渡して、他のすべてのフィールドを保ちつつ本文を完全に
省いた低コストな探索を行ってください(候補に絞った求人の本文は detail で取得するか、
このフラグなしで検索を再実行してください)。
ファセットフィルター(値は freehire の統制語彙に由来します。同一ファセット内で OR にするにはカンマ区切りにします):
--region <codes>— マクロリージョン。例:global、eu、us、apac、latam、cis。--region eu,us。リージョンが解決 できなかった 求人にマッチさせるにはnoneを使います(後述の「部分的なデータ」を参照)。--country <codes>— ISO-3166 alpha-2。例:--country DE,GB--city <names>— 都市名。例:--city Berlin--seniority <levels>—junior、middle、senior、staff、principal、lead、…--category <cats>—backend、frontend、fullstack、devops、ml_ai、qa、…--skill <names>— 正規のスキル。例:--skill go,kubernetes--company <slug>— 会社のスラッグ(結果のcompany_slugから)--remote <mode>—remote|hybrid|onsite(work_modeファセット)--facet <key=value>— その他の任意のファセットパラメータ(繰り返し可能)。例:--facet salary_min=100000
ロケーションはファセットであり、フリーテキストではありません。
linkedin-searchの--locationとは異なり、 freehire は地理を構造化された--region/--country/--cityファセットを通じてフィルタリングします。ある市場の実際の値は/api/v1/jobs/facetsで確認してください (スコープを絞るには?q=<role>を付けます) — ファセットの値を勝手に作らないでください。
求人の詳細を取得する
bun run .agents/skills/freehire-search/cli/src/cli.ts detail <slug|url> [--format json|plain]
slug は search 結果の id です(例: golang-zensar-2bxu6dxm)。完全な
https://freehire.me/jobs/<slug> URL を渡すこともできます。(HTML を除去した)
完全な説明、スキル、リージョン/国、そして求人情報が強化されている場合は
シニアリティ、カテゴリ、雇用形態、給与を返します。salary は freehire が
期間を記録している場合、その期間を保持します(INR 300000–300000/year、INR 12000/month)。報酬は
同じ期間でのみ比較してください。
すでにスラッグを持っている求人情報に使用してください — 追跡中の応募、共有された
リンク、または掲載が終了して検索に表示されなくなった求人など。search が
たった今返したヒットを再取得しても、すでに持っている説明を読み直すだけです。
使用例
# Senior backend roles, table view
bun run .agents/skills/freehire-search/cli/src/cli.ts search -q "backend engineer" --seniority senior --limit 10 --format table
# Remote React roles in the EU
bun run .agents/skills/freehire-search/cli/src/cli.ts search -q "react" --remote remote --region eu --format table
# DevOps roles in Germany posted in the last 14 days
bun run .agents/skills/freehire-search/cli/src/cli.ts search --category devops --country DE --jobage 14 --format table
# ML/AI roles anywhere, fully remote
bun run .agents/skills/freehire-search/cli/src/cli.ts search -q "machine learning" --category ml_ai --remote remote --format table
# Descriptions as plain text instead of Markdown
bun run .agents/skills/freehire-search/cli/src/cli.ts search -q "platform engineer" --limit 5 --description-format text
# Full details for a specific job
bun run .agents/skills/freehire-search/cli/src/cli.ts detail golang-zensar-2bxu6dxm --format plain
出力形式
| 形式 | 最適な用途 |
|---|---|
json | デフォルト — プログラムでの利用向け。各検索結果の説明が含まれる唯一の形式です |
table | 人がすばやく確認する場合 |
plain | 1件の求人の詳細全体を読む場合(detail コマンド) |
検索結果の JSON は { "meta": { "count", "page", "total" }, "results": [...] } です。各結果には少なくとも id(freehire のスラッグ)、title、company、location、date、url、description が含まれます(値がない場合は null)。table と plain では説明が省略されます。説明を含めると、一覧が読みづらくなるためです。すべてのエラーは { "error": "...", "code": "..." } の形式で stderr に出力され、プロセスは終了コード 1 で終了します。
部分的なデータ
ファセットは求人ごとに算出されるため、不完全な場合があります。特に地理情報がそうです。求人の work_mode(例:remote)は特定できても、ソースの所在地テキストが曖昧な場合、地域や国を特定できないことがあります(freehire の辞書は推測しません)。そのため、次の点に注意してください。
- 地域や国が欠けている場合は「該当なし」ではなく「未特定」を意味します。
--region euで絞り込むと、実際には EU 内にある求人でも、地域が特定されていないものは表示されません。対象に含めたい場合は、ファセットの条件を広げるか削除してください。 - 未特定の求人に対応する専用のファセット値があります。
--region noneは地域が特定されていない求人に一致します。地域が明記されていないリモート求人をまとめて取得する場合に便利です。実際の地域との OR 条件にもできます。例:--region eu,none。 - 同じ理由で、
result.regions/countries/citiesが空の配列になることがあります。空の場合は「該当なし」ではなく、不明として扱ってください。
注意事項
- データは freehire.me の公開 API から取得されるため、認証情報は不要です。ユーザーごとの追跡(応募/保存)にのみキーが必要ですが、このスキルでは意図的に扱いません。検索と詳細表示のみに対応しています。
- 検索結果の
idは freehire のpublic_slugです。そのままdetailに渡してください。 dateはYYYY-MM-DD形式の求人掲載日です(API のposted_atタイムスタンプの日付部分で、すべての求人ポータル CLI が出力する形式です)。掲載日がない求人ではnullになることがあります。- ファセット値は管理された語彙です。絞り込みの前に
/api/v1/jobs/facetsを使って、クエリに対する最新の値(件数付き)を確認してください。 - API では、429/5xx に対して指数バックオフで再試行します。API に到達できない場合は、明確なメッセージを表示してゼロ以外の終了コードで終了します(ベストエフォートのサービスです。上記の依存関係に関する注意を参照してください)。
searchは/api/v1/agent/jobs/searchを呼び出します(他と同様に公開されています)。--no-descriptionは、全文を提供しない軽量な/api/v1/jobs/searchを呼び出します。このエンドポイントより古いセルフホスト版インスタンスは 404 を返し、CLI は空の検索結果ではなく、エンドポイント名を示すエラーを報告します。