ats-scanner-mcp
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., "@ats-scanner-mcpRun an ATS scan of my resume against this job posting and suggest edits."
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.
ats-scanner-mcp
A Jobscan-style ATS resume scanner packaged as an MCP server, so Claude Desktop can scan your resume against a job posting, show the match rate and missing keywords, and then propose edits — no subscription, no API key, nothing leaves your machine.
Claude Desktop is the "brain": the server does the deterministic parts an ATS does (keyword extraction, matching, searchability checks, scoring) and hands Claude structured results plus the raw text so it can reason about semantic gaps and rewrite bullets.
What it checks
Area | What the scanner does |
Hard skills | Matches ~250 dictionary skills (languages, frameworks, cloud, data, DevOps, AI/LLM, security, practices, tools) with alias handling ( |
Soft skills | Same, for communication / collaboration / leadership / ownership etc. |
Job title | Exact title in the resume, core title ( |
Education | Degree / certification requirements vs what the resume shows; softened when the posting says "or equivalent experience". |
Experience | Minimum years in the posting vs the date range in your Experience section. |
Searchability | Email, phone, LinkedIn, location, standard section headings, dates, measurable results, weak bullet openers, overlong bullets, length, file name, PDF parsing red flags (unreadable glyphs, multi-column layouts). |
Discovered phrases | Recurring phrases in the posting that aren't in the dictionary — Claude judges relevance. |
Match rate = hard skills 45% · searchability 20% · title 10% · soft skills 10% · education 10% · experience 5%.
Related MCP server: resume-tailor-mcp-server
Install
git clone https://github.com/<you>/ats-scanner-mcp.git
cd ats-scanner-mcp
npm install
npm run buildRequires Node 18+.
Claude Desktop configuration
Add to claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"ats-scanner": {
"command": "node",
"args": ["/absolute/path/to/ats-scanner-mcp/dist/index.js"],
"env": {
"ATS_RESUME_DIR": "/home/you/Documents/Resumes"
}
}
}
}Restart Claude Desktop. ATS_RESUME_DIR is optional (defaults to ~/Documents/Resumes); it lets you refer to resumes by bare file name.
Optional: ATS_EXTRA_SKILLS=/path/to/skills.json adds your own dictionary entries:
[
{ "name": "Amplify Gen 2", "aliases": ["amplify gen2"], "category": "cloud" },
{ "name": "Proxyware Detection", "category": "security" }
]Using it in Claude Desktop
Paste a posting and ask:
Run an ATS scan of
EQ_Maitland-Soto_Resume_2026.pdfagainst this posting and suggest edits: …
Or use the built-in tailor_resume prompt (the "+" / prompts menu in Claude Desktop), which walks Claude through: scan → report gaps → propose honest before/after edits → re-scan the edited draft with resume_text and report the new score.
Tools
Tool | Purpose |
| Full scan. |
| Title, company, hard/soft skills with importance + counts, education, years, discovered phrases. |
| What an ATS sees: sections, contact info, dates, bullet stats, warnings, extracted text. |
| Files in your resume folder. |
| Rank several resume variants against one posting. |
Resumes: PDF, Markdown, or plain text. (DOCX: export to PDF first.)
CLI (no Claude needed)
npm run cli -- ~/Documents/Resumes/my-resume.pdf posting.txt # markdown report
npm run cli -- ~/Documents/Resumes/my-resume.pdf posting.txt --json # structuredTry it with the bundled sample: npm run cli -- examples/Alex-Sample-Resume.pdf examples/sample-posting.txt
Development
npm test # vitest
npm run dev # tsc --watchLayout: src/skills.ts (dictionary) · src/text.ts (matching) · src/extract.ts (posting → profile) · src/resume.ts (resume parsing) · src/score.ts (scoring + checks) · src/report.ts (markdown) · src/index.ts (MCP server) · src/cli.ts.
Honest-use note
The scanner tells you which words are missing; it does not know whether you have the skill. The tailor_resume prompt instructs Claude to only add skills you can evidence and to say plainly when you don't have something. Keyword stuffing gets past filters and then fails in interviews.
License
MIT
Available Tools
5 toolscompare_resumesCompare several resumes against one postingARead-only
Scores multiple resume files against the same job posting and ranks them — useful for picking which variant of a master resume to tailor.
| Name | Required | Description | Default |
|---|---|---|---|
| job_text | Yes | ||
| job_title | No | ||
| resume_paths | Yes | Resume file paths (or bare file names inside the resume folder). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate readOnlyHint=true, so the tool is understood to be non-mutating. The description adds behavioral context by stating it scores and ranks resumes, which clarifies expected output behavior beyond the annotations.
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, well-structured sentence that immediately states the action and purpose. No filler or repetition of schema details.
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?
The description conveys the core behavior: multiple resumes are evaluated against one posting and ranked. Without an output schema, it could be clearer about the exact form of the ranking result, but the description is sufficient for basic invocation.
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 low at 33%, so the description must compensate. It does clarify that resume_paths are resume files and job_text is the posting text, but it does not explain the optional job_title parameter or provide additional detail about expected formats.
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 uses a specific verb ('scores', 'ranks') and a clear resource ('multiple resume files against the same job posting'). This clearly distinguishes it from siblings like parse_resume, scan_resume, and extract_job_keywords, which serve different purposes.
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 description provides a clear use case: 'useful for picking which variant of a master resume to tailor.' It implies when to use the tool but does not explicitly mention alternatives or state when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
extract_job_keywordsExtract keywords from a job postingARead-only
Pulls the ATS-relevant signals out of a job posting: title, company, hard skills and soft skills (with required/preferred importance and mention counts), education/certification requirements, minimum years of experience, and recurring phrases not in the skills dictionary.
| Name | Required | Description | Default |
|---|---|---|---|
| job_text | Yes | Full text of the job posting. | |
| job_title | No | Override the detected title. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, and the description adds useful behavioral detail about what is extracted, including required/preferred importance, mention counts, and handling of phrases not in the skills dictionary. It does not contradict the annotations and provides a clear model of the tool's output behavior.
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?
The description is a single sentence that front-loads the core action and then lists the extracted signals compactly. It is somewhat detailed but every listed element contributes to understanding the output, so it justifies its length.
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?
With no output schema, the description takes on the responsibility of explaining the return content, and it does so by naming the main output dimensions. It could mention the return format or behavior on invalid input, but the core information needed to call the tool is present.
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 both parameters are documented with clear descriptions. The tool description adds no parameter-specific semantics beyond the schema, so the baseline of 3 is appropriate.
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 states a specific verb ('Pulls') and a specific resource ('a job posting'), then enumerates the exact categories of output. It is clearly distinct from the resume-oriented sibling tools.
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 description makes the input source explicit and the use case fairly clear, but it does not name any alternatives or state when to choose this tool instead of scan_resume or parse_resume. The usage context is implied rather than explicitly defined.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_resumesList resume filesARead-only
Lists resume files (.pdf, .md, .txt) in the resume folder (default /root/Documents/Resumes; set ATS_RESUME_DIR to change) or a folder you pass.
| Name | Required | Description | Default |
|---|---|---|---|
| dir | No | Folder to list. Defaults to the configured resume folder. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already mark this as read-only, and the description adds useful behavior beyond that: supported file extensions, the default folder path, the ATS_RESUME_DIR override, and the ability to pass a custom directory. It does not disclose sorting or recursion behavior, but it covers the key operational details for a simple listing tool.
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?
The entire description is one efficient sentence that front-loads the core action and then packs the file types, default location, environment override, and optional parameter into a compact, scannable form. Every part earns its place.
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 read-only file-listing tool with one optional parameter and annotations covering the safety profile, the description is nearly complete. It could mention whether the result is a flat list or includes full paths, but the missing output details are minor for this tool's purpose.
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?
The schema documents the 'dir' parameter clearly, but the description adds extra meaning by specifying the default location and the environment variable that changes it. This goes beyond the schema's generic 'configured resume folder' wording.
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 clearly states the tool's action ('Lists resume files'), the resource (resume files), and the allowed file types (.pdf, .md, .txt). This immediately differentiates it from the sibling tools that scan, extract, parse, or compare resumes.
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 description makes it clear the tool is for enumeration in a resume folder, and the optional directory parameter gives usage context. However, it does not explicitly mention when to prefer this over the processing-focused sibling tools or what should trigger using an alternative.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
parse_resumeParse resume the way an ATS wouldARead-only
Shows what an ATS extracts from the resume: detected sections and headings, contact info, date range and estimated years of experience, bullet stats (metrics, weak verbs, overly long bullets), formatting/parsing warnings, and the raw extracted text.
| Name | Required | Description | Default |
|---|---|---|---|
| resume_path | No | Path to the resume (.pdf, .md, .txt). Absolute, ~-relative, or a bare file name inside the resume folder (/root/Documents/Resumes). | |
| resume_text | No | Raw resume text — use this to re-score an edited draft without saving a file. | |
| include_text | No | Include the full extracted text (needed for Claude to rewrite bullets). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so no destructive behavior needs disclosure. The description adds valuable behavioral context by enumerating exactly what the parse reveals: sections, contact info, date ranges, bullet stats, warnings, and raw text. This goes beyond the sparse annotation set and sets proper expectations for the output.
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?
The description is a single sentence that front-loads the core purpose and then efficiently lists the meaningful output categories. There is no filler, repetition of the title, or irrelevant detail. Every segment contributes to understanding what the tool returns.
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?
Since there is no output schema, the description correctly takes on the burden of describing return content, and it covers the major categories. It also gives usage context for the include_text parameter via the schema. However, it does not clarify precedence or interaction between resume_path and resume_text when both are provided, which would be useful for an agent deciding how to invoke the tool correctly.
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 all three parameters have meaningful descriptions in the schema itself. The tool description does not add parameter-level details, but it doesn't need to because the schema already documents resume_path, resume_text, and include_text adequately. Baseline 3 is appropriate.
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 uses a specific verb ('Shows what an ATS extracts') and clearly identifies the resource (a resume). It names several concrete outputs, which makes the tool's function unambiguous. However, it does not explicitly distinguish itself from the similar-sounding sibling 'scan_resume'.
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 description implies the tool is for getting an ATS-style parse and extraction of resume details, but it never states when to choose this over scan_resume or compare_resumes. No alternatives or exclusions are mentioned, so usage guidance remains implicit rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scan_resumeATS scan resume against job postingARead-only
Jobscan-style ATS scan. Scores a resume against a job posting (0-100 match rate), lists matched and MISSING hard/soft skills with importance (required vs preferred) and counts, checks title/education/years-of-experience fit, runs searchability & formatting checks, and returns concrete suggestions. Use resume_text to re-score a draft after edits.
| Name | Required | Description | Default |
|---|---|---|---|
| format | No | markdown = readable report; json = structured data; both. | markdown |
| job_text | Yes | Full text of the job posting (paste everything: title, responsibilities, requirements, nice-to-haves). | |
| job_title | No | Override the detected job title if the posting's first line isn't the title. | |
| resume_path | No | Path to the resume (.pdf, .md, .txt). Absolute, ~-relative, or a bare file name inside the resume folder (/root/Documents/Resumes). | |
| resume_text | No | Raw resume text — use this to re-score an edited draft without saving a file. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnlyHint annotation, the description reveals substantial behavioral detail: it computes a 0-100 score, flags matched and missing skills with importance levels, checks title/education/years-of-experience fit, runs searchability/formatting checks, and returns suggestions. This gives an agent a solid model of what will happen when invoked.
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?
The description is two sentences with no filler. The first packs in the action, scope, and deliverable list; the second adds a direct usage tip. Every phrase contributes value, and the most important information is front-loaded.
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?
Given the tool's complexity, the description covers the full scope of behavior without requiring an output schema: scoring, skill matching, fit checks, formatting/searchability checks, and suggestions. Combined with complete schema descriptions and the readOnlyHint annotation, an agent has enough context to select and invoke the tool correctly.
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?
Input schema coverage is 100%, so the schema already documents all five parameters thoroughly, making 3 the baseline. The description adds one meaningful workflow hint about using resume_text for re-scoring, but most parameter meaning is adequately carried by the schema itself.
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 opens with a specific verb+resource ('Scores a resume against a job posting') and immediately identifies the tool as a 'Jobscan-style ATS scan', clearly differentiating it from siblings like parse_resume, list_resumes, and compare_resumes. The listed concrete outputs (match rate, missing skills, fit checks, suggestions) leave no ambiguity about what the tool does.
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 description clearly establishes the core use case: scan a resume against a specific job posting. It also gives a concrete workflow pointer ('Use resume_text to re-score a draft after edits'), showing when the resume_text parameter is appropriate. It does not explicitly name alternative tools or exclusion conditions, so it stops short of a 5.
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.
5 tool updates
v1.0.0- First observed
compare_resumes - First observed
extract_job_keywords - First observed
list_resumes - First observed
parse_resume - First observed
scan_resume
TDQS
Scored across 5 tools
Each tool has a clearly distinct responsibility: scanning a resume, extracting job keywords, parsing a resume, listing resume files, and comparing multiple resumes. Even though scan_resume and compare_resumes both score resumes, one targets a single resume while the other ranks multiple files, so there is no real ambiguity.
All tool names follow a consistent lowercase snake_case verb_noun pattern: scan_resume, extract_job_keywords, parse_resume, list_resumes, compare_resumes. The verbs are distinct and descriptive, making the tool set easy to predict and navigate.
Five tools is a well-scoped size for an ATS scanning server. The set covers the core workflow without unnecessary duplication or bloat, and every tool clearly earns its place.
The tool surface covers the full resume-scanning workflow: list available resumes, parse and inspect a resume, extract job posting requirements, scan a resume against a posting, and compare multiple resume variants. There are no obvious dead ends or missing operations for the server's stated purpose.
Maintenance
Related MCP Connectors
AI resume triage for recruiters. Query your candidate pool from Claude or ChatGPT.
A job-search companion: tailor your CV to a role, score fit, fix ATS issues. Also via MCP.
Lint, match, and tailor resumes against real job postings, and save them to your Zelume account.
Free ATS resume score and job-match checker: scores a resume against a job description.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Claude to intelligently query and analyze your resume using RAG technology. Supports skill matching against job requirements and answering questions about your professional background from locally stored resume files.MIT
- FlicenseNot gradedqualityCmaintenanceHelps job seekers tailor their resume and generate cover letters against a specific job posting, powered by Claude.-
- AlicenseNot gradedqualityCmaintenanceEnables Claude Desktop to act as an ATS resume checker: lists resume files and evaluates them against job descriptions, providing formatting audits and keyword match scores.MIT
- AlicenseNot gradedqualityCmaintenanceEnables searching and evaluating job postings from LinkedIn and freehire.me directly through Claude Desktop. Provides tools to search jobs, fetch full posting details, and assess candidate fit using eligibility scans and a scoring rubric.MIT