Content
# Resume MCP
> **Local-only MCP server.** Enter a job description (JD) to generate a customized resume based on your profile.
> Your profile and generated documents **stay on your machine**. Only LLM calls are made with your API key outside, and using Local LLM (Ollama) makes it completely offline.
[](https://www.npmjs.com/package/@doyeonjeong/resume-mcp)
[](LICENSE)
Most resume AI tools require you to upload your career data to their servers. This tool doesn't. Your profile stays in `~/.resume-mcp/profile.json` on your disk, and the MCP server runs as a local process within your client (e.g., Cursor, Claude Code, Antigravity) — no third-party SaaS holds your data.
## Why MCP and Local?
- **Privacy by design** — Profile JSON exists only on your filesystem. No DB, no cloud sync, no telemetry.
- **Reusable** — Write your career data once and reuse it for dozens of customized resumes.
- **Modular pipeline** — Separate stages: `analyze_jd → match_profile_to_jd → generate_resume_bullets → generate_resume_markdown`. User intervention possible.
- **AI IDE native** — Works with MCP-compatible clients like Cursor, Claude Code, Cline, and Antigravity.
## Installation (60 seconds)
Add one line to your MCP client settings (e.g., `~/.cursor/mcp.json`, `~/.claude/mcp_config.json`):
```json
{
"mcpServers": {
"resume-mcp": {
"command": "npx",
"args": ["-y", "@doyeonjeong/resume-mcp"],
"env": {
"LLM_PROVIDER": "gemini",
"GOOGLE_API_KEY": "your_api_key_here"
}
}
}
}
```
Restart your client and type *"call get_profile"* to generate your profile template at `~/.resume-mcp/profile.json` on the first call.
### Choose LLM Provider
Cloud LLM is used for one-shot resume generation. Choose any available key:
```json
"env": {
"LLM_PROVIDER": "claude", // or "openai" | "gemini"
"ANTHROPIC_API_KEY": "...",
"OPENAI_API_KEY": "...",
"GOOGLE_API_KEY": "..."
}
```
Multi-stage pipelines (`analyze_jd`, `match_profile_to_jd`, etc.) use **Local LLM** by default. Use Ollama (recommended) or an OpenAI-compatible endpoint:
```json
"env": {
"LOCAL_LLM_PROVIDER": "ollama",
"LOCAL_LLM_MODEL": "gemma4:26b"
}
```
## Profile Setup
Fill `~/.resume-mcp/profile.json` with your career data:
```json
{
"name": "John Doe",
"title": "Backend Developer",
"summary": "...",
"skills": ["NestJS", "TypeScript", "..."],
"projects": [
{
"title": "Project Name",
"period": "2025.01 ~ 2025.06",
"role": "Backend Lead",
"description": "Your actual work",
"techStack": ["..."],
"achievements": "Specific, fact-based achievements",
"githubUrl": "https://github.com/you/project"
}
]
}
```
Or let AI fill it for you:
> "Update my profile. Skills are NestJS, TypeScript, Python, MCP SDK"
→ AI calls `update_profile` → file partially updated.
Placeholder values (e.g., "John Doe", "Project Name", "username/project") will cause the server to **reject generation** — preventing incorrect boilerplate resumes.
### Change Profile Location
```json
"env": {
"RESUME_MCP_PROFILE_PATH": "/path/to/your/profile.json"
}
```
## Usage Scenarios
### Scenario 1 — JD Input, One-Shot Resume
Paste JD into chat:
> "Generate a resume for this JD. Company: ROSAIC, Position: LLM Engineer.\n\n<JD text>"
→ AI calls `generate_resume({ jdText, companyName, position, language: "en" })` → markdown resume in 10-20 seconds.
### Scenario 2 — Modular Pipeline (more accurate, recommended)
Four tools, each stage allows user intervention:
| Stage | Tool | Output |
|---|---|---|
| 1 | `analyze_jd` | Structured JSON: required/preferred skills, ATS keywords, risk factors |
| 2 | `match_profile_to_jd` | Strong matches, partial matches, **items not to exaggerate** |
| 3 | `generate_resume_bullets` | ATS-friendly bullets, summary, self-introduction hooks |
| 4 | `generate_resume_markdown` | Final markdown resume, template selection (`general` / `backend` / `fullstack` / `ios` / `ai-agent`) |
Takes ~90 seconds (Local LLM). The key is stage 2 — preventing overstatement.
### Scenario 3 — One-Shot Cover Letter
> "Generate a cover letter for this JD"
→ `generate_cover_letter({ jdText, companyName, position, language: "en" })`
### Scenario 4 — Portfolio Summary
> "Summarize my profile into a one-page portfolio"
→ `generate_portfolio({ language: "en" })`
## MCP Tools
| Tool | Purpose |
|---|---|
| `get_profile` | Retrieve current profile |
| `update_profile` | Partially update profile JSON |
| `generate_resume` | One-shot JD-customized resume (Cloud LLM) |
| `generate_portfolio` | Portfolio summary (Cloud LLM) |
| `generate_cover_letter` | Cover letter (Cloud LLM) |
| `analyze_jd` | Analyze JD into structured JSON (Local LLM) |
| `match_profile_to_jd` | JD analysis × profile → matching report (Local LLM) |
| `generate_resume_bullets` | ATS-friendly bullets (Local LLM) |
| `generate_resume_markdown` | Final markdown resume (Local LLM) |
## Environment Variables
| Variable | Default | Description |
|---|---|---|
| `LLM_PROVIDER` | `gemini` | `claude` / `openai` / `gemini` |
| `ANTHROPIC_API_KEY` | — | Required when `LLM_PROVIDER=claude` |
| `OPENAI_API_KEY` | — | Required when `LLM_PROVIDER=openai` |
| `GOOGLE_API_KEY` | — | Required when `LLM_PROVIDER=gemini` |
| `LOCAL_LLM_PROVIDER` | `ollama` | `ollama` / `openai-compatible` |
| `LOCAL_LLM_BASE_URL` | provider default | Ollama: `http://localhost:11434` |
| `LOCAL_LLM_MODEL` | provider default | e.g., `gemma4:26b` |
| `LOCAL_LLM_API_KEY` | — | Token for OpenAI-compatible endpoint (e.g., HF Router) |
| `LLM_TIMEOUT_MS` | `120000` | Per-call timeout |
| `RESUME_MCP_PROFILE_PATH` | `~/.resume-mcp/profile.json` | Override profile path |
## Local LLM Setup
### Option A — Ollama (recommended)
```bash
brew install ollama # or https://ollama.com/download
ollama pull gemma4:26b
ollama serve
```
MCP environment variables:
```json
"LOCAL_LLM_PROVIDER": "ollama",
"LOCAL_LLM_MODEL": "gemma4:26b"
```
### Option B — OpenAI-compatible endpoint (MLX, vLLM, LM Studio, HF Router…)
```json
"LOCAL_LLM_PROVIDER": "openai-compatible",
"LOCAL_LLM_BASE_URL": "http://localhost:8080/v1",
"LOCAL_LLM_MODEL": "mlx-community/gemma-4-26b-a4b-it-4bit",
"LOCAL_LLM_API_KEY": "any-non-empty-string"
```
## Troubleshooting
| Error | Solution |
|---|---|
| `PROFILE_INCOMPLETE` | Replace placeholders in `~/.resume-mcp/profile.json` with actual values |
| `OLLAMA_CONNECTION_FAILED` | Run `ollama serve` (default port 11434) |
| `LOCAL_LLM_CONNECTION_FAILED` | Check `LOCAL_LLM_BASE_URL` |
| `LOCAL_LLM_AUTH_FAILED` | Missing/incorrect `LOCAL_LLM_API_KEY`. Check HF Router token permissions |
| `LOCAL_LLM_MODEL_UNAVAILABLE` | Model not served. Run `ollama pull <model>` or choose another model |
| `No LLM API key found` | At least one Cloud tool API key required (`ANTHROPIC_API_KEY`, `OPENAI_API_KEY`, `GOOGLE_API_KEY`) |
## Local Development
```bash
git clone https://github.com/doyeonjeong/IT-Resume-MCP.git
cd IT-Resume-MCP
npm install
cp env.example .env
```
### One-liner commands
```bash
npm run smoke # 5 seconds — server boot + 9 tool registrations (health check before publishing)
npm run inspect # Interactive tool calls in browser GUI (MCP Inspector)
npm run pack:test # Simulate publishing with actual npm tarball
```
Detailed IDE connection methods (Antigravity, Cursor, Claude Code, Cline, etc.) and 5-minute verification scenarios are in [TESTING.md](./TESTING.md).
### Basic commands
```bash
npm test # Unit tests (53)
npm run build # NestJS build + chmod +x
npm run mcp # Run dev mode with tsx
```
Register local dev build with MCP client:
```json
{
"mcpServers": {
"resume-mcp-dev": {
"command": "node",
"args": ["/absolute/path/to/IT-Resume-MCP/dist/mcp-server.js"]
}
}
}
```
## Tech Stack
NestJS 11 · TypeScript · MCP SDK · Ollama · OpenAI / Anthropic / Gemini SDKs · Zod
## License
MIT — see [LICENSE](./LICENSE).
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
Python tool for converting files and office documents to Markdown.
awesome-claude-skills
A curated list of awesome Claude Skills, resources, and tools for...
antigravity-awesome-skills
The Ultimate Collection of 130+ Agentic Skills for Claude...
claude-context-mode
claude-context-mode plugin reduces MCP context bloat, saving up to 99% of tokens.
context-mode
MCP is the protocol for tool access. We're the virtualization layer for context.