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
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.
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.
- 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.
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.
- 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.
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
list_jobs/search_jobstool exists. The only read path isfind_job(jobUrl), which requires the caller to already know the exact posting URL.update_jobis rejected for them) — even thoughfind_jobcan still surface their id, title, and status.Requested capability
list_jobs(orsearch_jobs) — return jobs matching optional filters:status(new / draft / applied / interview / offer / rejected / expired / archived)location/country(free-text or structured match)companytagshasMatchScore(boolean) /matchScoreRangeappliedDateRange/createdDateRangecursor/limitoroffset/limit)jobId,company,jobTitle,location,status,matchScore,appliedDate,jobUrl, whether it was created via MCP or the web app.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 fromlist_jobswithout needing the original URL again.update_jobto 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, sincesave_match_resultcurrently isn't blocked for them but the ordinary edit path is.save_cover_letter(jobId, coverLetterText)— a save/persist tool mirroringsave_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.set_status(jobId, status)convenience wrapper — not strictly necessary sinceupdate_jobalready supports astatusfield, 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
list_jobs({ location: "Netherlands", status: "new" })list_jobs({ matchScoreRange: [70, 100] })cross-referenced against cover-letter presence fromget_jobsave_cover_letterfor eachget_job(jobId)to pull current state without needing the original URL againPriority
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.