MCP server for browsing and searching job application documents
Strong tool naming (all verb-first), comprehensive descriptions (avg 180 chars), and complete input schemas with types and descriptions. All 13 tools are explicitly registered with @mcp.tool decorators and proper parameter annotations. Pagination support across list/search tools. Tool annotations present (readOnlyHint, idempotentHint, openWorldHint). Main gaps: output schemas not formally documented in code; error handling is minimal (only get_resume_profile and get_resume_full return explicit error objects); no per-tool error recovery guidance; some parameter descriptions could be more prescriptive about constraints (e.g., mode enum values not listed in descriptions, only in docstrings).
Get aggregate statistics about the entire resume collection: total counts, averages, and frequency distributions.
Return the full extracted text of a document, as {"text": "..."}. Note: takes a file path (see list_resumes), not a resume_id — use get_resume_profile or list_resumes to fetch structured data by resume_id instead. Returns {"error": ...} if path is not found.
Get a resume's complete nested structure in one call: profile fields plus all work experiences (with achievements), badge skills, side projects (with technologies), and education entries (with competencies). Prefer get_resume_profile plus the scoped list_* tools (list_work_experiences, list_skills, list_side_projects, list_education) when you only need part of this — it's more token-efficient. Use get_resume_full when you need the whole picture at once. Returns {"error": ...} if resume_id is not found.
Get a resume's top-level fields (contact info, professional statement, education) without the nested work experience and badge skill lists. See also: get_resume_full for everything about this resume in one call. Returns {"error": ...} if resume_id is not found.
List all education entries across all resumes, optionally filtered by institution, degree, or competency. Response includes total_count and items for pagination.
Output schemas not formally documented. While tools return structured data (model_dump()), the response field structure is not declared in docstrings or schema annotations. LLMs cannot plan downstream calls without knowing what fields to expect.
Enum constraints not documented in parameter descriptions. 'mode' parameter accepts 'and', 'or', 'regex' but descriptions only mention this in docstrings, not in the parameter description field. LLMs cannot reliably parse docstring text for constraints.
Inferred effective spec: <=2025-11-25.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 63 | <=2025-11-25 | v2 |
Rank resumes against a job description using a hybrid ATS-style scoring model. Combines skill matching (fuzzy, with alias resolution) and keyword matching. Returns resumes sorted by overall_score (descending), with per-resume skill and keyword breakdowns.
List resumes as lightweight identity records — id, name, email, phone only. Use this to orient and pick a resume_id before fetching details with other tools. Much more token-efficient than list_resumes when you only need to identify who is present. Pass query to filter by first or last name (absorbs the old search_resumes_by_name tool). Response includes total_count and items for pagination.
List all documents. When doc_type is 'resume' (or omitted), structured resume data is returned if available; otherwise flat file metadata is returned. Response includes total_count and items for pagination. See also: list_resume_summaries for a lighter-weight, more token-efficient listing; get_resume_full for one resume's full nested structure by resume_id.
List all side projects across all resumes, optionally filtered by project name or description. Response includes total_count and items for pagination.
List all badge skills across all resumes, optionally filtered by skill name. Response includes total_count and items for pagination.
List all work experiences across all resumes, optionally filtered by company name or position title. Response includes total_count and items for pagination.
Search across all documents for a keyword or phrase. Response includes total_count, items, has_more, next_offset, and message for pagination.
Find which resumes list one or more given badge skills. Returns resume identity and matched skill names only — more token-efficient than list_resumes when filtering by skill.
Minimal error recovery guidance. Only get_resume_profile and get_resume_full return explicit error objects. Other tools (search_resumes, list_work_experiences, etc.) do not document what happens on failure or how to recover. No actionable error messages.
get_collection_stats has minimal description (70 chars). Does not explain what 'aggregate statistics' means, what fields are returned, or when to call it. Lacks context for LLM selection.
No batch variants for common multi-item operations. Agents calling list_work_experiences in a loop for each resume waste tokens. A batch_get_resumes or similar would improve efficiency.