Job Application MCP

Job Application MCP

A local-first, open-source MCP server that analyzes jobs, matches your CV, tailors documents, and tracks applications — all on your machine with no data uploaded.

Category
访问服务器

README

<div align="center">

Job Application MCP

A local-first, open-source job application assistant built on the Model Context Protocol.

Analyse jobs · Match against your CV · Tailor documents · Preview forms · Track applications — all on your machine, nothing uploaded, submission stays in your hands.

License: AGPL-3.0-or-later Node TypeScript Status: Alpha

</div>


Table of contents


Why

Job hunting is repetitive: read a posting, check it against your CV, tweak a cover letter, fill the same fields on yet another form, and remember where you applied.

Job Application MCP turns that into a set of tools any MCP-compatible AI client (Claude Desktop, Claude Code, others) can drive for you — while keeping you in control:

  • Your CV and applications never leave your machine in the free core.
  • The assistant prepares and previews; you review and submit.
  • It's open source under AGPL-3.0, so you can audit exactly what it does.

ℹ️ This repository is the free community core described in BUSINESS_PROPOSAL.md. Paid AI/cloud/business services are intentionally out of scope here.


What it does (free core)

Capability Description
🧩 Local MCP server A stdio server you connect from any MCP client.
👤 Candidate profile One local profile: skills, headline, contact, summary.
📄 CV parsing Parse PDF / DOCX / TXT locally — no upload, no network.
🔍 Job analysis Paste a job description; get extracted key skills + a short summary.
🎯 Match scoring Heuristic 0–100 score with matched / missing skills.
✂️ Tailoring suggestions Structural advice on which skills to surface or add.
✍️ Answer drafting A template starter for screening questions (you rewrite it).
📝 Form autofill preview Maps your profile onto form fields — preview only, never submits.
📊 Application tracking Local SQLite store with a status pipeline (draft → submitted → offer…).

What it deliberately does NOT do

  • ❌ No automated submission. You submit manually on the employer's site.
  • ❌ No automation of LinkedIn or Indeed — their Terms of Service prohibit it. Paste the description and complete those by hand.
  • ❌ No CAPTCHA solving, 2FA bypass, or login recovery — it pauses for manual action.
  • ❌ No AI rewriting, cloud sync, or premium adapters — those are future Pro/cloud services.

These aren't missing features; they're the design.


How it works

┌─────────────────┐      stdio (JSON-RPC)      ┌──────────────────────┐
│  MCP client     │  ◀────────────────────────▶│  job-application-mcp │
│  (Claude, etc.) │                             │  (this server)       │
└─────────────────┘                             └──────────┬───────────┘
                                                           │ reads / writes
                                                           ▼
                                                ┌──────────────────────┐
                                                │  local SQLite DB     │
                                                │  + parsed CV text    │
                                                │  (JOB_MCP_DATA_DIR)  │
                                                └──────────────────────┘

You (or an AI client) call tools. Each tool does a small, auditable thing and returns structured JSON. Tools that touch external sites do not exist; everything operates on data you provide and store locally.


Quick start

Requirements

  • Node.js ≥ 22 (uses the built-in node:sqlite — no native compilation needed)
  • npm

Install & build

git clone https://github.com/<your-user>/job-application-mcp.git
cd job-application-mcp
npm install
npm run build      # -> dist/

Verify it works

npm test           # 40 unit tests (scoring, store, licence, credits, ai, payments, audit-fixes)
node dist/cli/cli.js --help

Connect an MCP client

Build the project, then add the server to your MCP client's config.

Claude Desktop / Claude Code

{
  "mcpServers": {
    "job-application-mcp": {
      "command": "node",
      "args": ["/ABSOLUTE/path/to/job-application-mcp/dist/src/index.js"]
    }
  }
}

⚠️ Use an absolute path — MCP clients launch the server from their own working directory, not yours.

Run directly (no client)

node dist/cli/cli.js serve      # equivalent to: node dist/src/index.js

The server speaks JSON-RPC over stdio. See A full example flow for raw request examples.


Tools reference

All 23 tools are local and synchronous-ish (CV parsing and AI calls are async). Arguments are validated with zod; the MCP client receives a JSON Schema for each. The 13 free-core tools (profile → autofill) are the everyday workflow. The credits/Pro and admin/business tools are wire-ready seams for the hosted Pro service (see Business model); they run locally today and do not require any subscription.

Profile

Tool Args Returns
get_profile — The local candidate profile (auto-created on first call).
update_profile full_name?, email?, phone?, location?, headline?, summary?, skills?, experience_years? Updated profile. skills replaces the list.

CVs

Tool Args Returns
parse_cv file_path? or text, label? Parsed CV stored locally; detected skills + a short preview.
list_cvs — All stored CVs.

parse_cv supports .pdf (pdf-parse), .docx (mammoth), and plain text. If you pass text, it's stored as-is. file_path must be inside the data dir (or a folder listed in JOB_MCP_CV_DIRS) — paths outside the allow-list are rejected, so an MCP client can't read arbitrary files.

Jobs

Tool Args Returns
analyze_job description (≥20 chars), title?, company?, url?, store?=true Extracted keywords + summary; stored as a job (unless store: false).
get_job job_id A stored job with its keywords.

Matching & prep

Tool Args Returns
match_cv job_id, cv_id, save?=false 0–100 score, matched/missing/extra skills; optionally creates a draft application.
tailor_cv job_id, cv_id Tailored CV draft. With your own AI API key (AI_API_KEY): AI-rewritten prose; without: heuristic local draft.
cover_letter job_id, cv_id Cover-letter draft (AI with your own key, else heuristic).
draft_answer question, cv_id?, job_id? Screening-answer draft (AI with your own key, else heuristic template). Always review.

AI tools and your own key. tailor_cv, cover_letter, and draft_answer use a real AI provider when you set AI_PROVIDER (openai or anthropic) and AI_API_KEY — on the Free or Pro plan. Without a key they fall back to a local heuristic. The Pro hosted path additionally debits an AI credit; using your own key is never debited. See Business model.

Applications & forms

Tool Args Returns
save_application job_id, cv_id?, match_score?, tailored_cv_text?, cover_letter?, answers?, notes? A draft application record. Does not submit.
list_applications status? Application records (optionally filtered by status).
update_application_status application_id, status, notes? Updates status; sets submitted_at when status is submitted.
autofill_form application_id, form_fields? A preview mapping of profile data onto form fields. Nothing is submitted.

Status pipeline: draft → ready → submitted → interview → offer → rejected → closed.

Analytics & status

Tool Args Returns
application_analytics — Counts by status, average match score, recent activity. Pro entitlement adds an advanced breakdown.
status — Server/plan/credits snapshot (plan label, AI credit balance, active features).

Credits & Pro (wire-ready seams)

Tool Args Returns
credits — Current AI credit balance + recent ledger entries.
topup_credits code, amount Apply an AI-credit top-up code (idempotent per code). Admin/test.
grant_monthly_credits amount? Grant the monthly AI allowance (idempotent per calendar month). Admin/test.

Admin / business (wire-ready seams)

Tool Args Returns
admin_create_account email, name, plan? Create a business account.
admin_add_candidate account_id, profile_id, role? Add a candidate/coach to an account.
admin_list_team account_id List an account's team members.
admin_usage_report account_id Usage summary for an account.

A full example flow

Here's a complete session using the stdio JSON-RPC interface directly. (An MCP client like Claude does this for you in natural language.)

node dist/src/index.js

Send these lines (one JSON-RPC object per line):

// 1. handshake
{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"demo","version":"0"}}}
{"jsonrpc":"2.0","method":"notifications/initialized"}

// 2. set up your profile
{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"update_profile","arguments":{"full_name":"Ada Lovelace","headline":"Backend Engineer","skills":["python","sql","aws","docker"]}}}

// 3. analyse + store a job (paste the description text)
{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"analyze_job","arguments":{"title":"Backend Engineer","company":"Acme Co","description":"We need a backend engineer with Python, SQL, and AWS to build data pipelines. PostgreSQL and Docker are a plus."}}}

// 4. parse a CV (file path or pasted text)
{"jsonrpc":"2.0","id":4,"method":"tools/call","params":{"name":"parse_cv","arguments":{"label":"main-cv","text":"Ada Lovelace — Backend Engineer. Python, SQL, AWS, PostgreSQL. Built ETL pipelines..."}}}

// 5. score the CV against the job (save=true creates a draft application)
{"jsonrpc":"2.0","id":5,"method":"tools/call","params":{"name":"match_cv","arguments":{"job_id":1,"cv_id":1,"save":true}}}

// 6. preview autofill for a form (no submission)
{"jsonrpc":"2.0","id":6,"method":"tools/call","params":{"name":"autofill_form","arguments":{"application_id":1,"form_fields":[{"name":"name","label":"Full name"},{"name":"email","label":"Email"},{"name":"salary","label":"Salary expectation"}]}}}

// 7. after you submit on the employer's site, mark it submitted
{"jsonrpc":"2.0","id":7,"method":"tools/call","params":{"name":"update_application_status","arguments":{"application_id":1,"status":"submitted"}}}

Step 6 returns a mapping where the salary field is flagged requires_user_review: true — sensitive fields always need your eyes.


Configuration

All config is via environment variables. The free core needs none of them.

Variable Default Purpose
JOB_MCP_DATA_DIR ./data Where the SQLite DB and parsed data live.
JOB_MCP_CV_DIRS — Extra folders parse_cv may read from (OS path separator: ; on Windows, : elsewhere).
JOB_MCP_HTTP_PORT 8787 Port for the local HTTP bridge (loopback only).
JOB_MCP_HTTP_TOKEN — Optional bearer token the bridge requires on /call.

The following enable your own AI key (works on Free or Pro) and are placeholders for future hosted Pro/cloud services (see .env.example):

Variable Purpose
AI_PROVIDER / AI_API_KEY openai or anthropic + your own key → real AI drafts for tailor_cv / cover_letter / draft_answer. Free users use this without any subscription.
AI_MODEL / AI_BASE_URL Optional model + base URL override (e.g. an OpenAI-compatible endpoint).
JOB_MCP_LICENCE_SERVER Pro licence activation endpoint (hosted service).
SUPABASE_URL / SUPABASE_ANON_KEY Cloud sync & auth (Pro, hosted).

Project layout

job-application-mcp/
├── src/
│   ├── index.ts           # stdio MCP server entrypoint
│   ├── http.ts            # local HTTP bridge entrypoint (127.0.0.1)
│   ├── server.ts          # server factory + tool registry
│   ├── tools/             # one file per MCP tool (23 total)
│   │   ├── types.ts       # ToolDef / AnyTool / result helpers
│   │   ├── profile.ts     # get/update_profile
│   │   ├── cv.ts          # parse_cv, list_cvs
│   │   ├── job.ts         # analyze_job, get_job
│   │   ├── matching.ts    # match_cv, tailor_cv, cover_letter, draft_answer
│   │   ├── application.ts # save/list/update_application, autofill_form
│   │   ├── analytics.ts   # application_analytics, status
│   │   ├── pro.ts         # credits, topup_credits, grant_monthly_credits
│   │   └── admin.ts       # admin_create_account / add_candidate / list_team / usage_report
│   ├── store/             # SQLite layer (node:sqlite)
│   │   ├── db.ts          # open / migrate / close / reset
│   │   ├── profile.ts     # profile CRUD
│   │   └── applications.ts# cv / job / application CRUD
│   ├── cv/parser.ts       # PDF / DOCX / TXT parsing (path allow-listed)
│   ├── ai/                # provider abstraction (mock / openai / anthropic)
│   ├── licence/           # entitlement tokens + credits + referrals
│   ├── payments/          # payment-webhook seam (server-side, not in clients)
│   ├── sync/              # cloud-sync seam (local no-op until Pro)
│   ├── features.ts        # feature gating (plan + credits + AI mode)
│   └── lib/
│       ├── types.ts       # domain types
│       ├── crypto.ts      # HMAC-SHA256 + constant-time compare
│       ├── entitlement.ts # Entitlement value type + plan limits
│       └── scoring.ts     # keyword extraction + match scoring (pure)
├── cli/cli.ts             # human CLI: job-mcp serve | serve:http | --help
├── extension/             # Chrome MV3 extension (form capture → preview)
├── desktop/               # Electron wrapper UI (launches the bridge)
├── .github/workflows/ci.yml  # build + typecheck + test + stdio smoke
├── tests/                 # node:test suite
├── BUSINESS_PROPOSAL.md   # open-core + paid-service model
├── CLAUDE.md              # guide for Claude Code working in this repo
└── LICENSE                # AGPL-3.0-or-later

Companion apps

The free core is the stdio MCP server above. Two optional companions live in this repo and talk to a local HTTP bridge (same tools, loopback only):

HTTP bridge

npm run serve:http      # 127.0.0.1:8787 by default

Endpoints: GET /health, POST /call with {"name","arguments"}. Optional bearer auth via JOB_MCP_HTTP_TOKEN. Source: src/http.ts.

Chrome extension — extension/

Captures form fields on a career page and asks the bridge to preview an autofill mapping. Never submits. Load it unpacked from extension/. See extension/README.md.

Desktop app — desktop/

An Electron wrapper that launches the bridge and shows a dashboard (status, profile, applications). Run with cd desktop && npm install && npm start. See desktop/README.md.

Both companions are read/preview only and reach only 127.0.0.1. They inherit the project's no-submission, no-LinkedIn/Indeed-automation rules.


Develop

npm run build       # tsc -> dist/
npm run typecheck   # tsc --noEmit
npm test            # node --test (scoring + store)
npm run dev         # tsc --watch

Adding a tool

  1. Create src/tools/<name>.ts exporting a ToolDef<z.ZodObject<…>>.
  2. Register it in src/tools/index.ts (add to the tools array).
  3. Add a test in tests/ if it has pure logic worth covering.

Tools receive parsed, typed input and return a ToolResult ({ summary, data?, notes? }). The server handles JSON Schema generation, validation, and error wrapping for you.


How matching works

Matching is a pure, heuristic function in src/lib/scoring.ts — no AI, no network.

  1. Extract keywords from the job description: tokenize, drop stopwords and filler verbs, weight tech hints and frequent terms.
  2. Score: for each job keyword, check the candidate's curated profile skills plus skills detected in the CV text. Stem-ish matches count (e.g. react ≈ reactjs).
  3. Result: score (0–100), matched, missing, extra, and notes (e.g. "Below 50% — consider tailoring or skipping").

Formula: score = matched/total × 100 plus a small, capped breadth bonus for extra skills (only when there are job keywords). It's intentionally simple and auditable — a baseline you can replace with the Pro AI scorer later.


Privacy & data

  • Local-first. CVs, profile, and applications live in JOB_MCP_DATA_DIR (default ./data), which is gitignored. The free core makes no network calls.
  • No PII in logs. CV text and personal fields aren't logged at info level.
  • Sensitive fields are flagged. autofill_form marks salary, authorization, gender, disability, and consent fields as requires_user_review: true.
  • You can wipe everything by deleting the data directory.

Roadmap / Pro upgrade

The free core is the foundation. BUSINESS_PROPOSAL.md describes the open-core model. Likely next steps:

  • Free core: match_cv + tailor_cv integration test through the MCP layer; richer keyword extraction (skill taxonomy).
  • Distribution: Windows installer via GitHub Releases; Chrome Web Store extension for form-field capture.
  • Pro (separate hosted services): AI CV tailoring & cover letters, encrypted cloud backup, multi-device sync, maintained site adapters, application analytics.
  • Business: multi-candidate accounts, team dashboards, white-label.

Tool handlers are written so a Pro upgrade can slot in without changing the public tool surface — e.g. tailor_cv returns heuristic suggestions today and could call an AI service tomorrow.


Limitations

  • Keyword extraction is heuristic and will miss or mis-rank some skills. Confirm against the source posting before relying on a match score.
  • No browser automation. Form fields must be supplied to autofill_form (manually or, later, via the extension). The tool previews; it doesn't fill.
  • LinkedIn / Indeed: analysis-only, paste the description, submit manually.
  • Alpha status: APIs and stored schemas may change before 1.0.

License

Copyright © 2026 Job Application MCP contributors.

This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. See LICENSE.

A separate commercial licence is available for embedding without AGPL obligations — see BUSINESS_PROPOSAL.md §8.


Contributing

Issues and PRs welcome. By contributing you agree your contributions will be licensed under the same AGPL-3.0-or-later terms.

Please keep the free core fully local and free — no feature in this repo may gate a free-core capability behind a paid/network service. See CLAUDE.md for the conventions used in this codebase.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选