MCP 服务器

workorai

io.github.work0r-ai/workorai
商业与运营 公开且可连接 MCP 2025-11-25

此 MCP 可以做什么

Supports a talent marketplace with job search, candidate matching, applications, invitations, hiring workflows, interviews, and explainable recruiting decisions.

candidate.accept_invitation
Accept invitation
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.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'status': {'type': 'string'}}, 'additionalProperties': False}
candidate.apply_to_job
Apply to job
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.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'reused': {'type': 'boolean'}, 'status': {'type': 'string'}, 'applicationId': {'type': 'string'}}, 'additionalProperties': False}
candidate.decline_invitation
Decline invitation
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.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'status': {'type': 'string'}}, 'additionalProperties': False}
candidate.get_applications
Get applications
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.
输入模式
{'type': 'object', 'properties': {'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'applications': {'type': 'array', 'items': {'type': 'object', 'properties': {'job': {'type': 'object'}, 'jobId': {'type': 'string'}, 'status': {'type': 'string'}, 'appliedAt': {'type': 'string', 'format': 'date-time'}, 'withdrawnAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'interviewScore': {'type': ['number', 'null']}, 'interviewEvaluationStatus': {'type': ['string', 'null']}}, 'additionalProperties': False}}}, 'additionalProperties': False}
candidate.get_job
Get job
Fetch a single published job by id.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'job': {'type': 'object'}}, 'additionalProperties': False}
candidate.get_saved_jobs
Get saved jobs
List the candidate's saved (bookmarked) jobs, newest first. Only currently PUBLISHED jobs are returned — a job saved earlier then closed/archived is omitted.
输入模式
{'type': 'object', 'properties': {'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'savedJobs': {'type': 'array', 'items': {'type': 'object', 'properties': {'jobId': {'type': 'string'}, 'title': {'type': 'string'}, 'salary': {'type': ['string', 'null']}, 'jobType': {'type': 'string'}, 'savedAt': {'type': 'string', 'format': 'date-time'}, 'location': {'type': ['string', 'null']}, 'seniority': {'type': 'string'}, 'workModel': {'type': 'string'}}, 'additionalProperties': False}}}, 'additionalProperties': False}
candidate.search_jobs
Search matched jobs
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.
输入模式
{'type': 'object', 'properties': {'q': {'type': 'string'}, 'tier': {'enum': ['best', 'good', 'weak'], 'type': 'string', '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).'}, 'limit': {'type': 'number'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}, 'offset': {'type': 'number'}, 'jobType': {'enum': ['FULL_TIME', 'PART_TIME', 'CONTRACT', 'FREELANCE'], 'type': 'string'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL'], 'type': 'string'}, 'workModel': {'enum': ['REMOTE', 'HYBRID', 'ON_SITE'], 'type': 'string'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'jobs': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'jobId': {'type': 'string'}, 'title': {'type': 'string'}, 'matchScore': {'type': ['number', 'null']}, 'matchReasons': {'type': 'array', 'items': {'type': 'string'}}, 'seniorityFit': {'type': 'string'}, 'matchExplanation': {'type': 'object', 'properties': {'score': {'type': 'number', 'description': 'The 0-100 job-fit score (same as matchScore).'}, 'rationale': {'type': 'string', 'description': 'A ready-to-quote plain-English sentence narrating the score (coverage, proof, any haircut).'}, 'web3Bonus': {'type': 'number'}, 'similarity': {'type': 'number', 'description': 'Calibrated semantic similarity to the role (0-100).'}, 'matchedMust': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Required skills the candidate HAS.'}, 'matchedNice': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Nice-to-have skills the candidate has.'}, 'missingMust': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Required skills the candidate is MISSING â\x80\x94 the gaps to probe.'}, 'missingNice': {'type': 'array', 'items': {'type': 'string'}}, 'reliability': {'type': 'number', 'description': 'How trustworthy the evidence is (0-100): a verified interview + corroborating GitHub/LinkedIn lift it.'}, 'mustCoverage': {'type': 'number', 'description': "Fraction (0-1) of the job's REQUIRED skills the candidate covers."}, 'niceCoverage': {'type': 'number'}, 'interviewScore': {'type': ['number', 'null'], 'description': 'Their overall interview score (0-100); null = no evaluated interview (use this, not verifiedSkills, to tell if they interviewed).'}, 'verifiedSkills': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Job-relevant skills the candidate PROVED in their interview â\x80\x94 the strongest signal; lead your explanation with these. Empty if none of their proven skills overlap THIS job (not the same as no interview â\x80\x94 check interviewScore).'}, 'verifiedUplift': {'type': 'number', 'description': 'Points the verified interview skills added to the score.'}, 'reliabilityValue': {'type': 'number', 'description': 'The winning spine value (0-100) before corroboration.'}, 'matchedNiceGroups': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Satisfied N-of-M nice-to-have groups, one label per coverage unit.'}, 'missingNiceGroups': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Unsatisfied N-of-M nice-to-have groups, one label per coverage unit.'}, 'reliabilitySource': {'type': 'string', 'description': "Which proof carried the reliability spine (e.g. 'interview', 'github')."}, 'interviewCompleted': {'type': 'boolean', 'description': 'false = the interview score comes from a partial/abandoned (early-exit) interview, already haircut-discounted â\x80\x94 flag it when justifying.'}}, 'description': 'White-box explanation of WHY this candidate ranks here â\x80\x94 quote it to justify your shortlist on our data, not a black box.'}, 'matchedMustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'missingMustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'matchedNiceToHaveSkills': {'type': 'array', 'items': {'type': 'string'}}}}}, 'page': {'type': 'object'}, 'filters': {'type': 'object'}, 'tierCounts': {'type': 'object', 'properties': {'best': {'type': 'number'}, 'good': {'type': 'number'}, 'weak': {'type': 'number'}, 'matched': {'type': 'number'}, 'unmatched': {'type': 'number'}}, 'description': "Band sizes for a tier cascade: matched = jobs covering >=1 required skill, unmatched = none; best/good/weak split the matched pool (all bands 0 on a free-text q / no-interview browse). Start at tier:'best', cascade if needed."}}, 'additionalProperties': False}
candidate.set_saved_job
Save / unsave job
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.
输入模式
{'type': 'object', 'required': ['jobId', 'saved'], 'properties': {'jobId': {'type': 'string'}, 'saved': {'type': 'boolean', 'description': 'Desired saved state. true bookmarks the job, false removes the bookmark. Idempotent â\x80\x94 a retry never flips the state.'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'saved': {'type': 'boolean'}}, 'additionalProperties': False}
candidate.withdraw_application
Withdraw application
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.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'status': {'type': 'string'}}, 'additionalProperties': False}
employer.archive_job
Archive job
Transition a CLOSED job to ARCHIVED. Returns NOT_FOUND for missing or non-owner jobs and CONFLICT when the job is not in CLOSED.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'job': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'perks': {'type': 'array', 'items': {'type': 'string'}}, 'title': {'type': 'string'}, 'salary': {'type': ['string', 'null']}, 'status': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}, 'company': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}}}, 'jobType': {'enum': ['FULL_TIME', 'PART_TIME', 'CONTRACT', 'FREELANCE'], 'type': 'string'}, 'closedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'location': {'type': ['string', 'null']}, 'rawInput': {'type': ['string', 'null']}, 'createdAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL'], 'type': 'string'}, 'updatedAt': {'type': 'string', 'format': 'date-time'}, 'viewCount': {'type': 'number'}, 'workModel': {'enum': ['REMOTE', 'HYBRID', 'ON_SITE'], 'type': 'string'}, 'dataSource': {'enum': ['USER_EDITED', 'AI_PARSED'], 'type': 'string'}, 'employerId': {'type': 'string'}, 'hiredCount': {'type': 'number'}, 'description': {'type': ['string', 'null']}, 'publishedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'referralBonus': {'type': ['number', 'null']}, 'mustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'qualifications': {'type': 'array', 'items': {'type': 'string'}}, 'applicationCount': {'type': 'number'}, 'niceToHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'responsibilities': {'type': 'array', 'items': {'type': 'string'}}}}}, 'additionalProperties': False}
employer.cancel_invitation
Cancel invitation
Cancel a pending invitation sent to a candidate. The invitation record is deleted; the employer can re-invite the same candidate later.
输入模式
{'type': 'object', 'required': ['jobId', 'candidateUserId'], 'properties': {'jobId': {'type': 'string', 'description': 'The job the invitation belongs to'}, 'apiKey': {'type': 'string', 'description': 'Employer MCP API key'}, 'candidateUserId': {'type': 'string', 'description': 'The candidate whose invitation to cancel'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'jobId': {'type': 'string'}, 'candidateUserId': {'type': 'string'}}, 'additionalProperties': False}
employer.close_job
Close job
Transition a PUBLISHED job to CLOSED. Returns NOT_FOUND for missing or non-owner jobs and CONFLICT when the job is not in PUBLISHED.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'job': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'perks': {'type': 'array', 'items': {'type': 'string'}}, 'title': {'type': 'string'}, 'salary': {'type': ['string', 'null']}, 'status': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}, 'company': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}}}, 'jobType': {'enum': ['FULL_TIME', 'PART_TIME', 'CONTRACT', 'FREELANCE'], 'type': 'string'}, 'closedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'location': {'type': ['string', 'null']}, 'rawInput': {'type': ['string', 'null']}, 'createdAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL'], 'type': 'string'}, 'updatedAt': {'type': 'string', 'format': 'date-time'}, 'viewCount': {'type': 'number'}, 'workModel': {'enum': ['REMOTE', 'HYBRID', 'ON_SITE'], 'type': 'string'}, 'dataSource': {'enum': ['USER_EDITED', 'AI_PARSED'], 'type': 'string'}, 'employerId': {'type': 'string'}, 'hiredCount': {'type': 'number'}, 'description': {'type': ['string', 'null']}, 'publishedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'referralBonus': {'type': ['number', 'null']}, 'mustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'qualifications': {'type': 'array', 'items': {'type': 'string'}}, 'applicationCount': {'type': 'number'}, 'niceToHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'responsibilities': {'type': 'array', 'items': {'type': 'string'}}}}}, 'additionalProperties': False}
employer.create_job
Create job
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.
输入模式
{'type': 'object', 'required': ['rawText'], '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.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'job': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'perks': {'type': 'array', 'items': {'type': 'string'}}, 'title': {'type': 'string'}, 'salary': {'type': ['string', 'null']}, 'status': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}, 'company': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}}}, 'jobType': {'enum': ['FULL_TIME', 'PART_TIME', 'CONTRACT', 'FREELANCE'], 'type': 'string'}, 'closedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'location': {'type': ['string', 'null']}, 'rawInput': {'type': ['string', 'null']}, 'createdAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL'], 'type': 'string'}, 'updatedAt': {'type': 'string', 'format': 'date-time'}, 'viewCount': {'type': 'number'}, 'workModel': {'enum': ['REMOTE', 'HYBRID', 'ON_SITE'], 'type': 'string'}, 'dataSource': {'enum': ['USER_EDITED', 'AI_PARSED'], 'type': 'string'}, 'employerId': {'type': 'string'}, 'hiredCount': {'type': 'number'}, 'description': {'type': ['string', 'null']}, 'publishedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'referralBonus': {'type': ['number', 'null']}, 'mustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'qualifications': {'type': 'array', 'items': {'type': 'string'}}, 'applicationCount': {'type': 'number'}, 'niceToHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'responsibilities': {'type': 'array', 'items': {'type': 'string'}}}}}, 'additionalProperties': False}
employer.delete_job
Delete job
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.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'jobId': {'type': 'string'}}, 'additionalProperties': False}
employer.get_applicant_detail
Get applicant detail
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.
输入模式
{'type': 'object', 'required': ['applicationId'], 'properties': {'apiKey': {'type': 'string'}, 'applicationId': {'type': 'string'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'detail': {'type': 'object', 'properties': {'jobId': {'type': 'string'}, 'github': {'type': ['object', 'null'], 'description': 'GitHub profile analysis blob from the WorkorAI profile-analyzer (~40 fields incl. repo summaries, language distribution, contribution stats). Treat as opaque; consult the workorai-agent-kit catalog or surface fields on demand.'}, 'resume': {'type': 'object', 'properties': {'awards': {'type': 'array', 'items': {'type': 'object', 'properties': {'title': {'type': 'string'}, 'issuer': {'type': 'string'}, 'awardDate': {'type': 'string'}, 'description': {'type': 'string'}}}}, 'skills': {'type': 'array', 'items': {'type': 'object', 'properties': {'skillName': {'type': 'string'}, 'proficiencyLevel': {'type': 'string'}}}}, 'projects': {'type': 'array', 'items': {'type': 'object', 'properties': {'projectUrl': {'type': 'string'}, 'description': {'type': 'string'}, 'projectName': {'type': 'string'}}}}, 'education': {'type': 'array', 'items': {'type': 'object', 'properties': {'grade': {'type': 'string'}, 'degree': {'type': 'string'}, 'endDate': {'type': 'string'}, 'startDate': {'type': 'string'}, 'schoolName': {'type': 'string'}, 'fieldOfStudy': {'type': 'string'}}}}, 'languages': {'type': 'array', 'items': {'type': 'object', 'properties': {'proficiency': {'type': 'string'}, 'languageName': {'type': 'string'}}}}, 'personalInfo': {'type': 'object', 'properties': {'city': {'type': 'string'}, 'email': {'type': 'string'}, 'phone': {'type': 'string'}, 'country': {'type': 'string'}, 'summary': {'type': 'string'}, 'headline': {'type': 'string'}, 'lastName': {'type': 'string'}, 'firstName': {'type': 'string'}, 'githubUrl': {'type': 'string'}, 'websiteUrl': {'type': 'string'}, 'linkedinUrl': {'type': 'string'}}, 'description': 'Contact fields (email, phone, linkedinUrl, githubUrl, websiteUrl) are blank strings when reviewStatus is below SHORTLISTED. firstName/lastName/city/country/headline/summary are always populated when present on the source resume.'}, 'publications': {'type': 'array', 'items': {'type': 'object', 'properties': {'url': {'type': 'string'}, 'title': {'type': 'string'}, 'publisher': {'type': 'string'}, 'description': {'type': 'string'}, 'publicationDate': {'type': 'string'}}}}, 'certifications': {'type': 'array', 'items': {'type': 'object', 'properties': {'name': {'type': 'string'}, 'issueDate': {'type': 'string'}, 'credentialUrl': {'type': 'string'}, 'expirationDate': {'type': 'string'}, 'issuingOrganization': {'type': 'string'}}}}, 'workExperience': {'type': 'array', 'items': {'type': 'object', 'properties': {'endDate': {'type': 'string'}, 'jobTitle': {'type': 'string'}, 'startDate': {'type': 'string'}, 'companyName': {'type': 'string'}, 'description': {'type': 'string'}, 'isCurrentRole': {'type': 'boolean'}}}}}, 'description': 'Resume data sanitized to remove server-local paths and internal flags. The personalInfo contact fields (email, phone, linkedinUrl, githubUrl, websiteUrl) are blanked when reviewStatus is below SHORTLISTED â\x80\x94 same contact-gating rule as the contact field on list_applicants.'}, 'status': {'enum': ['INVITED', 'APPLIED', 'WITHDRAWN', 'DECLINED'], 'type': 'string'}, 'jobTitle': {'type': 'string'}, 'linkedin': {'type': ['object', 'null'], 'description': 'LinkedIn profile analysis blob from the WorkorAI profile-analyzer (~30 fields incl. headline, experience entries, skill endorsements). Treat as opaque; consult the workorai-agent-kit catalog or surface fields on demand.'}, 'appliedAt': {'type': 'string', 'format': 'date-time'}, 'interview': {'type': ['object', 'null'], 'properties': {'facts': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'number'}, 'qas': {'type': 'array', 'items': {'type': 'object', 'properties': {'notes': {'type': ['string', 'null']}, 'score': {'type': ['number', 'null']}, 'answer': {'type': 'string'}, 'question': {'type': 'string'}}}}, 'name': {'type': 'string'}, 'notes': {'type': ['string', 'null']}, 'score': {'type': ['number', 'null']}, 'summary': {'type': 'string'}, 'expectedAnswer': {'type': 'string'}}}}, 'summary': {'type': ['string', 'null']}, 'completed': {'type': 'boolean', 'description': 'false = partial/abandoned interview (early exit); the score is a haircut-discounted partial signal'}, 'overallScore': {'type': ['number', 'null']}}, 'description': 'Interview overview minus transcript. Use employer.get_applicant_transcript for the verbatim conversation.'}, 'reviewStatus': {'enum': ['NEW', 'REVIEWING', 'SHORTLISTED', 'REJECTED', 'HIRED'], 'type': 'string'}, 'applicationId': {'type': 'string'}, 'resumeAvailable': {'type': 'boolean'}}}}, 'additionalProperties': False}
employer.get_applicant_transcript
Get applicant transcript
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.
输入模式
{'type': 'object', 'required': ['applicationId'], 'properties': {'apiKey': {'type': 'string'}, 'applicationId': {'type': 'string'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'transcript': {'type': 'array', 'items': {'type': 'object', 'properties': {'role': {'enum': ['assistant', 'user'], 'type': 'string'}, 'text': {'type': 'string'}}}}, 'applicationId': {'type': 'string'}}, 'additionalProperties': False}
employer.get_candidate
Get candidate
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.
输入模式
{'type': 'object', 'required': ['userId'], 'properties': {'apiKey': {'type': 'string'}, 'userId': {'type': 'string'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'candidate': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'skills': {'type': 'array', 'items': {'type': 'string'}}, 'summary': {'type': ['string', 'null']}, 'headline': {'type': ['string', 'null']}, 'location': {'type': ['string', 'null']}, 'avatarUrl': {'type': ['string', 'null']}, 'interview': {'type': ['object', 'null'], 'properties': {'summary': {'type': ['string', 'null']}, 'completed': {'type': 'boolean', 'description': 'false = partial/abandoned interview (early exit); the score is a haircut-discounted partial signal'}, 'completedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'evaluatedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'overallScore': {'type': ['number', 'null']}}}, 'invitedAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL', None], 'type': ['string', 'null']}, 'matchScore': {'type': 'number'}, 'displayName': {'type': 'string'}, 'applicationStatus': {'enum': ['INVITED', 'APPLIED', 'WITHDRAWN', 'DECLINED'], 'type': 'string'}, 'existingApplications': {'type': 'array', 'items': {'type': 'object', 'properties': {'jobId': {'type': 'string'}, 'status': {'enum': ['INVITED', 'APPLIED', 'WITHDRAWN', 'DECLINED'], 'type': 'string'}, 'jobTitle': {'type': 'string'}, 'createdAt': {'type': 'string', 'format': 'date-time'}, 'invitedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'jobStatus': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}, 'declinedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'withdrawnAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'applicationId': {'type': 'string'}}}, 'description': "Every JobApplication this candidate has on any of the employer's jobs (all 4 statuses, all 4 job statuses). Lets the agent decide whether re-inviting will succeed: WITHDRAWN allows re-invite (the service UPDATEs the row back to INVITED), DECLINED is terminal, INVITED is already pending acceptance, APPLIED means the candidate is already in the funnel."}, 'matchedMustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'missingMustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}}}}, 'additionalProperties': False}
employer.get_candidate_evidence
Get candidate interview evidence
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.
输入模式
{'type': 'object', 'required': ['jobId', 'userId'], 'properties': {'jobId': {'type': 'string', 'description': 'One of YOUR published vacancies â\x80\x94 the evidence is scoped to it (must-linked facts use its required skills).'}, 'apiKey': {'type': 'string'}, 'userId': {'type': 'string', 'description': 'A candidate from search_candidates_for_job for THIS jobId. The interview evidence to explain your ranking.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'evidence': {'type': 'object', 'properties': {'facts': {'type': 'array', 'items': {'type': 'object', 'properties': {'qas': {'type': 'array', 'items': {'type': 'object', 'properties': {'answer': {'type': 'string'}, 'question': {'type': 'string'}}}}, 'claim': {'type': 'string'}, 'factScore': {'type': ['number', 'null']}, 'mustLinked': {'type': 'boolean'}}}}, 'github': {'type': ['object', 'null'], 'properties': {'trustRank': {'type': 'number'}, 'web3Repos': {'type': 'number'}, 'mergedPrestigeLanguages': {'type': 'array', 'items': {'type': 'string'}}}}, 'headline': {'type': ['string', 'null']}, 'linkedin': {'type': ['object', 'null'], 'properties': {'recognizedCerts': {'type': 'number'}, 'historyCoherence': {'type': 'number'}}}, 'interview': {'type': ['object', 'null'], 'properties': {'summary': {'type': ['string', 'null']}, 'completed': {'type': 'boolean', 'description': 'false = partial/abandoned interview (early exit); the score is a haircut-discounted partial signal'}, 'interviewId': {'type': 'number'}, 'overallScore': {'type': ['number', 'null']}}}, 'truncation': {'type': 'array', 'items': {'type': 'string'}}, 'candidateId': {'type': 'string'}, 'resumeSummary': {'type': ['string', 'null']}, 'experienceYears': {'type': ['number', 'null']}}, 'additionalProperties': False}}, 'additionalProperties': False}
employer.get_job
Get job
Fetch a single employer job record by id. Returns NOT_FOUND for missing jobs and for jobs owned by another employer (no existence leak).
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'job': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'perks': {'type': 'array', 'items': {'type': 'string'}}, 'title': {'type': 'string'}, 'salary': {'type': ['string', 'null']}, 'status': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}, 'company': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}}}, 'jobType': {'enum': ['FULL_TIME', 'PART_TIME', 'CONTRACT', 'FREELANCE'], 'type': 'string'}, 'closedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'location': {'type': ['string', 'null']}, 'rawInput': {'type': ['string', 'null']}, 'createdAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL'], 'type': 'string'}, 'updatedAt': {'type': 'string', 'format': 'date-time'}, 'viewCount': {'type': 'number'}, 'workModel': {'enum': ['REMOTE', 'HYBRID', 'ON_SITE'], 'type': 'string'}, 'dataSource': {'enum': ['USER_EDITED', 'AI_PARSED'], 'type': 'string'}, 'employerId': {'type': 'string'}, 'hiredCount': {'type': 'number'}, 'description': {'type': ['string', 'null']}, 'publishedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'referralBonus': {'type': ['number', 'null']}, 'mustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'qualifications': {'type': 'array', 'items': {'type': 'string'}}, 'applicationCount': {'type': 'number'}, 'niceToHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'responsibilities': {'type': 'array', 'items': {'type': 'string'}}}}}, 'additionalProperties': False}
employer.invite_candidate
Invite candidate
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).
输入模式
{'type': 'object', 'required': ['jobId', 'candidateUserId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string'}, 'candidateUserId': {'type': 'string'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'status': {'type': 'string'}, 'applicationId': {'type': 'string'}}, 'additionalProperties': False}
employer.list_applicants
List applicants
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.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'jobId': {'type': 'string'}, 'applicants': {'type': 'array', 'items': {'type': 'object', 'properties': {'source': {'enum': ['APPLIED', 'INVITED'], 'type': 'string', 'description': 'APPLIED = candidate applied directly. INVITED = candidate accepted an invitation the employer had sent earlier (i.e. `invitedById` was set on the row).'}, 'status': {'enum': ['INVITED', 'APPLIED', 'WITHDRAWN', 'DECLINED'], 'type': 'string'}, 'contact': {'type': ['object', 'null'], 'properties': {'email': {'type': ['string', 'null']}, 'phone': {'type': ['string', 'null']}, 'githubUrl': {'type': ['string', 'null']}, 'websiteUrl': {'type': ['string', 'null']}, 'linkedinUrl': {'type': ['string', 'null']}}, 'description': 'Non-null only when reviewStatus is SHORTLISTED or HIRED (contact gating).'}, 'appliedAt': {'type': 'string', 'format': 'date-time'}, 'candidate': {'type': 'object', 'properties': {'userId': {'type': 'string'}, 'headline': {'type': ['string', 'null']}, 'location': {'type': ['string', 'null']}, 'avatarUrl': {'type': ['string', 'null']}, 'displayName': {'type': 'string'}}}, 'interview': {'type': 'object', 'properties': {'summary': {'type': ['string', 'null']}, 'completed': {'type': 'boolean', 'description': 'false = partial/abandoned interview (early exit); the score is a haircut-discounted partial signal'}, 'overallScore': {'type': ['number', 'null']}}}, 'jobFitScore': {'type': ['number', 'null'], 'description': 'Live job-fit score (0-100) from the matching combiner â\x80\x94 same engine as search_candidates_for_job. null if the job is not indexed yet.'}, 'reviewStatus': {'enum': ['NEW', 'REVIEWING', 'SHORTLISTED', 'REJECTED', 'HIRED'], 'type': 'string'}, 'applicationId': {'type': 'string'}, 'matchExplanation': {'type': ['object', 'null'], 'properties': {'score': {'type': 'number', 'description': 'The 0-100 job-fit score (same as matchScore).'}, 'rationale': {'type': 'string', 'description': 'A ready-to-quote plain-English sentence narrating the score (coverage, proof, any haircut).'}, 'web3Bonus': {'type': 'number'}, 'similarity': {'type': 'number', 'description': 'Calibrated semantic similarity to the role (0-100).'}, 'matchedMust': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Required skills the candidate HAS.'}, 'matchedNice': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Nice-to-have skills the candidate has.'}, 'missingMust': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Required skills the candidate is MISSING â\x80\x94 the gaps to probe.'}, 'missingNice': {'type': 'array', 'items': {'type': 'string'}}, 'reliability': {'type': 'number', 'description': 'How trustworthy the evidence is (0-100): a verified interview + corroborating GitHub/LinkedIn lift it.'}, 'mustCoverage': {'type': 'number', 'description': "Fraction (0-1) of the job's REQUIRED skills the candidate covers."}, 'niceCoverage': {'type': 'number'}, 'interviewScore': {'type': ['number', 'null'], 'description': 'Their overall interview score (0-100); null = no evaluated interview (use this, not verifiedSkills, to tell if they interviewed).'}, 'verifiedSkills': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Job-relevant skills the candidate PROVED in their interview â\x80\x94 the strongest signal; lead your explanation with these. Empty if none of their proven skills overlap THIS job (not the same as no interview â\x80\x94 check interviewScore).'}, 'verifiedUplift': {'type': 'number', 'description': 'Points the verified interview skills added to the score.'}, 'reliabilityValue': {'type': 'number', 'description': 'The winning spine value (0-100) before corroboration.'}, 'matchedNiceGroups': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Satisfied N-of-M nice-to-have groups, one label per coverage unit.'}, 'missingNiceGroups': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Unsatisfied N-of-M nice-to-have groups, one label per coverage unit.'}, 'reliabilitySource': {'type': 'string', 'description': "Which proof carried the reliability spine (e.g. 'interview', 'github')."}, 'interviewCompleted': {'type': 'boolean', 'description': 'false = the interview score comes from a partial/abandoned (early-exit) interview, already haircut-discounted â\x80\x94 flag it when justifying.'}}, 'description': 'White-box explanation of WHY this candidate ranks here â\x80\x94 quote it to justify your shortlist on our data, not a black box.'}}}}}, 'additionalProperties': False}
employer.list_invitations
List invitations
List the pending (INVITED) candidates on one of the employer's jobs — candidates who have been invited but have not yet accepted or declined.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string', 'description': 'The job to list invitations for'}, 'apiKey': {'type': 'string', 'description': 'Employer MCP API key'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'jobId': {'type': 'string'}, 'invitations': {'type': 'array', 'items': {'type': 'object', 'properties': {'candidate': {'type': 'object', 'properties': {'userId': {'type': 'string'}, 'headline': {'type': ['string', 'null']}, 'location': {'type': ['string', 'null']}, 'avatarUrl': {'type': ['string', 'null']}, 'displayName': {'type': 'string'}}}, 'invitedAt': {'type': 'string', 'format': 'date-time'}, 'applicationId': {'type': 'string'}}}}}, 'additionalProperties': False}
employer.list_jobs
List jobs
List jobs owned by the current employer account.
输入模式
{'type': 'object', 'properties': {'limit': {'type': 'number'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}, 'offset': {'type': 'number'}, 'status': {'oneOf': [{'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}, {'type': 'array', 'items': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}}]}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'jobs': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'perks': {'type': 'array', 'items': {'type': 'string'}}, 'title': {'type': 'string'}, 'salary': {'type': ['string', 'null']}, 'status': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}, 'jobType': {'enum': ['FULL_TIME', 'PART_TIME', 'CONTRACT', 'FREELANCE'], 'type': 'string'}, 'closedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'location': {'type': ['string', 'null']}, 'rawInput': {'type': ['string', 'null']}, 'createdAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL'], 'type': 'string'}, 'updatedAt': {'type': 'string', 'format': 'date-time'}, 'viewCount': {'type': 'number'}, 'workModel': {'enum': ['REMOTE', 'HYBRID', 'ON_SITE'], 'type': 'string'}, 'dataSource': {'enum': ['USER_EDITED', 'AI_PARSED'], 'type': 'string'}, 'employerId': {'type': 'string'}, 'hiredCount': {'type': 'number'}, 'description': {'type': ['string', 'null']}, 'publishedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'referralBonus': {'type': ['number', 'null']}, 'mustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'qualifications': {'type': 'array', 'items': {'type': 'string'}}, 'applicationCount': {'type': 'number'}, 'niceToHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'responsibilities': {'type': 'array', 'items': {'type': 'string'}}}}}, 'page': {'type': 'object', 'properties': {'limit': {'type': 'number'}, 'total': {'type': 'number'}, 'offset': {'type': 'number'}, 'hasMore': {'type': 'boolean'}}}, 'filters': {'type': 'object', 'properties': {'limit': {'type': 'number'}, 'offset': {'type': 'number'}, 'status': {'type': 'array', 'items': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}}}}}, 'additionalProperties': False}
employer.publish_job
Publish job
Transition a DRAFT job to PUBLISHED. Returns NOT_FOUND for missing or non-owner jobs and CONFLICT when the job is not in DRAFT.
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'job': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'perks': {'type': 'array', 'items': {'type': 'string'}}, 'title': {'type': 'string'}, 'salary': {'type': ['string', 'null']}, 'status': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}, 'company': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}}}, 'jobType': {'enum': ['FULL_TIME', 'PART_TIME', 'CONTRACT', 'FREELANCE'], 'type': 'string'}, 'closedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'location': {'type': ['string', 'null']}, 'rawInput': {'type': ['string', 'null']}, 'createdAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL'], 'type': 'string'}, 'updatedAt': {'type': 'string', 'format': 'date-time'}, 'viewCount': {'type': 'number'}, 'workModel': {'enum': ['REMOTE', 'HYBRID', 'ON_SITE'], 'type': 'string'}, 'dataSource': {'enum': ['USER_EDITED', 'AI_PARSED'], 'type': 'string'}, 'employerId': {'type': 'string'}, 'hiredCount': {'type': 'number'}, 'description': {'type': ['string', 'null']}, 'publishedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'referralBonus': {'type': ['number', 'null']}, 'mustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'qualifications': {'type': 'array', 'items': {'type': 'string'}}, 'applicationCount': {'type': 'number'}, 'niceToHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'responsibilities': {'type': 'array', 'items': {'type': 'string'}}}}}, 'additionalProperties': False}
employer.search_candidates_by_query
Search candidates by query
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.
输入模式
{'type': 'object', 'required': ['query'], 'properties': {'page': {'type': 'number'}, 'query': {'type': 'string', 'maxLength': 512}, 'apiKey': {'type': 'string'}, 'pageSize': {'type': 'number'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'page': {'type': 'object', 'properties': {'page': {'type': 'number'}, 'total': {'type': 'number'}, 'pageSize': {'type': 'number'}}}, 'jobId': {'type': ['string', 'null']}, 'query': {'type': 'string'}, 'reason': {'enum': ['NOT_INDEXED', 'NO_CATEGORIES'], 'type': 'string'}, 'entries': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'skills': {'type': 'array', 'items': {'type': 'string'}}, 'summary': {'type': ['string', 'null']}, 'headline': {'type': ['string', 'null']}, 'location': {'type': ['string', 'null']}, 'avatarUrl': {'type': ['string', 'null']}, 'invitedAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL', None], 'type': ['string', 'null']}, 'matchScore': {'type': 'number'}, 'displayName': {'type': 'string'}, 'applicationStatus': {'enum': ['INVITED', 'APPLIED', 'WITHDRAWN', 'DECLINED'], 'type': 'string'}, 'matchedMustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'missingMustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}}}}, 'tierCounts': {'type': 'object', 'properties': {'matched': {'type': 'number'}, 'unmatched': {'type': 'number'}}}}, 'additionalProperties': False}
employer.search_candidates_for_job
Search candidates for a job
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).
输入模式
{'type': 'object', 'required': ['jobId'], 'properties': {'page': {'type': 'number'}, 'sort': {'enum': ['bestMatch', 'newest'], 'type': 'string'}, 'tier': {'enum': ['best', 'good', 'weak'], 'type': 'string', 'description': 'Match-quality band (required-skill coverage + fit). Omit to get the full ranked pool. To shortlist, START with tier:"best" â\x80\x94 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 â\x86\x92 tierCounts bands are 0).'}, 'jobId': {'type': 'string'}, 'apiKey': {'type': 'string'}, 'pageSize': {'type': 'number'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'page': {'type': 'object', 'properties': {'page': {'type': 'number'}, 'total': {'type': 'number'}, 'hasMore': {'type': 'boolean'}, 'pageSize': {'type': 'number'}}}, 'jobId': {'type': ['string', 'null']}, 'reason': {'enum': ['NOT_INDEXED', 'NO_CATEGORIES'], 'type': 'string'}, 'entries': {'type': 'array', 'items': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'skills': {'type': 'array', 'items': {'type': 'string'}}, 'summary': {'type': ['string', 'null']}, 'headline': {'type': ['string', 'null']}, 'location': {'type': ['string', 'null']}, 'avatarUrl': {'type': ['string', 'null']}, 'invitedAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL', None], 'type': ['string', 'null']}, 'matchScore': {'type': 'number'}, 'displayName': {'type': 'string'}, 'matchExplanation': {'type': 'object', 'properties': {'score': {'type': 'number', 'description': 'The 0-100 job-fit score (same as matchScore).'}, 'rationale': {'type': 'string', 'description': 'A ready-to-quote plain-English sentence narrating the score (coverage, proof, any haircut).'}, 'web3Bonus': {'type': 'number'}, 'similarity': {'type': 'number', 'description': 'Calibrated semantic similarity to the role (0-100).'}, 'matchedMust': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Required skills the candidate HAS.'}, 'matchedNice': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Nice-to-have skills the candidate has.'}, 'missingMust': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Required skills the candidate is MISSING â\x80\x94 the gaps to probe.'}, 'missingNice': {'type': 'array', 'items': {'type': 'string'}}, 'reliability': {'type': 'number', 'description': 'How trustworthy the evidence is (0-100): a verified interview + corroborating GitHub/LinkedIn lift it.'}, 'mustCoverage': {'type': 'number', 'description': "Fraction (0-1) of the job's REQUIRED skills the candidate covers."}, 'niceCoverage': {'type': 'number'}, 'interviewScore': {'type': ['number', 'null'], 'description': 'Their overall interview score (0-100); null = no evaluated interview (use this, not verifiedSkills, to tell if they interviewed).'}, 'verifiedSkills': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Job-relevant skills the candidate PROVED in their interview â\x80\x94 the strongest signal; lead your explanation with these. Empty if none of their proven skills overlap THIS job (not the same as no interview â\x80\x94 check interviewScore).'}, 'verifiedUplift': {'type': 'number', 'description': 'Points the verified interview skills added to the score.'}, 'reliabilityValue': {'type': 'number', 'description': 'The winning spine value (0-100) before corroboration.'}, 'matchedNiceGroups': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Satisfied N-of-M nice-to-have groups, one label per coverage unit.'}, 'missingNiceGroups': {'type': 'array', 'items': {'type': 'string'}, 'description': 'Unsatisfied N-of-M nice-to-have groups, one label per coverage unit.'}, 'reliabilitySource': {'type': 'string', 'description': "Which proof carried the reliability spine (e.g. 'interview', 'github')."}, 'interviewCompleted': {'type': 'boolean', 'description': 'false = the interview score comes from a partial/abandoned (early-exit) interview, already haircut-discounted â\x80\x94 flag it when justifying.'}}, 'description': 'White-box explanation of WHY this candidate ranks here â\x80\x94 quote it to justify your shortlist on our data, not a black box.'}, 'applicationStatus': {'enum': ['INVITED', 'APPLIED', 'WITHDRAWN', 'DECLINED'], 'type': 'string'}, 'matchedMustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'missingMustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}}}}, 'advisory': {'type': 'object', 'properties': {'code': {'enum': ['EMPTY_BEST_REVIEW_MUST_HAVES'], 'type': 'string'}, 'message': {'type': 'string', 'description': 'Ready-to-relay plain-English advisory text.'}}, 'description': "OPTIONAL, present only when NO candidate reaches the Best tier for a constrained vacancy (best===0 but candidates exist below). A non-restrictive nudge to relay to the employer: the vacancy's must-have requirements may be strict enough that nobody is an exceptional match â\x80\x94 consider moving the less-critical must-haves to nice-to-have to widen the pool. A SUGGESTION, never an instruction to auto-edit the job."}, 'tierCounts': {'type': 'object', 'properties': {'best': {'type': 'number'}, 'good': {'type': 'number'}, 'weak': {'type': 'number'}, 'matched': {'type': 'number'}, 'unmatched': {'type': 'number'}}, 'description': "Band sizes to plan a tier cascade: matched = cover >=1 required skill, unmatched = cover none; best/good/weak split the matched pool (best+good+weak === matched on a scored search; all bands 0 on a newest browse). Use to decide whether to fetch tier:'best' then 'good'/'weak'."}}, 'additionalProperties': False}
employer.set_review_status
Set review status
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.
输入模式
{'type': 'object', 'required': ['applicationId', 'reviewStatus'], 'properties': {'apiKey': {'type': 'string'}, 'reviewStatus': {'enum': ['NEW', 'REVIEWING', 'SHORTLISTED', 'REJECTED', 'HIRED'], 'type': 'string'}, 'applicationId': {'type': 'string'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'reviewStatus': {'type': 'string'}, 'applicationId': {'type': 'string'}}, 'additionalProperties': False}
employer.update_job
Update job
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.
输入模式
{'type': 'object', 'required': ['jobId', 'fields'], 'properties': {'jobId': {'type': 'string'}, 'apiKey': {'type': 'string', 'description': 'Optional WorkorAI MCP key for in-session authentication when the MCP client was initialized anonymously.'}, 'fields': {'type': 'object', 'properties': {'perks': {'type': 'array', 'items': {'type': 'string'}}, 'title': {'type': 'string'}, 'salary': {'type': 'string'}, 'jobType': {'enum': ['FULL_TIME', 'PART_TIME', 'CONTRACT', 'FREELANCE'], 'type': 'string'}, 'location': {'type': 'string'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL'], 'type': 'string'}, 'workModel': {'enum': ['REMOTE', 'HYBRID', 'ON_SITE'], 'type': 'string'}, 'description': {'type': 'string'}, 'referralBonus': {'type': 'number'}, 'mustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'qualifications': {'type': 'array', 'items': {'type': 'string'}}, 'niceToHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'responsibilities': {'type': 'array', 'items': {'type': 'string'}}}, 'additionalProperties': False}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'ok': {'type': 'boolean'}, 'job': {'type': 'object', 'properties': {'id': {'type': 'string'}, 'perks': {'type': 'array', 'items': {'type': 'string'}}, 'title': {'type': 'string'}, 'salary': {'type': ['string', 'null']}, 'status': {'enum': ['DRAFT', 'PUBLISHED', 'CLOSED', 'ARCHIVED'], 'type': 'string'}, 'company': {'type': 'object', 'properties': {'name': {'type': ['string', 'null']}}}, 'jobType': {'enum': ['FULL_TIME', 'PART_TIME', 'CONTRACT', 'FREELANCE'], 'type': 'string'}, 'closedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'location': {'type': ['string', 'null']}, 'rawInput': {'type': ['string', 'null']}, 'createdAt': {'type': 'string', 'format': 'date-time'}, 'seniority': {'enum': ['INTERN', 'JUNIOR', 'MIDDLE', 'SENIOR', 'LEAD', 'PRINCIPAL'], 'type': 'string'}, 'updatedAt': {'type': 'string', 'format': 'date-time'}, 'viewCount': {'type': 'number'}, 'workModel': {'enum': ['REMOTE', 'HYBRID', 'ON_SITE'], 'type': 'string'}, 'dataSource': {'enum': ['USER_EDITED', 'AI_PARSED'], 'type': 'string'}, 'employerId': {'type': 'string'}, 'hiredCount': {'type': 'number'}, 'description': {'type': ['string', 'null']}, 'publishedAt': {'type': ['string', 'null'], 'format': 'date-time'}, 'referralBonus': {'type': ['number', 'null']}, 'mustHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'qualifications': {'type': 'array', 'items': {'type': 'string'}}, 'applicationCount': {'type': 'number'}, 'niceToHaveSkills': {'type': 'array', 'items': {'type': 'string'}}, 'responsibilities': {'type': 'array', 'items': {'type': 'string'}}}}}, 'additionalProperties': False}
request_access
Request access
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.
输入模式
{'type': 'object', 'properties': {'role': {'enum': ['CANDIDATE', 'EMPLOYER'], 'type': 'string'}}, 'additionalProperties': False}
输出模式
{'type': 'object', 'properties': {'guides': {'type': 'array'}, 'message': {'type': 'string'}, 'capabilityManifest': {'type': 'object', 'properties': {'auth': {'type': 'string'}, 'endpoint': {'type': 'string'}, 'keyPrefix': {'type': 'string'}, 'transport': {'type': 'string'}, 'sessionRules': {'type': 'array'}, 'referenceDocs': {'type': 'array'}, 'runtimePolicy': {'type': 'string'}, 'activeCapabilities': {'type': 'array'}, 'visibleWithoutAuth': {'type': 'array'}, 'plannedCapabilities': {'type': 'array'}}, 'additionalProperties': False}}, 'additionalProperties': False}
已添加
employer.cancel_invitation
2026年9月17日 12:53
已添加
employer.list_invitations
2026年9月17日 12:53
已添加
employer.get_applicant_transcript
2026年9月17日 12:53
已添加
employer.get_applicant_detail
2026年9月17日 12:53
已添加
employer.set_review_status
2026年9月17日 12:53
已添加
employer.list_applicants
2026年9月17日 12:53
已添加
employer.invite_candidate
2026年9月17日 12:53
已添加
employer.get_candidate_evidence
2026年9月17日 12:53
已添加
employer.get_candidate
2026年9月17日 12:53
已添加
employer.search_candidates_by_query
2026年9月17日 12:53
已添加
employer.search_candidates_for_job
2026年9月17日 12:53
已添加
employer.delete_job
2026年9月17日 12:53
已添加
employer.archive_job
2026年9月17日 12:53
已添加
employer.close_job
2026年9月17日 12:53
已添加
employer.publish_job
2026年9月17日 12:53
已添加
employer.update_job
2026年9月17日 12:53
已添加
employer.create_job
2026年9月17日 12:53
已添加
employer.get_job
2026年9月17日 12:53
已添加
employer.list_jobs
2026年9月17日 12:53
已添加
candidate.apply_to_job
2026年9月17日 12:53
已添加
candidate.withdraw_application
2026年9月17日 12:53
已添加
candidate.decline_invitation
2026年9月17日 12:53
已添加
candidate.accept_invitation
2026年9月17日 12:53
已添加
candidate.get_saved_jobs
2026年9月17日 12:53
已添加
candidate.set_saved_job
2026年9月17日 12:53
已添加
candidate.get_applications
2026年9月17日 12:53
已添加
candidate.get_job
2026年9月17日 12:53
已添加
candidate.search_jobs
2026年9月17日 12:53
已添加
request_access
2026年9月17日 12:53