Skip to main content
Glama
developermaroof

mcp-job-tracker

mcp-job-tracker

CI

An MCP server that lets Claude track your job applications. You tell Claude about an application, and it saves it in a local JSON file on your computer. You can then list your applications, update their status and see which ones need a follow-up. There is no database and no account to set up.

Tools

  • add_application saves a new application with the status applied.

  • list_applications lists your applications, newest first. If some are hidden by the limit, the last line says how many.

  • update_status changes the status of one application.

  • followups_due lists applications that are still applied after a number of days, so you know who to follow up with.

The possible statuses are applied, replied, interview, rejected and offer.

Tool

Input

Required

Description

add_application

company

Yes

Company name

role

Yes

Job title or role

platform

Yes

Where you applied, for example LinkedIn, Upwork or Rozee

url

No

Link to the job posting

notes

No

Any extra notes

applied_date

No

Date you applied, as YYYY-MM-DD. Must be a real date and not in the future. Default: today.

list_applications

status

No

Only show applications with this status

limit

No

How many applications to show, newest first. Whole number, at least 1. Default: 20.

update_status

id

Yes

ID of the application

status

Yes

The new status

followups_due

days

No

Show applications still in applied for more than this many days. Default: 7.

Related MCP server: Career Compass MCP

Requirements

  • Node.js 20 or newer (required by the MCP TypeScript SDK, @modelcontextprotocol/server)

  • npm (installed with Node.js)

  • Claude Desktop, or another MCP client that can start a stdio server

Install and build

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

npm run build runs the TypeScript compiler (tsc) and writes the JavaScript output to build/. Run it again after every change to src/index.ts.

Connect to Claude Desktop

  1. In Claude Desktop, open Settings > Developer > Edit Config. This opens claude_desktop_config.json. On Windows the file is at %APPDATA%\Claude\claude_desktop_config.json.

  2. Add the server inside mcpServers:

    {
      "mcpServers": {
        "job-tracker": {
          "command": "C:\\Program Files\\nodejs\\node.exe",
          "args": ["C:\\path\\to\\mcp-job-tracker\\build\\index.js"]
        }
      }
    }

    Replace C:\\path\\to\\mcp-job-tracker with the folder where you cloned the project.

  3. Fully quit Claude Desktop and open it again. Closing the window is not enough, because Claude Desktop keeps running in the system tray. Right-click the Claude icon in the system tray (bottom right of the taskbar), choose Quit, then start Claude Desktop again.

Notes for Windows:

  • Every backslash in the JSON file must be doubled (\\). A single backslash is an escape character in JSON, and the config will not load.

  • Use the full path to node.exe, not just node. Claude Desktop does not always see the same PATH as your terminal. To find the path, run where.exe node in a terminal and use the path it prints, with the backslashes doubled.

  • If mcpServers already has other servers, put a comma after the closing } of the entry before this one. Do not put a comma after the last entry.

On macOS the config file is at ~/Library/Application Support/Claude/claude_desktop_config.json, and paths use forward slashes, for example /Users/you/mcp-job-tracker/build/index.js.

If the tools do not show up, check the log files in %APPDATA%\Claude\logs on Windows or ~/Library/Logs/Claude on macOS.

Example prompts

  • "Add a job application: Frontend Developer at Acme Corp on LinkedIn, link https://example.com/jobs/123."

  • "I applied to Globex for a React Developer role on Upwork on 2026-10-20. Add it."

  • "Show my job applications."

  • "Show my last 5 applications."

  • "Show only the applications where I have an interview."

  • "Globex replied to me. Update application 2 to replied."

  • "Which applications need a follow-up?"

  • "Which applications have had no reply for more than 14 days?"

How it works

  • stdio transport. Claude Desktop starts the server as a child process (node build/index.js) and talks to it through standard input and standard output. Each message is a JSON-RPC message on its own line. There is no network port and no web server.

  • zod validation. Every tool describes its inputs with a zod schema. The MCP SDK turns these schemas into JSON Schema so Claude knows which inputs each tool takes, and it checks every call against the schema before the tool code runs. Invalid input, such as a missing role, an unknown status or a date in the future, is rejected with an error message and nothing is saved.

  • Never use console.log. In a stdio server, stdout is used only for protocol messages. console.log writes to stdout, so any log line would get mixed into the messages, the client would not be able to read them, and the connection can break. Use console.error instead. It writes to stderr, which Claude Desktop saves in its log files.

  • Storage. Applications are saved in data/applications.json inside the project folder. The path is worked out from the location of build/index.js, not from the current working directory, because Claude Desktop can start the server from any folder. The data folder and the file are created automatically on the first tool call. Each new application gets the next free ID number. The file is listed in .gitignore, so your job search data is never committed.

Project structure

mcp-job-tracker/
  .github/
    workflows/
      ci.yml            GitHub Actions: build and test on every push and pull request
  src/
    index.ts            Server code: storage helpers and the 4 tools
    lib.ts              Pure helpers: date check, follow-up filter, newest-first sorting
    lib.test.ts         Vitest tests for lib.ts (not included in the build)
  build/                Compiled JavaScript, created by npm run build (not in git)
  data/
    applications.json   Your saved applications, created on first use (not in git)
  .gitignore
  LICENSE               MIT license
  package.json          Dependencies and the build and test scripts
  package-lock.json     Exact dependency versions
  tsconfig.json         TypeScript compiler settings
  README.md

Development

npm install
npm run build
npm test

npm test runs the Vitest tests in src/lib.test.ts once. Running the tests needs Node.js 22.12 or newer (required by Vitest). GitHub Actions runs the build and the tests on Node.js 22 and 24 for every push and pull request to main.

License

MIT. See LICENSE.


Built by Maroof Qureshi

developermaroof.com

Available Tools

4 tools
add_applicationC

Add a new job application to the tracker

NameRequiredDescriptionDefault
urlNoLink to the job posting
roleYesJob title or role
notesNoAny extra notes
companyYesCompany name
platformYesWhere you applied (e.g. LinkedIn, Upwork, Rozee)
applied_dateNoDate you applied, YYYY-MM-DD (default today)

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden for a mutation tool. It does not say whether duplicate applications are rejected, whether any fields are defaulted server-side beyond what the schema states, or what the caller gets back on success.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with no wasted words. It is efficient but arguably under-specified rather than genuinely well-structured for a mutation tool with six parameters.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a six-parameter write operation with no annotations and no output schema, the description should cover duplicate handling and expected outcome. It provides neither, leaving meaningful gaps an agent must guess at.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema documents all six fields including the applied_date default of today. The description adds no meaning beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Add a new job application to the tracker'), which is clearly distinct from the read-oriented siblings list_applications and followups_due. It does not explicitly name or contrast an alternative, so it falls short of a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance on when to use this versus update_status or list_applications, and no prerequisites or exclusions. The implicit usage (creating a new record) is obvious from the verb, but nothing is stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

followups_dueA

List applications still in "applied" status for more than N days, so you can follow up

NameRequiredDescriptionDefault
daysNoMinimum days since applying (default 7)

TDQS

A3.7/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full burden. 'List' signals a read-only operation and the filter semantics are disclosed, but nothing is said about result ordering, pagination, or what fields come back for a follow-up workflow.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

One sentence with zero filler and the filter criterion front-loaded. Minor deduction for the nested quoting of "applied" and the loose 'N days' phrasing, which reads slightly less cleanly than the schema's 'days'.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a one-parameter, zero-required read tool this covers the essential semantics: the status filter, the threshold, and the intent. With no output schema, the return shape is left unspecified, which is the only real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single 'days' parameter already documents its meaning and default of 7. The description's 'more than N days' matches the schema but adds no boundary or format detail beyond it, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description gives a specific verb ('List'), a specific resource ('applications'), and a precise filter predicate ('still in "applied" status for more than N days'). This is enough for an agent to distinguish it from the sibling list_applications, which is an unfiltered listing, without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The trailing clause 'so you can follow up' implies the intended scenario, but it never states when to prefer this over list_applications, nor any exclusions or prerequisites. Usage is inferable but not spelled out.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_applicationsA

List job applications, optionally filtered by status

NameRequiredDescriptionDefault
limitNoMaximum number of applications to show, newest first (default 20)
statusNoOnly show applications with this status

TDQS

A3.6/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the disclosure burden. 'List' implies a read-only operation, but it doesn't mention pagination behavior, ordering, or result scope beyond what the schema states (newest first). For a simple list tool this is adequate but thin.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single, front-loaded sentence with zero waste that conveys the resource and the optional filter immediately.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter read tool with a fully documented schema and no output schema, the description is complete enough to invoke correctly. Minor gap in not hinting at result shape or ordering, but the schema covers the essentials.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both parameters are fully documented in the schema (limit, status enum). The description only restates the status filter, adding no syntax or format beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (List) and resource (job applications) with the key optional filter. It implicitly distinguishes itself from siblings like add_application and update_status, though it doesn't name them explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'optionally filtered by status' implies the filtering use case, but there's no explicit guidance on when to use this vs followups_due or when not to filter. Usage context is inferred rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

update_statusC

Change the status of a job application

NameRequiredDescriptionDefault
idYesID of the application
statusYesNew status

TDQS

C2.9/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries the full behavioral burden. It does not state whether status transitions are validated, whether changes are reversible, whether side effects occur (e.g., timestamps, notifications), or what permissions are required for this mutation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

A single short sentence with the operation front-loaded and zero filler. However, it is terse to the point of omitting useful context, so it is not maximally effective.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a simple two-parameter mutation with fully documented schema and no output schema, the description is minimally adequate. It lacks behavioral detail about side effects and valid transitions, which an agent would want before invoking a write operation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the status enum is fully enumerated with per-field descriptions, so the schema does the heavy lifting. The description adds no additional meaning about the id format or the semantics of each status value, which is the baseline case.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific verb ("Change") and resource ("the status of a job application"), making the operation unambiguous. It does not explicitly distinguish itself from siblings like add_application, but the intent is still clear from the wording.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

There is no guidance on when to use this versus add_application or list_applications, and no mention of prerequisites such as the application must already exist. The agent must infer usage entirely from the name and schema.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 4 tool updatesv1.0.0
    • First observedadd_application
    • First observedfollowups_due
    • First observedlist_applications
    • First observedupdate_status

TDQS

B3.3/5.0

Scored across 4 tools

Disambiguation4/5

Each tool has a clear primary action and resource: list, add, update status, and a specialized follow-up query. The only mild overlap is between list_applications (which accepts a status filter) and followups_due, but the day-based threshold makes followups_due meaningfully distinct.

Naming Consistency4/5

Three of four tools follow a clean verb_noun pattern (list_applications, update_status, add_application). followups_due breaks the pattern as a noun_qualifier phrase, but it remains readable and unambiguous.

Tool Count4/5

Four tools is a tight, well-scoped set for a lightweight job-application tracker. Every tool serves a distinct purpose in the core workflow, though the surface is on the thin side.

Completeness3/5

The core lifecycle (add, list, update status, follow up) is covered, but there is no get-single-application, no delete/remove, and no way to edit fields other than status. These notable gaps will limit agents needing record-level detail or cleanup.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    D
    maintenance
    Enables searching justjoin.it for job listings and tracking applications locally with status updates, all via natural language in Claude.
    4
    MIT
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to manage a personal job application tracker, allowing users to list, add, update, and delete job applications with company, role, and status details through natural language.
    -
  • F
    license
    Not graded
    quality
    A
    maintenance
    Enables Claude Web users to manage their job application workflow by storing profile and resume data, analyzing job descriptions, preparing applications, and tracking progress — all with manual submission and no platform automation.
    1
    -