Application Tracker MCP
# Application Tracker MCP
A privacy-first [Model Context Protocol](https://modelcontextprotocol.io/) server for managing job, fellowship, and graduate-school applications locally.
It gives an MCP client a durable local workspace for:
- saving a job description and application status;
- comparing a private factual profile to a role without inventing experience;
- creating editable LaTeX CV and cover-letter starters;
- producing an interview-prep scaffold;
- discovering roles from opt-in public Greenhouse, Lever, and Ashby job-board APIs.
It does **not** submit applications, scrape logged-in sites, bypass CAPTCHAs/rate limits, or send data to a hosted service.
## Why an MCP server?
An LLM is useful for interpreting a job description and drafting language. It should not be the database of record or silently decide facts about a candidate. This server keeps the repeatable operations local and explicit:
```text
Private profile + job description
↓
MCP tools: save / analyse / scaffold / track
↓
Agent drafts wording from factual evidence
↓
Human reviews, edits, and submits
```
The server owns tracking and document scaffolding. The MCP client owns conversational reasoning. The user owns the final claims and submission.
## Privacy model
The public repository contains **no applicant data**. It includes only fictional examples.
- Configure `APPLICATION_TRACKER_ROOT` to a private local directory.
- Keep profiles, real application records, PDFs, job descriptions, and notes outside the repository or in ignored directories.
- The server accepts only paths relative to `APPLICATION_TRACKER_ROOT`; it rejects absolute paths and path traversal.
- Do not commit the configured data workspace. The included `.gitignore` ignores `data/`, `applications/`, `private/`, PDFs, and LaTeX build output.
Read [SECURITY.md](SECURITY.md) before using the server with sensitive information.
## Quick start
Requires Python 3.10+ and the official Python MCP SDK.
```bash
git clone https://github.com/YOUR_GITHUB_USERNAME/application-tracker-mcp.git
cd application-tracker-mcp
python -m venv .venv
. .venv/bin/activate
pip install -e .
# Pick a private directory that is NOT inside the Git checkout.
export APPLICATION_TRACKER_ROOT="$HOME/.local/share/application-tracker"
application-tracker-mcp
```
The server uses MCP's standard `stdio` transport. The client launches it as a subprocess and communicates using JSON-RPC over standard input/output. See the [MCP transport specification](https://modelcontextprotocol.io/specification/draft/basic/transports).
### Example client configuration
Use a client configuration equivalent to the following (adapt the absolute paths):
```json
{
"mcpServers": {
"application-tracker": {
"command": "/absolute/path/to/application-tracker-mcp/.venv/bin/application-tracker-mcp",
"env": {
"APPLICATION_TRACKER_ROOT": "/absolute/private/path/application-tracker-data"
}
}
}
}
```
## MCP tools
| Tool | Purpose |
|---|---|
| `create_application` | Saves a private application record and its job description. |
| `list_applications` | Lists records, optionally by status. |
| `update_application_status` | Tracks drafting, applied, interview, offer, rejected, and closed states. |
| `analyse_application_fit` | Matches only declared private profile skills/evidence against the saved JD. |
| `render_application_drafts` | Writes editable LaTeX CV and cover-letter starters plus a tailoring brief. |
| `create_interview_prep` | Creates a factual interview-practice scaffold. |
| `compile_application_tex` | Runs Tectonic on a generated `.tex` file without using a shell. |
| `discover_public_jobs` | Fetches roles from public Greenhouse, Lever, or Ashby APIs. |
## Example workflow
1. Copy the fictional [profile example](examples/profile.example.json) into your **private** data workspace and replace it with your own verified facts.
2. Ask an MCP client to call `create_application` with the job description.
3. Call `analyse_application_fit` with a relative profile path such as `private/profile.json`.
4. Ask the agent to write a factual tailoring brief using the returned evidence.
5. Call `render_application_drafts` to create local, editable `.tex` files.
6. Review and edit the files. If Tectonic is installed, call `compile_application_tex`.
7. Use `update_application_status` as the process progresses.
8. Before an interview, call `create_interview_prep` with only truthful highlights.
The `examples/` directory is documentation only. It is deliberately fictional and does not demonstrate a real applicant.
## Public job discovery
The repository has a small safe subset of the larger job-discovery concept. It supports only public APIs:
```text
discover_public_jobs(provider="greenhouse", board="example-board", location_contains="Berlin")
discover_public_jobs(provider="lever", board="example-company")
discover_public_jobs(provider="ashby", board="example-company")
```
It intentionally does not scrape LinkedIn, StepStone, Xing, authenticated pages, or sites with CAPTCHAs. It does not apply to jobs.
## LaTeX notes
`render_application_drafts` creates generic, editable LaTeX starters. The server never writes a real applicant's data into this repository; it only writes into your private workspace at runtime.
If [Tectonic](https://tectonic-typesetting.github.io/) is on `PATH`, `compile_application_tex` can compile an artifact safely using argument lists, not a shell. Otherwise, compile the `.tex` file with your preferred local LaTeX workflow.
## Development
```bash
python -m unittest discover -s tests -v
python -m compileall src tests
```
The server targets the official Python MCP SDK v2 (`mcp>=2,<3`), whose high-level server class is `MCPServer`. [SDK migration notes](https://github.com/modelcontextprotocol/python-sdk/blob/main/docs/whats-new.md)
## Project status
This is an early local-first foundation. Good next additions are encrypted-at-rest user storage, a richer document-template system, more public ATS connectors, and client-specific installation guides.
TDQS
Scored across 8 tools
Each tool targets a distinct action and resource: create/list/update applications, analyse fit, render drafts, create interview prep, compile TeX, and discover jobs. There is no overlap or ambiguity between tool purposes.
All tools follow a consistent verb_noun snake_case pattern (create_application, list_applications, update_application_status, analyse_application_fit, etc.). The only minor deviation is the British spelling 'analyse' vs 'analyze', but the pattern is uniform.
Eight tools is well within the ideal 3-15 range and each tool serves a clearly defined function in the application tracking workflow. The count feels appropriate for the domain and not excessive or thin.
The toolset covers the core lifecycle: create, list, update, analyse, render, compile, and prepare for interviews. A delete application tool is missing, and there is no explicit single-application getter, but list_applications can serve that need, so the gaps are minor.