Skip to main content
Glama
edwardyun12

job-tracker-mcp

by edwardyun12
README.md
# job-tracker-mcp

A personal job-application tracker, exposed as an [MCP](https://modelcontextprotocol.io) server so any MCP-aware LLM client (Claude Desktop, Cline, or my own [Nexus](https://github.com/edwardyun12/nexus-ai) assistant) can manage it through plain conversation instead of a UI.

> "Add a job application for Amazon, Software Engineer Intern, deadline September 1st" → it's in Notion, correctly filed, no clicking required.

**▶ See it running, no setup:** this server powers the live [Nexus demo](https://nexus-ai-zkmf.onrender.com) — open it and ask *"list my job applications"* or add one; the three tools below are what the assistant is calling behind the scenes.

## Why this exists

I'm job-hunting in the UK and wanted a tracker I'd actually keep using — and a real project to learn [Model Context Protocol](https://modelcontextprotocol.io) with, beyond just consuming someone else's MCP server. Building the tool layer myself (rather than wiring up Notion's own official MCP server) is the point: it forces you to design the actual interface an LLM gets to reason over, not just proxy a REST API.

## How it works

```
you: "I finished my internship at Vitality, add it as an offer"
        │
        ▼
LLM decides to call add_application(company: "Vitality", position: "...", status: "Offer")
        │
        ▼
this server executes it against the Notion API and returns a plain-text confirmation
        │
        ▼
LLM relays that back to you in natural language
```

The server itself has zero natural-language understanding — it just declares three tools with typed schemas. The LLM (via whatever client you connect it to) decides *when* to call which tool and *how* to fill in the arguments from your sentence. See [`src/index.ts`](src/index.ts) for the tool registrations and [`src/notion.ts`](src/notion.ts) for the Notion API layer they call into.

## Tools

| Tool | What it does |
|---|---|
| `add_application` | Records a new application (`company`, `position`, optional `deadline`/`status`/`notes`). Applied date is set automatically. |
| `list_applications` | Lists tracked applications, optionally filtered by `status` and/or a `deadlineBefore` cutoff. |
| `update_status` | Finds an application by company name and updates its status. If the name matches more than one application, it lists them and updates nothing rather than guessing which one you meant. |

Status values: `Applied`, `Screening`, `Interview Scheduled`, `Awaiting Result`, `Offer`, `Rejected`, `Withdrawn`.

## Setup

**1. Create a Notion integration**

- Go to [notion.so/my-integrations](https://www.notion.so/my-integrations), create an internal integration, copy the token.

**2. Share a page with it**

Notion integrations can't see anything until a page is explicitly shared with them — this is a hard requirement of Notion's permission model, not something the code can skip. Create any page (e.g. "Job Tracker Data"), then `•••` → **Connections** → select your integration.

**3. Create the tracker database**

This server doesn't auto-provision the database yet (see [Roadmap](#roadmap)) — create one manually under the shared page with these properties:

| Property | Type |
|---|---|
| Company | Title |
| Position | Text |
| Applied Date | Date |
| Deadline | Date |
| Status | Select (options: `Applied`, `Screening`, `Interview Scheduled`, `Awaiting Result`, `Offer`, `Rejected`, `Withdrawn`) |
| Notes | Text |

**4. Configure**

```bash
npm install
cp .env.example .env
```

Fill in `.env`:
```
NOTION_API_TOKEN=ntn_...
NOTION_DATA_SOURCE_ID=...    # the database's data source ID — Notion's
                             # 2025-09-03 API splits database ID from data
                             # source ID; this is the one queries run against
```

**5. Build and connect**

```bash
npm run build
```

Point any MCP client at `dist/index.js`. Example for Claude Desktop / Cline config:

```json
{
  "mcpServers": {
    "job-tracker": {
      "command": "node",
      "args": ["--use-system-ca", "/absolute/path/to/job-tracker-mcp/dist/index.js"]
    }
  }
}
```

`--use-system-ca` is only needed on networks that TLS-inspect outbound HTTPS (e.g. behind a corporate proxy) — Node's bundled CA store won't trust that network's root cert even though your OS already does.

**Or consume it as a dependency.** [Nexus](https://github.com/edwardyun12/nexus-ai) installs this repo straight from GitHub and spawns the built `dist/index.js` itself, passing the Notion credentials through to the child process — no separate config file, no manual `.env` beside it. That path is why the server reads its credentials from the environment first and only falls back to a local `.env`.

## Tech stack

TypeScript, [`@modelcontextprotocol/sdk`](https://github.com/modelcontextprotocol/typescript-sdk) (stdio transport), [Zod](https://zod.dev) for tool schema validation, Notion API directly (no SDK — see [`src/notion.ts`](src/notion.ts)).

## Roadmap

- **`ensure_tracker_exists` tool** — have the server create its own Notion database on first use (schema defined in code) instead of the manual step above. Notion's permission model still requires a human to share *one* page with the integration once; everything past that point should be automatable.
- **`research_company` tool** — given a company name, search for and extract basic facts (industry, size, HQ), then generate interview-prep questions tailored to that company's actual interview style (e.g. Amazon's Leadership-Principles-based behavioral questions), reported via MCP's progress notifications so a client can show live step-by-step progress instead of a single opaque "thinking" state.

TDQS

A3.9/5.0

Scored across 3 tools

Disambiguation5/5

Each tool targets a distinct operation: adding, listing, and updating applications. No overlap in purpose.

Naming Consistency5/5

All tools follow a consistent verb_noun pattern with snake_case: add_application, list_applications, update_status.

Tool Count4/5

Three tools cover core workflows for a job tracker, though a delete or archive tool might be expected. Count is well-scoped for the domain.

Completeness4/5

Covers create, read, and update operations, but lacks a delete or archive function, which is a minor gap for full lifecycle management.

Maintenance

ActivitySlowing
ResponsivenessNo issues