Skip to content

Feature request: read/list access to saved jobs, plus the ability to act on existing records #114

Description

@upendedshark

Summary

The JobSync MCP server currently only supports writing jobs (add_job, add_jobs_batch, update_job) and looking up a single job if you already have its exact posting URL (find_job). There's no way for an MCP client to browse, filter, or query the set of jobs already saved in JobSync. This makes it impossible to do basic tracking/triage work — e.g. "which jobs in the Netherlands haven't been applied to yet" — without leaving the assistant and checking the app directly.

Current limitations

  • No list_jobs / search_jobs tool exists. The only read path is find_job(jobUrl), which requires the caller to already know the exact posting URL.
  • There's no way to query by status, country/location, company, tag, or match score.
  • Jobs created through the JobSync web app (rather than via MCP) are explicitly reported as not editable via MCP (update_job is rejected for them) — even though find_job can still surface their id, title, and status.
  • There's no tool to persist a cover letter against a job record — cover letters have to live outside JobSync entirely (as separate documents), so they're not visible next to the job the way a match analysis is.
  • No pagination or bulk-read pattern exists at all, since there's no listing endpoint to paginate.

Requested capability

  1. list_jobs (or search_jobs) — return jobs matching optional filters:
    • status (new / draft / applied / interview / offer / rejected / expired / archived)
    • location / country (free-text or structured match)
    • company
    • tags
    • hasMatchScore (boolean) / matchScoreRange
    • appliedDateRange / createdDateRange
    • Pagination (cursor/limit or offset/limit)
    • Returns at minimum: jobId, company, jobTitle, location, status, matchScore, appliedDate, jobUrl, whether it was created via MCP or the web app.
  2. get_job(jobId) — fetch full detail for a single job by id (not just by URL), including the full stored description, saved match analysis, and any saved cover letter text. Useful once a job id is known from list_jobs without needing the original URL again.
  3. Remove (or explain/relax) the "web-app-created jobs can't be updated via MCP" restriction. At minimum, allow update_job to work on any job the account owns regardless of how it was created — or if there's a real technical reason for the split (e.g. different storage schema), expose a way to at least append a match analysis or cover letter to those records too, since save_match_result currently isn't blocked for them but the ordinary edit path is.
  4. save_cover_letter(jobId, coverLetterText) — a save/persist tool mirroring save_match_result, so a drafted cover letter is stored against the job record and visible in the app, instead of only existing as an external document. Ideally support versioning if a cover letter is redrafted.
  5. A lightweight set_status(jobId, status) convenience wrapper — not strictly necessary since update_job already supports a status field, but worth considering alongside the above if a lower-friction, single-purpose tool is preferred for the common "mark this applied/interview/rejected" action.

Example use cases this unblocks

  • "Which jobs in the Netherlands are still unapplied?" → list_jobs({ location: "Netherlands", status: "new" })
  • "Show me every job scoring above 70 that I haven't drafted a cover letter for yet" → list_jobs({ matchScoreRange: [70, 100] }) cross-referenced against cover-letter presence from get_job
  • "Write cover letters for all my open Australian applications" → list, then iterate and save_cover_letter for each
  • "I edited a job in the app, can you rescan and rescore it?" → get_job(jobId) to pull current state without needing the original URL again

Priority

This is the single biggest gap in an otherwise solid MCP surface for job-search tracking — without it, any assistant using JobSync via MCP is limited to acting on jobs the user explicitly names or links, and can never answer aggregate/status questions about the pipeline as a whole.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions