Add comprehensive Application Tracker REST and MCP coverage, document the MCP workflow, add Markdown/ActionLint checks, bump the release version, and fill all extracted translations.
10 KiB
Application Tracker REST and MCP Parity
Status
Approved design for implementation planning. Campaign tracking is out of scope because the current app, database schema, changelog, guides, and tests do not ship a campaign field or campaign endpoint.
Goal
Make every shipped Application Tracker capability available outside the web UI through:
- the public REST/OpenAPI surface under
/api/openapi; - Reactive Resume MCP tools for agent-only workflows;
- the bundled
resume-builderskill, so agents know the application tracker tools exist.
The result should let a user track applications through an MCP client alone: create records, import existing rows, move stages, log notes, manage contacts and follow-ups, attach sent documents, run AI copilot actions, and inspect pipeline health.
Current Shipped Capabilities
The current application tracker supports:
- application records with company, role, location, salary, source, source URL, job description, notes, tags, status, archive state, linked resume, sent resume PDF, cover-letter PDF, contacts, follow-up date/note, applied date, and activity timeline;
- fixed stages:
saved,applied,screening,interview,offer,rejected; - create, edit, archive/unarchive, mark rejected, move stage, delete;
- board, table, search, sort, tag filter, archived toggle, and command-palette open/create shortcuts;
- bulk table actions: move stage, add tag, archive, delete;
- CSV import with header mapping and a 500-row cap;
- insights from aggregate stage/source counts plus client-derived weekly application velocity;
- timeline notes and automatic created/stage activity entries;
- contacts embedded on each application;
- Application Copilot actions: job-posting autofill, resume match score, tailored resume copy, cover-letter draft, follow-up draft;
- PDF upload/remove for resume file and cover letter through the generic storage route.
Existing API Coverage
The app already routes most behavior through packages/api/src/features/applications:
list,getById,create,import,update,addNote,delete;bulkUpdate,bulkDelete,stats,tags;ai.autofill,ai.matchScore,ai.draftMessage,ai.tailorResume.
These procedures are already authenticated and user-scoped through protectedProcedure and applicationService. The implementation should reuse them instead of adding a parallel controller or new business layer.
REST Design
Keep the existing application procedures and improve parity with the public OpenAPI surface.
Public Application Endpoints
Existing endpoints remain:
GET /applicationsGET /applications/{id}POST /applicationsPOST /applications/importPUT /applications/{id}POST /applications/{id}/notesDELETE /applications/{id}POST /applications/bulk-updatePOST /applications/bulk-deleteGET /applications/statsGET /applications/tagsPOST /applications/ai/autofillPOST /applications/{id}/ai/match-scorePOST /applications/{id}/ai/draft-messagePOST /applications/{id}/ai/tailor-resume
Add public document endpoints under the Applications tag:
POST /applications/{id}/documents/{kind}wherekindisresumeorcover-letter.- Accept a PDF file via OpenAPI file upload.
- Store through the existing storage service.
- Update only the matching application fields:
- resume:
resumeFileUrl,resumeFileName; - cover letter:
coverLetterUrl,coverLetterName.
- resume:
- Return the updated application.
DELETE /applications/{id}/documents/{kind}.- Delete the owned storage object best-effort.
- Clear only the matching application fields.
- Return the updated application.
This makes the document upload/remove UI available through public REST without exposing the generic storage route, which remains tagged Internal because it also serves profile-picture use cases.
REST Behavior Details
- Use existing ownership checks: every application mutation must be scoped by
userId. - Reject non-PDF document uploads, matching the UI.
- Keep file size at the existing storage limit: 10MB.
- Preserve existing delete cleanup for uploaded documents when an application is deleted.
- Do not add server-side search/sort endpoints for board/table parity. The UI derives search and sort from
list, and external clients can do the same.listalready exposes status, tags, and archive filtering. - Do not add campaign fields or endpoints.
- Regenerate or update
docs/spec.jsonso the public API reference includes all application endpoints.
MCP Design
Add application tools to packages/mcp using the existing metadata pattern:
- add names to
MCP_TOOL_NAME; - add schemas/descriptions to
TOOL_META; - add behavior hints to
TOOL_ANNOTATIONS; - register handlers in
registerTools; - let
buildMcpServerCardderive tool entries fromTOOL_META; - add focused tests so tool registration, annotations, and server card stay synchronized.
All MCP handlers should call the injected in-process oRPC RouterClient. They should not import database code or reimplement ownership checks.
MCP Tools
Read/discovery:
list_applications: list applications, with optionalstatus,tags, andincludeArchived.read_application: read one full application by ID.list_application_tags: list distinct tags.get_application_stats: return aggregate stage/source counts.
Write:
create_application: create an application.update_application: update editable fields, including stage, archive state, contacts, follow-up, tags, linked resume, source URL, job description, notes, and document URLs.add_application_note: append a timeline note.delete_application: permanently delete one application.bulk_update_applications: move, archive/unarchive, or add tags to multiple applications.bulk_delete_applications: permanently delete multiple applications.import_applications: bulk-create parsed application rows, matching the RESTimportshape.attach_application_document: attach a sent resume or cover letter PDF.remove_application_document: remove a sent resume or cover letter PDF.
AI:
autofill_application_from_job: extract company, role, location, salary, and job description from a job posting URL or pasted job description.score_application_match: score the linked resume against the job description and persist match metadata.tailor_resume_for_application: create and link a tailored resume copy.draft_application_message: draft either a cover letter or follow-up message.
MCP Attachment Input
attach_application_document should support agent-only use. The tool should accept:
id;kind:resumeorcover-letter;fileName;contentType:application/pdf;dataBase64: PDF bytes encoded as base64.
The handler can decode the base64 and call the same shared application-document service used by the public REST file upload. This avoids forcing MCP clients to provide browser File objects while still giving agents the same document capability as the UI.
MCP Output Shape
Prefer JSON text outputs for data-bearing tools. Human-readable success strings are fine for destructive/simple tools only when no structured data is useful. For create/update/read/list/stats/AI tools, return JSON so agents can chain calls reliably.
Tool Annotations
- Read tools: read-only, idempotent, non-destructive.
- AI generation tools:
autofill_application_from_jobis read-only but non-idempotent if it fetches a URL or calls AI.draft_application_messageis read-only but non-idempotent.score_application_matchandtailor_resume_for_applicationare write, non-idempotent.
- Delete tools are destructive.
update_application,bulk_update_applications, and document remove are write/idempotent when the same input repeats, except tag append remains effectively idempotent because the service de-duplicates tags.create_application,import_applications, note append, and document attach are write/non-idempotent.openWorldHintshould befalsefor closed account data tools andtrueonly for job-posting autofill because it can fetch an external URL.
Skill Update
Update skills/resume-builder/SKILL.md in place.
Add concise guidance that Reactive Resume MCP can manage applications as well as resumes. The skill should tell agents:
- use application tools when the user wants to track job applications, import a spreadsheet, move an opportunity through stages, add notes/contacts/follow-ups, attach sent documents, or use Application Copilot;
- use
list_applicationsbefore acting on existing records; - use
create_applicationorimport_applicationsfor new records; - use
tailor_resume_for_applicationafter a linked resume and job description exist; - review AI-generated cover letters and follow-ups before sending.
Do not turn the skill into a full API reference. Keep it short and point agents at MCP tools by name.
Documentation Updates
Update:
docs/guides/using-the-mcp-server.mdx: add Application Tracker tools, examples, and troubleshooting notes.docs/use-cases/api-mcp-resume-automation.mdx: expand scope from resume-only automation to resume plus application tracking.docs/spec.json: refresh the public OpenAPI spec so docs show application routes.
The existing job application and CSV guides already describe the UI behavior accurately and should not need broad rewrites.
Testing Plan
Focused tests:
- API/service tests for attaching/removing resume and cover-letter documents, including ownership and storage cleanup.
- DTO/router tests for application document upload constraints if the route logic is not already covered through service tests.
- MCP tests that:
- every
MCP_TOOL_NAMEhas metadata and annotations; - server card includes the new tools;
registerToolsregisters application tools;- one read handler and one write handler call the expected oRPC client procedure;
- base64 document attachment rejects non-PDF input.
- every
Validation commands:
pnpm --filter @reactive-resume/api testpnpm --filter @reactive-resume/mcp testpnpm --filter @reactive-resume/api typecheckpnpm --filter @reactive-resume/mcp typecheckpnpm exec turbo boundaries- a focused Biome check on touched files; use a non-mutating check first unless formatting edits are intentionally being applied.
Non-Goals
- Custom stages.
- Campaign tracking.
- Server-side board/search/sort endpoints.
- A standalone application schema resource in MCP.
- New dependencies.
- Refactoring the application tracker UI.