Skip to main content
Glama
dcassil

resume-kit MCP Server

by dcassil

Resume Intelligence Toolkit (resume-kit)

A reusable, trustworthy system for evaluating, comparing, aligning, generating, and validating resume materials against specific jobs. It answers five core questions:

  • Can an ATS reliably parse this resume?

  • How closely does this resume match a specific job?

  • Which relevant qualifications are missing or poorly represented?

  • What truthful changes would improve alignment?

  • Did the revised resume actually improve?

Resume-kit is a shared core engine exposed through an agent plugin, an MCP server, a CLI (resume-tool), and a REST API. All interfaces are thin adapters over the same core — no business rule lives only in a route, command, handler, or skill.

Installation

resume-kit ships as a single self-contained wheel that vendors every internal import package. Choose extras for the surface(s) you want:

pip install resume-kit          # core engine + export (base)
pip install "resume-kit[cli]"   # + the resume-tool CLI
pip install "resume-kit[mcp]"   # + the MCP server
pip install "resume-kit[api]"   # + the FastAPI/uvicorn REST API
pip install "resume-kit[all]"   # everything

The base install carries the engine and export third-party runtime dependencies (pydantic, markitdown, pdfminer.six, python-docx, reportlab). Extras add typer (cli), mcp (mcp), and fastapi + uvicorn (api).

The resume-tool command

Installing the cli extra exposes the console script:

pip install "resume-kit[cli]"
resume-tool --help

Deterministic ingest pipeline

Turning a resume/job file into structured JSON is split into deterministic rails around one confined interpretation step, so only the text→schema mapping needs an agent — extraction and validation are mechanical:

resume-tool init                                   # scaffold resume-kit/ + config.json (idempotent)
resume-tool extract-text resume.docx               # deterministic text (docx/pdf/md/txt), no LLM, no network
#  → agent maps the extracted text onto the ResumeDocument schema (the one agentic step)
resume-tool validate-faithfulness \                # HARD GATE: exits non-zero on drift
  --source resume.docx --json resume-kit/resumes/resume-original.json
resume-tool set-active \                            # record active pointer + originating source path
  --resume resumes/resume-original.json --source resume.docx

Text extraction (markitdown, pdfminer.six, python-docx) is bundled in the base install — docx/pdf/md/txt all extract deterministically with no optional extra. validate-faithfulness is a machine gate: it diffs the produced JSON against the source (bullet/section parity, dropped/added tokens, altered high-signal fields, non-ASCII scan) and exits non-zero when the conversion is not faithful, so an unfaithful conversion never silently reaches disk. The resume-kit/ working directory and its config.json (active resume/job pointers, their source paths, and alias_file) are owned by code via init / set-active — not hand-authored.

BuildDoc vs. ScoreDoc — the scoring projection

The resume the pipeline edits and exports (ResumeDocument, the BuildDoc) is kept distinct from the representation that scoring reads. Before any scoring or matching runs, a deterministic, offline project_scoredoc projects the BuildDoc into a ScoreDoc: a zoned keyword index, segmented sections tagged by zone (skills list, experience, summary, …), and extracted entities plus years of experience. All scoring and matching read the ScoreDoc — not the raw resume JSON.

This is why a skill listed in a categorized custom section (e.g. a stringList "Cloud Skills" section) now counts as a canonical skill rather than incidental body text: the projection maps it into the skills zone, so it earns the same keyword-placement credit as additional.technicalSkills. The ScoreDoc is also what powers the ats-view "what the ATS sees" report — the read-only view of the sections, entities/YoE, and zoned keywords an ATS is likely to parse (resume-tool ats-view --resume <path>), identical across the CLI, MCP, API, and facade surfaces.

Resume baselining and final fit (original → base → structure → refine → tailored → final)

Before any job-specific tailoring, a resume moves through a fixed, deterministic baselining lineage that produces four tracked versions:

resume-tool build-base                              # original → base (auto): strips PII, normalizes
                                                    #   presentation, behind the claim-preservation gate
resume-tool analyze-shape \                         # base → structure report: redundant/non-standard
  --resume resumes/resume-base.json                 #   sections, mappings, and informational budgets
resume-tool build-structure                         # base → structure: canonicalizes shape losslessly
                                                    #   behind ledger + claims-preserved gates
resume-tool analyze-best-practices \                # job-independent best-practices report; each finding
  --resume resumes/resume-structure.json            #   is auto_suggestible or needs_user_input
resume-tool build-refine --answers answers.json     # structure → refine: applies auto-suggestible rewrites
                                                    #   + user-supplied facts, behind the same gate
  • original — the faithful, code-owned ingest of the source file (produced by the pipeline above; never edited in place).

  • baseoriginal with only auto-safe structural fixes applied (PII removed, formatting/date presentation normalized). build-base runs the structural check and writes <name>-base.json only if the claim-preservation gate holds — no employer/title/degree/skill claim may be added, dropped, or altered. Findings that need judgment are deferred to the walkthrough.

  • structurebase projected into the canonical resume schema: redundant skill/custom sections are merged and deduped, section order is normalized, and custom sections with no canonical home are seeded into evidence and omitted from canonical output. build-structure writes <name>-structure.json only when the content ledger is fully accounted and whole-resume claims are preserved.

  • refinestructure after the generic best-practices walkthrough: every finding is classified auto_suggestible (a truthful rewrite is applied now) or needs_user_input (the user supplies real facts, e.g. a metric). Applied behind the same claim-preservation gate. If no structure exists yet, build-refine falls back to base, then original. It writes <name>-refine.json; the CLI/capability/API surface is build-refine, and the MCP tool is resume_build_refine.

Migration: the former standard pass is now refine. Legacy standard_resume pointers still resolve as a read-alias for existing projects, and build-standard surfaces remain as one-release deprecation aliases for build-refine.

All job-specific tailoring runs off refine, not original. The active resume resolves as refine ?? standard(legacy) ?? structure ?? base ?? original, so once baselining has run, downstream tailoring and edit sessions operate on the best-practices-improved refine version by default. The lineage is fully deterministic and offline: no LLM or network is touched on the baselining path.

After the job-specific improve/tailor loop produces a tailored resume, run the perfect fit pass before export:

resume-tool fit --root . --job jobs/job.json              # inspect ranked budget-fit decisions
resume-tool fit --root . --job jobs/job.json --auto-fit   # commit logged auto-fit decisions

perfect is job-specific and non-destructive of the master lineage: it reads the resolved tailored input, writes <name>-<job>-final.json, and records every removal as either a ranked decision or a logged auto-fit change in the content ledger. The MCP surface is resume_build_perfect with the same root, job, decisions, and auto_fit inputs. Export remains the rendered page hard gate: the exporter enforces shape_policy.informational_budgets.max_pages, blocking over-length output unless the caller uses the explicit page-budget override.

Project aliases and accepted terminology edits

The deterministic matcher loads the packaged seed alias lexicon plus an optional project alias file from resume-kit/config.json's alias_file pointer. Manual synonym growth still goes through the truth-gated manage-synonyms workflow. In addition, resume-tool review-edits commit self-heals that project file for accepted terminology edits: when a user accepts or edits a terminology proposal that mirrors the employer's wording, the commit records the resume term as an alias of the accepted employer term with source: "accepted_edit" provenance and the caller-supplied timestamp. Rejected, skipped, auto-mode, non-terminology, and malformed edits never grow aliases.

Improve-phase edit sessions

Targeted resume improvements are written through the code-owned edit-session orchestrator, not direct JSON edits. The flow is: build truthful ChangeProposal records, prompt the user for a mode (interactive, review_at_end, or auto), run resume-tool review-edits open, then loop through resume-tool review-edits prompt and resume-tool review-edits decide. Rejections and user-modified edits carry a structured EditFeedbackReasonCode plus an optional note. Finally resume-tool review-edits commit applies the hard gate and writes the tailored resume to the reported working_path; resume-tool validate-truth remains the final truth check. Intentional out-of-band edits must be accepted with resume-tool review-edits reconcile before the session continues.

The loop records outcomes as EditFeedback via resume-tool record-edit-feedback and can rebuild the deterministic preference profile with resume-tool refresh-preferences --now <iso>. Confirmed user evidence is added with resume-tool add-evidence --confirmed --content ...; validate-truth classifies those near-match claims as USER_CONFIRMED, while actively refuted claims remain CONTRADICTED. UNSUPPORTED means missing evidence, not an active refutation; each claim carries a machine-readable reason_code such as missing_evidence, strong_evidence_overlap, or refuted_by_evidence.

The full job-specific path is original → base → structure → refine → tailored → final: refine performs the job-independent wording pass, tailor proposes and commits truthful job-alignment edits, and the final fit only fits that tailored content to the configured shape and page budgets.

Composable agent flows

The resume-intelligence plugin exposes the same path as four composable flow skills, plus one complete guide:

  • complete-resume-flow - the start-here guide for the end-to-end order.

  • prepare-base-resume (Flow 1) - run once per source resume to build the reusable original -> base -> structure -> refine lineage and seed durable full-resume evidence.

  • ingest-job (Flow 2) - run once per job to parse/activate the job and grow the project alias file before scoring.

  • tailor-resume (Flow 3) - run per job to score, apply truthful edit-session changes, validate facts, and re-score.

  • finalize-resume (Flow 4) - run per tailored job resume to fit and export under the rendered page gate.

Repeated-use path: run Flow 1 once per resume, then run Flows 2, 3, and 4 many times for different jobs. The older resume-workflow skill remains as a thin compatibility pointer to complete-resume-flow and the four flow skills.

Related MCP server: Resume MCP Server

Release Notes

Unreleased - composable complete flow (RIT-T-0174)

  • Adds complete-resume-flow as the canonical composite guide for the four reusable flow skills.

  • Retains resume-workflow as a compatibility pointer, so per-stage gates live only in prepare-base-resume, ingest-job, tailor-resume, and finalize-resume.

  • Documents the repeated-use model: Flow 1 once per resume; Flows 2/3/4 many times per job.

Unreleased — perfect fit stage (RIT-T-0153)

  • Documents the job-specific perfect stage after tailoring: resume-tool fit / resume_build_perfect writes <name>-<job>-final.json without mutating the original / base / structure / refine lineage.

  • Clarifies that export enforces the rendered max_pages page hard gate after the fit pass.

Unreleased — canonical structure stage (RIT-I-0019)

  • Inserts the lossless structure stage into resume baselining, making the tracked lineage original → base → structure → refine.

  • Adds shape analysis and build-structure: redundant skill/custom sections are merged into canonical skills, unsupported custom sections are seeded into evidence and omitted from canonical output, ambiguous mappings are deferred, and writes are gated by content-ledger accounting plus whole-resume claim preservation.

  • Keeps the wording pass behavior unchanged: build-refine now reads structure ?? base ?? original, projects canonical structure back to the BuildDoc read model, and writes refine.

Package 0.9.0 / plugin 1.2.0 — test-run tightening (RIT-T-0126–0130)

  • Keyword hygiene gate (schemas.keyword_hygiene): full requirement sentences are no longer scored as keywords. Applied at the matching scoring boundary and at job parse time, so match / check-keywords / check-gaps stop counting unmatchable prose in the denominator (fixes artificially depressed match scores and cluttered missing/non-injectable lists).

  • check-gaps degeneracy warning: when the tailored and master resumes resolve to near-identical content, the report now warns that the injectable split is unreliable instead of presenting every miss as an unfixable gap.

  • set-active path normalization: a leading resume-kit/ on a user-supplied pointer is stripped, so cwd-relative and working-dir-relative paths resolve identically and build-base no longer fails on a doubled path.

  • check-best-practices quantification: MISSING_QUANTIFICATION emits one finding per unquantified bullet across the whole resume, prioritized where a metric adds most (impact-verb bullets first), with no aggregate MISSING_QUANTIFICATION_MORE cap.

  • job-hunter bridge: reconciled three stale capability dispatch names left by the RIT-A-0005 rename.

Package 0.8.0 / plugin 1.0.0 — ScoreDoc scoring projection + ATS-view report (RIT-I-0017)

  • Separates the scoring representation (ScoreDoc) from the build representation (ResumeDocument) via the deterministic, offline project_scoredoc. All scoring and matching now read the zoned ScoreDoc (keyword index + segmented sections + extracted entities/YoE) rather than the raw resume JSON.

  • Fixes the categorized-skills regression: skills in a stringList custom section are projected into the skills zone, so they earn the same keyword-placement credit as additional.technicalSkills (no placement penalty for categorizing skills).

  • Adds the read-only ats-view "what the ATS sees" report, rendered off the ScoreDoc and identical across the CLI, MCP, API, and facade surfaces.

Package 0.7.0 / plugin 1.0.0 — initial resume baselining (RIT-I-0016)

  • Adds the initial original → base → refine baselining lineage as the mandatory pre-tailoring phase: build-base (auto structural fixes behind the claim-preservation gate), analyze-best-practices (job-independent report classifying each finding auto_suggestible vs needs_user_input), and build-refine (best-practices walkthrough behind the same gate; legacy build-standard remains a deprecation alias). This was later extended by the structure stage.

  • Makes refine the default tailoring input — active resolution is refine ?? standard(legacy) ?? base ?? original in the initial lineage, so tailoring and edit sessions operate on the best-practices-improved version rather than the raw ingest.

  • The entire baselining path is deterministic and offline (no LLM, no network), proven end-to-end by the lineage integration test.

Package 0.6.0 / plugin 0.7.0 — enforced edit loop (RIT-I-0015)

  • Enforces the human-in-the-loop edit-session write gate across CLI, MCP, API, and facade surfaces; bulk unlogged writes and truth-failing accepted changes fail with machine-readable errors.

  • Fixes truth semantics so CONTRADICTED is reserved for structural conflicts or active refutations, UNSUPPORTED means missing evidence, and every provenance claim includes a stable reason_code.

  • Extends learning with edit feedback, preference refresh, user-confirmed evidence, specific-over-vague preference derivation, and project alias growth from accepted terminology edits.

Building & publishing

Build the umbrella wheel and sdist locally with uv:

uv build            # produces dist/resume_kit-*.whl and dist/resume_kit-*.tar.gz

The wheel vendors all import packages (schemas, core, document-parser, job-parser, ats, matching, policy, evidence, alignment, export, facade, cli, mcp, api, and the job-hunter bridge) via Hatch force-include, so the shipped metadata declares only third-party dependencies — no internal resume-kit-* requirements. The per-package pyproject.toml files remain only for local uv workspace development.

Publishing to PyPI uses Trusted Publishing (OIDC, no long-lived API tokens). The GitHub Actions workflow in .github/workflows/publish.yml builds and publishes on a v* version tag; it is not triggered by ordinary pushes. To cut a release, push a tag:

git tag v0.1.0
git push origin v0.1.0

As a manual fallback (also Trusted-Publishing-friendly), you can upload from a local build with twine:

uv build
python -m twine upload dist/*

resume-kit is published on PyPI at https://pypi.org/project/resume-kit/. Releases are cut by pushing a vX.Y.Z tag (Trusted Publishing via GitHub Actions); the twine commands above are the manual fallback.

Status

Early development. Built by selectively porting proven behavior from Resume-Matcher (Apache 2.0) into a clean, modular architecture. Resume-Matcher is a donor codebase and upstream reference, not the product architecture. See references/ for the upstream audit, reuse inventory, and attribution.

Language & distribution

Implemented in Python (the donor codebase and all extractable subsystems are Python: Pydantic models, MarkItDown extraction, LiteLLM providers). Distribution targets PyPI, not npm — see ADR-0001.

Principles

  • Deterministic parsing, checks, diffs, and scoring before any LLM reasoning; LLM usage is optional, explicit, and replaceable by local/no-LLM modes.

  • Never fabricate employers, titles, dates, accomplishments, metrics, certifications, or experience. The user is the final authority over truth.

  • Original resumes are preserved by default; every change ships with a structured diff, claim provenance, and a truth-validation report.

Repository layout

packages/      core, schemas, document-parser, job-parser, matching, alignment,
               evidence, policy, ats, llm, export, cli, mcp, api
plugins/       resume-intelligence agent plugin
integrations/  job-hunter bridge
references/    upstream-audit.md, reuse-inventory.md, attribution.md, ADRs
tests/         fixtures, characterization, unit, integration, evals

License

Apache 2.0. See LICENSE and NOTICE.

A
license - permissive license
Not graded
quality - not tested
B
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

View all related MCP servers

Related MCP Connectors

  • GetJobzi MCP server for job search, application tracking, and career forecasting.

  • MCP server providing access to the Scorecard API to evaluate and optimize LLM systems.

  • Hosted MCP for denial, prior auth, reimbursement, workflow validation, batch scoring, and feedback.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/dcassil/resume-kit'

If you have feedback or need assistance with the MCP directory API, please join our Discord server