Job Hunting MCP
No description available
Ask AI about Job Hunting MCP
Powered by Claude Β· Grounded in docs
I know everything about Job Hunting MCP. Ask me about installation, configuration, usage, or troubleshooting.
0/500
Reviews
Documentation
π°π· Job Hunting MCP β νκ΅ μ·¨μ μμ₯ νΉν MCP μλ²
νκ΅ μ·¨μ μ€λΉ κ³Όμ μμ λ°λ³΅λλ μλ₯ μμ μ μλννλ MCP(Model Context Protocol) μλ²μ λλ€.
ν΅μ¬ κ°μΉ: μ΄λ ₯μ/κ²½λ ₯κΈ°μ μ/μκΈ°μκ°μλ₯Ό ν λ² μ λ ₯νλ©΄, κ³΅κ³ λ³Β·μ¬μ΄νΈλ³λ‘ λ§μΆ€ λ³νν©λλ€. κ°μ μλ₯λ₯Ό μ¬μ΄νΈλ§λ€ λ€μ μ°λ κ³ ν΅μ μμ±λλ€.
μ¬μ©λ²: Claude Desktop, ChatGPT Desktop, Gemini CLI λ± MCP ν΄λΌμ΄μΈνΈμ μ°κ²°νλ©΄ λ°λ‘ μ¬μ©ν μ μμ΅λλ€. λ³λ LLM μ€μΉ μμ΄ MCP ν΄λΌμ΄μΈνΈμ AIκ° μλ₯ μμ±κΉμ§ μ²λ¦¬ν©λλ€.
μ΄ MCPκ° νλ μΌ
| κΈ°λ₯ | μ€λͺ |
|---|---|
| μ±μ©κ³΅κ³ κ΄λ¦¬ | 6κ° μ¬μ΄νΈμμ κ³΅κ³ κ²μ + μ κ·ν μ μ₯ |
| νλ‘ν νμ± | μ΄λ ₯μ/κ²½λ ₯κΈ°μ μλ₯Ό ꡬ쑰νλ λ§μ€ν° νλ‘νλ‘ λ³ν |
| μ ν©λ λΆμ | κ³΅κ³ -νλ‘νμ 5κ°μ§ μ°¨μμΌλ‘ λ§€μΉ λΆμ |
| μ¬μ΄νΈλ³ μμ λ³ν | μν°λ/μ¬λμΈ/μ‘μ½λ¦¬μ/μ ν/κ·Έλ£Ήλ°μ΄ μμ λ³΅λΆ ν μ€νΈ |
| κ²½λ ₯κΈ°μ μ λ§μΆ€ν | κ³΅κ³ μꡬμ¬νμ λ§κ² bullet point μ¬μμ± |
| μκΈ°μκ°μ μμ± | λ¬Έν μλ λΆμ β μμ¬ μΆμ² β μ΄μ μμ± |
| ν¬νΈν΄λ¦¬μ€ μ λ ¬ | κ³΅κ³ κΈ°μ€μΌλ‘ νλ‘μ νΈ κ΄λ ¨λ μ μ¬λ°°μΉ |
| μ§μ κ΄λ¦¬ | μ§μ μν μΆμ (μ μ₯ β μ§μ β ν©κ²©/λΆν©κ²©) |
| λ©΄μ μ€λΉ | κ³΅κ³ +κ²½λ ₯ κΈ°λ° μμ μ§λ¬Έ λ° λ΅λ³ ν¬μΈνΈ |
| κΈ°μ μ±μ₯μ± λΆμ | DART μ¬λ¬΄μ ν 3κ°λ + λ΄μ€ λΆμ β GROWING/STABLE/DECLINING νμ , λΈλλλͺ μλ λ³ν |
λΉ λ₯Έ μμ
1. μ€μΉ
git clone https://github.com/PracLee/job_hunting_mcp.git
cd job_hunting_mcp
npm install
npm run build
2. MCP ν΄λΌμ΄μΈνΈμ μ°κ²°νλ©΄ λ!
μ΄ MCP μλ²λ MCPλ₯Ό μ§μνλ AI ν΄λΌμ΄μΈνΈμ μ°κ²°νλ©΄ λ°λ‘ μ¬μ©ν μ μμ΅λλ€. λ³λ LLM μ€μΉκ° νμ μμ΅λλ€ β ν΄λΌμ΄μΈνΈμ AIκ° μλ₯ μμ±κΉμ§ λͺ¨λ μ²λ¦¬ν©λλ€.
βββββββββββββββββββββββββββ Tool νΈμΆ ββββββββββββββββββββββββ
β MCP ν΄λΌμ΄μΈνΈ (AI) β ββββββββββββββββββ β μ΄ MCP μλ² β
β β β β
β β’ Claude Desktop (μΆμ²) β β β’ κ³΅κ³ κ²μ/μ κ·ν β
β β’ Claude Code (CLI) β ββββββββββββββββββ β β’ νλ‘ν νμ± β
β β’ Gemini CLI β κ²°κ³Ό λ°ν β β’ λ§€μΉ λΆμ β
β β’ κΈ°ν MCP νΈν μ± β β β’ μμ λ³ν β
β β β β’ μ§μ κ΄λ¦¬ β
β β β β
β μλ₯ μμ±μ ν΄λΌμ΄μΈνΈ β β λ°μ΄ν° μ²λ¦¬ + λ‘μ§ β
β AIκ° μ§μ μ²λ¦¬ β β β
βββββββββββββββββββββββββββ ββββββββββββββββββββββββ
μ¬κΈ°μ λννλ©΄ μ¬κΈ°μ μ€νλ¨
μλμμ μ¬μ©νλ ν΄λΌμ΄μΈνΈλ₯Ό κ³¨λΌ μ€μ νμΈμ.
β Claude Desktop (μΆμ²)
λ‘컬 μ€μ νμΌμ JSONμ μΆκ°νλ©΄ λ©λλ€.
| OS | μ€μ νμΌ κ²½λ‘ |
|---|---|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
{
"mcpServers": {
"job-hunting": {
"command": "node",
"args": ["/μ λκ²½λ‘/job_hunting_mcp/dist/index.js"]
}
}
}
β Claude Code (CLI)
claude mcp add job-hunting node /μ λκ²½λ‘/job_hunting_mcp/dist/index.js
β Gemini CLI
| OS | μ€μ νμΌ κ²½λ‘ |
|---|---|
| macOS / Linux | ~/.gemini/settings.json |
| Windows | %USERPROFILE%\.gemini\settings.json |
Claude Desktopκ³Ό λμΌν JSON ν¬λ§·(mcpServers)μ μ¬μ©ν©λλ€.
β οΈ ChatGPT Desktop
μ£Όμ: ChatGPTμ MCP μ°κ²°μ Claude Desktopμ²λΌ λ‘컬 μ€μ νμΌ λ°©μμ΄ μλλλ€. νμ¬(2026.03 κΈ°μ€) 곡μ λ¬Έμμ λ°λ₯΄λ©΄ Developer Mode β Apps νλ¦μΌλ‘, ChatGPT Business / Enterprise / Edu μκΈμ μ μΉ νκ²½μμ MCP μλ²λ₯Ό λ±λ‘νλ λ°©μμ λλ€. κ°μΈ μ¬μ©μμ© λ‘컬 stdio μ°κ²°μ μμ§ κ³΅μ μ§μλμ§ μμ μ μμΌλ―λ‘, OpenAI 곡μ MCP λ¬Έμλ₯Ό νμΈνμΈμ.
κΈ°ν MCP νΈν ν΄λΌμ΄μΈνΈ
MCP νμ€(stdio)μ μ§μνλ μ±μ΄λ©΄ μ΄λμλ μ¬μ© κ°λ₯ν©λλ€.
command: "node", args: ["/μ λκ²½λ‘/dist/index.js"]λ‘ λ±λ‘νλ©΄ λ©λλ€.
Windows μ¬μ©μ μ°Έκ³ : κ²½λ‘ κ΅¬λΆμλ₯Ό
\\λ‘ μ¬μ©νμΈμ. μ:"args": ["C:\\Users\\μ΄λ¦\\job_hunting_mcp\\dist\\index.js"]
3. νκ²½ μ€μ (μ νμ¬ν)
cp .env.example .env
λλΆλΆμ κ²½μ° .env μ€μ μμ΄ λ°λ‘ μ¬μ©ν μ μμ΅λλ€.
μλλ νμν κ²½μ°μλ§ μ€μ ν©λλ€:
# μ¬λμΈ API κ²μ νμ§μ λμ΄λ €λ©΄ (μ ν)
SARAMIN_API_KEY=your-saramin-api-key
# DB μ μ₯ μμΉ λ³κ²½ (κΈ°λ³Έ: ./data/job_hunting.db)
DB_PATH=./data/job_hunting.db
κΈ°μ
μ±μ₯μ± λΆμ (company_analyze) μ¬μ© μ
company_analyze λꡬλ DART(κΈμ΅κ°λ
μ 곡μ)μ λ€μ΄λ² λ΄μ€ APIλ₯Ό μ¬μ©ν©λλ€.
API ν€λ₯Ό μ€μ νμ§ μμΌλ©΄ λꡬ νΈμΆ μ μ€μ μλ΄ λ©μμ§λ₯Ό λ°νν©λλ€.
# DART OpenAPI ν€ β κΈ°μ
μ¬λ¬΄μ ν(λ§€μΆΒ·μμ
μ΄μ΅Β·λΆμ±λΉμ¨ λ±) μ‘°ν
# λ°κΈ: https://opendart.fss.or.kr/ β νμκ°μ
β OpenAPI μ μ² (무λ£, μ¦μ λ°κΈ)
DART_API_KEY=your-dart-api-key
# λ€μ΄λ² κ²μ API β κΈ°μ
λ΄μ€/보λ κ²μ
# λ°κΈ: https://developers.naver.com/apps/ β μ ν리μΌμ΄μ
λ±λ‘ β μ¬μ© API: κ²μ μ ν (무λ£)
NAVER_NEWS_CLIENT_ID=your-naver-client-id
NAVER_NEWS_CLIENT_SECRET=your-naver-client-secret
μ°Έκ³ : DART APIλ κ΅λ΄ μμ₯μ¬(μ½μ€νΌΒ·μ½μ€λ₯)μ μΈλΆκ°μ¬ λμ λΉμμ₯μ¬μ μ¬λ¬΄ λ°μ΄ν°λ₯Ό μ 곡ν©λλ€. μκ·λͺ¨ μ€ννΈμ μ΄λ DART 미곡μ κΈ°μ μ μ¬λ¬΄ λ°μ΄ν° μμ΄ λ΄μ€ λΆμλ§ μ§νλ©λλ€.
4. κ°λ°/ν μ€νΈ
npm run dev # tsxλ‘ μ§μ μ€ν (κ°λ°)
npm start # λΉλλ JS μ€ν
npm test # ν
μ€νΈ (νμ¬ Vitest μ 체 μ€μνΈ)
5. λ‘컬 HTTP/SSE μλ²λ‘ λμ°κΈ° (λ€νΈμν¬ μ°λμ©)
Gemini, Claude Desktop λ± λ‘컬 νλ‘μΈμ€ μ°κ²° μΈμ λ€νΈμν¬ ν΅μ (HTTP/SSE)μΌλ‘ μ΄ MCP μλ²λ₯Ό λμΈ μ μλλ‘ κΈ°λ₯μ μΆκ°νμ΅λλ€. κΈ°λ³Έ 3000λ² ν¬νΈλ‘ μ€νλ©λλ€.
# μ’
μμ± μ€μΉ
npm install
# λΉλ λ° μ€ν
npm run build
npm run start:sse
# κ°λ° λͺ¨λλ‘ μ€ν μ
npm run dev:sse
μ€ν ν λΈλΌμ°μ νΉμ μΈλΆ MCP ν΄λΌμ΄μΈνΈμμ http://localhost:3000/sse μλν¬μΈνΈλ‘ μ°κ²°ν μ μμ΅λλ€.
π‘ ChatGPT λ±μ ngrokμΌλ‘ μ°κ²°νκΈ° (μΈλΆλ§ ν¬μλ©)
λ‘컬 μλ²λ₯Ό μΈλΆ μΉ νκ²½(ChatGPT μΉ λ±)κ³Ό μ°λνκ³ μΆλ€λ©΄, ngrokμ μ¬μ©νμ¬ ν¬νΈ ν¬μλ©μ ν μ μμ΅λλ€.
- λ‘컬μμ μλ² μ€ν (
npm run start:sse: 3000ν¬νΈ) - μλ‘μ΄ ν°λ―Έλ μ°½μ μ΄κ³
ngrokμ€ν:ngrok http 3000 - μμ±λ Forwarding λλ©μΈ(
https://xxxx.ngrok.appλ±)μ 볡μ¬ν©λλ€. - ChatGPT GPTsλ ν μΈλΆ ν΄λΌμ΄μΈνΈμμ μ΄ MCP μλ²λ₯Ό λ±λ‘ν λ, URL λ€μ λ°λμ
/sseλ₯Ό λΆμ¬μ κΈ°μ ν©λλ€. πhttps://xxxx.ngrok-free.app/sse
(κ³ κΈ) λ‘컬 LLM μ°λ
λλΆλΆμ μ¬μ©μλ μ΄ μΉμ μ΄ νμ μμ΅λλ€. Claude Desktop λ± MCP ν΄λΌμ΄μΈνΈμ AIκ° μλ₯ μμ±μ μ²λ¦¬νκΈ° λλ¬Έμ λλ€.
μλλ μμ μ€νλΌμΈ νκ²½μμ μ¬μ©νκ±°λ, MCP μλ² λ΄λΆμμ μ체μ μΌλ‘ LLMμ νΈμΆνκ³ μΆμ λλ₯Ό μν κ³ κΈ μ€μ μ λλ€.
Ollama
brew install ollama # macOS
ollama pull qwen2.5 # νκ΅μ΄ μ°μ (μΆμ², μ΅μ 16GB RAM)
ollama serve # μλ² μμ
# .env
LLM_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_MODEL=qwen2.5
LM Studio / vLLM λ± OpenAI νΈν λ‘컬 μλ²
LLM_PROVIDER=openai-compatible
LOCAL_LLM_BASE_URL=http://localhost:1234/v1
LOCAL_LLM_MODEL=local-model
LOCAL_LLM_API_KEY=not-needed
λ‘컬 LLM μ΅μ μ¬μ
| λͺ¨λΈ | RAM | λΉκ³ |
|---|---|---|
| qwen2.5 7B (Q4) | 16GB+ | νκ΅μ΄ μΆμ² |
| llama3 8B (Q4) | 16GB+ | λ²μ© |
| gemma2 9B (Q4) | 16GB+ | λΉ λ―ν¨, λ€λ₯Έ μ± λ«μμΌ |
| 70B λͺ¨λΈ | 64GB+ | κ³ μ¬μ νμ |
μ¬μ©λ² β μ€μ νλ‘μ°
Step 1: νλ‘ν λ±λ‘ (μ΅μ΄ 1ν)
μ΄λ ₯μμ κ²½λ ₯κΈ°μ μ ν μ€νΈλ₯Ό μ λ ₯νλ©΄ μλμΌλ‘ ꡬ쑰νν©λλ€.
"λ΄ μ΄λ ₯μ νμ±ν΄μ€"
β profile_parse_resume νΈμΆ
β κΈ°μ μ€ν, νλ‘μ νΈ, κ²½λ ₯ μ°μ°¨, λλ©μΈ μλ μΆμΆ
β λ§μ€ν° νλ‘ν DB μ μ₯
Step 2: κ³΅κ³ λ±λ‘
κ΄μ¬ κ³΅κ³ λ₯Ό 볡λΆνκ±°λ μ¨λΌμΈ κ²μν©λλ€.
# λ°©λ² 1: μ¨λΌμΈ κ²μ
"μμΈ, Java λ°±μλ, 3~5λ
μ°¨ κ³΅κ³ μ°Ύμμ€"
β jobs_search(keywords: ["Java", "λ°±μλ"], location: "μμΈ", sources: ["wanted", "jumpit", "groupby", "remember"])
"Python/FastAPI λ°±μλ κ³΅κ³ μ°Ύμμ€"
β jobs_search(keywords: ["Python", "FastAPI"])
β `sources`λ₯Ό μλ΅νλ©΄ νμ¬ μ¬μ© κ°λ₯ν κ²μ μμ€λ₯Ό λͺ¨λ μ‘°ννκ³ , κ²°κ³Όλ₯Ό κ΄λ ¨λ μμΌλ‘ μ λ ¬
β κΈ°λ³Έκ° `auto_save: true` μ΄λ―λ‘ μ¨λΌμΈ κ²μ κ²°κ³Όλ DBμ upsertλμ΄ λ°νλ `job_id`λ‘ λ°λ‘ `match_score_job` νΈμΆ κ°λ₯
# λ°©λ² 2: URLλ‘ μμΈ μ‘°ν
"μ΄ κ³΅κ³ μμΈ λ³΄μ¬μ€: https://www.wanted.co.kr/wd/12345"
β jobs_get_detail(job_id: "https://www.wanted.co.kr/wd/12345")
# λ°©λ² 3: ν
μ€νΈ 볡λΆ
"μ΄ κ³΅κ³ λ±λ‘ν΄μ€" + κ³΅κ³ μ λ¬Έ λΆμ¬λ£κΈ°
β jobs_add(company_name: "ν μ€", job_title: "μλ² κ°λ°μ", raw_text: "...")
Step 3: μ ν©λ λΆμ
"μ΄ κ³΅κ³ λ λ΄ νλ‘ν λ§€μΉν΄μ€"
β match_score_job(job_id: "jp_xxx")
β overall_score + breakdown + scoring_meta λ°ν
β λ°μ΄ν°κ° λΉμ΄ μλ μΆμ 50μ μΌλ‘ κ³ μ νμ§ μκ³ μ μΈνλ©°, `scoring_meta.applied_weights`μ μ€μ λ°μλ κ°μ€μΉκ° νμλ¨
β coverageκ° 50% λ―Έλ§μ΄λ©΄ `overall_score` λμ `scoring_meta.provisional_score`, `confidence`, `INSUFFICIENT_DATA` μνκ° λ°νλ¨
Step 4: μλ₯ λ§μΆ€ν
# κ²½λ ₯κΈ°μ μ
"μ΄ κ³΅κ³ μ λ§κ² κ²½λ ₯κΈ°μ μ μμ ν΄μ€"
β resume_tailor(job_id: "jp_xxx")
# μκΈ°μκ°μ
"μ§μλκΈ° μμ¬ μΆμ²ν΄μ€"
β coverletter_brainstorm(job_id: "jp_xxx", question: "μ§μλκΈ°")
"μ§μλκΈ° μ΄μ μ¨μ€"
β coverletter_generate(job_id: "jp_xxx", question_type: "motivation")
# ν¬νΈν΄λ¦¬μ€
"μ΄ κ³΅κ³ κΈ°μ€μΌλ‘ νλ‘μ νΈ μμ μ¬λ°°μΉν΄μ€"
β portfolio_reorder(job_id: "jp_xxx")
Step 5: μ¬μ΄νΈλ³ μμ λ³ν (ν΅μ¬!)
κ°μ νλ‘νμ κ° μ¬μ΄νΈ μμμ λ§κ² μλ λ³νν©λλ€.
"μν°λ μμμΌλ‘ λ³νν΄μ€"
β resume_export(target_platform: "wanted")
β ν μ€ μκ° + μ±κ³Ό μ€μ¬ κ²½λ ₯ + κΈ°μ νκ·Έ
"μ¬λμΈ μμμΌλ‘ λ³νν΄μ€"
β resume_export(target_platform: "saramin")
β μΈμ μ¬ν + κ²½λ ₯μ¬ν(ν) + νλ ₯ + μ격μ¦
"μ‘μ½λ¦¬μ μμμΌλ‘ λ³νν΄μ€"
β resume_export(target_platform: "jobkorea")
β μ΄λ ₯μ + κ²½λ ₯κΈ°μ μ λΆλ¦¬
"μ ν μμμΌλ‘ λ³νν΄μ€"
β resume_export(target_platform: "jumpit")
β κΈ°μ μ€μ¬ νλ‘ν + νλ‘μ νΈ μΉ΄λ
"κ·Έλ£Ήλ°μ΄ μμμΌλ‘ λ³νν΄μ€"
β resume_export(target_platform: "groupby")
β μ€ννΈμ
ν₯ κ°κ²° μκ° + κΈ°μ νκ·Έ + μ±κ³Ό
LLMμΌλ‘ λ¬Έμ₯μ 보κ°νλ €λ©΄:
resume_export(target_platform: "wanted", enhance_with_llm: true)
Step 6: μ§μ κ΄λ¦¬ & λ©΄μ
# μ§μ κΈ°λ‘
"μ΄ κ³΅κ³ μ§μ μλ£λ‘ κΈ°λ‘ν΄μ€"
β application_create(job_id: "jp_xxx", status: "applied")
# μν λ³κ²½
"μλ₯ ν©κ²©νμ΄"
β application_update_status(application_id: "app_xxx", new_status: "document_passed")
# νν© μ‘°ν
"μ§μ νν© λ³΄μ¬μ€"
β application_list
# λ©΄μ μ€λΉ
"μ΄ νμ¬ λ©΄μ μ€λΉν΄μ€"
β interview_prepare(job_id: "jp_xxx")
β μμ κΈ°μ μ§λ¬Έ + κ²½ν μ§λ¬Έ + λ΅λ³ ν¬μΈνΈ
Tool μ 체 λͺ©λ‘
μ±μ©κ³΅κ³ (3κ°)
| Tool | μ€λͺ |
|---|---|
jobs_search | ν€μλ/쑰건μΌλ‘ κ³΅κ³ κ²μ. auto_save=true κΈ°λ³Έκ°μΌλ‘ κ²μ κ²°κ³Όλ₯Ό DBμ upsertνλ©°, search_meta.sources_result_countμ μμ€λ³ warningsλ₯Ό ν¨κ» λ°ν |
jobs_get_detail | νΉμ κ³΅κ³ μμΈ μ‘°ν (URL λΆμ¬λ£κΈ° μ§μ) |
jobs_add | κ³΅κ³ ν μ€νΈλ₯Ό 볡λΆνμ¬ μλ λ±λ‘ |
νλ‘ν (7κ°) - v1.0 μμ§ νμ¬
| Tool | μ€λͺ |
|---|---|
profile_parse_resume | μ΄λ ₯μ/κ²½λ ₯κΈ°μ μ νμ±. reset_overridesλ‘ κ°μ μ΄κΈ°ν λ° νμ± diff μ 곡 |
profile_get | 3κ³μΈ΅(raw, parsed, confirmed) μ격 λΆλ¦¬ κ΅¬μ‘°λ‘ νλ‘ν μ λ¬Έ μ‘°ν |
profile_update_skills | μ€μΈμ μ€ν¬ μμ (λΈλ리μ€νΈ) λ° λ³΄μ‘° μ€ν¬ μꡬ μΆκ°(νμ΄νΈλ¦¬μ€νΈ) |
profile_update_experience | μμ μμ ν ν μ€νΈμμ κΌ¬μΈ μ΄ κ²½λ ₯ κ°μ μ μλ μ λ° κ΅μ |
profile_confirm_skills | μλ μΆμΆλ(parsed) μ 체 κΈ°μ λ€μ "κ²μ¦λ(user_confirmed)" κ³μΈ΅μΌλ‘ μΉκ²© |
profile_list_versions | νμ±ν λλ§λ€ μ μ₯λ κ³Όκ±° μ΄λ ₯μ μ€λ μ·(λ²μ ) νμ€ν 리 μ‘°ν |
profile_rollback_version | μλͺ» νμ±λ κΈ°λ‘μ λ²λ¦¬κ³ νΉμ κ³Όκ±° λ²μ μ IDλ₯Ό ν΅ν΄ νμλ¨Έμ 볡ꡬ |
λ§€μΉ (2κ°)
| Tool | μ€λͺ |
|---|---|
match_score_job | κ³΅κ³ -νλ‘ν 5μ°¨μ λ§€μΉ λΆμ. μΆλ³ μ μμ scoring_meta(μ μ© κ°μ€μΉ/μ μΈ μΆ, coverage, confidence) λ°ν |
match_rank_jobs | μ¬λ¬ κ³΅κ³ μ ν©λ μ λνΉ |
μλ₯ (5κ°)
| Tool | μ€λͺ |
|---|---|
resume_tailor | κ³΅κ³ λ§μΆ€ κ²½λ ₯κΈ°μ μ (ν΄λΌμ΄μΈνΈ AIκ° μ²λ¦¬) |
resume_export | νλ«νΌλ³ μμ λ³ν (5κ° μ¬μ΄νΈ + λ²μ©) |
coverletter_brainstorm | μμμ μμ¬ μΆμ² (ν΄λΌμ΄μΈνΈ AIκ° μ²λ¦¬) |
coverletter_generate | μμμ μ΄μ μμ± (ν΄λΌμ΄μΈνΈ AIκ° μ²λ¦¬) |
portfolio_reorder | κ³΅κ³ κΈ°μ€ νλ‘μ νΈ μ¬λ°°μΉ (ν΄λΌμ΄μΈνΈ AIκ° μ²λ¦¬) |
μ§μ κ΄λ¦¬ (3κ°)
| Tool | μ€λͺ |
|---|---|
application_create | μ§μ κΈ°λ‘ μμ± |
application_update_status | μν λ³κ²½ |
application_list | νν© λͺ©λ‘ + ν΅κ³ |
λ©΄μ (1κ°)
| Tool | μ€λͺ |
|---|---|
interview_prepare | μμ μ§λ¬Έ/λ΅λ³ ν¬μΈνΈ (ν΄λΌμ΄μΈνΈ AIκ° μ²λ¦¬) |
κΈ°μ λΆμ (1κ°)
| Tool | μ€λͺ |
|---|---|
company_analyze | DART μ¬λ¬΄μ ν + λ€μ΄λ² λ΄μ€λ‘ κΈ°μ μ±μ₯μ± νκ° (GROWING / STABLE / DECLINING) |
company_analyze μμΈ
- λ°μ΄ν° μμ€: DART κΈμ΅κ°λ μ μ μ곡μ(μ¬λ¬΄μ ν 3κ°λ ) + λ€μ΄λ² λ΄μ€(μ΅κ·Ό NμΌ)
- μ§μ λ²μ: κ΅λ΄ μμ₯μ¬(μ½μ€νΌΒ·μ½μ€λ₯), μΈλΆκ°μ¬ λΉμμ₯μ¬, κ΅λ΄ μ μ μΈκ΅κ³ λ²μΈ
- λΈλλλͺ
μλ λ³ν: λ³μΉ/λΈλλλͺ
β λ²μΈλͺ
μλ λ§€ν (μ:
λ°°λ―Όβμ°μννμ λ€,ν μ€βλΉλ°λ¦¬νΌλΈλ¦¬μΉ΄) - μ λ’°λ λ°ν:
search_path+confidence(high/medium/low/none)λ‘ κ²μ κ²½λ‘ ν¬λͺ νκ² κ³΅κ° - API ν€ λ―Έμ€μ μ: λꡬ νΈμΆ μμ μ λ°κΈ μλ΄ λ©μμ§ λ°ν (μλ² μ¬μμ λΆνμ)
μ
λ ₯: "λ°°λ―Ό"
β λΈλλλ§΅: λ°°λ―Ό β μ°μννμ λ€
β DART: corp_code μ‘°ν + 3κ°λ
μ¬λ¬΄μ ν
β λ€μ΄λ² λ΄μ€: μ΅κ·Ό 90μΌ κ΄λ ¨ κΈ°μ¬
β LLM μ’
ν© λΆμ β GROWING / STABLE / DECLINING
DART_API_KEY,NAVER_NEWS_CLIENT_ID,NAVER_NEWS_CLIENT_SECRETμ€μ νμ. ν€ λ―Έμ€μ μ λꡬ νΈμΆ μμ μ λ°κΈ μλ΄λ₯Ό λ°νν©λλ€.
μ±μ© μ¬μ΄νΈ μ§μ νν©
| μ¬μ΄νΈ | κ³΅κ³ κ²μ | μμ λ³ν | API ν€ νμ | λΉκ³ |
|---|---|---|---|---|
| μν°λ | β | β | λΆνμ | μΉ API |
| μ¬λμΈ | β | β | μ ν (SARAMIN_API_KEY) | API μ°μ , λ―Έμ€μ μ μΉ ν¬λ‘€λ§ ν΄λ°± |
| μ‘μ½λ¦¬μ | β | β | λΆνμ | μΉ νμ± |
| μ ν | β | β | λΆνμ | μΉ API |
| κ·Έλ£Ήλ°μ΄ | β | β | λΆνμ | μ€ννΈμ μ λ¬Έ, Next.js SSR νμ± |
| λ¦¬λ©€λ² | β | - | λΆνμ | κ²½λ ₯μ§ μ λ¬Έ, λ΄λΆ API νμ± |
κ²ν ν μ μΈν νλ«νΌ
| νλ«νΌ | μ μΈ μ΄μ |
|---|---|
| λ‘μΌνμΉ | μλΉμ€ μ’ λ£ |
| νμ μμ² | μ±μ© νλ«νΌμ΄ μλ (μ€ννΈμ λΆμ). μ±μ©μ μν°λ μ°λμ΄λΌ μ€λ³΅ |
| μμμΊ£ | ν리λμ νλ‘μ νΈ λ§€μΉ μ λ¬Έ. μ κ·μ§ μ±μ© μ€ν€λ§μ ꡬ쑰 λΆμΌμΉ |
κΈ°μ μ€ν
| κ΅¬λΆ | κΈ°μ |
|---|---|
| Runtime | Node.js 18+ (κΆμ₯ 20+) |
| Language | TypeScript (strict) |
| MCP SDK | @modelcontextprotocol/sdk |
| DB | SQLite (better-sqlite3) β λ‘컬 νμΌ, λ³λ μ€μΉ λΆνμ |
| LLM | MCP ν΄λΌμ΄μΈνΈ AI μ¬μ© (κ³ κΈ: Ollama / LM Studio λ‘컬 μ°λ κ°λ₯) |
| Validation | Zod |
| Test | Vitest (68건) |
νλ‘μ νΈ κ΅¬μ‘°
src/
βββ index.ts # μ§μ
μ
βββ server.ts # MCP μλ² μ€μ
βββ tools/ # MCP Tool λ μ΄μ΄ (μ
λ ₯ κ²μ¦/μλ΅ μ§λ ¬ν)
β βββ jobs/ # μ±μ©κ³΅κ³ κ²μ/μΆκ°
β βββ profile/ # νλ‘ν νμ±
β βββ match/ # μ ν©λ λΆμ
β βββ resume/ # κ²½λ ₯κΈ°μ μ λ§μΆ€ν + μμ λ³ν
β βββ coverletter/ # μκΈ°μκ°μ
β βββ portfolio/ # ν¬νΈν΄λ¦¬μ€ μ λ ¬
β βββ application/ # μ§μ κ΄λ¦¬
β βββ interview/ # λ©΄μ μ€λΉ
βββ services/ # λλ©μΈ μλΉμ€ λ μ΄μ΄
β βββ jobs-service.ts # κ²μ μ§κ³/μ λ ¬
β βββ profile-service.ts # νλ‘ν νμ±/κ΅μ
β βββ match-service.ts # λ§€μΉ λΆμ
β βββ resume-service.ts # μ΄λ ₯μ λ§μΆ€ν/λ³ν
β βββ ... # coverletter/company/application λ±
βββ adapters/ # μ±μ© μ¬μ΄νΈλ³ μ΄λν°
β βββ base-adapter.ts # κ³΅ν΅ μΈν°νμ΄μ€
β βββ wanted-adapter.ts # μν°λ
β βββ saramin-adapter.ts # μ¬λμΈ
β βββ jobkorea-adapter.ts # μ‘μ½λ¦¬μ
β βββ jumpit-adapter.ts # μ ν
β βββ groupby-adapter.ts # κ·Έλ£Ήλ°μ΄ (μ€ννΈμ
)
β βββ remember-adapter.ts # λ¦¬λ©€λ² (κ²½λ ₯μ§)
βββ core/ # ν΅μ¬ λΌμ΄λΈλ¬λ¦¬
β βββ llm-client.ts # LLM μΆμν (Ollama / OpenAI νΈν λ‘컬)
β βββ tech-dictionary.ts # κΈ°μ μ¬μ (80+ νλͺ©, νκ΅μ΄ λμμ΄)
β βββ resume-parser.ts # μ΄λ ₯μ κ·μΉ κΈ°λ° νμ±
β βββ job-normalizer.ts # κ³΅κ³ ν
μ€νΈ μ κ·ν
β βββ job-search.ts # κ³΅κ³ κ²μ relevance μ μ κ³μ°
β βββ match-scoring.ts # μ ν©λ κ³μ° λ‘μ§
β βββ platform-templates.ts # νλ«νΌλ³ μμ ν
νλ¦Ώ (6μ’
)
β βββ utils.ts
βββ db/ # SQLite DB
β βββ connection.ts
β βββ repositories/
βββ types/ # νμ
μ μ
tests/ # ν
μ€νΈ
βββ services/ # μλΉμ€/μ½μ΄ λ‘μ§ ν
μ€νΈ
βββ tools/ # E2E ν΅ν© ν
μ€νΈ
μ€κ³ μμΉ
- MCP ν΄λΌμ΄μΈνΈ μ°μ β Claude Desktop/ChatGPT λ±μ μ°κ²°νλ©΄ λ°λ‘ μ¬μ©. λ³λ LLM μ€μΉ λΆνμ
- κ·μΉ κΈ°λ° ν΅μ¬ β κ²μ/λ§€μΉ/μμ λ³νμ κ·μΉ κΈ°λ°. AIλ μλ₯ μμ±μλ§
- νμ κ²½ν κΈμ§ β κΈ°μ‘΄ κ²½νμ μ¬κ΅¬μ±/κ°μ‘°νλ λ°©ν₯μΌλ‘λ§ μ§μ
- νκ΅ μμ₯ νΉν β νκ΅μ μ΄λ ₯μ/μμμ/μ±μ©κ³΅κ³ ꡬ쑰μ λ§μΆ€
- νμ₯ κ°λ₯ β μ μ±μ© μ¬μ΄νΈ μΆκ° =
SourceAdapterꡬν 1κ° - λΉκ°λ°μ μΉν β μ€μΉ ν λνλ§μΌλ‘ λͺ¨λ κΈ°λ₯ μ¬μ© κ°λ₯
νΌλλ°± λ° λ¬Έμ
μ΄ νλ‘μ νΈμ κΈ°ν λ°°κ²½κ³Ό κ°λ° νκ³ λ μλ κΈμμ νμΈνμ€ μ μμ΅λλ€:
μ¬μ© μ€ λ°κ²¬ν λ²κ·Έ, λΆμ‘±ν μ , κ°μ μμ΄λμ΄ λ± νΌλλ°±μ΄ μλ€λ©΄ μ λΈλ‘κ·Έμ λκΈλ‘ μμ λ‘κ² λ¨κ²¨μ£ΌμΈμ!
λ³κ²½ μ΄λ ₯
v1.1.0 (2026-04-01)
νλ‘ν μ€ν€λ§ νμ₯
total_experience_monthsνλ μΆκ° β κ²½λ ₯μ μ° λ¨μ μΈ μ λ¨μλ‘λ μ μ₯user_confirmed_skills/user_rejected_skillsνλ μΆκ° β μ€ν¬ νμ /κ±°λΆ μν¬νλ‘μ° μ§μ- κΈ°μ‘΄ DB μλ λ§μ΄κ·Έλ μ΄μ (ALTER TABLE)
μ΄λ ₯μ νμ μ νλ μ λ©΄ κ°μ
- μΉμ
ν€λ νλ¨ κ°ν:
κΈ°μ μ€ν: Python, ...κ°μ΄:λ€ λ΄μ©μ΄ μλ μ€μ ν€λλ‘ μλͺ» μΈμνλ λ²κ·Έ μμ β νλ‘μ νΈ μΉμ μ€κ° μ λ¨ νμ ν΄μ - κ²½λ ₯ μ°μ°¨ κ³μ°:
μ΄ Nλ Nκ°μν¨ν΄ 1μμ μ μ©,monthsκ° λμ λ°ν - μ΄λ¦ μΆμΆ:
μ΄λ³μ¬ κ²½λ ₯κ°μ μ±μ©μ¬μ΄νΈ λ³΅ν© νμμμ μ΄λ¦ μΆμΆ κ°λ₯ - νλ‘μ νΈ μ λͺ© κ°μ§: bullet(
-,β’) μΌλ‘ μμνλ μ€μ νλ‘μ νΈ μ λͺ©μΌλ‘ μ€μΈνλ λ²κ·Έ μμ - κΈ°μ μ€ν μΆμΆ:
κΈ°μλ¨λ ν€μλ λ§€μΉ λ°©μ§ βκΈ°μ μ€ν:λͺ μ ννλ§ νμ© - νλ ₯ μ 곡 νμ±:
νκ³Ό?ν¨ν΄μ΄ νκ΅λͺ (νμ±λνκ΅)μ μ 곡μΌλ‘ μ€μΈνλ λ²κ·Έ μμ - νλ‘μ νΈ μ ν¨μ± νν° μΆκ°:
νλ ₯,보μ κΈ°μλ± μΉμ ν€λ λ° κ°μΈμ 보 λΈλ‘μ΄ νλ‘μ νΈλ‘ λ±λ‘λλ λ¬Έμ ν΄μ
λ¬Έμ ν΄κ²°
better-sqlite3 λ²μ λΆμΌμΉ μ€λ₯ (NODE_MODULE_VERSION mismatch)
μ¦μ: MCP μλ² μ€ν μ μλμ κ°μ μ€λ₯ λ°μ
Error: The module '...better_sqlite3.node' was compiled against a different Node.js version
μμΈ: better-sqlite3λ λ€μ΄ν°λΈ λ°μ΄λ리λ‘, λΉλν Node.js λ²μ κ³Ό μ€ν νκ²½μ Node.js λ²μ μ΄ λ€λ₯΄λ©΄ μΆ©λν©λλ€.
Claude Desktop Cowork κ°μ νκ²½μ λ΄λΆμ μΌλ‘ λ³λμ Node.js λ²μ μ μ¬μ©νλ κ²½μ°κ° μμ΅λλ€.
ν΄κ²°λ²: μ€ν νκ²½μ Node.js λ²μ μΌλ‘ λ§μΆ°μ rebuild
nvmμ΄ μλ€λ©΄ λ¨Όμ μ€μΉνμΈμ: https://github.com/nvm-sh/nvm LLM ν΄λΌμ΄μΈνΈλ§λ€ μꡬνλ Node.js λ²μ μ΄ λ€λ₯Ό μ μμΌλ―λ‘, nvmμΌλ‘ λ²μ μ μ ννλ κ²μ κΆμ₯ν©λλ€.
# μ€ν νκ²½ Node λ²μ νμΈ ν ν΄λΉ λ²μ μΌλ‘ rebuild
nvm install 22 # μμΌλ©΄ μ€μΉ
nvm use 22
cd /path/to/job_hunting_mcp
npm rebuild better-sqlite3
μ΄ν MCP ν΄λΌμ΄μΈνΈ(Claude Desktop λ±)λ₯Ό μ¬μμνλ©΄ μ μ λμν©λλ€.
λΌμ΄μ μ€
MIT
