Skip to main content
Glama

JobApplication

Find jobs on the sites you choose, hide the ones you don't want, see how well each one matches your skills, and get a tailored PDF resume for each job — in one click.

Made for people who don't code. You use it by talking to Claude (Claude Code or Claude Desktop); Claude runs the tool, explains things in plain English, and fixes settings for you.

📸 Screenshot of the dashboard goes here (docs/screenshots/dashboard.png)

What it does

  • Searches LinkedIn (public job pages, no login), FINN.no (Norway) and the Simplify GitHub lists (US students). The BI Norwegian Business School portal needs a login and is planned for a later version.

  • Filters by job title words, words to avoid (e.g. "senior"), places, job type, age of the ad, companies and ad language. Hidden jobs are kept with the reason, so nothing disappears silently.

  • Scores each job: which of your skills the ad mentions, and which skills in the ad you didn't list.

  • Builds a tailored resume: only the two Skills lines change per job (the ad's matching keywords go first); every other letter of your resume stays exactly as you wrote it. The PDF is named First_Last_Company_Role.pdf.

  • Writes a tailored cover letter (English or Norwegian): Claude writes the text, the tool checks that every number and name in it comes from your resume or the ad, that it fits on one page and avoids clichés.

  • Tracks what you did: interested → applied → interview → offer.

  • Imports your Word or PDF resume into the PDF template. Claude types it; the tool checks every word, link and the page count against your original file.

  • Runs on your computer only. Your jobs, resume and settings stay in a private folder (~/JobApplication-data), never in this repository.

Related MCP server: career-agent

Install with Claude (easiest)

  1. Install Claude Code (or use Claude Desktop, see below).

  2. Download this folder (green Code button → Download ZIP, then unzip it, or git clone).

  3. Open Claude Code in that folder and paste this sentence:

    Set up JobApplication for me on this computer, step by step, and ask me what jobs I'm looking for.

    (or type /setup). Claude installs what's needed, creates your private folder, asks about the jobs you want, and runs a first check.

Then just ask things like "find new jobs", "make a resume for the DNV one", "I applied to it", or use the shortcuts /find-jobs, /tailor, /cover-letter, /applied, /import-resume, /report-bug, /update.

Manual install (Mac)

# 1. tools (Homebrew from https://brew.sh first, if you don't have it)
brew install uv tectonic pandoc
# 2. the app (in this folder)
uv sync
# 3. your private folder with example settings and an example resume
uv run jobapp init
# 4. check everything
uv run jobapp doctor

Linux works the same (curl -LsSf https://astral.sh/uv/install.sh | sh; TeX Live or tectonic; pandoc).

Everyday use

uv run jobapp poll                     # search the job sites now
uv run jobapp list --sort match        # best matches first
uv run jobapp show <id>                # one job in detail
uv run jobapp build <id> --reveal      # tailored PDF, shown in Finder
uv run jobapp mark <id> applied        # keep track
uv run jobapp serve --background       # dashboard in your browser (keeps running; --stop to stop)
uv run jobapp schedule install         # search automatically at the times in config.yaml
uv run jobapp connectors sync obsidian # optional: one note per job in Obsidian (see below)
uv run jobapp rescore                  # after editing keywords.yaml

Your settings are in ~/JobApplication-data/config.yaml; after editing run uv run jobapp config validate — it explains mistakes and suggests the right spelling. Filter words match whole words; add * for word beginnings/endings (robot* → robotics, *analytiker → Finansanalytiker).

Word or PDF resume import

uv run jobapp resume import ~/Desktop/resume.docx --prepare   # or resume.pdf; Claude follows import/prompt.md
uv run jobapp resume import --verify                          # checks words, links, pages, markers
uv run jobapp resume import --accept                          # use it (old resume is backed up)

With your own API key (uv run jobapp key set ANTHROPIC_API_KEY, stored in the Mac Keychain) the whole loop runs automatically: uv run jobapp resume import resume.docx --api (or resume.pdf). A Word file gives the best result (bold/italic are kept); a PDF works too as long as its text can be selected (not a scan).

Cover letters

uv run jobapp letter <id> --prepare      # Claude follows letters/<id>/prompt.md and writes letters/<id>/body.md
uv run jobapp letter <id> --verify       # facts, length, one page, banned phrases, keywords, language
uv run jobapp letter <id> --accept       # output/First_Last_Company_Role_CoverLetter.pdf + .txt for web forms

Or just ask Claude: /cover-letter <id> (or click Cover letter ✉ on a job in the dashboard). --language no writes a Norwegian søknad; --api runs the loop with your own API key. Settings live in ~/JobApplication-data/coverletter/: template.tex (layout), style.yaml (language, tone, word limit, banned phrases like "passionate" or "I am writing to express", sign-off) and samples/ (drop in your own past letters — used for tone only). Profiles made before this feature: uv run jobapp coverletter init.

Obsidian (optional)

If you keep notes in Obsidian, JobApplication can write one note per job into your vault — same layout as a hand-made job note: details table, Apply link, a Status checklist and room for your own notes. It is off until you switch it on in config.yaml:

connectors:
  obsidian:
    enabled: true
    vault: ~/Documents/Obsidian Vault   # the folder you opened as a vault in Obsidian
    folder: Jobs                        # notes go in Jobs/Full-Time, Jobs/Internships, Jobs/Part-Time

Then uv run jobapp connectors sync obsidian writes notes for the jobs you already have (--dry-run shows what it would do first). After that every search adds notes for new jobs and keeps _Dashboard.md and _New Today.md up to date. Your own writing in a note is never changed — only the status, match and link fields at the top and the "Applied" tick box. You can rename or move notes; they are found by job_id. Extras: two_way: true lets you change a job's status in the note (or tick "Applied") and have it show up here at the next search; git_push: true commits the Jobs folder (and pushes it) if your vault uses git; min_match: 40 only writes notes for good matches; one_note_per_title: true keeps one note per company + title (reposts share it). The two generated notes can have other names (dashboard_file: "_JobApplication Dashboard.md", new_today_file: ...); an existing file at that name that JobApplication didn't make is never overwritten (doctor says so; connectors sync obsidian --adopt-dashboards replaces it on purpose).

Several resumes (optional)

Have two versions of your resume (say one for robotics jobs and one for ML jobs)? List them in config.yaml:

resume:
  variants:
    perception: {tex: resume/perception.tex, keywords: resume/keywords.yaml, prefer_if: [perception, vision, slam, "robot*"]}
    mle:        {tex: resume/mle.tex,        keywords: resume/keywords.yaml, prefer_if: [machine learning, ml, llm]}
  default_variant: perception

Each job uses the resume whose prefer_if words best fit its title (then its description), else the default. Choose yourself with uv run jobapp build <id> --variant mle (remembered for that job; --variant auto goes back to automatic) or the "Resume" drop-down on the dashboard. list/show show which one a job uses.

Keyword match

matched = words from your keywords.yaml found in the ad. missing = skills from a built-in vocabulary (src/jobapp/resume/skills_vocab.yaml: tech, business/analytics, Norwegian equivalents) that the ad mentions and your list doesn't have — never names, slogans or "About us" text. Add your own terms to it in keywords.yaml:

extra_vocab:
  Foxglove: []
  Isaac ROS: [isaac-ros]

After editing keywords run uv run jobapp rescore.

Moving from the older jobdesk tracker

uv sync --extra mongo, then uv run jobapp migrate --from-mongo --dry-run (and without --dry-run) copies the jobs from its Mongo database (read-only; safe to run again). Status, applied date, saved job descriptions, the resume variant, the date found and each job's existing Obsidian note are kept; the next search recognises the same LinkedIn/Simplify jobs instead of adding copies. Contacts and messages stay in the old system.

Claude Desktop

JobApplication includes an MCP server, so Claude Desktop can use it too. Print your personal config snippet:

uv run jobapp mcp-config

and paste it into ~/Library/Application Support/Claude/claude_desktop_config.json (Claude Desktop → Settings → Developer → Edit Config), then restart Claude Desktop. It looks like:

{
  "mcpServers": {
    "jobapplication": {
      "command": "<HOME>/.local/bin/uv",
      "args": ["--directory", "<HOME>/JobApplication", "run", "jobapp", "mcp"],
      "env": { "JOBAPP_HOME": "<HOME>/JobApplication-data" }
    }
  }
}

Tools: find_jobs, list_jobs, job_details, build_resume, mark_job, import_resume_prepare, import_resume_submit_tex, doctor, update_config_filters.

Something wrong?

uv run jobapp doctor explains each problem with a fix. uv run jobapp report-bug makes a zip of logs and diagnostics with your name, email, phone numbers and passwords removed — send that to the developer. uv run jobapp version shows which version you have (mention it when you ask for help).

Being a good citizen

JobApplication is a personal tool, not a crawler: it waits at least 2 seconds between requests to the same site, slows down when a site asks it to (HTTP 429), uses only public pages, never logs in for you, and follows the site rules we know about (e.g. FINN.no: no abTestKey, never industry + occupation together, nothing under /job/salary/). Note that FINN.no's robots.txt asks AI training crawlers to stay away from /job/; JobApplication doesn't train anything, but if you want to be extra careful, leave the FINN source switched off. It never applies or sends emails for you.

For developers

docs/ARCHITECTURE.md, docs/ADDING_A_SOURCE.md, CHANGELOG.md. Tests: uv run pytest (offline); real network checks: uv run pytest -m live. scripts/privacy_scan.sh keeps personal data out of the repo.

MIT licensed.

Available Tools

12 tools
build_resumeB

Build the tailored PDF resume for a job. variant: which resume to use if the user has several (saved for this job; 'auto' = pick automatically; leave empty to keep the current choice).

NameRequiredDescriptionDefault
job_idYes
variantNo

TDQS

B3.2/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It does disclose non-obvious behavior about how the variant argument resolves ('saved for this job', 'auto' picks automatically, empty keeps the current choice), which is real value. However, it says nothing about side effects (where the PDF is written, whether it overwrites a prior build), permissions, or repeat-call behavior.

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?

Two sentences, purpose front-loaded, with the parameter explanation compactly parenthesized. The parenthetical is dense but every clause adds information; nothing is wasted.

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?

No output schema and no annotations, so the description should be more self-sufficient than it is. It covers what is produced and how variant resolves, but omits the job_id source, the output destination, and any side effects, leaving an agent to guess at invocation context.

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 0%, so the description must compensate. It compensates well for variant, effectively enumerating its accepted values despite no enum in the schema. The required job_id parameter gets no explanation at all (format, source, or validity), so half the parameters remain undocumented.

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 (build) and a concrete artifact (tailored PDF resume) tied to a job, which clearly separates it from siblings like cover_letter_prepare or find_jobs. It stops short of naming an alternative tool or stating the full workflow context, but the action and resource are unambiguous.

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 explicit when-to-use guidance: nothing says this is the step after selecting a job, that job_id must come from find_jobs/job_details, or that a prepare/submit flow does not apply here. The variant note implies the tool is called on an already-chosen job, but that is inference, not stated guidance.

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

cover_letter_prepareA

Start a tailored cover letter for a job (language 'en' or 'no'; default from coverletter/style.yaml): returns the prompt. Write only the letter body following it, then call cover_letter_submit.

NameRequiredDescriptionDefault
job_idYes
languageNo

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It does disclose the non-obvious return behavior (a prompt, not letter content) and the required follow-up call, plus that language defaults come from coverletter/style.yaml. It says nothing about permissions, error cases, idempotency, or job_id validity, so the behavioral picture is only partially covered.

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?

Dense and front-loaded: the action comes first, then the language/default caveat, then the workflow instruction. No filler sentences, though the telegraphic phrasing around 'returns the prompt' reads slightly clipped.

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 two-parameter prompt-generation tool with no output schema, the description supplies what an agent needs: the input semantics, the fact that output is a prompt to be obeyed, and the next call. Only failure/permission behavior is absent, which is a minor gap for this tool class.

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 0% and neither property has a description, but the description supplies the real semantics for 'language' ('en' or 'no', default sourced from coverletter/style.yaml) which the schema lacks entirely. 'job_id' is left at name-only inference, so compensation is partial rather than complete.

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+resource ('Start a tailored cover letter for a job') and clarifies the surprising mechanic that the tool returns a prompt rather than a letter. It also names the follow-up sibling (cover_letter_submit), so an agent can place it in the workflow, though it never explicitly contrasts itself with that sibling's own purpose.

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

Usage Guidelines4/5

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

Gives clear operational context: call this first, write only the letter body from the returned prompt, then call cover_letter_submit. There are no explicit when-not conditions or scope exclusions, but the sequencing guidance is unambiguous for this tool's role.

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

cover_letter_submitB

Check a cover letter body (facts traceable to the resume/ad, length, banned phrases, keywords, language, one page). If it passes and accept_if_ok, makes the PDF + plain text in the output folder.

NameRequiredDescriptionDefault
bodyYes
job_idYes
accept_if_okNo

TDQS

B3.4/5.0
Behavior3/5

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

With no annotations, the description carries the full burden, and it does disclose a real side effect (creates PDF + plain text in the output folder) plus the gate that triggers it (passing checks AND accept_if_ok). It does not say what happens on failure, whether existing output files are overwritten, or what permissions/paths are required, which are significant gaps for a write-capable tool.

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?

Two dense sentences, front-loaded with the validation purpose and with the consequential write behavior placed second where it matters. The parenthetical check list is long but each item earns its place by defining what 'passes' means.

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?

There is no output schema and no annotations, so the description should cover results too. It implies a pass/fail diagnostic but never says what the check returns on failure (error list? reasons?), nor what the output files are named or where exactly they land, leaving the agent unable to predict the response.

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 0%, so the description must compensate for all three parameters. It usefully clarifies accept_if_ok's role (write only happens when checks pass and this flag is set) and body is described in passing as the letter to check, but job_id is never explained and no formats or constraints are given for any parameter.

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 gives a specific verb+resource ('Check a cover letter body') and enumerates the checks performed, plus the secondary action (making the PDF and plain text files). It is clearly distinguishable from a generic submit tool, but it never names or contrasts with the sibling cover_letter_prepare, so sibling differentiation is left to inference.

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?

Usage is implied rather than stated: the tool is meant to run on a drafted body, and 'If it passes and accept_if_ok' explains the conditional write path. There is no explicit when-to-use/when-not or pointer to cover_letter_prepare for the drafting step, so the agent must infer the workflow position.

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

doctorC

Check the installation and settings; each problem has a fix hint.

NameRequiredDescriptionDefault
check_sitesNo

TDQS

C2.6/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. It discloses that problems include fix hints, but says nothing about whether the check is read-only, what permissions are needed, or how results are structured beyond the hint.

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 that avoids waste. It is efficient, though the second clause is somewhat vague and could be more specific about output.

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 tool with no annotations, no output schema, and an undocumented parameter, the description is too sparse. It omits when to use the tool, what the parameter does, and any behavioral details beyond the existence of fix hints.

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

Parameters1/5

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

Schema description coverage is 0% and the description does not mention the sole parameter 'check_sites' at all. With no explanation of what the boolean controls, the agent cannot infer its effect from the description.

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 ('Check') and resource ('installation and settings'), distinguishing it from the job/resume/config sibling tools. The added note that problems come with fix hints clarifies the diagnostic nature, though it does not explicitly differentiate from all siblings.

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?

Provides no guidance on when to use this tool versus alternatives. The mention of fix hints implies troubleshooting, but there is no explicit trigger condition, prerequisite, or alternative tool named.

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

find_jobsC

Search the job sites now (or check on a search already running).

NameRequiredDescriptionDefault
sourceNo
wait_secondsNo

TDQS

C2.9/5.0
Behavior2/5

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

With no annotations, the description carries the full behavioral burden, yet it only hints that a search may still be running. It never states whether the call blocks, what it returns (new results vs. status), whether it writes data to the site, or rate-limit/auth constraints.

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 tightly-worded sentence with the primary action front-loaded. It wastes no words but is under-specified rather than genuinely concise.

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?

A two-parameter search tool with no annotations, no output schema, and undocumented parameters needs more than one parenthetical sentence to be callable correctly.

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

Parameters2/5

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

Both parameters have 0% schema description coverage, so the description must compensate and does not: 'source' is never mentioned, and only the phrase 'check on a search already running' loosely gestures at the polling semantics of wait_seconds.

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 ('Search the job sites'), so an agent can tell it initiates a job search. It doesn't differentiate itself from siblings like list_jobs or job_details, which is where 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 Guidelines3/5

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

The parenthetical '(or check on a search already running)' implies two usage modes — trigger a new search or poll an in-flight one — but names no alternatives or selection criteria against siblings such as list_jobs or job_details.

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

import_resume_prepareA

Start a resume import from a Word (.docx) or PDF file (docx_path = path to either): returns the prompt to follow.

NameRequiredDescriptionDefault
docx_pathYes

TDQS

A3.6/5.0
Behavior3/5

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

With no annotations, the description carries the full behavioral burden. It usefully discloses that the call returns 'the prompt to follow' rather than completing an import, but says nothing about whether it writes files, what permissions are needed, or whether it is safe to re-run.

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 the action first and the input clarification parenthetical immediately after. No wasted words.

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 one-parameter tool with no output schema, the essentials are covered, but as the opening step of a prepare/submit pair the description omits the follow-up step and any indication of what the returned prompt expects. An agent can call it, but not confidently place it in the workflow.

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

Parameters4/5

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

Schema coverage is 0% and the parameter name 'docx_path' is misleading, so the description earns real credit by stating it is the path to either a .docx or PDF file. It still omits path format (absolute/relative) and validation behavior.

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 ('Start a resume import from a Word (.docx) or PDF file') and clarifies the accepted input formats. It does not explicitly name the sibling it hands off to (import_resume_submit_tex), so sibling differentiation is only implied by the prepare/submit naming.

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 word 'Start' implies this is the first step of a flow, but the description never says when to use it versus import_resume_submit_tex or build_resume, nor what happens next. Usage must be inferred from the two-step naming convention.

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

import_resume_submit_texC

Check a LaTeX version of the imported resume against the source Word or PDF file.

NameRequiredDescriptionDefault
texYes
accept_if_okNo

TDQS

C2.7/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, and it undersells the operation: 'Check' reads as a read-only comparison, yet the tool is named submit_tex and exposes an accept_if_ok flag that implies the check can commit or accept the imported resume. Nothing is said about side effects, what a mismatch does, or reversibility.

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 filler. It is appropriately short, though the brevity is achieved partly by omitting needed information rather than by tight writing.

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?

With no annotations, no output schema, 0% schema coverage, and an undocumented side-effecting flag, the description leaves an agent unable to call this correctly or predict its effects. It should at minimum explain what a successful check returns and what accept_if_ok does.

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

Parameters2/5

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

Schema description coverage is 0% for both parameters. The description loosely implies the 'tex' input is the LaTeX file under test, but it never explains the required tex string's format or the accept_if_ok flag at all, which is the one parameter with real behavioral consequence.

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 concrete action (check/compare) on a specific resource: the LaTeX version of an imported resume against the source Word/PDF. This places it in the import_resume_* workflow and separates it from siblings like build_resume or import_resume_prepare, though it never names a sibling explicitly and the name's 'submit' verb is not reconciled with the description's 'check'.

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 when-to-use guidance, no stated prerequisites (presumably a prior import_resume_prepare call), and no indication of what to do if the check fails. The agent must infer the whole position of this step in the workflow from the name alone.

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

job_detailsC

Everything about one job, including the description and keyword match.

NameRequiredDescriptionDefault
job_idYes

TDQS

C2.6/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 and does not meet it. It never states that this is a read-only operation, what happens with an invalid or unknown job_id, or whether any authentication/configuration is required. It partly discloses returned content ('description and keyword match') but nothing about side effects or failure modes.

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 compact sentence with no filler, and the scope ('one job') is front-loaded before the content hint. It is efficiently sized, though brevity here edges into under-specification rather than crispness.

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 one-parameter lookup with no annotations and no output schema, the description minimally suffices: it says what the tool returns in broad terms. But with no output schema to fall back on, it should have enumerated the returned fields more concretely and explained the input identifier, so gaps remain.

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

Parameters2/5

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

Schema description coverage is 0% and the single parameter (job_id, string) has no description. The tool description mentions 'one job' but never explains the identifier's format or where the agent should obtain it (presumably from find_jobs/list_jobs), so it does not compensate for the coverage gap.

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

Purpose3/5

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

The phrase 'Everything about one job' identifies the resource and its scope (a single job), implicitly distinguishing it from collection tools like find_jobs and list_jobs. However, it uses a vague catch-all ('everything') instead of a specific verb such as 'retrieve' or 'get', and it never names a sibling explicitly.

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 statement of when to call this tool versus find_jobs, list_jobs, or mark_job, and no prerequisites (e.g. that a job_id must first come from find_jobs). The only usage signal is implicit: the singular resource suggests lookup after a search, but nothing in the text says so.

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

list_jobsC

List saved jobs (best match first by default).

NameRequiredDescriptionDefault
sortNomatch
limitNo
searchNo
statusNo
min_matchNo
show_hiddenNo

TDQS

C2.6/5.0
Behavior2/5

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

With no annotations, the description carries the full behavioral burden, but it only discloses the default ordering ('best match first'). It says nothing about pagination, whether hidden jobs are excluded by default, required auth, or what fields come back — notable gaps for a 6-parameter read tool.

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

Conciseness3/5

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

A single front-loaded sentence with zero filler is structurally clean. However, the brevity comes at the cost of under-specification rather than efficiency, so it is only adequate.

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 6-parameter tool with no annotations and no output schema, the description gives an agent almost nothing beyond the ordering default. Missing are the meanings of the filter/sort parameters, pagination behavior, and the distinction from find_jobs.

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

Parameters2/5

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

Schema description coverage is 0% across 6 parameters, so the description must compensate and largely fails. 'Best match first by default' weakly hints at the sort parameter's default, but search, status, min_match, limit, and show_hidden are left entirely undefined in both the schema and the description.

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 ('saved jobs'), plus a scope hint that saved jobs are the domain. It does not differentiate from the sibling find_jobs, so an agent cannot tell from the description alone whether listing and finding are the same operation.

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 when-to-use guidance, no prerequisites, and no mention of alternatives such as find_jobs or job_details. The only implicit signal is the verb 'List' itself, which is the bare minimum.

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

mark_jobC

Set status: new, interested, applied, interview, rejected, offer, ignored.

NameRequiredDescriptionDefault
job_idYes
statusYes

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 of behavioral disclosure. 'Set status' implies a mutation, but it never states whether the change is idempotent, whether it can overwrite an existing status, what permissions are needed, or what happens on an invalid job_id — all material for a write tool.

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 terse line with no filler, and the enumerable values are placed immediately after the verb. It is efficient, though it borders on under-specification rather than deliberate brevity.

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 two-parameter mutation tool with no annotations, no output schema, and no schema descriptions, the definition leaves too much unspecified: the effect of the operation, idempotency, and failure behavior are all missing.

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 0%, so the description must compensate. It does add real value by enumerating the accepted status values, which the schema does not encode as an enum. However, job_id is left entirely unexplained, so coverage is only partial.

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 gives a specific verb (Set) and the resource being changed (a job's status), and the enumerated values make the intent unambiguous. It does not, however, distinguish itself from siblings like find_jobs or job_details beyond the implicit fact that it mutates rather than reads.

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 statement of when to use this tool versus the sibling tools, no preconditions, and no exclusions. The only guidance is the list of accepted status values, which is parameter information rather than usage routing.

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

open_dashboardA

Start the dashboard in the background (if needed) and open it in the browser. Returns its address.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.2/5.0
Behavior4/5

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

With no annotations, the description carries the full behavioral burden and does reasonably well: it discloses a background server start, a browser-launch side effect, conditional execution ('if needed'), and the return value. It omits failure modes (port conflicts, browser launch failure) and whether the server persists, which keeps it short of a 5.

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?

Two short sentences, action first, return value last. Every clause earns its place with no redundancy.

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 zero-parameter tool with no output schema, the description covers the trigger, the side effects, and the return format ('its address'), which is enough to call it correctly. Minor gaps around lifecycle and error behavior keep it just under complete.

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

Parameters4/5

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

The tool takes zero parameters and the schema is fully described, so there is no parameter nuance the description could add. Baseline 4 applies for a no-argument tool.

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?

States a specific verb and resource pair (start the dashboard, open it in the browser) plus the returned artifact ('its address'). No sibling tool overlaps with dashboard launching, so there is no ambiguity to resolve.

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 phrase '(if needed)' implies the call is safe to make when a dashboard may already be running, which is light usage context. There is no explicit when-to-use/when-not-to-use guidance, but with no sibling alternative for this capability there is little to disambiguate.

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

update_config_filtersB

Change the job filters in config.yaml (only the fields you pass). Old file kept as config.yaml.bak.

NameRequiredDescriptionDefault
job_typesNo
languagesNo
locationsNo
max_age_daysNo
title_excludeNo
title_includeNo
companies_excludeNo
companies_includeNo

TDQS

B3/5.0
Behavior3/5

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

With no annotations, the description carries the full burden. It usefully discloses two behaviors beyond the schema: partial-update semantics (only passed fields change) and that the prior file is preserved as config.yaml.bak. However, it omits permissions required, whether relative or absolute path resolution, and whether filters affect already-recorded jobs.

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?

Two short sentences, zero padding, and the core action and file target are front-loaded. Every clause carries information, including the backup behavior in the second sentence.

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 an 8-parameter mutation tool with no annotations, no output schema, and 0% schema description coverage, this is too thin. Key details an agent needs — value formats, matching semantics for include/exclude lists, units for max_age_days, and the effect of changes — are absent from both the description and the schema.

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

Parameters2/5

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

Schema description coverage is 0% across 8 parameters, so the description must compensate and does not: it never explains job_types, languages, locations, max_age_days, or the include/exclude list semantics. Nothing is added beyond the self-descriptive parameter names, and the numeric max_age_days unit and string-match rules are left undefined.

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 and resource: 'Change the job filters in config.yaml'. It is unambiguous about what is being modified, though it does not differentiate itself from siblings (which are mostly job/resume tools) or note relationships to diagnostic tools like doctor.

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 tool versus alternatives, no prerequisites, and no mention of when not to use it. The parenthetical '(only the fields you pass)' describes merge behavior rather than usage context, so an agent gets no routing help from this sentence.

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 updatesv0.1.5
    • Changedbuild_resume1 field changed
      • addedInput schema / properties / variant
        Added value: +{
        +  "anyOf": [
        +    {
        +      "type": "string"
        +    },
        +    {
        +      "type": "null"
        +    }
        +  ],
        +  "default": null,
        +  "title": "Variant"
        +}
    • Addedcover_letter_prepare
    • Addedcover_letter_submit
    • Addedopen_dashboard
  2. 9 tool updatesv0.1.2
    • First observedbuild_resume
    • First observeddoctor
    • First observedfind_jobs
    • First observedimport_resume_prepare
    • First observedimport_resume_submit_tex
    • First observedjob_details
    • First observedlist_jobs
    • First observedmark_job
    • First observedupdate_config_filters

TDQS

B3.4/5.0

Scored across 12 tools

Disambiguation5/5

Each tool has a clearly distinct purpose: the two-phase workflows (cover_letter_prepare/submit, import_resume_prepare/submit_tex) are explicitly named as pairs, and search/list/detail/status tools target separate concerns. Even closely related tools like import_resume_submit_tex vs build_resume are differentiated by their descriptions (import validation vs tailored PDF generation).

Naming Consistency4/5

All names are consistently snake_case, which makes the set readable and predictable. However, verb position varies (verb_noun like list_jobs/build_resume vs noun_verb like cover_letter_prepare/import_resume_submit_tex), and singleton names like 'doctor' and 'job_details' don't follow the verb_noun pattern.

Tool Count5/5

Twelve tools is well-scoped for a job-application assistant covering search, tracking, cover letters, resume import/build, config, and diagnostics. Each tool earns its place with no redundant or filler entries.

Completeness4/5

The surface covers the full workflow: find/detail/list jobs, mark status, tune filters, prepare/submit cover letters, import and build resumes, plus dashboard and diagnostics. Minor gaps exist (no delete/remove job, no explicit export or application-submission tool), but agents can work around these.

Maintenance

ActivityNo data
ResponsivenessOutdated data

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Enables Claude to parse CVs, search job boards (Remotive, Arbeitnow, Adzuna, Greenhouse/Lever), tailor resumes and cover letters, and prepare application packages with direct apply links—without ever auto-submitting. It runs 100% locally and free, storing jobs and applications as JSON files.
    -
  • F
    license
    Not graded
    quality
    C
    maintenance
    Enables Claude Desktop to manage a job search end-to-end: find and score job listings, tailor resumes, generate application messages, and track application history, while leaving final external actions to the user.
    -
  • F
    license
    Not graded
    quality
    B
    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
    -
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables Claude to read and update the local job-search tracker, adding postings from screenshots, pasted text or links, drafting application emails, syncing Gmail to log sent applications and replies, and answering questions about what's due or which jobs match a criteria. Every change is validated and appears live on the dashboard with a timeline entry.
    MIT