Job Application MCP
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@Job Application MCPMatch my CV to this job posting"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
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 --helpConnect 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.jsThe 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 |
| — | The local candidate profile (auto-created on first call). |
|
| Updated profile. |
CVs
Tool | Args | Returns |
|
| Parsed CV stored locally; detected skills + a short preview. |
| — | 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 |
|
| Extracted keywords + summary; stored as a job (unless |
|
| A stored job with its keywords. |
Matching & prep
Tool | Args | Returns |
|
| 0–100 score, matched/missing/extra skills; optionally creates a draft application. |
|
| Tailored CV draft. With your own AI API key ( |
|
| Cover-letter draft (AI with your own key, else heuristic). |
|
| Screening-answer draft (AI with your own key, else heuristic template). Always review. |
AI tools and your own key.
tailor_cv,cover_letter, anddraft_answeruse a real AI provider when you setAI_PROVIDER(openaioranthropic) andAI_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 |
|
| A draft application record. Does not submit. |
|
| Application records (optionally filtered by status). |
|
| Updates status; sets |
|
| 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 |
| — | Counts by status, average match score, recent activity. Pro entitlement adds an advanced breakdown. |
| — | Server/plan/credits snapshot (plan label, AI credit balance, active features). |
Credits & Pro (wire-ready seams)
Tool | Args | Returns |
| — | Current AI credit balance + recent ledger entries. |
|
| Apply an AI-credit top-up code (idempotent per code). Admin/test. |
|
| Grant the monthly AI allowance (idempotent per calendar month). Admin/test. |
Admin / business (wire-ready seams)
Tool | Args | Returns |
|
| Create a business account. |
|
| Add a candidate/coach to an account. |
|
| List an account's team members. |
|
| 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.jsSend 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 |
|
| Where the SQLite DB and parsed data live. |
| — | Extra folders |
|
| Port for the local HTTP bridge (loopback only). |
| — | Optional bearer token the bridge requires on |
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 |
|
|
| Optional model + base URL override (e.g. an OpenAI-compatible endpoint). |
| Pro licence activation endpoint (hosted service). |
| 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-laterCompanion 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 defaultEndpoints: 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 --watchAdding a tool
Create
src/tools/<name>.tsexporting aToolDef<z.ZodObject<…>>.Register it in
src/tools/index.ts(add to thetoolsarray).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.
Extract keywords from the job description: tokenize, drop stopwords and filler verbs, weight tech hints and frequent terms.
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).Result:
score(0–100),matched,missing,extra, andnotes(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_formmarks salary, authorization, gender, disability, and consent fields asrequires_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_cvintegration 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.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/firyomaefx/job-application-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server