{"name":"io.github.work0r-ai/workorai","slug":"work0r-ai-workorai","title":null,"description":"WorkorAI talent marketplace MCP: candidate job search and employer hiring with explainable matching","url":"https://mcp.market/server/work0r-ai-workorai","rating":null,"grade":"B","score":76,"certified":false,"status":"active","category":"search","tags":["search"],"presence":{"score":15,"stars":0,"forks":0,"downloads_week":null,"last_push_at":"2026-07-04T04:34:05.000Z","license":"MIT"},"uptime":{"percent":100,"checks":28,"ok":28,"last_checked_at":"2026-11-04T10:30:25.693Z","last_ok_at":"2026-11-04T10:30:25.693Z","latency_ms":105},"claimed":false,"transport":"remote","callable_via_gateway":true,"default_price_micros":0,"repository":"https://github.com/work0r-ai/agent-kit","website":null,"version":"0.4.3","remotes":[{"type":"streamable-http","url":"https://workorai.com/mcp"}],"packages":[],"tools":[{"name":"candidate.accept_invitation","description":"Accept an employer's invitation to a job (INVITED -> APPLIED). Idempotent — accepting an already-accepted invite succeeds. Returns NOT_INVITED when there is no open invitation (e.g. already withdrawn/declined), and NOT_FOUND when the job/invite is not found or the job is no longer public.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"candidate.apply_to_job","description":"Apply the candidate to a PUBLISHED job, reusing their evaluated profile interview as evidence. Idempotent (re-applying succeeds; `reused` is true when an application row already existed). Requires a completed + evaluated interview — otherwise returns GATE_LOCKED / GATE_EVALUATING / GATE_FAILED. A missing or non-public job returns NOT_FOUND.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"candidate.decline_invitation","description":"Decline an employer's invitation to a job (INVITED -> DECLINED). TERMINAL — a declined invite blocks any re-invite from the employer, so only decline when the candidate is sure. Idempotent (declining again succeeds). Returns NOT_INVITED when there is no open invitation, NOT_FOUND when the job/invite is not found.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"candidate.get_applications","description":"List the candidate's own job applications (newest first) with status, dates, the originating interview score, and a job summary. Returns only the caller's applications — no jobId input, so it is not an enumeration surface.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."}},"additionalProperties":false}},{"name":"candidate.get_job","description":"Fetch a single published job by id.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"candidate.get_saved_jobs","description":"List the candidate's saved (bookmarked) jobs, newest first. Only currently PUBLISHED jobs are returned — a job saved earlier then closed/archived is omitted.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."}},"additionalProperties":false}},{"name":"candidate.search_jobs","description":"Semantically rank published jobs against the authenticated candidate profile (embedding-based fit). Optional tier (best|good|weak) narrows to a match-quality band — start with tier:'best' for the strongest fits and cascade only if needed; omit for the full ranked list (read tierCounts for the band sizes). Each scored row carries matchExplanation (the white-box 'why': fit score, the candidate's skills that match the job's required set, and a rationale). A free-text `q`, or a candidate who has not completed an interview yet, instead browses published jobs by recency — those rows carry NO fit score (`matchScore` is `null`, no bands); treat them as a browse list, not a ranking.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"q":{"type":"string"},"workModel":{"type":"string","enum":["REMOTE","HYBRID","ON_SITE"]},"seniority":{"type":"string","enum":["INTERN","JUNIOR","MIDDLE","SENIOR","LEAD","PRINCIPAL"]},"jobType":{"type":"string","enum":["FULL_TIME","PART_TIME","CONTRACT","FREELANCE"]},"limit":{"type":"number"},"offset":{"type":"number"},"tier":{"type":"string","enum":["best","good","weak"],"description":"Match-quality band. Omit for the full ranked list. START with tier:\"best\" (strongest fits), cascade to \"good\"/\"weak\" only if you need more; read tierCounts to decide. Ignored on a free-text q / no-interview browse (no bands)."}},"additionalProperties":false}},{"name":"candidate.set_saved_job","description":"Set whether a PUBLISHED job is in the candidate's saved list (idempotent desired-state, NOT a toggle — pass saved:true to bookmark, saved:false to remove). Returns NOT_FOUND for a missing or non-public job.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"},"saved":{"type":"boolean","description":"Desired saved state. true bookmarks the job, false removes the bookmark. Idempotent — a retry never flips the state."}},"required":["jobId","saved"],"additionalProperties":false}},{"name":"candidate.withdraw_application","description":"Withdraw the candidate's active application to a job (APPLIED -> WITHDRAWN). Idempotent (withdrawing again succeeds). Returns NOT_APPLIED when there is no active application (e.g. only an open invitation, or already declined), and NOT_FOUND when no application exists for the job.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"employer.archive_job","description":"Transition a CLOSED job to ARCHIVED. Returns NOT_FOUND for missing or non-owner jobs and CONFLICT when the job is not in CLOSED.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"employer.cancel_invitation","description":"Cancel a pending invitation sent to a candidate. The invitation record is deleted; the employer can re-invite the same candidate later.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Employer MCP API key"},"jobId":{"type":"string","description":"The job the invitation belongs to"},"candidateUserId":{"type":"string","description":"The candidate whose invitation to cancel"}},"required":["jobId","candidateUserId"],"additionalProperties":false}},{"name":"employer.close_job","description":"Transition a PUBLISHED job to CLOSED. Returns NOT_FOUND for missing or non-owner jobs and CONFLICT when the job is not in PUBLISHED.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"employer.create_job","description":"Parse raw text via Gemini AI and create a DRAFT job under the current employer. Synchronous: latency 5-30s. The agent can then call employer.update_job to refine fields and employer.publish_job to make it live.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"rawText":{"type":"string","description":"Free-form job description (up to 10000 characters). Parsed by Gemini AI; the call typically takes 5-30 seconds. On a client-side timeout, recover by calling employer.list_jobs with status=DRAFT and pick the most recent row."}},"required":["rawText"],"additionalProperties":false}},{"name":"employer.delete_job","description":"Permanently delete a DRAFT job that was never published. Returns NOT_FOUND for missing or non-owner jobs and CONFLICT when the job is not in DRAFT.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"employer.get_applicant_detail","description":"Full applicant bundle: resume, interview light slice (overallScore + summary + facts), GitHub analysis, LinkedIn analysis. The verbatim transcript is delivered by employer.get_applicant_transcript; the resume's contact fields are blanked unless the application is SHORTLISTED or HIRED.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string"},"applicationId":{"type":"string"}},"required":["applicationId"],"additionalProperties":false}},{"name":"employer.get_applicant_transcript","description":"Verbatim interview transcript for one applicant. Ownership-only gate (same as the UI Download button — no SHORTLISTED/HIRED requirement). Returns an empty array when the source interview never produced turns.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string"},"applicationId":{"type":"string"}},"required":["applicationId"],"additionalProperties":false}},{"name":"employer.get_candidate","description":"Fetch a discoverable candidate by user id. Returns search-entry shape plus a light interview slice (overallScore + summary + completedAt + evaluatedAt) and `existingApplications`: every JobApplication this candidate has on any of the employer's jobs (all 4 statuses, all 4 job statuses) so the agent can decide whether re-inviting will succeed. Heavy artefacts (transcript, facts, resume, github, linkedin) live behind employer.get_applicant_detail and require an application.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string"},"userId":{"type":"string"}},"required":["userId"],"additionalProperties":false}},{"name":"employer.get_candidate_evidence","description":"Fetch the interview EVIDENCE (facts proven in the interview + their Q&A, the interview summary, the résumé summary, and GitHub/LinkedIn signals) for ONE candidate AGAINST one of your published jobs — the white-box basis to explain WHY a candidate ranks where they do. Use it AFTER search_candidates_for_job: shortlist with the scorecard, then read the evidence here for the few you care about and write your own comparative review. Returns NOT_FOUND if the job is missing / not yours / not published, or the candidate is not in that job's searchable pool.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string"},"jobId":{"type":"string","description":"One of YOUR published vacancies — the evidence is scoped to it (must-linked facts use its required skills)."},"userId":{"type":"string","description":"A candidate from search_candidates_for_job for THIS jobId. The interview evidence to explain your ranking."}},"required":["jobId","userId"],"additionalProperties":false}},{"name":"employer.get_job","description":"Fetch a single employer job record by id. Returns NOT_FOUND for missing jobs and for jobs owned by another employer (no existence leak).","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"employer.invite_candidate","description":"Invite a discoverable candidate to one of the employer's PUBLISHED jobs. Creates a JobApplication with status=INVITED. If a prior WITHDRAWN row exists for this (candidate, job) pair, the row is UPDATEd back to INVITED (re-invite is allowed after the candidate withdrew on their own). INVITED, APPLIED, and DECLINED rows still block with INVITE_BLOCKED: INVITE_NOT_ALLOWED. Inspect `existingApplications` on employer.get_candidate before calling to know which case applies. Returns INVITE_BLOCKED with one of several sub-reasons (JOB_NOT_FOUND, JOB_NOT_PUBLISHED, CANDIDATE_NOT_FOUND, NOT_DISCOVERABLE, INVITE_NOT_ALLOWED) when the invite cannot be created. A missing vacancy and a vacancy owned by another employer both return JOB_NOT_FOUND (you cannot tell them apart — anti-enumeration).","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string"},"jobId":{"type":"string"},"candidateUserId":{"type":"string"}},"required":["jobId","candidateUserId"],"additionalProperties":false}},{"name":"employer.list_applicants","description":"List the live (APPLIED) applicants on one of the employer's jobs. The candidate showcase + interview overallScore/summary are always returned; contact fields are only included when the application is SHORTLISTED or HIRED.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string"},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"employer.list_invitations","description":"List the pending (INVITED) candidates on one of the employer's jobs — candidates who have been invited but have not yet accepted or declined.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Employer MCP API key"},"jobId":{"type":"string","description":"The job to list invitations for"}},"required":["jobId"],"additionalProperties":false}},{"name":"employer.list_jobs","description":"List jobs owned by the current employer account.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"status":{"oneOf":[{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED","ARCHIVED"]},{"type":"array","items":{"type":"string","enum":["DRAFT","PUBLISHED","CLOSED","ARCHIVED"]}}]},"limit":{"type":"number"},"offset":{"type":"number"}},"additionalProperties":false}},{"name":"employer.publish_job","description":"Transition a DRAFT job to PUBLISHED. Returns NOT_FOUND for missing or non-owner jobs and CONFLICT when the job is not in DRAFT.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"}},"required":["jobId"],"additionalProperties":false}},{"name":"employer.search_candidates_by_query","description":"Free-form semantic search across discoverable (interviewed) candidates with no job context. The query is embedded and candidates are ranked by semantic similarity — a preliminary search with no per-vacancy fit score (there is no vacancy to fit). For a scored ranking, use employer.search_candidates_for_job with a job id.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string"},"query":{"type":"string","maxLength":512},"page":{"type":"number"},"pageSize":{"type":"number"}},"required":["query"],"additionalProperties":false}},{"name":"employer.search_candidates_for_job","description":"Semantically rank discoverable (interviewed) candidates against one of the employer's own jobs, with a per-candidate fit score AND a white-box explanation. WORKFLOW for finding the best hire: 1) call with tier:'best' to get the strongest candidates (cover the required skills + proven in interview), cascade to tier:'good' then tier:'weak' only if you need more (read tierCounts to decide; paginate within a band via page.hasMore, not page.total); 2) each row carries matchExplanation — the white-box 'why' (the fit score, the skills the candidate PROVED in their interview, what they're missing, and a plain-English rationale) — use it to explain your shortlist on OUR data, not a black box; 3) for the few you shortlist, call employer.get_candidate_evidence(jobId, userId) for the interview facts + Q&A to write a deeper comparative review. Omit tier for the full ranked pool (back-compat). Returns NOT_FOUND when the job is missing / owned by another employer (no existence leak), or NOT_INDEXED / NO_CATEGORIES when the job is not indexed for semantic search yet (re-save / republish, then retry).","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string"},"jobId":{"type":"string"},"sort":{"type":"string","enum":["bestMatch","newest"]},"page":{"type":"number"},"pageSize":{"type":"number"},"tier":{"type":"string","enum":["best","good","weak"],"description":"Match-quality band (required-skill coverage + fit). Omit to get the full ranked pool. To shortlist, START with tier:\"best\" — the strongest candidates (cover the required skills, proven in interview); only cascade to \"good\" then \"weak\" if you need more. Read tierCounts to decide; paginate within a band using page.hasMore (NOT page.total, which is the full pool). Each row carries matchExplanation (the white-box \"why\"); then call employer.get_candidate_evidence for the interview evidence to explain your ranking. Ignored on sort:\"newest\" (a recency browse has no bands → tierCounts bands are 0)."}},"required":["jobId"],"additionalProperties":false}},{"name":"employer.set_review_status","description":"Update the employer review state on an application (NEW / REVIEWING / SHORTLISTED / REJECTED / HIRED). SHORTLISTED and HIRED unlock the candidate's direct contact in subsequent list_applicants / get_applicant_detail calls. WITHDRAWN applications surface as CONFLICT.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string"},"applicationId":{"type":"string"},"reviewStatus":{"type":"string","enum":["NEW","REVIEWING","SHORTLISTED","REJECTED","HIRED"]}},"required":["applicationId","reviewStatus"],"additionalProperties":false}},{"name":"employer.update_job","description":"Update the fields of an existing employer job. Accepts a partial whitelist; rawInput and dataSource are not editable (the wrapper auto-flips dataSource to USER_EDITED on every agent update). Non-owner reads return NOT_FOUND.","write_action":true,"price_micros":0,"input_schema":{"type":"object","properties":{"apiKey":{"type":"string","description":"Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously."},"jobId":{"type":"string"},"fields":{"type":"object","properties":{"title":{"type":"string"},"seniority":{"type":"string","enum":["INTERN","JUNIOR","MIDDLE","SENIOR","LEAD","PRINCIPAL"]},"salary":{"type":"string"},"location":{"type":"string"},"workModel":{"type":"string","enum":["REMOTE","HYBRID","ON_SITE"]},"jobType":{"type":"string","enum":["FULL_TIME","PART_TIME","CONTRACT","FREELANCE"]},"description":{"type":"string"},"mustHaveSkills":{"type":"array","items":{"type":"string"}},"niceToHaveSkills":{"type":"array","items":{"type":"string"}},"perks":{"type":"array","items":{"type":"string"}},"responsibilities":{"type":"array","items":{"type":"string"}},"qualifications":{"type":"array","items":{"type":"string"}},"referralBonus":{"type":"number"}},"additionalProperties":false}},"required":["jobId","fields"],"additionalProperties":false}},{"name":"request_access","description":"Use when someone wants to find work/jobs (candidate) or hire/find candidates (employer) but the authenticated role tools are not usable yet. Explains role-specific onboarding (candidate profile interview, employer key generation), MCP key location, and next steps for both surfaces.","write_action":false,"price_micros":0,"input_schema":{"type":"object","properties":{"role":{"type":"string","enum":["CANDIDATE","EMPLOYER"]}},"additionalProperties":false}}],"scan":{"score":76,"grade":"B","scanned_at":"2026-09-26T11:38:17.110Z","report":{"scannerVersion":"0.1.9","scannedAt":"2026-09-26T11:38:17.007Z","components":{"code":{"score":-1,"max":25,"notes":["remote-only server, no package to scan"]},"reliability":{"score":20,"max":20,"notes":["remote reachable in 1294ms"]},"poisoning":{"score":15,"max":15,"notes":["29 tool descriptions checked"]},"auth":{"score":3,"max":15,"notes":["open endpoint exposes 6 write-action tools with no auth"]},"maintenance":{"score":12,"max":15,"notes":["last push 84 days ago"]},"identity":{"score":7,"max":10,"notes":["registry namespace matches repository owner"]}},"findings":[{"id":"auth.open-write","severity":"high","component":"auth","title":"Write-action tools reachable without authentication"}],"inputs":{"probes":[{"url":"https://workorai.com/mcp","reachable":true,"authRequired":false,"latencyMs":1294,"serverInfo":{"name":"workor-mcp","version":"0.1.0"}}],"packages":[],"repo":{"found":true,"owner":"work0r-ai","repo":"agent-kit","archived":false,"pushedAt":"2026-07-04T04:34:05Z","stars":0,"forks":0,"openIssues":0,"ownerType":"Organization","ownerAvatarUrl":"https://avatars.githubusercontent.com/u/257310036?v=4","ownerCreatedAt":"2026-01-26T13:30:22Z","license":"MIT"},"icon":{"url":"https://workorai.com/favicon.ico","source":"site","width":48,"height":48},"presence":{"stars":0,"forks":0,"downloadsWeek":null,"license":"MIT","lastPushAt":"2026-07-04T04:34:05.000Z","score":15}}}},"grade_history":[],"reviews":[]}