job-search-mcp
job-search-mcp
Claude Desktop 用の個人向け求人検索アシスタントです。Claude に求人を探してもらうと、実際の求人ボードを検索し、あなたへの適合度を 0〜100 でスコアリングして、ワンクリックで選別できるランキングボードに表示します。すべてローカルで動作し、API キーやアカウントは不要です。
これは MCP App です。Claude Desktop が通信する小さなサーバーと、チャット内に直接表示されるインラインボードで構成されています。
対象範囲: 米国のソフトウェアエンジニアリング職向けに調整されています(組み込みのソースとロールフィルターは米国のテック企業を対象としています)。他の職種や地域では検索結果が少なくなります。
対応環境: Claude Desktop 向けに構築・テストされています。ローカル(stdio)サーバーを実行し、MCP App UI をレンダリングする他の MCP クライアント(VS Code (Copilot)、Cursor、Goose など)でも動作するはずです(未テスト)。リモート専用クライアント(ChatGPT、Web/モバイル版 Claude)はローカルサーバーを起動できないため、動作しません。

機能
実際の求人ボードを検索 — LinkedIn に加えて 8 つの ATS/求人ソース(Greenhouse、Lever、Ashby、Workday、SmartRecruiters、Hacker News、RemoteOK、Remotive)を、あなたの対象ロールと場所を使って検索します。
各求人を あなた 向けにスコアリング — Claude が完全な説明文を読み、あなたのスキル、経験年数、シニア度の適合、ロールを考慮して、0〜100 の適合スコアと一言の理由を付けます。
素早く選別可能 — 各カードで Apply / Skip、または一括操作(「60 未満をすべて却下」など)。
記憶する — 進行中のショートリスト、応募済みのトラッカーを保持し、同じ求人を(6 か月間)二度表示しません。
Related MCP server: Jobless MCP
セットアップ
1. Claude Desktop にこのアプリを認識させます。 設定ファイルを開きます:
Windows:
%APPDATA%\Claude\claude_desktop_config.jsonmacOS:
~/Library/Application Support/Claude/claude_desktop_config.json
"mcpServers" の下にこれを追加します。npx が 公開パッケージ を取得してくれるので、クローンやビルドは不要です:
{
"mcpServers": {
"job-search": {
"command": "npx",
"args": ["-y", "@servation/job-search-mcp"]
}
}
}2. Claude Desktop を完全に終了して再起動します(Windows ではシステムトレイから終了してください。ウィンドウを閉じるだけでは不十分です)。以上です。
npm install
npm run build代わりに設定でこのフォルダの dist/main.js を指定します:
{
"mcpServers": {
"job-search": {
"command": "node",
"args": ["D:\\job-search-mcp\\dist\\main.js"]
}
}
}使い方
Claude に話しかけるだけです。例:
「プロフィールを保存」 — まず履歴書を貼り付けます。Claude がスキル、ロール、経験年数、場所を抽出し、検索とスコアリングをあなたに合わせます。
「カリフォルニアのシニアレベルのバックエンドエンジニアの求人を今週投稿されたもので探して」
「応募者が少ない求人を探して」 — LinkedIn の早期応募者フィルターを追加します。
「60 未満をすべて却下して」
「応募したものを表示して」
「ボードを再スコアリングして」
典型的な初回実行:プロフィールを保存 → 「求人を探す」 → Claude がスコアリングしてランキングボードを表示 → あなたが Apply/Skip を選択。
ボード
ボードは進行中のショートリストです。求人は Apply(トラッカーに移動)または Skip(完全に非表示)するまでボードに残ります。新しい検索では、ボード上、トラッカー内、却下済み、または過去 6 か月に表示された求人を自動的にスキップするため、同じ求人を続けて二度見ることはありません。
カードの Applied または Skip をクリックするか、Claude に指示します。ウィジェットで選別した内容は保持されます。
ツール(参考用)
これらのツールを名前で呼ぶことはほとんどありません(Claude が適切なものを選びます)が、内部では次のようになっています:
Tool | 説明 |
| ロール/場所でボードを検索(オプションのフィルター:シニア度、タイプ、新しさ、リモート、給与、応募者数、ソース)。 |
| Claude が検索結果の求人を 0〜100 で適合度スコアリング(検索後に自動実行)。 |
| ランキングボード(または |
| 単一の求人に Apply / Skip / 保存(カードのボタンも同様)。 |
| スコアやソースで一度に多数を選別(例:60 未満をすべて却下)。 |
| 現在のボードをテキストで一覧表示(スコア済みの全求人 + 未スコアのもの)。 |
| トラッカー — 保存または応募した求人。 |
| ボード上のすべての求人を最初から再スコアリング。 |
| 整理:未スコアの残りやボード全体をクリア(応募済み/却下済みには触れません)。 |
| 履歴書プロフィールを保存(検索とスコアリングに使用)。 |
データの保存場所
データはマシン上の 1 つの JSON ファイルに保存されます。クラウドはなく、検索する求人ボード以外には何も送信されません:
インストール版:
~/.job-search-mcp/jobs.jsonソースから実行:
./data/jobs.jsonJOB_SEARCH_MCP_DATA環境変数で上書き可能。
オプション: LinkedIn Premium モード
デフォルトでは、LinkedIn はパブリックゲストエンドポイントを使用します。ログイン不要でアカウントログインのリスクもなく、完全な求人説明文が得られます。自動アクセスは依然として自分の IP から実行され、ゲストモードでも LinkedIn の利用規約に違反することに注意してください。自己責任で使用してください。よりリッチな/Premium データが必要な場合は、サーバー設定に env ブロックを追加して、ログイン済みアカウントを使用できます:
"job-search": {
"command": "npx",
"args": ["-y", "@servation/job-search-mcp"],
"env": {
"LINKEDIN_LI_AT": "<your li_at cookie>",
"LINKEDIN_JSESSIONID": "ajax:1234567890123456789"
}
}ログイン済みの linkedin.com タブ → DevTools → Application → Cookies から両方の Cookie を取得します。
⚠️ 注意: これは LinkedIn の利用規約に違反し、アカウントがフラグ付けされたり制限されたりする可能性があります。Cookie は約 1 か月で期限切れになり、LinkedIn の内部エンドポイントは予告なく変更されます。何か失敗した場合は自動的にゲストモードにフォールバックします。完全に安全を保つには(ゲストのみ)、
envブロックを省略してください。
スコアリングの仕組み
Claude(ホストモデル)が直接スコアリングを行います。各説明文を読み、適合度を判断するため、精度が高いです。決定論的な式(scoring.ts の computeMatchScore)は、すべてを過大評価しがちな弱いローカルモデルを使用する場合のフォールバックとして保持されていますが、デフォルトでは有効ではありません。
開発
npm run typecheck # type-check UI + server + harness
npm run build # build the UI bundle (vite single-file) + compile the server (tsc)
npm run serve:stdio # run the server from source (tsx) for local testing
npm run harness # work on the review UI without Claude Desktop (see harness/)
npm run canary # check every job source is still returning postingsサーバーは stdio のみ(main.ts → server.ts)。UI は React アプリで、単一のインライン HTML ファイル(src/mcp-app.tsx → dist/mcp-app.html)にバンドルされ、サーバーが ui:// リソースとして提供します。
UI を開発するときは harness/ を使用します。これは Claude Desktop のローカル代替で、合成ジョブストアと実際の ui/* ブリッジに対してウィジェットをレンダリングします。ブラウザタブで dist/mcp-app.html を開くと「Connecting…」と表示されるだけで、壊れやすい部分(リンクの開閉、テーマ、マウント後の更新)はすべてホスト経由なので、相手側にホストがある場合にのみ表示されます。
求人ソースが停止した場合、npm run canary でどのソースかがわかります。企業スラッグは頻繁に腐るため、修正は通常、新しいリリースではなく、updateCompanyDirectoriesFromRegistry() が実行時に再読み取りするリモートスラッグレジストリに属します。
Available Tools
10 toolsbulk_statusBulk TriageA
Triage MANY board jobs at once by score and/or source — e.g. dismiss every scored job under 60. Applies status to all scanned (board) jobs matching the filters; the server selects them, so you do NOT need the individual job ids. below_score/above_score match SCORED jobs only (use clear_jobs for un-evaluated ones). Provide at least one filter. Returns text; call show_board afterward to display.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Optional note to attach to every matched job. | |
| source | No | Restrict to one source. | |
| status | Yes | Status to apply to every match. | |
| above_score | No | Match scored jobs with matchScore AT OR ABOVE this. | |
| below_score | No | Match scored jobs with matchScore BELOW this (e.g. 60). |
clear_jobsClear JobsA
Clear jobs from the review board. which='unscored' (default) removes only the not-yet-evaluated leftovers; which='all' clears the whole board. Saved/applied jobs (the tracker) and dismissed jobs are NOT affected — dismissed jobs still won't be re-sourced. Returns text; call show_board to display.
| Name | Required | Description | Default |
|---|---|---|---|
| which | No | 'unscored' (default) clears un-evaluated jobs; 'all' clears the whole board. |
evaluate_jobsEvaluate JobsA
Score one or more sourced jobs for THIS candidate (holistic). YOU assign each job a 0-100 fit score directly, using the candidate summary (shown in find_jobs / whats_promising) and the job description. Weigh the must-have requirements, the candidate's actual skills and years of experience (a role demanding far more seniority/years than the candidate has should score LOWER), domain fit, and standout strengths. Calibrate and use the FULL range — do not bunch everything at 80+: 80-100 = strong fit and realistic; 60-79 = good with real gaps; 40-59 = partial/stretch (e.g. wrong level); below 40 = poor or wrong field. Pass { job_id, score, reason } per job. Use the EXACT bracketed ids; do not invent them. Score every job in one call. Returns text; call show_board afterward to display the ranked board.
| Name | Required | Description | Default |
|---|---|---|---|
| evaluations | Yes | One entry per job to score. |
find_jobsFind JobsA
Source live jobs (LinkedIn + Greenhouse, Lever, Ashby, Workday, SmartRecruiters, Hacker News, RemoteOK, Remotive), dedup them, and return them as text with full descriptions. Uses the saved profile's roles/location by default; pass query/location/filters to override. This returns UNSCORED jobs and does NOT show a card UI — immediately score all of them with evaluate_jobs (a 0-100 fit score + reason each), then show_board once, to present the single ranked board. Do not just list them back.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max jobs to return/persist this run (default 15). | |
| query | No | Role/keyword filter, e.g. 'backend java spring'. Overrides the profile's target roles. | |
| remote | No | Workplace type (LinkedIn); also sets remote preference. | |
| sort_by | No | LinkedIn result ordering. | |
| sources | No | Restrict to these sources (default: all). | |
| job_type | No | Employment type (LinkedIn). | |
| location | No | Location filter, e.g. 'California' or 'Remote'. Overrides the profile's search location. | |
| max_years | No | Candidate's years of experience for this search (overrides the saved profile); also defaults the seniority filter. | |
| salary_min | No | Minimum annual salary filter (LinkedIn), e.g. 100000. | |
| date_posted | No | Recency filter (LinkedIn). | |
| verify_urls | No | If true, network-verify each job URL (slower). Default false. | |
| max_applicants | No | Surface low-applicant LinkedIn jobs (uses LinkedIn's early-applicant filter, ~under 25). Exact applicant-count filtering requires the LinkedIn cookie. | |
| experience_level | No | Seniority filter (LinkedIn). |
rescore_boardRe-score BoardA
Re-score the WHOLE board from scratch — every job, INCLUDING ones that already have a score. Use this when the user asks to 'rescore'/'re-evaluate' the board or after the scoring approach changed. Returns all board jobs with their ids + descriptions; call evaluate_jobs with a FRESH { job_id, score, reason } for EACH (do not skip already-scored ones), then call show_board. Set include_saved=true to also re-score the saved/applied tracker.
| Name | Required | Description | Default |
|---|---|---|---|
| include_saved | No | Also re-score the saved/applied tracker jobs (default false). |
review_savedReview Saved JobsA
List the tracker as text: jobs marked saved (interested) or applied, with their status, score, and notes. Use this to see what you're tracking or have applied to. To DISPLAY the tracker widget, call show_board with view='saved'.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
save_profileSave Resume ProfileA
Extract the candidate's profile from their resume text (which the user pastes in chat) and save it. Pull: full name; core technical skills; suggested target roles; preferred/search location; total years of professional experience (integer); and pass the resume text as rawText. The profile is used by find_jobs (target roles + location) and by scoring (years of experience drives the experience penalty), so set yearsOfExperience accurately. Merges with any existing profile.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Candidate's full name. | |
| skills | No | Core technical skills. | |
| rawText | No | The full resume text, stored for reference. | |
| targetRoles | No | Suggested target job titles. | |
| prefersRemote | No | Whether the candidate prefers remote. | |
| searchLocation | No | Preferred location, e.g. 'California' or 'Remote'. | |
| blockedCompanies | No | Companies to exclude from sourcing. | |
| yearsOfExperience | No | Total years of professional experience (integer). |
set_statusSet Job StatusA
Triage a job by id: 'saved' (interested/tracking), 'applied' (also stamps the date), 'dismissed' (skip), or 'discovered' (undo back to the board). Moves it between the scanned/saved/dismissed lists and persists. Optionally attach notes. Called by the review UI; also usable directly.
| Name | Required | Description | Default |
|---|---|---|---|
| notes | No | Optional notes to attach to the job. | |
| job_id | Yes | The job's id. | |
| status | Yes | New triage status. |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes | |
| view | No | |
| count | Yes | |
| scored | Yes | |
| profile | Yes |
show_boardShow BoardA
Display the job board (or the saved/applied tracker) as an interactive widget. Call this ONCE, at the end of a request, after doing the work (find_jobs/evaluate_jobs/bulk_status/clear_jobs/whats_promising are text-only and do NOT render). view='board' (default) shows the ranked board; view='saved' shows the tracker.
| Name | Required | Description | Default |
|---|---|---|---|
| view | No | 'board' (default) = the ranked board; 'saved' = the applied/saved tracker. |
Output Schema
| Name | Required | Description |
|---|---|---|
| jobs | Yes | |
| view | No | |
| count | Yes | |
| scored | Yes | |
| profile | Yes |
whats_promisingWhat's PromisingA
List the current job board as text: every scored job (with its id) and any UNSCORED jobs with their ids + descriptions so you can evaluate them. To score the unscored ones, call evaluate_jobs with the EXACT bracketed ids shown. Use this to review jobs already found (find_jobs only returns brand-new ones). To re-score jobs that ALREADY have a score, use rescore_board instead. To DISPLAY the board widget to the user, call show_board (this returns text for you to act on).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max unscored jobs to surface for evaluation (default 15). |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
10 tool updates
v0.1.1- First observed
bulk_status - First observed
clear_jobs - First observed
evaluate_jobs - First observed
find_jobs - First observed
rescore_board - First observed
review_saved - First observed
save_profile - First observed
set_status - First observed
show_board - First observed
whats_promising
TDQS
Scored across 10 tools
Each tool has a clearly distinct purpose: bulk_status for bulk triage, clear_jobs for clearing, evaluate_jobs for scoring single jobs, find_jobs for sourcing, rescore_board for re-evaluating all, review_saved for tracker text, save_profile for profile, set_status for individual triage, show_board for display, and whats_promising for listing. No overlap.
All tool names follow a consistent verb_noun pattern in snake_case (e.g., bulk_status, evaluate_jobs, save_profile). The only minor deviation is 'whats_promising' using a contraction, but it still follows the pattern and is easily readable.
10 tools is well within the ideal 3-15 range for a focused job search server. Each tool addresses a necessary function without bloat, and the count feels natural for the domain.
The tool set covers the core workflow: sourcing (find_jobs), scoring (evaluate_jobs, rescore_board), triaging (bulk_status, set_status, clear_jobs), tracking (review_saved), display (show_board), and profile management (save_profile). Minor gaps like no explicit profile update tool exist, but save_profile merges, so it's almost complete.
Maintenance
Related MCP Connectors
AI job matching in your assistant: ranked offers, tailored resumes, application tracking.
Tailor resumes, score ATS fit, find hiring leads, and send cold outreach, from your agent.
Job search for your AI: save jobs, research companies, keep stories, track applications.
Your personal career coach. Scanning jobs for you, daily.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables job search and scraping across multiple job boards (LinkedIn, Indeed, Glassdoor, etc.) with advanced filtering, directly from Claude Desktop or other MCP clients.6MIT
- AlicenseNot gradedqualityBmaintenancePersonalized job search inside Claude. Get ranked job matches based on your actual skills, not keywords.2MIT
- AlicenseAqualityDmaintenanceTransforms Claude into an AI job-hunting assistant that searches remote job boards, scores roles against your CV, generates tailored cover letters, and logs everything to a Notion tracker.11MIT
- AlicenseNot gradedqualityDmaintenanceEnables searching and evaluating job postings from LinkedIn and freehire.me directly through Claude Desktop. Provides tools to search jobs, fetch full posting details, and assess candidate fit using eligibility scans and a scoring rubric.MIT