Skip to main content
Glama
jrootn
by jrootn
README.md
# 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

A3.6/5.0

Scored across 8 tools

Disambiguation5/5

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.

Naming Consistency5/5

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.

Tool Count5/5

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.

Completeness4/5

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.

Maintenance

ActivitySlowing
ResponsivenessNo issues