resumeai-mcp
Drive Big Interview ResumeAI scans for a resume against a job description via an AI agent, returning structured ATS/credibility feedback.
Check login status and remaining daily scan allowance (
auth_status).List past scans, paged newest-first, for reuse checks and deletion candidates (
list_scans).Start a scan by uploading an absolute text-based PDF/DOCX resume plus job title, company, job description, and optional scoring guide; identical inputs reuse the existing scan without spending an allowance (
start_scan).Poll a scan's state—queued, scanning, complete, failed, or unknown—without hammering the site (
get_scan_status).Retrieve structured feedback: overall medal, four category badges (readability, credibility, ATS fit, format), criteria, action items, and matched/unmatched ATS keywords; saves a local backup (
get_scan_feedback).Delete a scan from My Scans after backing up feedback locally (
delete_scan).Support an honest agent loop: tailor resume → rescan until ATS Fit and Credibility both reach Gold.
Keep local history: ledger, feedback backups, and snapshots under
~/.resumeai-mcp.Use account-safe pacing: 2–5 s human-like delays, one scan in flight, one tool at a time, and daily operation limits.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@resumeai-mcpstart a new resume scan and monitor its progress"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
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.
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-mcpOpen 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 |
|
installs the exact locked dependencies |
| |
Google Chrome | the browser the server drives | google.com/chrome, or bundled Chromium (see below) |
An MCP client | calls the tools | Claude Code ( |
A Big Interview account | the scans are yours | NEU: |
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 scansThe 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.
| default | meaning |
|
| your school's Big Interview portal |
|
| ledger, feedback backups, snapshots (created |
|
| the browser profile = your login session ( |
|
| run the browser invisibly |
|
|
|
|
| page-load timeout |
|
| 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=trueThe session lives in PROFILE_DIR. Your school's SSO usually re-authenticates silently, so you rarely need to
repeat this.
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: ✔ ConnectedStart 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.pdffor "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 |
| logged in? scans left today? |
| past scans, newest first, paged |
| uploads and scans (uses 1 of 5 daily scans); returns the existing scan instead if the exact same inputs were already scanned |
| queued / scanning / complete / failed / unknown |
| medal, 4 category badges, every criterion, action items, ATS keywords; saves a local backup |
| 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.
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"| Pflowchart 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] --> stThe 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 |
| the SSO session ended |
|
|
| close it and retry |
| 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 |
| 0 scans left today, or 12 operations done today | wait until local midnight |
| guide name doesn't match the site | use the name exactly as shown on the scan page |
| image-only / scanned PDF | export a text-based PDF or DOCX |
| a scan is running | poll |
| a submission couldn't be confirmed, or a status couldn't be read | don't rescan; follow the hint (the next |
| the website's layout changed | |
| portal unreachable | read tools already retried twice: check your connection; after a scan/delete, check My Scans before retrying |
|
| fix permissions/space; nothing is deleted without a backup |
| wrong path or venv | re-run |
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:
Open the snapshot named in the error's
hintand find what moved.Update the locator or parser: scan form →
src/resumeai_mcp/scans.py(_submit); My Scans list →scans.py(parse_my_scans, which reads theUserResumeAssignmentScansApppage data); feedback →src/resumeai_mcp/feedback.py(ResumeAssignmentReviewSummaryApppage data); login →auth.py.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).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 fixturesuv run pytest -q # offline: no browser, no site, no scansLive 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 toolsauth_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.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| confirm | No | ||
| scan_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| scan_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| scan_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | ||
| cursor | No |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| company | Yes | ||
| job_title | Yes | ||
| resume_path | Yes | ||
| scoring_guide | No | Graduate - STEM Focus | |
| job_description | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
No output parameters | ||
TDQS
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.
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.
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.
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.
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.
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.
6 tool updates
v0.0.1- First observed
auth_status - First observed
delete_scan - First observed
get_scan_feedback - First observed
get_scan_status - First observed
list_scans - First observed
start_scan
TDQS
Scored across 6 tools
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.
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.
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.
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
Related MCP Connectors
Live SEO workflow tools for Claude Code, Codex, and AI agents.
Work on your own computers from Claude or ChatGPT: run commands, edit and search files.
Use your Mac, Windows or Linux computer from ChatGPT, Claude or Codex: files, commands, documents.
Source-checked CLI guides and model-aware planning for Claude Code, Codex, and Grok Build.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceExposes 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.1MIT
- AlicenseAqualityBmaintenanceEnables parsing a master resume, analyzing job descriptions for ATS/match scores, generating truthful tailored resumes, tracking applications, and producing PDF reports through Claude Desktop.17MIT
- AlicenseAqualityBmaintenanceEnables an AI agent to run local tools on the user's own machine via stdio, including command execution, workspace file read/write, and system status checks.52MIT
- AlicenseAqualityBmaintenanceEnables 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.71MIT