job-search-mcp
Personal MCP server (stdio) that aggregates job listings from Remotive and Arbeitnow, with local SQLite caching, application tracking, and saved searches.
Setup
npm install
npm run build # emits dist/
npm test # 27 tests
npm run typecheck
Requires Node 20+. The cache DB lives at ~/.job-search-mcp/jobs.db (override with JOB_SEARCH_MCP_DB).
Environment variables
No API keys needed — both providers are public.
| Var | Needed for |
|---|---|
JOB_SEARCH_MCP_DB |
optional DB path override |
Register in Claude Desktop
claude_desktop_config.json:
{
"mcpServers": {
"job-search": {
"command": "node",
"args": ["/absolute/path/to/job-search-mcp/dist/index.js"]
}
}
}
Register in Claude Code
claude mcp add job-search \
-- node /absolute/path/to/job-search-mcp/dist/index.js
Tools & example prompts
| Tool | Example prompt |
|---|---|
search_jobs |
"Find remote QA automation jobs with Playwright posted in the last week" |
get_job_details |
"Show me the full description of that Clipster job" |
whats_new |
"Anything new since yesterday matching playwright?" |
track_job |
"Mark that job as applied — note: sent CV via referral" |
list_tracked |
"Show my application pipeline" / "What am I interviewing for?" |
save_search / run_saved_search / list_saved_searches |
"Save this as my daily qa-remote search" → "Run my qa-remote search" |
set_profile / get_profile |
Paste your CV (or attach the file) → "store this as my profile" → the model derives target titles/skills and proposes searches; later: "search based on my CV" |
Job ids look like remotive:2091062 / arbeitnow:<slug> and appear in every search result block.
Smoke test
node smoke.mjs spins up the built server over stdio and exercises every tool against the live APIs (uses a throwaway DB at /tmp/job-search-smoke.db).
Provider quirks discovered during development
- Remotive (
https://remotive.com/api/remote-jobs): endpoint as documented.publication_datehas no timezone suffix (treated as UTC).salaryis a free-text string — parsed best-effort into min/max/currency. Descriptions are heavy HTML (Tailwind inline styles) — stripped and truncated to ~1500 chars. Remotive asks not to poll aggressively, so responses are cached in-memory for 15 minutes per query on top of the SQLite cache. - Arbeitnow (
https://www.arbeitnow.com/api/job-board-api): endpoint as documented;remoteandvisa_sponsorshipparams work. Undocumented: asearchquery param is honored by the API (visible in its pagination links) — used here, plus a client-side all-terms filter as a safety net since server-side matching is loose.created_atis a unix timestamp. Heavily German-market (many listings in German). Paginated vialinks.next; the adapter fetches up to 3 pages.
Discrepancies vs. the original spec: none for endpoints — both matched their docs. The only additions are the undocumented Arbeitnow search param (used) and the Remotive no-timezone date quirk (handled).