We raised a $50M Series B led by BenchmarkLearn more
Metaview logo — MCP server on Gumloop

Metaview

Access your Metaview interview notes and hiring insights.

Book a demo

Installation

Set up the Metaview MCP server in Gumloop

Do this once to provision your hosted server URL.

1

Create a Gumloop account

To use this MCP, you need a Gumloop account. If you don't have one yet, sign up and start a 14-day free trial.

2

Add and authorize the Metaview server

In Gumloop, open Connectors and add Metaview. Depending on the app, you'll either sign in via OAuth or paste an API key. Either way, the credential is stored securely in Gumloop.

Then use it in your client

Use in GumloopUse in Gumloop
1

Use Metaview in an agent

Once Metaview is set up, just open any Gumloop agent, add Metaview as a connector, and start chatting with the agent.

Tools (38)

  • Get Application Review Details

    <usecase> Get the full state of one Application Review: the ACTIVE ICP, any pending DRAFT edit, the RANKING version if a rerank is in flight, the version history, evaluation status, a decision/calibration summary, and the fit-band distribution of the current ranking. This is the tool to read before refining an ICP. It tells you what the review is currently scoring against, whether an edit is already pending or a rerank is running (so you know to wait), and how candidates are distributed across fit bands (so you can judge whether the bar is where you want it). Pair with list_application_review_candidates to inspect individual ranked applicants. </usecase> <instructions> Args: application_review_id: The review to inspect. detail_level: How much data to return. 'full' — (default) the ICP text, version history, evaluation status, decisions, and fit distribution. 'concise' — run and rerank state, active/ranking display versions, pending counts, and next-step guidance. Use this for cheap polling after an ICP update or restore. icp_version: Return the full ICP text of a specific historical version instead of only the summary. This is a display version number (1, 2, 3, ...) as shown in version_history and the web app, not a raw internal id. Omit to get the ACTIVE / DRAFT / RANKING texts. Use version_history in the response to discover which versions exist and to pick a restore target for restore_application_review_icp. Version numbers are the positional numbers users see in the web app: approved versions numbered 1, 2, 3, ... oldest first. A pending draft is not numbered. icp_version is only available at detail_level='full'. </instructions> <response_format> Full (default): {"application_review_id": "550e8400-...", "job_title": "Senior PM, Travel Booking", "run_state": "ACTIVE", "icp_update_supported": true, "active_icp": {"version": 3, "text": "# Ideal Candidate Profile...", "activated_at": "2025-01-16T09:00:00Z", "activated_by": "Alice Smith"}, "pending_draft": null, "ranking_version": null, "version_history": [{"version": 3, "lifecycle_state": "ACTIVE", "change_source": "user_edit", "reasoning": "Raised the seniority bar", "created_at": "2025-01-16T08:55:00Z", "activated_at": "2025-01-16T09:00:00Z"}], "evaluation": {"in_progress": false, "evaluating_since": null}, "decisions": {"progressed": 12, "rejected": 30, "unreviewed": 97}, "pending_admission_count": 3, "pending_evaluation_count": 0, "fit_distribution": {"great": 14, "good": 40, "okay": 55, "no_evidence": 8, "poor": 25}, "next": "Read the active ICP, then refine it..."} Concise: {"application_review_id": "550e8400-...", "run_state": "ACTIVE", "active_version": 3, "ranking_version": 4, "rerank_in_flight": true, "pending_admission_count": 3, "pending_evaluation_count": 0, "next": "A full rerank is in progress..."} </response_format> <notes> evaluation.in_progress is true whenever the review holds the evaluation lock. When a ranking_version is present a full rerank is running and its results are not yet readable; when it is absent the lock reflects routine incremental scoring of new applicants and the ACTIVE ranking remains stable. fit_distribution counts admitted candidates per fit band for the ACTIVE version — the aggregate to watch across ICP edits. It contains no per-candidate ranking data. pending_admission_count is applicants matched but not yet admitted onto the roster; pending_evaluation_count is admitted candidates not yet scored against the active version. decisions counts only admitted candidates (progressed / rejected / unreviewed). icp_update_supported tells you whether update_application_review_icp and restore_application_review_icp will work on this review — some reviews can only have their ICP managed in the Metaview web app. All read tools work regardless. </notes> <examples> Inspect a review before refining its ICP: get_application_review_details(application_review_id="550e8400-...") Poll a rerank without re-reading the full ICP: get_application_review_details(application_review_id="550e8400-...", detail_level="concise") Read the full text of an earlier ICP version (display number): get_application_review_details(application_review_id="550e8400-...", icp_version=2) </examples> <data_model> - An APPLICATION REVIEW (a REVIEW) evaluates inbound applicants for one ATS job against an ICP (Ideal Candidate Profile). Applicants who match the review's configured ATS stage are admitted, scored against the ICP, and ranked. A review is tied to one or more ATS job ids and can be active or archived. - An ICP is the Ideal Candidate Profile the review scores applicants against. It is versioned through a lifecycle: DRAFT (a proposed edit, not yet applied) -> RANKING (approved and being applied, a full rerank of every admitted candidate is in flight) -> ACTIVE (live, the version candidates are currently scored against) -> ARCHIVED (a superseded former ACTIVE version). At most one DRAFT, one RANKING, and one ACTIVE version exist per review at any time. - ICP version numbers are the positional numbers users see in the web app: the approved versions (RANKING / ACTIVE / ARCHIVED, never DRAFT) numbered 1, 2, 3, ... oldest first. A pending DRAFT is not numbered — it is surfaced as pending_draft, not as a version. All version numbers in these tools speak this display numbering, so the agent and the human see the same numbers. - Each version records its change_source provenance (agent_suggestion = proposed by the in-app review agent; user_edit = written by a person or via MCP; restore = a rollback to an earlier version) and, once activated, who activated it and when. - Applying an ICP edit triggers a FULL RERANK: a Step Functions run re-scores every admitted candidate against the new version. While it runs, the review holds an evaluation lock (evaluating_since is set) and a RANKING version exists; on completion the RANKING version becomes ACTIVE and the previous ACTIVE version is ARCHIVED. Reranks are free (no credits are spent) but heavyweight, and take time for large reviews. - RESTORING a previous version (only ARCHIVED versions can be restored) mints a NEW latest version with the source's content rather than reactivating the old row. Prior evaluations against that content are carried over, so the rerank after a restore is typically fast — only candidates the source version never saw are re-scored. A restore is itself reversible: the replaced version stays in the history and can be restored back. - Separately, INCREMENTAL EVALUATION scores newly-synced ATS applicants onto the existing ACTIVE version. This also sets the evaluation lock but creates no RANKING version; the ACTIVE ranking being read stays stable throughout. - ADMISSION is review-local: a candidate is ADMITTED (part of the ranked roster, debited one credit at admission) or PENDING (matched but not yet admitted onto the review). The candidate-listing tool returns only the ADMITTED roster — the candidates a rerank actually scores; pending applicants are reported as an aggregate count, not as rows. - FIT is reported only as a coarse band (FitLevel: great, good, okay, no_evidence, poor). The underlying numeric scores and ordinal rank positions are internal and are never exposed. - A human DECISION on an admitted candidate is PROGRESSED (advanced) or REJECTED, or absent (undecided / null), optionally with free-text feedback. These are the values the candidate-listing tool returns and its decision_filter accepts (lowercased); the review-details calibration summary counts the same undecided bucket as 'unreviewed'. Decisions can sync back to the ATS (stage moves, rejection emails). - Some reviews support updating their ICP via MCP and some do not (their ICP is managed only in the Metaview web app). get_application_review_details reports icp_update_supported for each review; all read tools work regardless. </data_model>

  • List Application Review Candidates

    <usecase> List the review's ADMITTED (ranked) roster, ranked against the ACTIVE ICP. This lists only candidates admitted onto the review — the roster a rerank actually scores. Applicants matched but not yet admitted are excluded and reported separately as pending_admission_count; admitted candidates not yet scored are reported as pending_evaluation_count. This is the feedback half of ICP refinement: after an ICP update reranks the review, use this to verify the bar moved the way you intended. Candidates carry only review-specific facts — the coarse fit band, human decision, the agent's fit reasoning, and (at detail_level=full) non-fraud AI column results. IMPORTANT: fit is reported only as a coarse band (great / good / okay / no_evidence / poor). Numeric scores and ordinal rank positions are never exposed, and the list is never ordered by internal score — it is ordered by fit band, then application date. For a candidate's full profile, resume, or ATS application detail, call fetch_candidates with the candidate_id and this application_review_id — that tool owns the deep candidate surface; this one owns only what the review knows. </usecase> <instructions> Args: application_review_id: The review to list candidates for. limit: Maximum candidates to return (default 20, max 100). offset: Pagination offset (default 0). detail_level: How much data to return per candidate. 'minimal' — candidate_id, name, fit band, decision, applied_at. 'summary' — (default) minimal plus decision metadata (decided_at, feedback) and the agent's fit reasoning summary. 'full' — summary plus non-fraud AI column results (column, value, fit, reasoning). decision_filter: Filter by human decision — 'all' (default), 'progressed', 'rejected', or 'undecided'. The per-candidate 'decision' field is returned as PROGRESSED, REJECTED, or null (undecided); pass the lowercase form to filter ('undecided' matches a null decision). fit_filter: Filter by fit band — one of great, good, okay, no_evidence, poor. Omit for all bands. </instructions> <response_format>{"application_review_id": "550e8400-...", "active_version": 3, "candidates": [{"candidate_id": "c1a2b3d4-...", "name": "Jane Smith", "overall_fit": "great", "decision": "PROGRESSED", "applied_at": "2025-01-14T09:00:00Z", "decided_at": "2025-01-16T11:00:00Z", "decision_feedback": "Strong product sense", "reasoning": "Led two 0-to-1 launches in travel..."}], "total_count": 142, "has_more": true, "pending_admission_count": 5, "pending_evaluation_count": 0, "next": "..."}</response_format> <notes>Only completed rankings are served. If a full rerank is in flight (a RANKING version exists), this tool returns an error directing you to poll get_application_review_details until the new version is ACTIVE — half-evaluated results would corrupt the refine/verify loop. If routine incremental evaluation of new applicants is running (no RANKING version), the stable ACTIVE ranking is served with pending_evaluation_count noting how many candidates are not yet scored. The response echoes active_version — the ACTIVE ICP version number (the same display number shown in the web app and get_application_review_details) the returned fit bands were computed against — so you can correlate bands to a specific ICP and detect drift without a second call (null when the review has no active ranking yet).</notes> <examples> List the top candidates for a review: list_application_review_candidates(application_review_id="550e8400-...") Check who was progressed: list_application_review_candidates(application_review_id="550e8400-...", decision_filter="progressed") Inspect only great-fit candidates with full column detail: list_application_review_candidates(application_review_id="550e8400-...", fit_filter="great", detail_level="full") </examples> <data_model> - An APPLICATION REVIEW (a REVIEW) evaluates inbound applicants for one ATS job against an ICP (Ideal Candidate Profile). Applicants who match the review's configured ATS stage are admitted, scored against the ICP, and ranked. A review is tied to one or more ATS job ids and can be active or archived. - An ICP is the Ideal Candidate Profile the review scores applicants against. It is versioned through a lifecycle: DRAFT (a proposed edit, not yet applied) -> RANKING (approved and being applied, a full rerank of every admitted candidate is in flight) -> ACTIVE (live, the version candidates are currently scored against) -> ARCHIVED (a superseded former ACTIVE version). At most one DRAFT, one RANKING, and one ACTIVE version exist per review at any time. - ICP version numbers are the positional numbers users see in the web app: the approved versions (RANKING / ACTIVE / ARCHIVED, never DRAFT) numbered 1, 2, 3, ... oldest first. A pending DRAFT is not numbered — it is surfaced as pending_draft, not as a version. All version numbers in these tools speak this display numbering, so the agent and the human see the same numbers. - Each version records its change_source provenance (agent_suggestion = proposed by the in-app review agent; user_edit = written by a person or via MCP; restore = a rollback to an earlier version) and, once activated, who activated it and when. - Applying an ICP edit triggers a FULL RERANK: a Step Functions run re-scores every admitted candidate against the new version. While it runs, the review holds an evaluation lock (evaluating_since is set) and a RANKING version exists; on completion the RANKING version becomes ACTIVE and the previous ACTIVE version is ARCHIVED. Reranks are free (no credits are spent) but heavyweight, and take time for large reviews. - RESTORING a previous version (only ARCHIVED versions can be restored) mints a NEW latest version with the source's content rather than reactivating the old row. Prior evaluations against that content are carried over, so the rerank after a restore is typically fast — only candidates the source version never saw are re-scored. A restore is itself reversible: the replaced version stays in the history and can be restored back. - Separately, INCREMENTAL EVALUATION scores newly-synced ATS applicants onto the existing ACTIVE version. This also sets the evaluation lock but creates no RANKING version; the ACTIVE ranking being read stays stable throughout. - ADMISSION is review-local: a candidate is ADMITTED (part of the ranked roster, debited one credit at admission) or PENDING (matched but not yet admitted onto the review). The candidate-listing tool returns only the ADMITTED roster — the candidates a rerank actually scores; pending applicants are reported as an aggregate count, not as rows. - FIT is reported only as a coarse band (FitLevel: great, good, okay, no_evidence, poor). The underlying numeric scores and ordinal rank positions are internal and are never exposed. - A human DECISION on an admitted candidate is PROGRESSED (advanced) or REJECTED, or absent (undecided / null), optionally with free-text feedback. These are the values the candidate-listing tool returns and its decision_filter accepts (lowercased); the review-details calibration summary counts the same undecided bucket as 'unreviewed'. Decisions can sync back to the ATS (stage moves, rejection emails). - Some reviews support updating their ICP via MCP and some do not (their ICP is managed only in the Metaview web app). get_application_review_details reports icp_update_supported for each review; all read tools work regardless. </data_model>

  • List Application Reviews

    <usecase> List the Application Reviews you can access, with summary information per review. An Application Review evaluates inbound applicants for a job against an ICP (Ideal Candidate Profile). Use this to find a review to inspect or refine, then call get_application_review_details for its ICP, version history, and evaluation status, or list_application_review_candidates for the ranked applicants. Each review reports its ATS job, run state, active ICP version summary, whether a pending ICP draft exists, whether a rerank is currently in flight, and admitted / pending candidate counts. </usecase> <instructions> Args: include_archived: Include archived reviews (default false). search_term: Case-insensitive substring match on the job title. Omit to list all. limit: Maximum number of reviews to return (default 20, max 50). offset: Pagination offset (default 0). Results are scoped to reviews you can access via ATS hiring-team membership, admin access, or an explicit share. </instructions> <response_format>{"reviews": [{"id": "550e8400-...", "job_title": "Senior PM, Travel Booking", "ats_job_ids": ["job_123"], "run_state": "ACTIVE", "active_version": {"version": 3, "lifecycle_state": "ACTIVE", "activated_at": "2025-01-16T09:00:00Z"}, "has_pending_draft": false, "rerank_in_flight": false, "admitted_count": 142, "pending_count": 3, "created_at": "2025-01-10T10:30:00Z", "updated_at": "2025-01-16T14:22:00Z"}], "total_count": 8, "has_more": false}</response_format> <notes>rerank_in_flight is true when a RANKING version exists (a full rerank triggered by an ICP update is running). While it is true, candidate rankings for this review are still being computed — list_application_review_candidates will decline to serve partial results; poll get_application_review_details until it clears.</notes> <examples> List active reviews: list_application_reviews() Find a review by job title: list_application_reviews(search_term="Travel Booking") Include archived reviews and paginate: list_application_reviews(include_archived=True, limit=50, offset=50) </examples> <data_model> - An APPLICATION REVIEW (a REVIEW) evaluates inbound applicants for one ATS job against an ICP (Ideal Candidate Profile). Applicants who match the review's configured ATS stage are admitted, scored against the ICP, and ranked. A review is tied to one or more ATS job ids and can be active or archived. - An ICP is the Ideal Candidate Profile the review scores applicants against. It is versioned through a lifecycle: DRAFT (a proposed edit, not yet applied) -> RANKING (approved and being applied, a full rerank of every admitted candidate is in flight) -> ACTIVE (live, the version candidates are currently scored against) -> ARCHIVED (a superseded former ACTIVE version). At most one DRAFT, one RANKING, and one ACTIVE version exist per review at any time. - ICP version numbers are the positional numbers users see in the web app: the approved versions (RANKING / ACTIVE / ARCHIVED, never DRAFT) numbered 1, 2, 3, ... oldest first. A pending DRAFT is not numbered — it is surfaced as pending_draft, not as a version. All version numbers in these tools speak this display numbering, so the agent and the human see the same numbers. - Each version records its change_source provenance (agent_suggestion = proposed by the in-app review agent; user_edit = written by a person or via MCP; restore = a rollback to an earlier version) and, once activated, who activated it and when. - Applying an ICP edit triggers a FULL RERANK: a Step Functions run re-scores every admitted candidate against the new version. While it runs, the review holds an evaluation lock (evaluating_since is set) and a RANKING version exists; on completion the RANKING version becomes ACTIVE and the previous ACTIVE version is ARCHIVED. Reranks are free (no credits are spent) but heavyweight, and take time for large reviews. - RESTORING a previous version (only ARCHIVED versions can be restored) mints a NEW latest version with the source's content rather than reactivating the old row. Prior evaluations against that content are carried over, so the rerank after a restore is typically fast — only candidates the source version never saw are re-scored. A restore is itself reversible: the replaced version stays in the history and can be restored back. - Separately, INCREMENTAL EVALUATION scores newly-synced ATS applicants onto the existing ACTIVE version. This also sets the evaluation lock but creates no RANKING version; the ACTIVE ranking being read stays stable throughout. - ADMISSION is review-local: a candidate is ADMITTED (part of the ranked roster, debited one credit at admission) or PENDING (matched but not yet admitted onto the review). The candidate-listing tool returns only the ADMITTED roster — the candidates a rerank actually scores; pending applicants are reported as an aggregate count, not as rows. - FIT is reported only as a coarse band (FitLevel: great, good, okay, no_evidence, poor). The underlying numeric scores and ordinal rank positions are internal and are never exposed. - A human DECISION on an admitted candidate is PROGRESSED (advanced) or REJECTED, or absent (undecided / null), optionally with free-text feedback. These are the values the candidate-listing tool returns and its decision_filter accepts (lowercased); the review-details calibration summary counts the same undecided bucket as 'unreviewed'. Decisions can sync back to the ATS (stage moves, rejection emails). - Some reviews support updating their ICP via MCP and some do not (their ICP is managed only in the Metaview web app). get_application_review_details reports icp_update_supported for each review; all read tools work regardless. </data_model>

  • Restore Application Review Icp

    <usecase> Restore a previous Application Review ICP version: the restored content becomes a new latest version, is approved on the spot, and a rerank starts against it. IMPORTANT: this applies immediately — there is no separate confirmation or approval step. The rerank after a restore is typically fast: prior evaluations against the restored content are reused, so only candidates that version never saw are re-evaluated. Always call get_application_review_details first and pick the target from version_history — the version argument is the same display number (1, 2, 3, ...) shown there and in the web app. version_history carries only summaries; to read the full ICP text of a candidate version before restoring it, call get_application_review_details again with icp_version set to that display number. Only a previous (superseded) version can be restored: the currently active version and a version mid-ranking are rejected. If the review has a pending, unapplied ICP draft, this restore supersedes it — exactly as restoring in the Metaview web app does. A restore is itself reversible — the replaced version stays in version_history, so you can restore back to it. </usecase> <instructions> Args: application_review_id: The review to restore a version on (from list_application_reviews). version: The display version number to restore, as shown in version_history from get_application_review_details (approved versions numbered 1, 2, 3, ... oldest first). Inspect a version's full text first via get_application_review_details(icp_version=N). Some reviews can only have their ICP managed in the Metaview web app; a restore against one is rejected. If a rerank is already running, the restore is rejected — poll for it to finish, then retry. </instructions> <response_format>{"application_review_id": "550e8400-...", "restored_version": 2, "status": "approved_and_ranking", "next": "Restore approved and a rerank started..."}</response_format> <examples> Read a past version's full text, then roll back to it: get_application_review_details(application_review_id="550e8400-...", icp_version=2) restore_application_review_icp(application_review_id="550e8400-...", version=2) </examples>

  • Update Application Review Icp

    <usecase> Replace an Application Review's ideal candidate profile (ICP) and immediately rerank every admitted candidate against the new profile. IMPORTANT: this is not a draft or a suggestion. The ICP text you pass is written as a user edit, approved on the spot, and triggers a full rerank of all admitted candidates. There is no separate confirmation or approval step — the moment you call this tool, the change is live. Only call it with complete, final ICP text you are ready to apply. The edit is reversible — restore a prior ICP version with restore_application_review_icp. Always call get_application_review_details first: read the current ICP, compose the full revised profile, and pass the current active_icp version number as base_version so a concurrent edit isn't silently clobbered. If the review has a pending, unapplied ICP draft, this edit supersedes it — exactly as approving an edit in the Metaview web app does. Reranks consume no credits (already-admitted candidates are not re-debited) but are heavyweight and can take a while on large reviews. After calling this, poll get_application_review_details with detail_level='concise' — the version moves RANKING then ACTIVE when evaluation completes. Candidate listings via list_application_review_candidates are unavailable until it completes. A further ICP update is rejected while that rerank is in flight — wait for it to finish before editing again. </usecase> <instructions> Args: application_review_id: The review to update (from list_application_reviews). icp_text: The complete, final ICP text. This replaces the current profile in full — do not send a diff or a partial edit. base_version: The active ICP version number you read from active_icp.version in get_application_review_details (the display number shown in the web app). If it no longer matches the review's current version (someone edited it since you read it), the update is rejected and you must re-read and re-apply. Some reviews can only have their ICP managed in the Metaview web app; an update against one is rejected. If a rerank is already running, the update is rejected — poll for it to finish, then retry. </instructions> <response_format>{"application_review_id": "550e8400-...", "submitted_version_base": 3, "status": "approved_and_ranking", "next": "Full rerank started..."}</response_format> <examples> Refine an ICP after reading its current version: update_application_review_icp(application_review_id="550e8400-...", base_version=3, icp_text="Senior PM with 6+ years in travel/booking marketplaces, strong on pricing experimentation...") </examples>

  • Fetch Candidates

    <usecase> ALWAYS use this tool to look up one or more people or candidates. This is the ONLY way to retrieve candidate scorecards, ATS feedback, resume files, application history, and professional profile data. Do NOT try to scrape LinkedIn or other websites directly — this tool fetches richer data than any public page and includes internal ATS records. Look up candidates by candidate ID, LinkedIn URL, email, phone number, or participant ID. Returns per-candidate results with two sections each: - profile: Professional background (experience, education, skills, location, etc.). Available when a LinkedIn URL is provided or can be resolved from ATS data. - ats: Internal ATS data including: - scorecards: Interview scorecard responses (questions and answers/scores) - applications: Job applications with title, status, and stage - feedback: Interviewer feedback notes - files: Resumes and other attached documents with download URLs Only available when the candidate exists in your ATS and you have permission to access their data. Use this tool when you need to: - Look up scorecard results for one or more candidates - Get a candidate's application status or interview stage - Retrieve resume or document files for a candidate - Get a candidate's professional profile (experience, education, skills) - Check interviewer feedback on a candidate ATS data access requires one of: - You are a Metaview admin - You are an ATS admin - The candidate appeared in a conversation you have access to - You provide an application_review_id for an accessible review whose admitted active roster includes the candidate Application Review-based access grants the generic candidate applications/files ATS shape while withholding scorecards and global ATS feedback. The profile section remains the generic professional-profile surface. Access is review-wide, matching the web app for multi-job reviews, and remains available during reranks because this data is independent of ranking state. Accepts 1-10 candidates per call. </usecase> <instructions> Args: candidates: A list of candidate lookups. Each entry is a dict with at least one identifier: - candidate_id: Metaview candidate UUID for direct lookup. This is the candidate_id returned by the application review tools (list_application_review_candidates), so a review listing pivots straight to a full profile. - application_review_id: Application Review UUID that authorizes access to the candidate. Requires candidate_id; the candidate must be on that accessible review's admitted active roster. - linkedin_url: LinkedIn profile URL (e.g. "https://www.linkedin.com/in/john-doe") or bare shorthand (e.g. "john-doe"). - email: Candidate email address. - phone_number: Candidate phone number. - participant_id: Metaview participant ID for direct lookup. This is the internal ID shown in conversation data (e.g. from the default:candidate field in search_conversations results). </instructions> <response_format> {"candidates": [ { "lookup": {"email": "john@example.com"}, "profile": { "name": "John Doe", "linkedin_url": "https://www.linkedin.com/in/john-doe", "location": "San Francisco, CA", ...}, "ats": { "name": "John Doe", "applications": [{"job_title": "...", "status": "...", "stage": "..."}], "scorecards": [{"question": "...", "answer_or_score": "..."}], "feedback": ["..."], "files": [{"file_name": "resume.pdf", "download_url": "..."}]} }, { "lookup": {"linkedin_url": "https://www.linkedin.com/in/jane-smith"}, "error": "No candidate found matching the provided identifiers." } ]} </response_format> <examples> Fetch a single candidate by email: fetch_candidates(candidates=[{"email": "john@example.com"}]) Fetch a candidate by candidate_id: fetch_candidates(candidates=[{"candidate_id": "c1a2b3d4-..."}]) Fetch multiple candidates: fetch_candidates(candidates=[ {"linkedin_url": "https://www.linkedin.com/in/john-doe"}, {"email": "jane@example.com"}, {"participant_id": "abc-123-def"}]) Fetch with multiple identifiers per candidate (for better matching): fetch_candidates(candidates=[ {"linkedin_url": "https://www.linkedin.com/in/john-doe", "email": "john@example.com"}]) Fetch a candidate from an Application Review: fetch_candidates(candidates=[{"candidate_id": "c1a2b3d4-...", "application_review_id": "550e8400-..."}]) </examples> <access_scope>Results are scoped server-side to interviews and candidates the authenticated user can already access in Metaview, within their workspace and role. Intended for the user's normal hiring workflow (reviewing, summarizing, exporting, ATS sync). Read-only.</access_scope>

  • List Note Templates

    <usecase> List AI Notes custom templates the caller can access. Returns a lightweight summary per template. Pass include_detail=true or call get_note_template for the full sections. </usecase> <instructions> Args: search_term: Filter templates by name (case-insensitive substring / regex). include_detail: When true, include the full sections list. offset: Pagination offset (default 0). limit: Page size (default 20, max 50). </instructions> <response_format> {"templates": [ {"id": "...", "name": "Engineering screen", "version": 3, "created_by": {"name": "Alice Smith"}, "created_at": "...", "updated_at": "...", "section_count": 5}], "total_count": 12, "has_more": false} The `id` field is INTERNAL ONLY — keep it for subsequent tool calls but never show it to the user. Refer to templates by name. </response_format> <data_model> - A NOTE TEMPLATE (AI Notes custom template) defines the structure of AI-generated interview notes. Each template has a name and an ordered list of sections. Template ids and group ids are internal — never surface them to the user; refer to both by name. - A SECTION is one named block in the generated notes — it has a directive (SINGLE for one block under a fixed heading, or REPEATING for one block per detected entity), a description (the instruction the LLM follows when writing that block — the single most important field), and an output type (TEXT, NUMBER, OPTIONS, or DATE). - A TEMPLATE GROUP (folder) is a public folder shared with the workspace. Templates live in the caller's personal folder by default or in a public template group. Use list_note_template_groups to see public folders, and manage_note_template to create/update/delete a template. - A SOURCE is a piece of content that feeds into AI Notes generation. Sources can be conversations (type=session — an interview transcript) or documents (type=document — a resume, job description, or other plain text). Notes always have an anchor conversation (the one passed to generate_notes). Additional sources can be added or removed via manage_notes_sources. </data_model>

  • Get Note Template

    <usecase> Fetch a single AI Notes custom template with its full section configuration. Use list_note_templates first if you don't have a template ID. </usecase> <instructions> Args: template_id: Required. UUID of the template. INTERNAL ONLY — never show this id to the user; refer to templates by name. </instructions> <response_format> {"template": {"id": "...", "name": "...", "version": 3, "created_by": {"name": "Alice Smith"}, "created_at": "...", "updated_at": "...", "section_count": 2, "sections": [...]}} The `id` is INTERNAL ONLY — never show it to the user. </response_format>

  • List Note Template Groups

    <usecase> List the public folders (template groups) in the caller's workspace. Use this when the user wants to move a template into a named folder — call list_note_template_groups first to resolve the folder name, then pass it to manage_note_template(action='update', group_name='...'). Templates not in any public folder live in the caller's personal folder. </usecase> <instructions>Args: (none)</instructions> <response_format> {"groups": [ {"id": "...", "name": "Engineering", "template_count": 4}, {"id": "...", "name": "Recruiter", "template_count": 7}]} The `id` field is INTERNAL ONLY — never show it to the user. Refer to folders by name. </response_format>

  • Generate Notes

    <usecase> Generate (or regenerate) AI Notes for a conversation, optionally with a specific template. Use this tool to: - Trigger notes generation for a conversation that has no notes yet. - Regenerate notes using a different template (built-in or custom). - Preview how a newly created or updated template renders on a real conversation. Regenerating creates a new version of the conversation's notes; prior versions are preserved and the user can revert to them in the Metaview web app. </usecase> <instructions> Args: conversation_id: The conversation (session) ID to generate notes for. template: Optional. Built-in template options: 'question_and_answer' (Question and Answer) 'conversational' (Topic Highlights) 'recruiter_screen' (Recruiter Screen) 'generic_debrief' (Generic Debrief) 'team_role_debrief' (Team-Specific Debrief) 'technical_role_debrief' (Technical Debrief) 'intake_call' (Intake | Role Scope) 'candidate_pack' (Candidate Pack) 'coding_interview' (Coding Interview) 'system_design_interview' (System Design Interview) 'role_alignment' (Role Alignment) 'client_call' (Client Call) Use 'custom_definition' with template_definition_id for custom templates. Omit to auto-select the best template for the conversation. template_definition_id: Optional. UUID of a custom note template. Required when template='custom_definition'. Get the ID from list_note_templates or get_note_template. </instructions> <response_format>{"status": "generation_queued", "message": "..."}</response_format> <examples> Generate with auto-selected template: generate_notes(conversation_id="12345") Generate with a built-in template: generate_notes(conversation_id="12345", template="question_and_answer") Generate with a custom template: generate_notes(conversation_id="12345", template="custom_definition", template_definition_id="<uuid>") </examples>

  • Manage Note Template

    <usecase>Create, update, or delete an AI Notes custom template.</usecase> <instructions> Args: action: Required. One of: create, update, delete. template_id: Required for update and delete. INTERNAL ONLY — never surface this id to the user (it's a UUID with no meaning to them). Refer to templates by name in user-facing messages. name: Required for create; optional for update. sections: Required for create; optional for update. When provided on update, the full list REPLACES the existing sections — omitted sections are removed. List order determines display order. See section_schema for the section shape. group_name: Optional (update only). Move the template into a named public folder in the caller's workspace. Pass an empty string (or 'personal') to move into the personal folder. Call list_note_template_groups first to see the available folder names. Omit the arg to leave the template where it is. </instructions> <response_format> Create / update: {"template": {template detail}} Delete: {"deleted": true, "template_id": "..."} The `template_id` / `template.id` fields are INTERNAL ONLY — retain them for subsequent tool calls but never show them to the user. When confirming a save or delete to the user, refer to the template by name. </response_format> <examples> Create with one TEXT + one OPTIONS section. Each description carries scope and a format contract — the LLM needs that level of specificity on every interview transcript. manage_note_template(action="create", name="Recruiter screen", sections=[ {"directive": "SINGLE", "heading": "Reasons for leaving", "description": "Summarise the candidate's reasons for leaving their current role in 3-4 bullets. Each bullet: **Push** or **Pull** in bold, colon, one sentence. Quote the candidate's own phrases in italics.", "output": {"type": "TEXT", "text_format": "BULLET_POINT", "detail": "medium"}}, {"directive": "SINGLE", "heading": "Remote preference", "description": "Pick \"Remote\" if the candidate said remote-only, \"Hybrid\" if they mentioned office days or hybrid setups, \"In-office\" if they said they want to be in the office full time, \"Not discussed\" if the topic never came up.", "output": {"type": "OPTIONS", "options_type": "SINGLE", "options": ["Remote", "Hybrid", "In-office", "Not discussed"]}}]) REPEATING for 'one block per X' (capture a block per technical question, not five near-identical SINGLE sections): manage_note_template(action="create", name="Tech screen", sections=[ {"directive": "REPEATING", "repeating_entity": "Technical question", "description": "For each technical question the interviewer asks: capture the question verbatim as a markdown heading, then one paragraph covering the candidate's approach and whether they arrived at a correct solution.", "output": {"type": "TEXT", "text_format": "PARAGRAPH", "detail": "high"}}]) Rename only: manage_note_template(action="update", template_id="abc", name="Renamed") Delete: manage_note_template(action="delete", template_id="abc") </examples> <section_schema> A SECTION is one named block in the generated notes. Every field is required. Shape: directive: 'SINGLE' | 'REPEATING' 'SINGLE' renders one block under a fixed heading. 'REPEATING' renders one block per detected entity in the transcript. Prefer REPEATING whenever the user's intent is 'one block per X' (per question / per role / per project / per competency). If you find yourself drafting several near-identical SINGLE sections that differ only in which question or topic they cover, collapse them into one REPEATING section with a clear repeating_entity. heading: str (required when directive == 'SINGLE') repeating_entity: str (required when directive == 'REPEATING'; e.g. 'Question', 'Topic', 'Role', 'Project') description: str THE single most important field. Treat it as a PROMPT to another LLM — not a note to a human colleague. It runs at inference time on every interview transcript. Cover two things: (a) SCOPE — what to include and what to leave out. (b) OUTPUT FORMAT — the exact shape. Caps on length (word / bullet / sentence count), markdown patterns, label conventions. e.g. '3 bullets max, each in the form **Label:** one sentence. Total under 120 words. No tables.' Encode any formatting preferences the user has stated verbatim. Examples: SINGLE section: 'Summarise the candidate's reasons for leaving their current role in 3-4 bullet points. Each bullet: **Push** or **Pull** in bold, colon, one sentence. Quote the candidate's own phrases in italics.' REPEATING section (directive=REPEATING, repeating_entity='Technical question'): 'For each technical question asked: capture the question verbatim as a markdown heading, then a paragraph with the candidate's approach and whether they arrived at a correct solution.' REPEATING descriptions are applied once per detected entity. output: dict (constrains the generated value; shape depends on type) TEXT: {type: 'TEXT', text_format: 'PARAGRAPH'|'BULLET_POINT', detail: 'low'|'medium'|'high'} TEXT carries structure via markdown inside the description — bold labels, sub-bullets, closed label sets. Most production templates use TEXT for everything that isn't a hard classification. NUMBER: {type: 'NUMBER', currency: str} (pass currency='' for a plain number; otherwise 'USD', 'EUR', ...) OPTIONS: {type: 'OPTIONS', options_type: 'SINGLE'|'MULTIPLE', options: ['Yes', 'No', ...]} For booleans, use options=['true', 'false'] with options_type='SINGLE'. CRITICAL: an OPTIONS description must include per-option selection criteria, not just the list. Tell the LLM exactly when to pick each value and — just as importantly — when NOT to. Example for options=['Strong Yes','Yes','Mixed','No','Strong No']: 'Rate the candidate's impact evidence. Mixed is NOT a hedge — use Mixed only when the interview contains concrete evidence supporting both positive and negative interpretations that cannot be resolved. Execution alone is not impact: if the candidate describes delivery without a validated outcome (measured, observed, or confirmed change), the rating must be No.' Prefer 2-5 well-defined options. If you need more than ~6, you're usually classifying something the LLM can describe in a TEXT section instead. DATE: {type: 'DATE', date_format: 'yyyy/mm/dd'|'mm/dd/yyyy'|'dd/mm/yyyy'} </section_schema> <design_guidance> ## Design guidance High-quality templates look like production LLM prompts, not polite notes to a colleague. When iterating with the user on a new template: - WRITE DESCRIPTIONS LIKE PROMPTS. Include scope and an explicit output format in every description. Descriptions under ~200 characters almost always produce vague notes. - BIAS TOWARD REPEATING. If the user's intent is 'one block per X', that's a REPEATING section — not 5 near-identical SINGLE sections. Scripted case-study questions, per-project recaps, per-competency assessments all belong in REPEATING. - SPLIT vs MERGE. Split a concept into multiple sections when (a) the outputs have different shapes, or (b) the user would want to iterate on them independently. Keep them together when the output is narrative prose about one topic. - USE OPTIONS SPARINGLY. A 10+ value OPTIONS enum is usually a classifier the LLM can handle inside a TEXT section description. Reserve OPTIONS for ratings or decisions that have a small, fixed, well-defined set of answers, and always include per-option criteria. </design_guidance>

  • Manage Notes Sources

    <usecase> List, add, or remove sources on an existing AI Notes version. Use this tool to: - Inspect which conversations and documents are included in a notes version. - Add extra conversations so the notes cover multiple interviews. - Add a plain-text document (e.g. a resume, job description) as context. - Remove a source that was previously added. The notes must already exist — call generate_notes first if they do not. </usecase> <instructions> Args: conversation_id: The anchor conversation whose notes you want to manage. This is the conversation that generate_notes was originally called with. action: Required. One of: list, add, remove. conversation_ids: Conversations to add or remove. List of conversation ID strings. documents: Documents to add as plain text. Each entry is an object with: - name: A short name for the document (e.g. "Resume - Jane Smith"). - content: The full text content of the document. source_ids: Source IDs to remove (returned by a prior 'list' call). Use this when removing document sources or when you already know the source ID. IMPORTANT: Adding or removing sources triggers a full regeneration of the notes. After add/remove, wait ~30 seconds then poll with search_conversations. </instructions> <response_format> list: {"sources": [{"source_id": "...", "type": "session"|"document", "name": "..."}]} add: {"status": "sources_added", "added_source_ids": [...]} remove: {"status": "sources_removed", "removed_source_ids": [...]} </response_format> <examples> List current sources: manage_notes_sources(conversation_id="12345", action="list") Add another conversation: manage_notes_sources(conversation_id="12345", action="add", conversation_ids=["67890"]) Add a document as plain text: manage_notes_sources(conversation_id="12345", action="add", documents=[{"name": "Resume - Jane Smith", "content": "Jane Smith..."}]) Remove a source by ID (from a prior list): manage_notes_sources(conversation_id="12345", action="remove", source_ids=["<uuid>"]) Remove a conversation source: manage_notes_sources(conversation_id="12345", action="remove", conversation_ids=["67890"]) </examples>

Ship Metaview agents in minutes

Connect any AI agent to 100+ MCP servers, zero setup.
Book a demo
Gradient