mcp-job-search
An MCP server that searches Berlin job listings across Arbeitnow, Stepstone, LinkedIn, Indeed, and Glassdoor, filters for English-friendly roles, and builds assisted-apply packets — cover letter, outreach email, LinkedIn referrer message, and apply URL — for each role.
It does not auto-submit applications. You stay the human pressing send.
Install
The fastest path uses uv (one command, no virtualenv juggling):
curl -LsSf https://astral.sh/uv/install.sh | sh # if you don't have uv
Then add this block to your Claude Desktop config:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"job-search": {
"command": "uvx",
"args": ["--from", "mcp-job-search", "mcp-job-search"]
}
}
}
Restart Claude Desktop. uvx downloads and caches the package on first call.
Tools
| Tool | What it does |
|---|---|
search_jobs |
Search Arbeitnow + Stepstone + JobSpy (LinkedIn/Indeed/Glassdoor). Honors a min_results floor — tops up with German listings if the English filter starves it. |
get_job_details |
Pull the full description for a single job. |
filter_english_jobs |
Keep only listings whose description is English-friendly. |
build_application_packet |
Per-job: cover letter, outreach email (if a contact email was found), LinkedIn referrer message, and a search URL to find a referrer. |
list_referral_targets |
For jobs without contact emails, return ready-to-paste LinkedIn DMs and a search URL for each. |
set_resume |
Point the server at a resume (PDF, DOCX, TXT) for the rest of the session. |
set_candidate |
Capture name/email/phone/LinkedIn/pitch at runtime so cover letters render properly. |
Slash-command prompts
| Prompt | What it does |
|---|---|
/start_job_search |
Guided intake: CV → email → job category (Warehouse / Mini-job / DevOps / Professional) → location, then searches and triages. |
/rewrite_cv_bullets |
Generates up to 10 tailored CV bullet points blending your real experience with a specific job description. No fabricated metrics, no JD keyword stuffing. |
How to use it
The fastest path is the slash command:
/start_job_search
Claude walks you through CV path, email, category, and location, then searches and surfaces the top 5 results grouped by company. You pick which to expand into an application packet.
Or just talk in plain English:
"Find me senior Python backend roles in Berlin, English-only."
"Build an application packet for job arbeitnow:backend-engineer-acme."
"Rewrite my CV bullets for the role at N26."
Configuration
The server reads ~/.config/mcp-job-search/config.yaml if present, else the bundled defaults (Berlin, English-only). For per-session overrides — your resume, your email, your name — use the set_resume and set_candidate tools (Claude calls them automatically during the guided flow).
If you want defaults to persist across sessions, drop a config file at the path above:
location: "Berlin"
english_only: true
resume_path: "/Users/you/Documents/resume.pdf"
candidate:
name: "Your Name"
email: "you@example.com"
linkedin_url: "https://linkedin.com/in/yourhandle"
pitch: "Backend engineer with 5+ years building Python services"
Limits + honest caveats
- Arbeitnow: free public API, no key. Coverage skews toward Berlin/EU tech and remote roles. The API has no server-side search, so the client paginates a few pages and filters locally.
- Stepstone: HTML scrape. Brittle when they redesign — open an issue if results start returning empty.
- JobSpy (LinkedIn / Indeed / Glassdoor): also scrape-based, via the
python-jobspypackage. LinkedIn rate-limits aggressively and Glassdoor's location parser sometimes errors on German city strings — Indeed is the most reliable of the three. - English filter: heuristic. A few German-language postings that mention "Englisch" will slip through, and a few English-friendly ones with mostly German boilerplate will get cut. The
min_resultstop-up will fill the gap with German jobs (taggedlanguage='de') so you always get a list. - Cover letters / referral messages: deterministic templates. Claude refines per job — you copy out.
Dev install (contributing)
git clone https://github.com/heykay/mcp-job-search
cd mcp-job-search
uv sync
uv run pytest
Local Claude Desktop entry pointing at your clone:
"job-search": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/mcp-job-search", "run", "mcp-job-search"]
}
License
MIT — see LICENSE.
Metadata
Release files for mcp-job-search 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| mcp_job_search-0.1.0.tar.gz | 24.2 kB | Without provenance | Details for mcp_job_search-0.1.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| mcp_job_search-0.1.0-py3-none-any.whl | Python 3 | none | any | Details for mcp_job_search-0.1.0-py3-none-any.whl |
Total release size: 54.9 kB
Release files / mcp_job_search-0.1.0.tar.gz
| Download URL | mcp_job_search-0.1.0.tar.gz |
|---|---|
| Size | 24.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9bad41fe8e78b4f5b7f3d6c5d9f7f2af1c57244dee0b216993bff79db49d2fae
|
|
BLAKE2b-256 checksum How to use checksums |
d6ed36c556685b3c671cac84fba44717b6985e5575009368c7837b0f17fc8370
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / mcp_job_search-0.1.0-py3-none-any.whl
| Download URL | mcp_job_search-0.1.0-py3-none-any.whl |
|---|---|
| Size | 30.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
305c37a4c7ef992b763d5aba96f5acd591c522949c64e73e710c822052d4e579
|
|
BLAKE2b-256 checksum How to use checksums |
a4f12117e1753984c03be4c65d035299644bf0de9e7dfef3d5413a8dfacf4f29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for mcp-job-search 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.