Metadata-Version: 2.4
Name: mcp-job-search
Version: 0.1.0
Summary: 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 letters, outreach emails, and LinkedIn referrer messages.
Project-URL: Homepage, https://github.com/heykay/mcp-job-search
Project-URL: Issues, https://github.com/heykay/mcp-job-search/issues
Author-email: Heykay <akhinoz@gmail.com>
License: MIT
License-File: LICENSE
Keywords: anthropic,berlin,claude,indeed,job-search,jobs,linkedin,mcp
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: End Users/Desktop
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business
Classifier: Topic :: Software Development :: Libraries
Requires-Python: >=3.11
Requires-Dist: httpx>=0.27.0
Requires-Dist: langdetect>=1.0.9
Requires-Dist: mcp[cli]>=1.2.0
Requires-Dist: pydantic>=2.6.0
Requires-Dist: pypdf>=4.0.0
Requires-Dist: python-docx>=1.1.0
Requires-Dist: python-jobspy>=1.1.70
Requires-Dist: pyyaml>=6.0
Requires-Dist: selectolax>=0.3.21
Provides-Extra: dev
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.5; extra == 'dev'
Description-Content-Type: text/markdown

# 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`](https://github.com/astral-sh/uv) (one command, no virtualenv juggling):

```bash
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`

```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:

```yaml
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-jobspy` package. 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_results` top-up will fill the gap with German jobs (tagged `language='de'`) so you always get a list.
- **Cover letters / referral messages**: deterministic templates. Claude refines per job — you copy out.

---

## Dev install (contributing)

```bash
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:

```json
"job-search": {
  "command": "uv",
  "args": ["--directory", "/absolute/path/to/mcp-job-search", "run", "mcp-job-search"]
}
```

## License

MIT — see [LICENSE](LICENSE).
