job-tracker-mcp

job-tracker-mcp

A local-first MCP server for tracking job applications, companies, and vacancies, storing everything in a single SQLite file and exposing 19 tools for managing the job search from clients like Claude.

Category
访问服务器

README

job-tracker-mcp

License: MIT Node >=20.11 TypeScript MCP

A local-first MCP server for tracking job applications, companies, and vacancies from Claude — or any other MCP client. Everything lives in a single SQLite file on your machine; nothing is sent anywhere.

The point is to stop keeping a job search in a spreadsheet. You are already talking to an assistant while tailoring a resume or reading a job description, so the assistant may as well be the one writing the record: "add an application for Acme, senior frontend, applied today", "what should I follow up on", "show me the funnel".

Features

  • 19 MCP tools over three linked entities: companies → vacancies → applications
  • Company database — employers with sphere, offices, work format, relocation policy, relevance, priority, and research status (new → researching → target → applied / not_interested / blacklist)
  • Vacancies — open roles filed under a company, with track, seniority, salary range, and full JD text
  • Applications — status pipeline (draft, applied, screening, tech_interview, final, offer, rejected, ghosted), contact details, notes, and per-application timeline events
  • Follow-up queue — overdue actions, applications gone quiet for 5+ days, and what is due this week
  • Funnel analytics — stage-by-stage conversion plus a breakdown by resume variant, so you can see which version of your resume actually converts
  • File attachments — resumes, cover letters, and JDs copied into a managed data directory and linked to the application
  • Auto-migrations — the schema is created and upgraded on startup; there is no separate setup step

Architecture

MCP client (Claude, etc.)
        │  stdio, newline-delimited JSON-RPC
        ▼
   src/mcp.ts          tool registration, zod input schemas, error mapping
        ▼
   src/core/*          applications, companies, vacancies, stats, dashboard, attachments
        ▼
   better-sqlite3      single file, WAL mode, foreign keys on
        ▲
   migrations/*.sql    applied in filename order, tracked in a migrations table

The core/ layer holds all the business logic and knows nothing about MCP. That was deliberate: this code originally sat behind both a REST API and an MCP server in the same project, and the two interfaces were thin adapters over the same functions. Only the MCP adapter was carried over here, but the seam is still there — core/ throws ApiError with an HTTP-ish status code, and mcp.ts translates that into an MCP error result.

Writes are synchronous (better-sqlite3 is a blocking driver), which is exactly what you want for a single-user local tool: no connection pool, no async bookkeeping, and multi-statement changes run inside real transactions.

Quick start

Requires Node.js 20.11+.

git clone https://github.com/kurkul608/job-tracker-mcp.git
cd job-tracker-mcp
npm install
npm run build

Register it with Claude Code:

claude mcp add job-tracker -- node /absolute/path/to/job-tracker-mcp/dist/mcp.js

Or add it to .mcp.json by hand:

{
  "mcpServers": {
    "job-tracker": {
      "command": "node",
      "args": ["/absolute/path/to/job-tracker-mcp/dist/mcp.js"],
      "env": {
        "JOB_TRACKER_DB_PATH": "/absolute/path/to/your/job-tracker.db"
      }
    }
  }
}

Set JOB_TRACKER_DB_PATH explicitly if you use it from an MCP client — clients start the server with their own working directory, and the default path is relative to it.

For local development without a build step:

npm run dev

Configuration

Environment variables

Variable Default Purpose
JOB_TRACKER_DB_PATH ./data/job-tracker.db SQLite database file. Parent directory is created if missing.
JOB_TRACKER_FILES_DIR ./data/files Root for attachments. Each application gets a <id>-<company-slug>/ subdirectory.

Both are resolved against the process working directory when relative.

Enumerated values

Field Values
Application status draft, applied, screening, tech_interview, final, offer, rejected, ghosted
resume_variant frontend, fullstack, ai
Company status new, researching, target, applied, not_interested, blacklist
Vacancy status open, applied, closed, irrelevant
Vacancy track frontend, fullstack, backend, ai, other
relevance high, medium, low
relocation yes, no, unknown
priority 1–3

Tools reference

Applications

Tool Description Key parameters
add_application Create an application record. A bare company name auto-creates the company; pass vacancy_id or company_id to file it under existing records. company, company_id, vacancy_id, position, jd_url, jd_text, source, salary_range, location_policy, notes, resume_variant, status, contact_name, contact_channel, contact_value, next_action_at
get_application Full application detail including timeline events and attachments. id
list_applications List applications, optionally filtered. status, source, q, company_id, vacancy_id
update_application Update editable fields; only provided fields change. id + any add_application field
update_status Move an application to another pipeline stage. id, status
add_note Append a note, call, or email to the application timeline. id, text, type (note|call|email)
attach_resume Copy a file into the tracker's data directory and link it. kind=resume also sets the application's resume_path. id, file_path, kind (resume|cover_letter|jd|other)
list_pending Follow-up queue: overdue actions, applications with no answer for 5+ days, and the upcoming week. —
funnel_stats Funnel counts with stage-to-stage conversion, plus a breakdown by resume variant. —

Companies

Tool Description Key parameters
list_companies List employers with filters for text, status, relevance, sphere, priority, remote/US-only, relocation, and whether they have open vacancies. q, status, relevance, sphere, priority, remote_only, us_only, relocation, has_vacancies, limit
get_company One company with its full tree: vacancies, and the applications filed under each. id
add_company Add an employer. Fails if the name already exists. name, sphere, offices, market, work_format, careers_url, linkedin_url, website, relocation, is_remote, has_us, relevance, status, priority, notes, source
upsert_company Create, or update the existing company matched by name. Useful when writing back research results. same as add_company
update_company Update an employer by id; only provided fields change. id + any add_company field
company_overview Counts across the company database plus the list of distinct spheres. —

Vacancies

Tool Description Key parameters
add_vacancy Add an open role under a company. company_id, title, track, seniority, url, location, work_format, salary_range, jd_text, status, priority, notes, posted_at
list_vacancies List vacancies across companies. company_id, status, track, priority, q, limit
get_vacancy One vacancy with its company and the applications filed against it. id
update_vacancy Update a vacancy; only provided fields change. id + any add_vacancy field

Example prompts

Once the server is registered, these work as plain requests:

  • "Add an application for Acme Corp, Senior Frontend Engineer, found on LinkedIn, remote US, I used the fullstack resume."
  • "I just had a screening call with Acme — move it to screening and log a note about what they asked."
  • "What do I need to follow up on today?"
  • "Show my funnel stats — which resume variant converts best?"
  • "Add Globex to the company database: fintech, remote-first, has a US office, mark it high relevance and priority 1."
  • "List target companies with open frontend vacancies that I haven't applied to yet."
  • "Add the vacancy from this URL under Globex, then create an application against it."
  • "Attach ~/resumes/acme-frontend.pdf to application 12 as the resume."

Data and privacy

Everything is local. The database is a single SQLite file, attachments are plain files on disk, and the server speaks only stdio to its client. The default data/ directory is gitignored.

Development

npm run dev     # run from source with tsx
npm run build   # compile to dist/
npm start       # run the compiled server

The schema lives in migrations/. To change it, add a new numbered .sql file — it is applied on the next startup and recorded in the migrations table. Existing files are never re-run.

License

MIT — see LICENSE.

推荐服务器

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 模型以安全和受控的方式获取实时的网络信息。

官方
精选