list_roles
List roles for the company (proxies GET /api/v1/company/[slug]/roles). Returns public role fields only; no internal weight_profile details.
Parameters
- include_inactive ?
- boolean
* required, ? optional
Evidal exposes every hiring-manager action as a tool over the Model Context Protocol. Point Claude Code, Cursor, or any MCP-aware client at the server URL and your agent can list roles, review candidates, and record decisions directly. This server requires a Bearer API key and an existing company.
Server URL: https://app.evidal.ai/api/mcp/{company}/hiring-manager
claude mcp add \ --transport http \ evidal-<company> \ https://app.evidal.ai/api/mcp/<company>/hiring-manager \ --header "Authorization: Bearer $EVIDAL_API_KEY"
The company-scoped skill.md ( /api/v1/company/{slug}/hiring-manager-skill.md) has the same snippet in machine-readable form.
List roles for the company (proxies GET /api/v1/company/[slug]/roles). Returns public role fields only; no internal weight_profile details.
Parameters
* required, ? optional
Fetch a single role by UUID or slug (proxies GET /api/v1/company/[slug]/roles/[roleId]).
Parameters
* required, ? optional
Create a new role for the company. IMPORTANT: roles are created as DRAFTS by default — they are NOT visible to candidates until you call publish_role. Before calling this tool, present the role details (title, level, description, location, compensation) to the user and get their explicit confirmation. After creation, show the user the draft role and ask "Ready to publish this role?" before calling publish_role. DESTRUCTIVE: creates a persistent row in the roles table; use idempotency_key to safely retry on network errors. EVI-366: `seniority_level` accepts one of L1_Assisted_Contributor | L2_Independent_Contributor | L3_End_to_End_Owner | L4_System_Domain_Lead | L5_Strategic_Principal — invalid values are rejected. `requirements[]` accepts entries shaped like { name, importance, type|nature, notes? } where importance is "Core"|"Important"|"Informational" (or lowercase) and type/nature is "Foundational"|"Emerging"|"Contextual" (or lowercase) — recommendation-schema shapes from `recommend_role` pipe directly in. `archetype_slug` must be one of the six canonical slugs (call `list_archetypes` to discover them); unknown slugs are rejected. `weight_adjustments` keys must be a subset of [grounding, causal, tradeoff, ownership, robustness]. EVI-386: `ai_assistance_check` accepts one of "auto" | "required" | "skip" — controls whether the onboarding bot coaches Step 3B (AI Assistance Evidence). Default "auto" coaches when the JD or candidate tools mention an AI keyword.
Parameters
* required, ? optional
Patch role fields (proxies PATCH /api/v1/company/[slug]/roles/[roleId]). Accepted fields: title, description, level, seniority_level, ai_native_required, archetype_slug, weight_adjustments, must_haves, nice_to_haves, requirements, custom_notes, location, compensation, ai_assistance_check. DESTRUCTIVE: mutates a persistent row; input shape is { role_id_or_slug, patch: {...} } — patch fields are merged, omitted fields are left unchanged. EVI-366: same enum and normalization rules as `create_role` apply to `seniority_level`, `requirements`, `archetype_slug`, and `weight_adjustments` keys. EVI-386: `ai_assistance_check` accepts one of "auto" | "required" | "skip" — see `create_role`.
Parameters
* required, ? optional
Set role.active = false (proxies POST /api/v1/company/[slug]/roles/[roleId]/deactivate). DESTRUCTIVE: the role stops accepting applications immediately.
Parameters
* required, ? optional
Publish a draft role so it becomes visible to candidates. Only call this AFTER the user has reviewed and confirmed the role details. Roles created via create_role start as drafts (active: false) — this tool flips them to active.
Parameters
* required, ? optional
Paginated candidate list with scores (proxies GET /api/v1/company/[slug]/candidates). Each row includes `lead_unlocked: boolean` indicating whether the candidate has been lead-unlocked for this company. Pass `unlocked_only: true` to restrict results to unlocked candidates. Never returns contact_email or display_name — PII is gated behind the Stripe unlock-lead flow and not exposed via MCP.
Parameters
* required, ? optional
Fetch a single candidate (proxies GET /api/v1/company/[slug]/candidates/[id]). Response includes `lead_unlocked: boolean` and `lead_unlocked_at: string|null` (ISO timestamp of the $100 lead-unlock payment, or null if not yet unlocked). PII gate (EVI-198): when `lead_unlocked=true`, the response ALSO includes `display_name` and `contact_email`. When not unlocked, those keys are ABSENT from the response. One `candidate.pii_read` audit row is emitted per PII-returning response. The `score` object (null until the v4 evaluation completes) carries: `total` (0-100), `normalized_percentile`, `dimensions` (the five named quality dimensions, each 0-100: `grounding`, `causal_reasoning`, `tradeoff_awareness`, `ownership_integrity`, `robustness`), `dimension_levels` (per-dimension object: `final` is the authoritative guardrail-reconciled band weak|moderate|strong, `level` is the un-capped natural band, `numeric_0_to_1` the 0-1 basis), `signal_scores` (per-lens evidence map the dimensions roll up from), `guardrail_overrides` (which dimensions a guardrail capped down and why — present only when a cap fired), `flagged` (boolean) + `flag_reasons` (string[] — the human-readable caps/concerns), `score_narrative` (plain-English summary; on a capped row it is prefixed with a "Final Evidal score: N/100." reconciliation preamble that names the fired caps), and `scored_at`. These score sub-fields are NOT candidate PII — they are company-visible regardless of lead-unlock state.
Parameters
* required, ? optional
Record a hiring decision for a candidate (proxies POST /api/v1/company/[slug]/candidates/[id]/decision). Allowed values: advance, reject, hold. The decision is timestamped server-side. DESTRUCTIVE: persists a decision row that drives downstream notifications (Slack, Lever sync); confirm with the user before invoking.
Parameters
* required, ? optional
Configure Slack notifications (proxies PATCH /api/v1/company/[slug]/slack/configure). Requires Slack to already be connected via the dashboard OAuth flow. DESTRUCTIVE: overwrites the company-wide notification channel and threshold; PATCH semantics apply only to the fields you send.
Parameters
* required, ? optional
Immediately rotate the company API key (proxies POST /api/v1/company/[slug]/api-key/rotate). DESTRUCTIVE: invalidates the current API key; this MCP session will need to re-authenticate with the new key on subsequent calls. Response contains the new raw key EXACTLY ONCE — the client must store it immediately.
No parameters.
Runs a live CNAME lookup and writes dns_verified=true to the company record on success (proxies GET /api/v1/company/[slug]/dns-status). Call this after adding your CNAME record to confirm it propagated. Returns { dns_verified, cname_found, points_to_evidal, expected_cname, last_checked } and emits an audit event on each call.
No parameters.
Patch company-level fields (proxies PATCH /api/v1/company/[slug]). Allowed fields: name, notification_email, domain, logo_url. Slug and secrets cannot be updated via this path. logo_url must be https and point to an image (SVG not allowed). After changing domain, dns_verified resets to false — call check_dns once your new CNAME has propagated. DESTRUCTIVE: mutates the company row; input shape is { patch: {...} } — patch fields are merged, omitted fields are left unchanged.
Parameters
* required, ? optional
Start a Stripe Checkout session for a role plan (proxies POST /api/v1/payment/stripe/checkout). Returns { checkout_url, session_id }. The checkout_url must be opened in a browser — it cannot be completed programmatically. Plans: full_access = $500 unlimited evals, pay_per_eval = $10/eval, lead_unlock = $100 per-candidate PII unlock. DESTRUCTIVE: opens a billable Stripe session; pass an idempotency_key to safely retry on network errors.
Parameters
* required, ? optional
Return per-role billing state + lead-unlock summary + active company-wide subscription (proxies GET /api/v1/company/[slug]/billing/status). Response: { roles: [{ role_id, slug, title, role_status, eval_count, trial_remaining, needs_payment, subscription_covered, subscription_over_cap }], lead_unlocks_count: number, subscription: { plan: "starter"|"growth", status, current_period_end, role_cap, trial_end, cancel_at_period_end } | null }. `subscription` is non-null when the company is on a monthly plan; `subscription_covered` is true for roles within `role_cap` (oldest-first), false otherwise. `lead_unlocks_count` is the total number of $100 candidate lead unlocks ever paid for this company (not paginated). Active, non-archived roles only.
No parameters.
Activate a role by charging the stored payment method directly (no browser redirect). Returns { status: 'activated' } on success or { status: 'requires_setup', checkout_url } if no payment method is on file or 3DS is required — open the checkout_url in a browser to save a card first. Plans: full_access = $500 unlimited evals, pay_per_eval = $10/eval. DESTRUCTIVE: bills the company's stored card on success; pass an idempotency_key to safely retry on network errors.
Parameters
* required, ? optional
Invite a teammate to the company (proxies POST /api/v1/company/[slug]/members/invite). Sends an invite email with a secure token. `role` = owner|admin|viewer. API-key callers have implicit owner scope and may invite at any role. Idempotent: if the email already has a pending invite or active membership, returns ok without re-sending. DESTRUCTIVE: grants persistent access to company data on accept; confirm with the user before invoking.
Parameters
* required, ? optional
Paginated list of company hiring-team members + pending invites (proxies GET /api/v1/company/[slug]/members). Returns `{ members: [{ id, user_id, email, role, status, invited_at, accepted_at }], total, limit, offset }`. `status` is `active` (accepted) or `pending` (invite outstanding). NOTE: `email` here is the hiring-team teammate email — NOT candidate PII. Treat the returned roster as confidential company-internal data. Default limit 50, max 100.
Parameters
* required, ? optional
Change a teammate's role (proxies POST /api/v1/company/[slug]/members/[user_id]/role). `role` = owner|admin|viewer. Guarded: cannot demote the last owner (returns 400). DESTRUCTIVE: changes a teammate's access scope; confirm with the user before invoking.
Parameters
* required, ? optional
Remove a teammate from the company (proxies DELETE /api/v1/company/[slug]/members/[user_id]). DESTRUCTIVE: revokes the member immediately. Guarded: cannot remove the last owner (returns 400).
Parameters
* required, ? optional
Paginated list of $100 lead unlocks for the company (proxies GET /api/v1/company/[slug]/unlocks). Admin+ only for session callers (financial data); API-key callers have implicit owner scope. Returns { unlocks: [{ candidate_agent_id, candidate_agent_id_short, amount_cents, unlocked_at, stripe_payment_intent_id }], pagination: { limit, offset, total } }. The stripe_payment_intent_id is the opaque Stripe identifier (non-secret; cannot be acted on without the platform secret key).
Parameters
* required, ? optional
Import a role from a Lever posting URL (Tier 1, no API key needed). Accepts a full `https://jobs.lever.co/acme/abc123` URL or a bare `acme/abc123` pair. Returns a pre-filled role object matching the `create_role` input schema. IMPORTANT: do NOT call `create_role` automatically — present the extracted fields to the user for review and get explicit confirmation before creating the role.
Parameters
* required, ? optional
Connect the company to Lever by storing an API key (proxies POST /lever/connect). The key is stored encrypted and never echoed back. Requires `lever_api_key` and `lever_subdomain`.
Parameters
* required, ? optional
Disconnect Lever integration (proxies POST /lever/disconnect). Deletes the stored API key and clears connection metadata. DESTRUCTIVE.
No parameters.
List open Lever postings for the connected company (proxies GET /lever/postings). Returns posting ID, title, department, location, commitment, and team. Requires Lever to be connected first via `connect_lever`.
No parameters.
Link (or unlink) an existing Evidal role to a Lever posting (proxies PATCH /api/v1/company/[slug]/roles/[roleId]/lever-link). Pass `lever_posting_id: null` to unlink. Requires Lever to be connected first via `connect_lever` and a posting ID from `import_lever_postings`. Owner/admin only — viewers will get 403. On link, the posting ID is re-validated against Lever before write; stale or forged IDs return 404. DESTRUCTIVE: mutates the role row and changes downstream Lever-sync behaviour.
Parameters
* required, ? optional
Push an Evidal candidate (email, name, score narrative, score breakdown) into Lever as an opportunity + note on the role's linked posting (proxies POST /api/v1/company/[slug]/lever/sync/[candidateAgentId]). DESTRUCTIVE: writes an opportunity and a note to your Lever account. Dedupes by email, so a second call writes a second note on the same opportunity rather than duplicating the candidate. Requires: Lever connected, the candidate's role linked via `link_role_to_lever_posting`, and the candidate has a `contact_email` on file. Owner/admin only.
Parameters
* required, ? optional
Generate an AI role recommendation given a title and description (proxies POST /api/v1/company/[slug]/roles/recommend). Returns { archetype: { recommended, confidence, alternatives, explanation }, seniority: { recommended, confidence, explanation }, dimension_weights: { grounding, causal, tradeoff, ownership, robustness }, requirements: [{ name, importance, nature, reason, usage_context }] }. The output is designed to be piped directly into `create_role` after letting the user confirm — `create_role` accepts both `nature` (returned here) and `type` (DB-canonical) and both titlecase and lowercase importance values. Rate limit: 20 calls per company per 5-minute window (shared with the dashboard).
Parameters
* required, ? optional
List the six canonical role archetypes (slug, name, description, default_weights). Returns the static catalog from `lib/archetypes.ts` — call this before `create_role` to discover the valid `archetype_slug` values. Read-only.
No parameters.