# honest-cv (pypi · honest-cv)

Honest, ATS-safe CVs and cover letters from a skill inventory you confirm yourself.

- Trust score: 70/100 (medium)
- Change this week: +4
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-10-22

## Components

- pypi · `honest-cv`: 70/100 (this document), [markdown](https://verifymcp.io/servers/jesuscabrerareveles-honest-cv/honest-cv.md), [page](https://verifymcp.io/servers/jesuscabrerareveles-honest-cv/honest-cv)

## Channel facts

- Registry: `pypi`
- Package: `honest-cv`
- Version: `0.3.3`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-10-22.

- **Supply Chain Security**: 50/100
  - Malware scan not yet available for this package.
  - No known CVEs affecting this package version or its production dependencies.
  - Runs hatchling.build at install time, a recognised build step with no custom scripting around it.
  - 1 of 38 dependencies flagged as unhealthy.
- **Provenance & Transparency**: 97/100
  - Source repository is publicly reachable at the declared URL.
  - Cryptographically verified build provenance (signed, bound to JesusCabreraReveles/honest-cv).
  - Clear OSI-approved license (MIT).
  - Actively maintained (last published 0 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 78/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 6831 tokens (~220/item across 31 items; 31 tools + 0 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 23/100
  - Stability observed for 7 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
- **Tool Safety**: 100/100
  - No prompt-injection markers were found in the server instructions, tool names or descriptions we captured.
  - All 4 tool(s) whose name or description implies an irreversible operation declare an MCP destructiveHint annotation.
  - An AI judge read all 32 captured unit(s) of tool text and found none that tries to manipulate the model reading it.
- **Capabilities**: 100/100
  - Implements a current MCP spec version (2026-07-28).

## Install

### How do I install the honest-cv MCP server?

honest-cv runs locally as a PyPI package, launched with uvx honest-cv. Ready-made configuration for Claude, Cursor, VS Code, Codex and 5 more is on this page, copied from each client's own documentation.

### Claude

```bash
claude mcp add jesuscabrerareveles-honest-cv -- uvx honest-cv
```

### Cursor

```json
{
  "mcpServers": {
    "jesuscabrerareveles-honest-cv": {
      "command": "uvx",
      "args": [
        "honest-cv"
      ]
    }
  }
}
```

### VS Code

```json
{
  "servers": {
    "jesuscabrerareveles-honest-cv": {
      "command": "uvx",
      "args": [
        "honest-cv"
      ]
    }
  }
}
```

### Codex

```bash
codex mcp add jesuscabrerareveles-honest-cv -- uvx honest-cv
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "jesuscabrerareveles-honest-cv": {
      "type": "local",
      "command": [
        "uvx",
        "honest-cv"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add jesuscabrerareveles-honest-cv --command uvx --arg honest-cv
```

### Hermes

```yaml
mcp_servers:
  jesuscabrerareveles-honest-cv:
    command: "uvx"
    args: ["honest-cv"]
```

### Netclaw

```json
{
  "McpServers": {
    "jesuscabrerareveles-honest-cv": {
      "Transport": "stdio",
      "Command": "uvx",
      "Arguments": [
        "honest-cv"
      ]
    }
  }
}
```

### Vellum

```bash
assistant mcp add jesuscabrerareveles-honest-cv -t stdio -c uvx -a honest-cv
```

### Other

```json
{
  "mcpServers": {
    "jesuscabrerareveles-honest-cv": {
      "command": "uvx",
      "args": [
        "honest-cv"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-10-22 (score 70, −14)

- [security regression] Malware scan: pass → unverified

### 2026-10-21 (score 84, +15)

- [security regression] Tool safety: pass → unverified
- [security regression] Stability: 0.17 → unverified
- [security improvement] Malware scan: unverified → pass
- [functional regression] Capabilities: pass → unverified
- [functional regression] Tool coverage: 100 → unverified
- [functional regression] Schema quality: 100 → unverified
- [functional] Package version: 0.3.2 → 0.3.3

### 2026-10-20 (score 69, +1)

No change was recorded against any check on this day. Stability & Change Management went from 13 to 17. That category is still filling its 30-day observation window: 4 days of observed history at the previous scan, 5 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-18 (score 68, +1)

No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-10-16 (score 67, +1)

- [functional regression] Schema quality: 156 → 220
- [functional improvement] Stability: unverified → 0.03
- [functional] Schema quality: good → excellent
- [functional] Package version: 0.2.0 → 0.3.2
- [functional] Package version: 0.2.0 → 0.3.1
- [functional] Package version: 0.2.0 → 0.3.0

### 2026-10-15 (score 66)

First indexed and scored.

## MCP tools (31)

### `init_profile` (~95 tokens)

Create a new profile folder with empty, commented YAML templates (profile, bullets,
skills, variants). Use it once, before anything else, when the person has no profile; to start
from LinkedIn or a JSON Resume, call import_profile afterwards. Refuses an existing profile and
overwrites nothing. Returns `created`: the files written.

Input parameters:

- `profile` (string, required): Folder to create. Must not hold a profile yet.

### `get_inventory` (~116 tokens)

Read the person's skill inventory. Use it at the start of a session and before
proposing skill changes; for CV content (roles, bullets, variants) use list_variants instead.
Returns `levels` (what P, L, F and X mean) and `skills` grouped by level, each with its
years, last_used_year, evidence, aliases and notes. Read-only.

Input parameters:

- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `set_skill` (~254 tokens)

Add or change one skill in the inventory. Use it for a single skill; for several at
once use set_skills, and for a whole marked list use checklist_apply. Raising a level (a new skill
counts as rising from X) needs `evidence`, and the server asks the person to confirm before saving;
lowering is always allowed. Returns `saved` (the stored skill) and `previous_level`.

Input parameters:

- `aliases`: Other spellings, e.g. k8s for Kubernetes.
- `evidence`: Where and how the person used it. Required to raise a level.
- `last_used_year`: Last calendar year the person used it, e.g. 2026.
- `level` (string, required): P production at a job, L own project or lab, F familiarity, X does not have it.
- `name` (string, required): Skill name, e.g. Kubernetes. Matches existing skills ignoring case.
- `notes`: Private notes; never printed on the CV.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `years`: Years of use, e.g. 2.5.

### `set_skills` (~163 tokens)

Add or change several skills in one call, for example a group the person just told
you about. Use set_skill for one skill and checklist_apply for a marked checklist. Every upgrade
needs `evidence`; the person confirms upgrades in a form, up to 10 per call, and only those they
answer "sí" are saved. Returns `saved`, `upgrades_confirmed`, `upgrades_refused` and
\`upgrades_not_asked_yet`: when that list is not empty, call set_skills again with those skills.

Input parameters:

- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `skills` (array, required): The skills to add or change.

### `import_profile` (~259 tokens)

Import an existing CV into the profile: a JSON Resume (.json), a LinkedIn data export
(.zip or its unzipped folder) or a LinkedIn profile PDF. Use it at the start, right after
init_profile, instead of typing everything; run it first with `dry_run`. Adds contact, roles with
their achievements, education, certifications, courses, publications and languages; only what the
profile lacks, never overwriting. Skills arrive without a level, so they go to
\<profile>/imported-skills.md for the person to mark, never to the inventory. Imported bullets are
tagged `imported`: review them with the person. Returns what was added and an optional `note` to
pass on. For a PDF nothing is written: it returns the `text`, to organize with the editing tools
(see the import_linkedin_pdf prompt).

Input parameters:

- `dry_run` (boolean): Report what would be added without writing.
- `path` (string, required): A JSON Resume (.json), a LinkedIn data export (.zip) or a LinkedIn profile PDF.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `checklist_list` (~156 tokens)

List the skill checklist templates the person can combine. Use it before
checklist_new, to let the person pick the ones that fit their profession. Returns `checklists`:
each with its `id`, `title`, `description`, number of `skills` and `origin` ("built-in", or
"yours" for templates in <profile>/checklists/). Any profession works. Pass `lang` in the
person's language to get the translated templates. Read-only.

Input parameters:

- `lang` (string): The person's language: the built-in templates in it, where translated.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `checklist_new` (~240 tokens)

Write a checklist file for the person to mark in their editor, merged from the
templates picked in checklist_list, without duplicates and prefilled from the inventory. Use it
when the person has many skills: it is much faster than asking one by one. Next step: once they
have marked it, call checklist_apply. Refuses to replace an existing file unless `overwrite`.
\`lists` may be empty when `extra` names the skills. Returns the file's `path` and its number of
\`skills`.

Input parameters:

- `extra`: More skill names to ask about, e.g. found in an imported profile.
- `lang` (string): The person's language: the file's headings and the built-in templates in it.
- `lists` (array, required): Ids from checklist_list, e.g. backend-jvm, or paths to .md templates.
- `overwrite` (boolean): Replace the file if it exists.
- `path`: File to write. Default: <profile>/checklist.md.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `checklist_apply` (~271 tokens)

Save the skills the person marked in a checklist file. Use it after checklist_new,
once the person says they are done, and again to resume. Lines that keep or lower a level are
saved at once; upgrades with evidence are confirmed in a form, up to 10 per call: call again while
\`upgrades_not_asked_yet` is not empty. Returns the counts saved, `pending_evidence` (marked lines
without evidence: ask where they used them, in groups, and save with set_skills),
\`skills_without_achievements` and `key_skills_without_achievements`.

Ask about nothing else: unmarked lines are for the person to mark in the file. After the
checklist, ask for the person's biggest achievements first, since one usually covers several
skills, then for the key skills still without one; save each with add_bullet. The rest wait for a
job post that asks for them (gap_report → `no_achievement`). Never write an achievement for
them.

Input parameters:

- `path` (string, required): A Markdown checklist marked by the person, e.g. <profile>/checklist.md.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `add_bullet` (~213 tokens)

Add one achievement to the bullet pool, the material every CV variant picks from. Use it
after the person approves the wording, one bullet per call; to change which bullets a CV shows,
use save_variant. `role` is a role id from upsert_role; leave it out for bullets used only in
Selected Impact. Use only facts the person stated, never invented numbers. Returns `saved`.

Input parameters:

- `id` (string, required): Unique bullet id, e.g. ft_k8s.
- `metrics`: Numbers it claims, e.g. 40%, kept for review.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `role`: Role id from profile.yaml this bullet belongs to.
- `tags`: Skills and topics it shows, e.g. Kubernetes.
- `text_en` (string, required): The achievement in English, as the person stated it.
- `text_es`: The same achievement in Spanish.

### `set_contact` (~199 tokens)

Update the person's contact details on the CV. Use it for name, email, phone,
location and links; roles, education and the rest have their own tools. Only the fields given
change; pass "clear" to remove an optional one. `links` replaces the whole list. Returns the
\`contact` as saved in profile.yaml.

Input parameters:

- `email`: Email for the CV.
- `links`: All the links to show, e.g. LinkedIn, GitHub, a site. Replaces the current list.
- `location`: One string, or one per language: {"en": "...", "es": "..."}.
- `name`: Full name as it should appear on the CV.
- `phone`: Phone, e.g. "+52 442 000 0000".
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `set_profile_details` (~187 tokens)

Replace the certifications, courses or spoken-languages line of the profile.
Use it for those three lists only; roles, education and publications have their own tools. Each
list you pass replaces the current one in full; leave a field out to keep it. A course or
training without an exam goes in `courses`, never in `certifications`. Returns the saved
values.

Input parameters:

- `certifications`: All the certifications, replacing the current list. Leave out to keep it.
- `courses`: All the courses and trainings without an exam, replacing the current list; leave out to keep it. A course is never a certification.
- `languages`: One string, or one per language: {"en": "...", "es": "..."}.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `upsert_role` (~269 tokens)

Add a job role, or change some fields of an existing one by its `id`. Use it while
interviewing the person about their work history; their achievements go in with add_bullet,
pointing to this id. A new role needs `title`, `company` and `start`; roles stay in date order,
newest first. Keep the person's real title. Returns the `role` as saved.

Input parameters:

- `company`: Company name.
- `context`: One string, or one per language: {"en": "...", "es": "..."}.
- `end`: Year it ended, e.g. "2024". "present" marks it as the current role.
- `id` (string, required): Short role id, e.g. acme. Bullets point to it.
- `location`: One string, or one per language: {"en": "...", "es": "..."}.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `start`: A year or year-month, e.g. "2021" or "2021-03".
- `title`: One string, or one per language: {"en": "...", "es": "..."}.

### `upsert_education` (~182 tokens)

Add an education entry, or change the one with the same institution and degree.
Use it for degrees and formal studies; courses and certifications go in set_profile_details. Say
honestly whether the degree was completed, e.g. "B.Sc. (unfinished)". Returns the `education`
entry as saved.

Input parameters:

- `degree`: One string, or one per language: {"en": "...", "es": "..."}.
- `end`: A year or year-month, e.g. "2021" or "2021-03".
- `institution` (string, required): School or university.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `start`: A year or year-month, e.g. "2021" or "2021-03".

### `upsert_publication` (~209 tokens)

Add a book, article or paper the person wrote, or change some fields of the one
with this `id`. Use it when the person mentions something they published; courses and
certifications go in set_profile_details. Every variant shows all publications unless it lists the
ones it wants (save_variant → `publications`). Returns the `publication` as saved.

Input parameters:

- `id` (string, required): Short id, e.g. book_adr_kit. Variants list these ids.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `title`: The title as published.
- `url`: A link to it.
- `venue`: Where it is published, e.g. "Amazon (self-published)" or "Medium". Never a publisher it did not have.
- `year`: A year or year-month, e.g. "2021" or "2021-03".

### `save_variant` (~306 tokens)

Create or replace a CV variant: the plan for one kind of role (title, summary, which
bullets and skills to show). Use it to set up a variant or tailor one to a job post; read the
current ones with list_variants first. It replaces the variant whole, so pass every field it
should define (list_variants → `own` shows them). A variant without `extends` needs `title` and
\`summary`. Every reference is checked before saving. Returns `saved` and the `variant`.

Input parameters:

- `competencies`: Short list of core competencies.
- `extends`: Variant to inherit from; set only what differs.
- `id` (string, required): Variant id, e.g. backend.
- `impact`: Bullet ids for Selected Impact.
- `max_pages`: Page limit, usually 1 or 2.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `publications`: Publication ids to show, in order; [] shows none. Not set: all of them.
- `roles`: Role id -> bullet ids to show, in order.
- `skills`: Skill groups: a label and skill names.
- `summary`: One string, or one per language: {"en": "...", "es": "..."}.
- `title`: One string, or one per language: {"en": "...", "es": "..."}.

### `remove_skill` (~130 tokens)

Delete a skill from the inventory, e.g. a duplicate or a misspelling, and from the
variants' skill groups and competencies. Use it only for mistakes: to record that the person
doesn't have a skill, use set_skill with level X instead, which keeps gap reports honest. Ask the
person first; it cannot be undone. Returns what was removed and `variants_updated`.

Input parameters:

- `name` (string, required): Skill name as in the inventory.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `remove_bullet` (~106 tokens)

Delete an achievement from the pool and from every variant that uses it. Use it when
the person wants it gone; to stop showing it in one CV, change that variant with save_variant
instead. Ask the person first; it cannot be undone. Returns what was removed and `variants_updated`.

Input parameters:

- `id` (string, required): Bullet id.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `remove_publication` (~105 tokens)

Delete a publication from the profile and from every variant that lists it. To
hide it from one CV only, change that variant's `publications` with save_variant instead. Ask the
person first; it cannot be undone. Returns what was removed and `variants_updated`.

Input parameters:

- `id` (string, required): Publication id from profile.yaml.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `remove_role` (~145 tokens)

Delete a role from the profile and from every variant. A role that still has bullets
is refused unless `with_bullets` is true, which deletes them too. To hide a role from one CV, edit
that variant with save_variant instead. Ask the person first; it cannot be undone. Returns what was
removed and `variants_updated`.

Input parameters:

- `id` (string, required): Role id from profile.yaml.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `with_bullets` (boolean): Also delete the role's bullets. Only if the person agreed to lose them.

### `list_variants` (~111 tokens)

Read every CV variant, with `extends` already applied and the text of each bullet
it uses. Use it before save_variant, build_cv or score_job, to know what each CV contains.
Returns `variants` (with `own`: the fields each one defines itself) and `unused_bullets`:
achievements no variant shows yet. Read-only.

Input parameters:

- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `build_cv` (~228 tokens)

Render a CV variant to PDF and/or DOCX, then verify the PDF for ATS safety. Use it when
the person wants the files; for a cover letter use build_letter, and to check a PDF made
elsewhere use verify_pdf. Files go to `out_dir`, default <profile>/out, replacing earlier builds
of the same variant and language. Returns the `files`, each PDF with its pages, `ats_ok` and
failed checks. A failed check is probably a bug in honest-cv: report it, never reword the
person's text to pass it.

Input parameters:

- `formats`: Formats to write: pdf, docx or both. Default: both.
- `lang` (string): Language of the output: en (English) or es (Spanish).
- `out_dir`: Output folder. Default: <profile>/out.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `variant` (string, required): Variant id from variants.yaml, e.g. backend.

### `verify_pdf` (~145 tokens)

Check whether any PDF is ATS-safe: one column, no ligatures, dates on their role's line,
text extractable, and the page count. Use it on a CV from any tool, e.g. the person's current
one; build_cv already runs it on the CVs it renders. Returns `ok`, `pages`, `checks` (each with
\`name`, `ok`, `detail`) and `text`: what an ATS reads. Read-only.

Input parameters:

- `max_pages`: Most pages allowed; the page_count check fails above it. Default: no limit.
- `path` (string, required): Path to any PDF, made with honest-cv or not.

### `check_claims` (~182 tokens)

Check any text about the person against their profile before it goes anywhere: a
cover letter, a summary, a LinkedIn text. build_letter and linkedin_profile run it too. Returns
\`problems`, which must be fixed (a skill marked X, or a familiarity skill not called familiarity
in its sentence), and `warnings` for the person (a technology the profile doesn't show, or a
number found nowhere in it). Fix them by removing or qualifying the claim, never by adding
skills. Read-only.

Input parameters:

- `keywords`: Keywords of the job post, so its technologies are checked too.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `text` (string, required): The draft: a cover letter, a summary, any text about the person.

### `build_letter` (~283 tokens)

Render an approved cover letter to a one-page PDF and/or DOCX with the CV's ATS
checks. Use it after drafting the letter with the person and running check_claims; for the CV
itself use build_cv. It runs check_claims again and refuses while there are problems. Returns the
\`files` and any `warnings` to show the person.

Input parameters:

- `closing`: Closing line. Default: Sincerely, / Atentamente,
- `company` (string, required): Company name, as in the job post.
- `formats`: Formats to write: pdf, docx or both. Default: both.
- `greeting`: Opening line. Default: Dear Hiring Team, / Estimado equipo de selección:
- `keywords`: Keywords of the job post, for check_claims.
- `lang` (string): Language of the output: en (English) or es (Spanish).
- `out_dir`: Output folder. Default: <profile>/out.
- `paragraphs` (array, required): The body, one string per paragraph, approved by the person.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `recipient`: Hiring manager or team, if the post names one.
- `role` (string, required): Job title, as in the job post.

### `export_json_resume` (~167 tokens)

Export a CV variant as a JSON Resume file, for other CV tools and sites that
import that format. Use build_cv for a PDF or DOCX instead. Same honesty rules as the CV: X skills
never appear, and F skills only in a "Familiarity" group. Writes to `out_dir`, default
\<profile>/out, and returns its `path`.

Input parameters:

- `lang` (string): Language of the output: en (English) or es (Spanish).
- `out_dir`: Output folder. Default: <profile>/out.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `variant` (string, required): Variant id from variants.yaml, e.g. backend.

### `linkedin_profile` (~237 tokens)

Write the LinkedIn texts for a variant, each within LinkedIn's limit: headline,
About, one description per position from its bullets, and the skills (P and L only, since
LinkedIn can't label familiarity). Use it when the person updates their LinkedIn profile. Writes
them to a Markdown file to copy from and returns them with their `path`, plus `left_out`: bullets
that didn't fit. After the person approves a polished headline or About, call it again with them:
they are checked like a letter and saved in that file.

Input parameters:

- `about`: A polished About the person approved, to save instead of the draft.
- `headline`: A polished headline the person approved, to save instead of the draft.
- `lang` (string): Language of the output: en (English) or es (Spanish).
- `out_dir`: Output folder. Default: <profile>/out.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `variant` (string, required): Variant id from variants.yaml, e.g. backend.

### `log_application` (~363 tokens)

Record a job application, or update the one for the same company and role. Use it
when the person sends a CV or letter, and whenever they tell you what happened (interview, offer,
rejection); list_applications reads them back. Fields not given keep their value. Save the post's
full text in `post`, since links expire, and your interview advice in `prep`. Each file in `files`
is copied to <profile>/sent/<id>/, so the record keeps what was sent. Returns the `application`
and `not_found`: paths it could not copy.

Input parameters:

- `company` (string, required): Company name, as in the job post.
- `date`: Date of this status, YYYY-MM-DD. Default: today.
- `files`: Paths of the CV and letter sent. A copy is kept in <profile>/sent/.
- `lang`: Language of the CV sent.
- `notes`: Contact person, salary range, next step... Added to the notes already there.
- `post`: The job post's full text, as the person gave it. Saved to <profile>/posts/.
- `prep`: What to prepare for the interview: skills to back with an example, gaps to explain, questions to ask. Replaces the list.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `role` (string, required): Job title, as in the job post.
- `status`: New status: draft, applied, interview, offer, rejected or withdrawn. Each change is kept in the history with its date.
- `url`: Link to the job post.
- `variant`: Variant id of the CV sent.

### `list_applications` (~128 tokens)

List the person's job applications, most recently updated first. Use it when
they ask how their search is going or which application to follow up; log_application records
changes. Returns `applications` (each with its id, status and `days_since_update`), a count per
status and `waiting`: open applications with no news for 14 days or more. Read-only.

Input parameters:

- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `status`: Only applications in these statuses. Default: all.

### `interview_prep` (~273 tokens)

Prepare the interview for one logged application from what the person can honestly
back up. Call it first with only `application` to get the saved job post (`post_text`), then again
with the post's keywords. For each keyword it returns their level, evidence, `stories` (the
bullets that show it, those in the CV they sent first) and a `standing`: strong (tell a story
from those bullets), no_achievement (ask for a real example), marked_pending (ask for evidence),
familiarity (say it is familiarity) or lacking (say so honestly). Every story must come from
\`stories`. With `notes`, saves the approved prep to <profile>/prep/<id>.md.

Input parameters:

- `application` (string, required): Application id, from list_applications.
- `keywords`: Required keywords from the job post, in its own wording. Leave out on the first call to get the saved post's text.
- `notes`: The prep notes the person approved, in Markdown. Saved to <profile>/prep/<application>.md, replacing earlier notes.
- `preferred`: Nice-to-have keywords from the job post.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).

### `score_job` (~211 tokens)

Measure how well each CV variant covers a job post's keywords, best first. Use it first
when the person shares a post, to pick a variant; then call gap_report on that variant to see
what is missing and why. Extract the keywords yourself in the post's own wording: `keywords` are
the required ones, `preferred` the nice-to-haves. Returns `scores`: per variant, the required and
overall coverage and each keyword found, found only as familiarity, or missing. Read-only.

Input parameters:

- `keywords` (array, required): Required keywords from the job post, in its own wording.
- `lang` (string): Language of the output: en (English) or es (Spanish).
- `preferred`: Nice-to-have keywords from the job post.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `variants`: Variant ids to score, from list_variants. Default: all.

### `gap_report` (~252 tokens)

Explain the keywords a job post asks for that one variant doesn't show, grouped by what
can honestly be done. Use it after score_job picked the variant, before editing it with
save_variant. Returns: `in_inventory_not_in_cv` (the person has it: add it, using
\`unused_bullets`, or name it in the summary or competencies), `familiarity_only` (only as
familiarity), `not_in_inventory` (do not claim it), `no_achievement` (P or L skills no bullet
shows: ask for one real achievement each) and `marked_in_checklist` (marked in their checklist,
still without evidence: ask where they used it). Read-only.

Input parameters:

- `keywords` (array, required): Required keywords from the job post, in its own wording.
- `lang` (string): Language of the output: en (English) or es (Spanish).
- `preferred`: Nice-to-have keywords from the job post.
- `profile`: Path of the profile folder. Leave it out to use the server's default (--profile or HONEST_CV_PROFILE).
- `variant` (string, required): Variant id from variants.yaml, e.g. backend.

## Diagnostics

Captured diagnostic sections: Provenance, Install scripts, Dependencies. The full working is on the page: https://verifymcp.io/servers/jesuscabrerareveles-honest-cv/honest-cv#diagnostics

## Score history

- 2026-10-22: 70
- 2026-10-21: 84
- 2026-10-20: 69
- 2026-10-19: 68
- 2026-10-18: 68
- 2026-10-17: 67
- 2026-10-16: 67
- 2026-10-15: 66

## Common questions

### What is the honest-cv MCP server?

honest-cv is an MCP server listed in the public MCP registry as io.github.JesusCabreraReveles/honest-cv. Honest, ATS-safe CVs and cover letters from a skill inventory you confirm yourself. This page covers its PyPI package (honest-cv).

### Is the honest-cv MCP server safe to use?

honest-cv scores 70 out of 100 on VerifyMCP. We found no known CVEs affecting it as of 22 October 2026. Its build provenance is signed and verified. That is a record of what we were able to check automatically, not an endorsement. The category breakdown on this page shows every signal behind the number, including the ones we could not confirm.

### What tools does the honest-cv MCP server expose?

honest-cv exposes 31 tools: init_profile, get_inventory, set_skill, set_skills, import_profile, and 26 more. Their descriptions and schemas cost roughly 6,185 tokens of context every time the server is loaded.

### Is the honest-cv MCP server still maintained?

honest-cv is still listed as active in the MCP registry. We last reached this channel on 22 October 2026. Those dates come from our own scans of the registry and the channel itself, not from anything the publisher announced.

### What licence is the honest-cv MCP server under?

honest-cv declares the MIT licence, which is OSI-approved. That covers the source only, and says nothing about the cost of any service it calls.

## Links

- PyPI project: https://pypi.org/project/honest-cv/
- Socket report: https://socket.dev/pypi/package/honest-cv
- Repository: https://github.com/JesusCabreraReveles/honest-cv
- Changelog RSS feed: https://verifymcp.io/servers/jesuscabrerareveles-honest-cv/honest-cv.xml
- Changelog JSON feed: https://verifymcp.io/servers/jesuscabrerareveles-honest-cv/honest-cv.json
- HTML version of this page: https://verifymcp.io/servers/jesuscabrerareveles-honest-cv/honest-cv
