interview-prep-mcp
# interview-prep-mcp
[](https://github.com/shenmali/Interview-MCP-First/actions/workflows/ci.yml)
[](https://pypi.org/project/interview-prep-mcp/)
[](https://pypi.org/project/interview-prep-mcp/)
[](LICENSE)
> An open-source Python MCP server for AI-assisted interview preparation. Runs in any
> MCP-compatible host — Claude Desktop, Cursor, Google Antigravity, Windsurf — and
> defaults to Google Gemini with optional OpenRouter for cross-provider model selection.
## What it does
`interview-prep-mcp` exposes 17 tools that cover the full interview-prep loop:
- **Parse** a job posting (URL or pasted text) and a CV (PDF or markdown).
- **Persist** company and interviewer research collected by the host's other MCPs
(e.g. `firecrawl`, `exa`) — this server doesn't scrape itself.
- **Generate** personalized interview questions using the active LLM.
- **Submit** practice answers and get scored evaluations.
- **Analyze** weak areas across your practice history.
It also exposes:
- A `interview-prep://interviews/{id}` resource bundling the full prep state for one session.
- Two MCP prompts: `daily_prep` and `mock_interview`.
## Install
The fastest way — no global `pip install`:
```bash
uvx interview-prep-mcp
```
### Claude Desktop (`claude_desktop_config.json`)
```json
{
"mcpServers": {
"interview-prep": {
"command": "uvx",
"args": ["interview-prep-mcp"],
"env": {
"GEMINI_API_KEY": "AIza...",
"OPENROUTER_API_KEY": "sk-or-..."
}
}
}
}
```
`OPENROUTER_API_KEY` is optional — leave it out if you only want to use Gemini.
### Google Antigravity
Antigravity uses the same `mcpServers` JSON in its MCP settings panel. Paste the same
block as above. Antigravity ships with Gemini already configured at the host level, so
you'll typically only need to add the MCP entry itself.
### Cursor (`~/.cursor/mcp.json`)
Same `mcpServers` block as Claude Desktop.
### Windsurf and other MCP-compatible hosts
Same `mcpServers` block; just paste it into whichever config path the host documents.
## Required env
| Variable | Required? | Purpose |
|---|---|---|
| `GEMINI_API_KEY` | Yes (default) | Direct Gemini API access. |
| `OPENROUTER_API_KEY` | No | Enables `set_model` to switch to any of 200+ OpenRouter models. |
You can run with only one of them set. If neither is set, the server still starts —
context tools (parsing, storage) work; smart tools will return a clear "no LLM provider
configured" error when invoked.
## Recommended companion MCPs
To research companies and interviewers, install these alongside:
- [`firecrawl-mcp`](https://github.com/mendableai/firecrawl-mcp-server) — scrape pages.
- [`exa-mcp-server`](https://github.com/exa-labs/exa-mcp-server) — web search.
The host orchestrates all three. `interview-prep-mcp` exposes `save_research_note` for
the host to persist whatever those companion MCPs returned.
## Quick start (5 minutes)
1. Set `GEMINI_API_KEY` and install the server in your host (see snippets above).
2. In a fresh chat: `parse_job_posting("https://example.com/jobs/123")`.
3. `parse_cv("/path/to/cv.pdf")` — first CV becomes active automatically.
4. `start_interview_prep("Acme", "Senior Backend Engineer", job_id=1, cv_id=1)`.
5. (Optional) Ask Claude to research the company via `firecrawl`/`exa` and call
`save_research_note(interview_id=1, kind="company", content="...")`.
6. `generate_questions(interview_id=1, count=10, types=["technical","behavioral"])`.
7. Answer questions; each answer goes to `submit_practice_answer`.
8. After several answers: `analyze_weak_areas(interview_id=1)`.
## Tool reference
| Tool | LLM? | Description |
|---|---|---|
| `parse_job_posting(source_or_text, is_html?)` | no | URL or text → structured JobPosting. |
| `parse_cv(file_path)` | no | PDF/markdown → CVProfile. First CV is set active. |
| `list_cv_profiles()` | no | All CVs with their `is_active` flag. |
| `set_active_cv(cv_id)` | no | Switch which CV other tools default to. |
| `match_cv_to_job(job_id, cv_id?)` | yes | Score + strengths + gaps. |
| `start_interview_prep(company, role, job_id?, cv_id?)` | no | New prep session. |
| `list_interviews()` | no | Active prep sessions. |
| `save_research_note(interview_id, kind, content, subject?, source_url?)` | no | Persist markdown research. `kind ∈ {company, interviewer, other}`. |
| `get_research(interview_id)` | no | Grouped by kind. |
| `generate_questions(interview_id, count, types)` | yes | Personalized Qs using job + cv + research. |
| `list_questions(interview_id)` | no | Previously generated. |
| `submit_practice_answer(question_id, answer_text)` | yes | Returns evaluation. |
| `get_practice_history(interview_id)` | no | Past attempts. |
| `analyze_weak_areas(interview_id)` | yes | Recurring gaps + recommended topics. |
| `list_models(provider?, ...filters)` | no | Gemini (curated) + OpenRouter (24h cached). |
| `set_model(model_id, provider?)` | no | Persist active model. |
| `get_active_model()` | no | Current selection. |
## Architecture
```
MCP Host
├── firecrawl-mcp ──────┐
├── exa-mcp ────────────┤
└── interview-prep-mcp ─┘
│
├── Tools layer
├── Service layer (parsers + storage + LLM router)
├── SQLite (~/.interview-prep/db.sqlite)
├── Config (~/.interview-prep/config.json)
└── LLM router ──┬── Gemini (default)
└── OpenRouter (optional)
```
The MCP composes with companion MCPs — it does not scrape itself. The host's Claude
calls `firecrawl`/`exa`, then feeds findings into `save_research_note`.
## Contributing
```bash
git clone https://github.com/shenmali/Interview-MCP-First
cd interview-prep-mcp
python3.11 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
ruff check .
mypy interview_prep_mcp
```
CI runs ruff + mypy + pytest on every PR.
## License
MIT — see `LICENSE`.
TDQS
Scored across 17 tools
Each tool targets a distinct operation: CV parsing vs job parsing, question generation vs answer submission, session management vs research notes. No two tools have overlapping purposes; even similar verbs like 'list' and 'get' are applied to different resources (interviews vs practice history vs questions).
All tools follow a consistent verb_noun_tool pattern in snake_case (e.g., parse_cv_tool, list_interviews_tool, set_active_cv_tool). Verbs are descriptive and uniformly placed at the start. No mixing of conventions or cryptic abbreviations.
17 tools is well-scoped for a specialized interview preparation server. The count covers essential workflows (CV management, job parsing, question generation, practice, feedback, research, model config) without being overwhelming or sparse.
Core CRUD-like operations are present for key entities (create/list for interviews, parse/list for CVs and jobs, generate/list for questions). Minor gaps: no update or delete tools for CVs, job postings, or research notes, but the primary workflow (parse-match-practice-analyze) is fully covered.