mcp-job-tracker
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-job-trackerAdd a Frontend Developer application at Acme Corp on LinkedIn"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-job-tracker
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_applicationsaves a new application with the statusapplied.list_applicationslists your applications, newest first. If some are hidden by the limit, the last line says how many.update_statuschanges the status of one application.followups_duelists applications that are stillappliedafter 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 |
|
| Yes | Company name |
| Yes | Job title or role | |
| Yes | Where you applied, for example LinkedIn, Upwork or Rozee | |
| No | Link to the job posting | |
| No | Any extra notes | |
| No | Date you applied, as | |
|
| No | Only show applications with this status |
| No | How many applications to show, newest first. Whole number, at least 1. Default: 20. | |
|
| Yes | ID of the application |
| Yes | The new status | |
|
| No | Show applications still in |
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 buildnpm 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
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.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-trackerwith the folder where you cloned the project.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 justnode. Claude Desktop does not always see the same PATH as your terminal. To find the path, runwhere.exe nodein a terminal and use the path it prints, with the backslashes doubled.If
mcpServersalready 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.logwrites 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. Useconsole.errorinstead. It writes to stderr, which Claude Desktop saves in its log files.Storage. Applications are saved in
data/applications.jsoninside the project folder. The path is worked out from the location ofbuild/index.js, not from the current working directory, because Claude Desktop can start the server from any folder. Thedatafolder 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.mdDevelopment
npm install
npm run build
npm testnpm 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
Available Tools
4 toolsadd_applicationC
Add a new job application to the tracker
| Name | Required | Description | Default |
|---|---|---|---|
| url | No | Link to the job posting | |
| role | Yes | Job title or role | |
| notes | No | Any extra notes | |
| company | Yes | Company name | |
| platform | Yes | Where you applied (e.g. LinkedIn, Upwork, Rozee) | |
| applied_date | No | Date you applied, YYYY-MM-DD (default today) |
TDQS
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.
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.
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.
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.
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.
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
| Name | Required | Description | Default |
|---|---|---|---|
| days | No | Minimum days since applying (default 7) |
TDQS
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.
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.
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.
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.
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.
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
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of applications to show, newest first (default 20) | |
| status | No | Only show applications with this status |
TDQS
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.
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.
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.
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.
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.
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
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | ID of the application | |
| status | Yes | New status |
TDQS
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.
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.
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.
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.
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.
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.
4 tool updates
v1.0.0- First observed
add_application - First observed
followups_due - First observed
list_applications - First observed
update_status
TDQS
Scored across 4 tools
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.
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.
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.
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
Related MCP Connectors
- jobwyreOAuthapp.jobwyre
Track job applications on a board: let Claude or ChatGPT read and update jobs, interviews, notes.
Job search tracker for Claude and ChatGPT: applications, interviews, follow-ups, company watch.
Manage job applications — jobs, companies, boards, notes, and profile — from your AI client.
Track job applications: find the ones to follow up on, add jobs, update status, notes and steps.
Related MCP Servers
- AlicenseBqualityDmaintenanceEnables searching justjoin.it for job listings and tracking applications locally with status updates, all via natural language in Claude.4MIT
- AlicenseNot gradedqualityAmaintenanceTurns Claude into a career co-pilot that manages resumes, cover letters, job applications, and interview prep using local YAML files.402 npm6MIT
- FlicenseNot gradedqualityCmaintenanceEnables 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.-
- FlicenseNot gradedqualityAmaintenanceEnables 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-