| PROJECT_PLAN.md | Loading last commit info... | |
| PROJECT_PROPOSAL.md | ||
| README.md |
AI Job Match — MCP Server + Dashboard
An AI-powered job search system made of two parts:
- MCP Server (
search-jobs-mcp) — exposes job-search tools (web search, storage, listing, deletion) to any MCP-compatible LLM client. - Client / Dashboard App — where a user uploads a resume, gets an AI-generated job profile, and sees ranked job matches they can apply to.
The LLM sits in the middle: it reads the resume, builds a profile, calls the MCP tools to search and store jobs, and scores each job against the profile.
1. How It Works (End-to-End Flow)
Step by step:
- Upload — user uploads a resume (PDF/DOCX) through the dashboard.
- Parse — backend extracts raw text from the resume.
- Profile generation — the LLM reads the resume text and produces a structured
job_profile(skills, years of experience, target roles, location preference, seniority, etc.). This is exposed back through the MCPjob_profiletool so any MCP client can fetch the current profile. - Keyword extraction — the LLM derives a short list of high-signal search keywords from the profile (e.g.
"senior backend engineer","Node.js","remote"). - Job search — the LLM calls
search_jobs(LangSearch Web Search API under the hood) using those keywords, plus location/limit/freshness filters. - Scoring — the LLM compares each returned job posting against the profile and assigns a match score (skills overlap, seniority fit, location fit, etc.).
- Storage — jobs above a score threshold are saved via
store_jobas structured JSON. - Listing — the dashboard calls
list_jobsto show saved jobs, most recently updated first, with their score. - Apply — user clicks "Apply," which opens the original posting URL (and optionally logs an "applied" status locally).
- Cleanup —
delete_joblets the user (or the LLM) remove stale/irrelevant postings.
2. MCP Server — search-jobs-mcp
A small FastMCP server that gives an LLM access to job-search tools. It searches the web for current job postings via the LangSearch Web Search API, stores useful job records in a local JSON file, and supports listing/deleting saved jobs.
Tool Overview
| Tool | Purpose |
|---|---|
job_profile | Returns the candidate profile the LLM uses for matching and ranking jobs. |
search_jobs | Searches the web for current job postings by role, location, limit, and freshness. |
store_job | Saves a job posting as structured JSON in local storage. |
list_jobs | Lists saved jobs, sorted by most recently updated first. |
delete_job | Deletes a saved job by id. |
Suggested Tool Schemas
// job_profile — no input, returns current profile
{
"name": "job_profile",
"output": {
"target_titles": ["string"],
"skills": ["string"],
"years_experience": "number",
"seniority": "junior | mid | senior | lead",
"location_preference": "string",
"remote_ok": "boolean",
"salary_expectation": "string | null",
"summary": "string"
}
}
// search_jobs
{
"name": "search_jobs",
"input": {
"role": "string",
"location": "string | null",
"limit": "number (default 10)",
"freshness": "day | week | month"
},
"output": [
{
"title": "string",
"company": "string",
"location": "string",
"url": "string",
"posted_at": "string",
"description_snippet": "string"
}
]
}
// store_job
{
"name": "store_job",
"input": {
"id": "string",
"title": "string",
"company": "string",
"location": "string",
"url": "string",
"score": "number",
"matched_keywords": ["string"],
"status": "new | applied | rejected | saved"
}
}
// list_jobs — no required input
{
"name": "list_jobs",
"output": [ /* array of stored job objects, sorted by updated_at desc */ ]
}
// delete_job
{
"name": "delete_job",
"input": { "id": "string" }
}
Local Storage
Jobs are stored in a local JSON file (e.g. data/jobs.json) as a simple array or map keyed by job id. This is fine for MVP; see the Roadmap section for moving to a real database.
Environment Variables
LANGSEARCH_API_KEY=your_key_here
JOBS_STORAGE_PATH=./data/jobs.json
MCP_SERVER_PORT=8000
Running the Server
# install dependencies
pip install -r requirements.txt # or: uv sync
# run the FastMCP server
python server.py
3. Client / Dashboard App
A web app the user interacts with directly.
Features
- Resume upload — drag-and-drop PDF/DOCX upload.
- AI job profile — auto-generated profile shown to the user (editable, since AI extraction won't always be perfect).
- Keyword view — shows the keywords the AI is using to search, editable before running a search.
- Job listing dashboard — ranked list of matching jobs with score, company, location, and a short "why it matches" explanation.
- Apply flow — one-click apply (opens posting or an internal application tracker).
- Saved / applied / rejected states — simple status tracking per job.
- Re-run search — refresh matches on demand or on a schedule.
Suggested Tech Stack
| Layer | Option |
|---|---|
| Frontend | React (Next.js) or plain React + Tailwind |
| Backend / API | Node.js (Express/Fastify) or Python (FastAPI) |
| LLM orchestration | Anthropic API (Claude) as MCP client |
| MCP transport | HTTP/SSE to search-jobs-mcp |
| Resume parsing | pdf-parse / mammoth (docx) or a hosted parser |
| Storage (MVP) | Local JSON (matches MCP server) |
| Storage (production) | PostgreSQL or SQLite + object storage for resumes |
| Auth | Clerk/Auth0/simple JWT, depending on scale |
Suggested API Routes (Backend)
POST /api/resume/upload -> parses resume, triggers profile generation
GET /api/profile -> returns current job_profile (proxies MCP tool)
PUT /api/profile -> lets user edit the AI-generated profile
POST /api/jobs/search -> triggers search_jobs + scoring, then store_job
GET /api/jobs -> proxies list_jobs for the dashboard
POST /api/jobs/:id/apply -> marks job as "applied", opens posting URL
DELETE /api/jobs/:id -> proxies delete_job
4. Repository Structure (Suggested)
project-root/
├── mcp-server/
│ ├── server.py
│ ├── tools/
│ │ ├── job_profile.py
│ │ ├── search_jobs.py
│ │ ├── store_job.py
│ │ ├── list_jobs.py
│ │ └── delete_job.py
│ ├── data/
│ │ └── jobs.json
│ └── requirements.txt
├── dashboard/
│ ├── src/
│ │ ├── pages/ (or app/)
│ │ ├── components/
│ │ └── lib/mcp-client.ts
│ └── package.json
├── docs/
│ ├── README.md
│ └── PROJECT_PLAN.md
└── .env.example
5. Roadmap (Post-MVP)
- Move from JSON file storage to Postgres/SQLite.
- Add authentication and multi-user support.
- Add background job for scheduled re-searches (daily/weekly).
- Add email/notification alerts for new high-score matches.
- Add application tracking with status pipeline (Applied → Interview → Offer → Rejected).
- Add resume improvement suggestions based on job description gaps.
- Add analytics (application-to-response rate, score accuracy over time).
6. Disclaimer
This project searches and aggregates publicly available job postings. Always confirm postings are legitimate and current before applying, and respect the terms of service of any source site the search results link to.