Skip to main content
Glama
devpatel25

resumeai-mcp

by devpatel25

Scan your resume against a job description on Big Interview ResumeAI, read the structured feedback, and let your AI agent tailor → rescan until ATS Fit and Credibility both hit Gold. Honestly.

Quick start · Install · Tools · How it works · Troubleshooting · Spec · Agent runbook


✨ Why

Big Interview ResumeAI has no public API. resumeai-mcp is a local MCP server (stdio) that drives the website for you with Playwright in a real Chrome profile, so an agent such as Claude Code can:

  • 📤 Scan a PDF/DOCX resume against a job description (idempotent: identical inputs reuse the old scan, no allowance spent)

  • ⏱️ Poll scan status without hammering the site

  • 🏅 Read feedback as strict JSON: overall medal, 4 category badges, every criterion, action items, matched/unmatched ATS keywords

  • 🔁 Loop: tailor → rescan until ATS Fit + Credibility are Gold, with stopping rules (RUNBOOK.md)

  • 🗂️ Keep history locally: a ledger and feedback backups, so tidying up My Scans never loses data

🔒 No password is ever stored. You log in once by hand (SSO + MFA); the server reuses that browser session. 🐢 Account-safe by design: 2–5 s human-like pauses, one scan in flight, ≤ 12 scan operations per day.

NOTE

Unofficial, personal-use tool, not affiliated with Big Interview. Built and verified against the Northeastern portal (neu.biginterview.com). Other schools' portals can be set with BASE_URL, but are untested.

Related MCP server: ResumePilot MCP

🚀 Quick start

Already have uv, Google Chrome and Claude Code? Four commands:

git clone https://github.com/devpatel25/Biginterview-MCP.git && cd Biginterview-MCP
uv sync --frozen && cp .env.example .env
uv run python scripts/login.py        # log in with SSO + MFA in the Chrome window, then press ENTER
claude mcp add --scope user resumeai -- uv --directory "$PWD" run resumeai-mcp

Open a new Claude Code session and ask: "Check my Big Interview status." Details for each step are below.

📦 Installation

1. Requirements

need

why

get it

macOS or Linux

tested on macOS

—

Python 3.11+

runtime

uv can install it for you: uv python install 3.12

uv

installs the exact locked dependencies

curl -LsSf https://astral.sh/uv/install.sh | sh (or brew install uv)

Google Chrome

the browser the server drives

google.com/chrome, or bundled Chromium (see below)

An MCP client

calls the tools

Claude Code (npm install -g @anthropic-ai/claude-code), or any stdio MCP client

A Big Interview account

the scans are yours

NEU: https://neu.biginterview.com

2. Install the server

git clone https://github.com/devpatel25/Biginterview-MCP.git
cd Biginterview-MCP
uv sync --frozen          # exact locked versions (fastmcp 2.14.7 + mcp 1.30.0); don't pip-install instead
cp .env.example .env      # defaults work for NEU; edit only if you need to
uv run pytest -q          # optional: offline self-check, no browser, no scans

The default BROWSER_CHANNEL=chrome uses your installed Google Chrome. If Chrome is missing, run uv run playwright install chrome, or use bundled Chromium: uv run playwright install chromium and set BROWSER_CHANNEL= (empty) in .env.

.env key

default

meaning

BASE_URL

https://neu.biginterview.com

your school's Big Interview portal

DATA_DIR

~/.resumeai-mcp

ledger, feedback backups, snapshots (created 0700)

PROFILE_DIR

~/.resumeai-mcp/resumeai-profile

the browser profile = your login session (0700)

HEADLESS

true

run the browser invisibly

BROWSER_CHANNEL

chrome

chrome, or empty for bundled Chromium

NAV_TIMEOUT_MS

30000

page-load timeout

HUMAN_DELAY_MIN_S / _MAX_S

2 / 5

random pause between UI actions

3. Log in (once, and whenever the session expires)

uv run python scripts/login.py          # opens Chrome: log in with SSO + MFA, then press ENTER in the terminal
uv run python scripts/login.py --check  # headless check → prints logged_in=true

The session lives in PROFILE_DIR. Your school's SSO usually re-authenticates silently, so you rarely need to repeat this.

WARNING

Never run login.py while your MCP client is using the server: the two can't share the profile (you'll get profile_in_use).

4. Connect your MCP client

Claude Code (run from the repo folder, or replace "$PWD" with the absolute repo path):

claude mcp add --scope user resumeai -- uv --directory "$PWD" run resumeai-mcp
claude mcp get resumeai   # Status: ✔ Connected

Start a new Claude Code session so it picks up the tools.

Most clients accept an mcpServers entry like this. Use absolute paths; if the client can't find uv, use its full path (which uv).

{
  "mcpServers": {
    "resumeai": {
      "command": "uv",
      "args": ["--directory", "/absolute/path/to/Biginterview-MCP", "run", "resumeai-mcp"]
    }
  }
}

5. First scan

In Claude Code, ask for example:

Check my Big Interview status, then scan /Users/me/resumes/Resume.pdf for "Data Science Co-op" at "Acme" with this job description: … Poll until it's done and summarize the feedback.

The agent will call auth_status → start_scan → get_scan_status (every ≥ 20 s) → get_scan_feedback. For the full tailor-and-rescan loop, point the agent at RUNBOOK.md.

Update / uninstall

git pull && uv sync --frozen                   # update
claude mcp remove resumeai --scope user        # disconnect
rm -rf ~/.resumeai-mcp                         # delete local data AND your saved login session

🧰 Tools

tool

what it does

auth_status()

logged in? scans left today?

list_scans(limit=20, cursor=null)

past scans, newest first, paged

start_scan(resume_path, job_title, company, job_description, scoring_guide="Graduate - STEM Focus")

uploads and scans (uses 1 of 5 daily scans); returns the existing scan instead if the exact same inputs were already scanned

get_scan_status(scan_id)

queued / scanning / complete / failed / unknown

get_scan_feedback(scan_id)

medal, 4 category badges, every criterion, action items, ATS keywords; saves a local backup

delete_scan(scan_id, confirm=false)

backs up feedback, then deletes the scan from My Scans

Every call returns {"ok": true, "data": …} or {"ok": false, "error": {"code", "message", "hint"}}.

Limits built in: 5 scans/day (the site's), at most 12 scan operations (starts + deletes) per day, one scan in flight, 2–5 s pauses between clicks, one tool at a time. resume_path must be an absolute path to a text-based PDF/DOCX (not a scanned image), 5 MB max. The default scoring guide is NEU's; pass scoring_guide with the exact name your portal shows if it differs.

{ "ok": true, "data": {
  "scan_id": "123456", "role_title": "Data Science Co-op", "company": "Acme",
  "scoring_guide": "Graduate - STEM Focus", "medal": "gold", "partial": false,
  "categories": {
    "readability": { "badge": "gold",   "criteria": [ … ] },
    "credibility": { "badge": "silver", "criteria": [ … ] },
    "ats_fit":     { "badge": "gold",   "criteria": [ … ],
                     "keywords_matched": ["Python", "SQL"], "keywords_unmatched": ["Airflow"] },
    "format":      { "badge": "gold",   "criteria": [ … ] }
  },
  "action_items": [ { "category": "credibility", "item": "…", "priority": "high" } ]
} }

Full schemas: PLAN.md §7–§8.

IMPORTANT

Honesty rule. Unmatched keywords are verification candidates, not a shopping list. The agent may add a keyword only when your real experience, projects or coursework back it. A truthful Silver beats a fabricated Gold.

🧭 How it works

flowchart LR
    A["MCP client<br/>(Claude Code agent)"] <-->|"stdio · 6 tools · JSON envelope"| S["resumeai-mcp<br/>(FastMCP)"]
    S -->|"Playwright, headless Chrome<br/>persistent profile"| B["Big Interview<br/>ResumeAI"]
    S --> D[("~/.resumeai-mcp<br/>ledger · feedback backups · snapshots")]
    L["scripts/login.py<br/>(one-time headed login)"] -.->|"saves session"| P[("PROFILE_DIR")]
    S -.->|"reuses session"| P
flowchart LR
    s[auth_status] --> st[start_scan] --> p{get_scan_status<br/>every ≥ 20 s}
    p -->|complete| f[get_scan_feedback]
    p -->|unknown / failed| x[stop & report]
    f -->|"ATS Fit + Credibility Gold"| done([done ✔])
    f -->|"not yet"| t[agent tailors resume<br/>honestly] --> st

The server never clicks blindly: every step checks for a known landmark first and stops with site_changed if the page looks different. Full design: PLAN.md.

🩺 Troubleshooting

you see

why

fix

auth_expired

the SSO session ended

uv run python scripts/login.py, then retry

profile_in_use

login.py (or another Chrome) holds the profile

close it and retry

internal_error on every tool

usually Chrome isn't installed / can't launch (details in the server's stderr log)

see Install (install Chrome or use Chromium); otherwise report the log

limit_reached

0 scans left today, or 12 operations done today

wait until local midnight

invalid_input "not found" for the scoring guide

guide name doesn't match the site

use the name exactly as shown on the scan page

invalid_input "no extractable text"

image-only / scanned PDF

export a text-based PDF or DOCX

invalid_input "still in flight"

a scan is running

poll get_scan_status until it completes

unknown_state

a submission couldn't be confirmed, or a status couldn't be read

don't rescan; follow the hint (the next start_scan recovers pending submissions)

site_changed

the website's layout changed

see When the site changes

network_error

portal unreachable

read tools already retried twice: check your connection; after a scan/delete, check My Scans before retrying

storage_error

DATA_DIR not writable / disk full

fix permissions/space; nothing is deleted without a backup

claude mcp get resumeai not connected

wrong path or venv

re-run uv sync --frozen and the claude mcp add line with the absolute repo path

The server logs to stderr (Claude Code shows it in the MCP logs); page contents are never logged.

🛠️ When the site changes

Every failed step saves the page to ~/.resumeai-mcp/snapshots/<step>-<time>-<random>.html. To fix:

  1. Open the snapshot named in the error's hint and find what moved.

  2. Update the locator or parser: scan form → src/resumeai_mcp/scans.py (_submit); My Scans list → scans.py (parse_my_scans, which reads the UserResumeAssignmentScansApp page data); feedback → src/resumeai_mcp/feedback.py (ResumeAssignmentReviewSummaryApp page data); login → auth.py.

  3. Re-capture a fixture: keep only the parser-relevant element, redact names/emails/filenames/ids, and save it as tests/fixtures/<name>.fixture.html (the only HTML that may be committed).

  4. uv run pytest -q, then record the change as a dated amendment in PLAN.md.

🔐 Your data

Everything stays on your machine under DATA_DIR (0700): ledger.jsonl (the scans this server created, with file hashes, never resume text), feedback/<scan_id>.json backups (kept), and snapshots/ (full page HTML, which is personal data: deleted automatically after 30 days, checked at every server start and every new snapshot). PROFILE_DIR holds your session cookies: treat it like a password; never copy, share or commit it.

🧪 Development

src/resumeai_mcp/
├── server.py     FastMCP app, 6 tools, JSON envelope, retries
├── browser.py    Playwright persistent context, human-like delays, snapshots
├── auth.py       login detection, auth_status
├── scans.py      list / start / status / delete, reuse key, daily budget
├── feedback.py   feedback-page parser → ScanFeedback
├── storage.py    ledger, feedback backups, snapshot retention
├── schemas.py    pydantic models
└── config.py     settings from .env
scripts/login.py  one-time headed login
tests/            offline tests + redacted HTML fixtures
uv run pytest -q          # offline: no browser, no site, no scans

Live changes are checked by hand (they use real scans): login.py --check → auth_status → list_scans → start_scan → poll → get_scan_feedback → the same start_scan again returns reused=true → delete_scan backs up first and reports allowance_restored truthfully.

Contributions welcome: open an issue or PR. Keep changes within PLAN.md, and record site-driven changes as dated amendments there.

📄 License

MIT © 2026 Dev Patel

Available Tools

6 tools
auth_statusA

Check the Big Interview login and the remaining daily scan allowance before starting any work. Returns logged_in (false is data, not an error), scans_remaining (null when not shown — never guessed), account_email (null when not visible), checked_at. If logged_in=false: stop and ask the user to run scripts/login.py. Pacing: the server adds random 2-5 s human-like delays between UI actions and runs one tool at a time; never call tools in parallel. On ok=false follow error.hint (PLAN.md §13): auth_expired, site_changed, unknown_state, internal_error and profile_in_use are never retried blindly; otherwise retry at most twice.

ParametersJSON Schema
NameRequiredDescriptionDefault

No parameters

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so: it discloses server-side pacing (random 2-5 s delays, one tool at a time, never parallel), null semantics ('never guessed'), that logged_in=false is data not an error, and a bounded retry policy. This is unusually rich behavioral context.

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?

Purpose and the pre-work trigger are front-loaded, then return fields, then failure handling and pacing. Every clause carries information, though the single dense paragraph packs several distinct concerns (returns, auth failure, pacing, retry policy) that would scan better as separated lines.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an auth/allowance gate with an output schema present, the description covers the return fields, the not-an-error case, the null cases, the prerequisite action on failure, concurrency constraints, and the retry matrix. Nothing an agent needs to call it correctly is missing.

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 no parameters, so there is no schema semantics to add; the baseline for a zero-param tool is 4. The description correctly spends its words on outputs and behavior instead.

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 ('Check the Big Interview login and the remaining daily scan allowance') and clearly positions itself as a pre-flight check distinct from the scan-oriented siblings. An agent can tell immediately that this is the auth/allowance gate rather than a scan action.

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

Usage Guidelines5/5

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

Explicitly says to run it 'before starting any work' and prescribes the exact action when logged_in=false (stop and ask the user to run scripts/login.py). It also routes error handling via error.hint and names which error states must never be blindly retried.

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

delete_scanA

Delete a scan from My Scans (optional history tidying; NOT a way to get more scans — never plan on allowance_restored). Feedback is always backed up locally first; the deletion is aborted if that fails. Deleting the latest result of the current loop requires confirm=true. Pacing: the server adds random 2-5 s human-like delays between UI actions and runs one tool at a time; never call tools in parallel. On ok=false follow error.hint (PLAN.md §13): auth_expired, site_changed, unknown_state, internal_error and profile_in_use are never retried blindly; otherwise retry at most twice.

ParametersJSON Schema
NameRequiredDescriptionDefault
confirmNo
scan_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and delivers: feedback is locally backed up first and deletion aborts if backup fails (reversibility/safety), the server injects random 2-5 s delays and runs one tool at a time so tools must never be called in parallel, and a concrete retry policy distinguishes never-retry errors (auth_expired, site_changed, unknown_state, internal_error, profile_in_use) from transient ones bounded at two retries. This is unusually rich operational disclosure.

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?

Purpose and the key anti-misuse warning are front-loaded, and every following sentence carries operational weight (backup, confirm, pacing, retry policy) rather than filler. It is dense with long parenthetical clauses, which costs a little readability, but nothing is expendable.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be described. Given a destructive mutation with no annotations, the description supplies the missing safety profile, concurrency constraints, confirmation rule, and error recovery guidance — everything needed to invoke it correctly and safely.

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 description coverage is 0%, so the description must compensate. It explains confirm meaningfully (required when deleting the latest result of the current loop, defaulting false in the schema) rather than restating the boolean, though scan_id's format/derivation is left to the agent (contextually obvious from list_scans). Strong compensation with a small remaining gap.

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+resource ('Delete a scan from My Scans') and immediately scopes it against a tempting but wrong interpretation ('NOT a way to get more scans'). This distinguishes it cleanly from siblings like list_scans and start_scan, which an agent could otherwise conflate with scan management.

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

Usage Guidelines5/5

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

Explicitly frames the tool as 'optional history tidying' and warns when NOT to use it ('never plan on allowance_restored'), then adds a precondition (confirm=true for the latest result of the current loop) and an error-handling policy keyed to specific codes. When-to-use, when-not, and what to do on failure are all covered.

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

get_scan_feedbackA

Structured feedback for a completed scan: overall medal, the four category badges (readability, credibility, ats_fit, format), each criterion's status (perfect / needs_work / warning) with the site's advice, action items (flagged items are listed even under a Gold badge), and ATS keywords matched/unmatched. partial=true means only the summary badges were readable. A local backup is written. Honesty rule: unmatched keywords are verification candidates, not a shopping list. Only add a keyword to the resume when it is backed by real experience, project, or coursework. Never fabricate skills, metrics, dates, degrees, or employment. A truthful Silver beats a fabricated Gold. Pacing: the server adds random 2-5 s human-like delays between UI actions and runs one tool at a time; never call tools in parallel. On ok=false follow error.hint (PLAN.md §13): auth_expired, site_changed, unknown_state, internal_error and profile_in_use are never retried blindly; otherwise retry at most twice.

ParametersJSON Schema
NameRequiredDescriptionDefault
scan_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.1/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so well: it discloses that partial=true means only badges were readable, that a local backup is written, that the server injects random 2-5 s delays and runs one tool at a time (never parallel), and how ok=false should be handled per error.hint with named non-retryable codes. This is far beyond what the schema conveys.

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 but front-loaded: content of the result comes first, then partial semantics, honesty rule, pacing, and error handling. Nearly every sentence carries operational information, though the honesty/pacing passages read as cross-tool boilerplate that lengthens the block.

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 read tool with an output schema present, the description still explains the payload shape and adds the safety, pacing, and error-handling context an agent needs. Only the scan_id parameter and how to obtain it go unexplained, a small gap given the simple input.

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 should compensate, yet it never mentions scan_id. It is a single self-evident identifier whose intent is clear from the tool context, so the omission is minor rather than damaging, but it adds no semantic detail over the schema.

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?

Opens with a specific verb+resource and enumerates exactly what the resource contains (medal, four badges, per-criterion status, action items, ATS keywords), which is precisely what distinguishes it from get_scan_status or list_scans. An agent knows it is the post-completion feedback reader, not a status poller.

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 (a 'completed scan', and partial=true for a truncated read), but the description never explicitly says when to call this versus get_scan_status, nor names an alternative. The rich error-retry guidance is about failure handling, not tool selection, so routing remains inferred.

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

get_scan_statusA

Poll a scan's state: queued, scanning, complete, failed (the site explicitly reported failure) or unknown (unreadable — stop and investigate; it is NOT a failure; hint names the saved snapshot). Poll no more often than once every 20 s; give up after 10 minutes (treat as scan_timeout and keep the scan_id). Also returns scans_remaining. Pacing: the server adds random 2-5 s human-like delays between UI actions and runs one tool at a time; never call tools in parallel. On ok=false follow error.hint (PLAN.md §13): auth_expired, site_changed, unknown_state, internal_error and profile_in_use are never retried blindly; otherwise retry at most twice.

ParametersJSON Schema
NameRequiredDescriptionDefault
scan_idYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.4/5.0
Behavior5/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 so richly: it distinguishes 'unknown' (unreadable, investigate, NOT a failure) from 'failed' (site reported failure), documents the server's 2-5 s randomized pacing and one-tool-at-a-time execution, and specifies retry limits and the ok=false/error.hint protocol. This is far beyond what the schema conveys.

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?

Front-loaded with the state enumeration an agent most needs, followed by polling cadence and error handling. It is a dense paragraph with no filler, though the pacing/retry material could be split or bulleted for faster scanning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value detail isn't required, and the description still flags that scans_remaining is returned. Combined with the state semantics, timeout rule, retry policy, and the unknown-vs-failed distinction, an agent has everything needed to poll and branch correctly.

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?

Only scan_id is accepted and its schema description coverage is 0%, so the description must compensate. It implies scan_id identifies the scan being polled ('keep the scan_id') but gives no format, source, or validation detail. This is adequate but thin for the one parameter present.

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 opens with a specific verb+resource ('Poll a scan's state') and enumerates the full set of possible states, so an agent knows exactly what this tool returns. It doesn't explicitly name or contrast against siblings like list_scans or get_scan_feedback, so the differentiation is inferred rather than stated.

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

Usage Guidelines5/5

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

It gives concrete when-to-use rules: poll no more than once every 20 s, give up after 10 minutes, treat timeout as scan_timeout while keeping the scan_id, never call tools in parallel. It also spells out the error.hint routing (auth_expired, site_changed, unknown_state, internal_error, profile_in_use never retried blindly; otherwise at most two retries), which is actionable conditional guidance.

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

list_scansA

List past scans (newest first) for reuse checks and deletion candidates. limit 1-50 (default 20); pass next_cursor from the previous response as cursor to continue; next_cursor=null means the last page. resume_sha256/jd_sha256 are only known for scans created by this server (null otherwise; such scans are never reused). Pacing: the server adds random 2-5 s human-like delays between UI actions and runs one tool at a time; never call tools in parallel. On ok=false follow error.hint (PLAN.md §13): auth_expired, site_changed, unknown_state, internal_error and profile_in_use are never retried blindly; otherwise retry at most twice.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNo
cursorNo

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.5/5.0
Behavior5/5

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

With no annotations, the description carries the full burden and does so richly: it discloses server pacing (random 2-5s delays, one tool at a time, never call in parallel), pagination semantics (next_cursor null = last page), and error handling (follow error.hint; auth_expired/site_changed/unknown_state/internal_error/profile_in_use never retried blindly; else retry at most twice). This is exactly the behavioral context an agent needs.

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?

Front-loaded with purpose, then parameters, then pacing and error rules; almost every clause earns its place. It is dense and slightly long, but there is no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema exists (so return shape is documented), and the description still covers pagination, pacing constraints, and the full error/retry policy. Nothing an agent needs to call this correctly is missing.

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

Parameters5/5

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

Schema coverage is 0% and the schema gives no descriptions, so the description must compensate — and it does: limit range 1-50 with default 20, cursor should carry next_cursor from the previous response, and null cursor means the final page. It also explains the meaning of resume_sha256/jd_sha256 nullability.

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 (List), resource (past scans), ordering (newest first), and the two concrete purposes (reuse checks and deletion candidates). An agent can immediately tell this apart from start_scan, get_scan_status, delete_scan, etc. without opening any schema.

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?

'for reuse checks and deletion candidates' implies when to use it, but no sibling is named as an alternative and no exclusion is given (e.g. when to prefer get_scan_status over listing). Usage context is implied rather than explicit.

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

start_scanA

Upload a resume + job description and start a scan (uses 1 of the 5 daily scans). Idempotent: if a completed scan exists for the same resume file, job description, scoring guide, job title and company, it is returned with reused=true and no allowance is used. resume_path must be an absolute path to a text-based .pdf/.docx (max 5 MB). Returns scan_id and state (queued/scanning; complete only when reused or already finished). Then poll get_scan_status no more often than every 20 s. Only one scan may be in flight; limit_reached means stop for the day. Pacing: the server adds random 2-5 s human-like delays between UI actions and runs one tool at a time; never call tools in parallel. On ok=false follow error.hint (PLAN.md §13): auth_expired, site_changed, unknown_state, internal_error and profile_in_use are never retried blindly; otherwise retry at most twice.

ParametersJSON Schema
NameRequiredDescriptionDefault
companyYes
job_titleYes
resume_pathYes
scoring_guideNoGraduate - STEM Focus
job_descriptionYes

Output Schema

ParametersJSON Schema
NameRequiredDescription

No output parameters

TDQS

A4.8/5.0
Behavior5/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 and does: idempotency with reused=true and no quota consumption, the 5-daily-scan allowance, single in-flight constraint, server-side random 2-5 s delays, and per-error retry semantics. This is unusually complete behavioral disclosure for a mutation 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?

Dense but well front-loaded: the core action and idempotency come first, then constraints, then polling and error guidance. Nearly every clause earns its place, though the error-policy sentence is packed tightly enough to be a little heavy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a mutation tool with no annotations and an output schema already present, the description still supplies what the schema cannot: quota, idempotency, concurrency, pacing, and the exact poll interval. Nothing an agent needs to call it correctly is missing.

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%, so the description must compensate. It documents resume_path thoroughly (absolute path, text-based .pdf/.docx, max 5 MB) and ties job_description/job_title/company to the idempotency key, but it never explains what scoring_guide values are valid beyond the default. It covers the non-obvious parameters well and leaves only the self-evident ones implicit.

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 ('Upload a resume + job description and start a scan') and distinguishes itself from the polling sibling by naming get_scan_status explicitly. An agent can tell exactly what this does versus list_scans or get_scan_feedback.

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

Usage Guidelines5/5

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

Explicit routing: 'Then poll get_scan_status no more often than every 20 s', 'Only one scan may be in flight', 'limit_reached means stop for the day', and 'never call tools in parallel'. It also gives a concrete retry policy and lists which errors must not be retried blindly.

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. 6 tool updatesv0.0.1
    • First observedauth_status
    • First observeddelete_scan
    • First observedget_scan_feedback
    • First observedget_scan_status
    • First observedlist_scans
    • First observedstart_scan

TDQS

A4.4/5.0

Scored across 6 tools

Disambiguation5/5

Each tool maps to a distinct step in the scan lifecycle: auth_status (auth check), list_scans (history), start_scan (create), get_scan_status (poll), get_scan_feedback (results), delete_scan (remove). The boundaries between polling status, retrieving feedback, and starting a scan are clear and non-overlapping.

Naming Consistency4/5

Most tools follow a clean verb_noun pattern (list_scans, start_scan, get_scan_status, get_scan_feedback, delete_scan). auth_status deviates slightly by leading with a noun-like token rather than an explicit verb, but it remains readable and consistent with the scan-status naming family.

Tool Count5/5

Six tools is well-scoped for a scan-and-feedback workflow, with each tool earning its place across auth, listing, creation, polling, results, and deletion. Nothing feels padded or redundant.

Completeness4/5

The surface covers the full lifecycle: authentication, listing, starting, polling, fetching feedback, and deletion. Minor gaps exist (no explicit cancel/abort for an in-flight scan or resume-management operation), but these are workable given the one-scan-in-flight constraint and idempotent start.

Maintenance

ActivityMaintained
ResponsivenessResponsive

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Exposes a structured professional resume as a set of AI-queryable tools, enabling AI clients like Claude Desktop to query summary, experience, skills, projects, and tailor resumes to job descriptions.
    1
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables parsing a master resume, analyzing job descriptions for ATS/match scores, generating truthful tailored resumes, tracking applications, and producing PDF reports through Claude Desktop.
    17
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Enables MCP clients such as Claude Desktop or compatible editors to run local, privacy-first job-search workflows including resume generation and STAR polishing, JD matching, GitHub project recommendations, mock interviews, and application tracking. It exposes these capabilities as callable tools through the Model Context Protocol.
    7
    1
    MIT