add_note_to_person
ChatGPTAdd a note to a person's activity feed. Pass person_ext_id (e.g. from search, search_people, or get_person) and the note content. content is plain text by default; set content_format='html' to pass sanitized rich formatting (<p>, <br>, <b>, <ul>/<li>, <a href>). To @-mention a teammate, put an @[user_id] token (the user_id from search_users) inline in content — they're notified and start following the person. A visible note can also notify teammates who follow the person and, for eligible Greenhouse teams, sync to the ATS activity feed. Returns the person's ext_id and the new note's ext_id.
archive_project
ChatGPTArchive an existing project, or restore an archived one. Pass the project's project_ext_id (e.g. from search or get_project); archived defaults to true to archive. This is reversible — call again with archived=false to unarchive and restore the project. Returns the project_ext_id and the project's new is_archived state. Archiving hides the project from active views but does not delete it or its candidates.
archive_sequence
ChatGPTArchive an outreach sequence template, or unarchive it to restore it (pass archived=false). Only sequence templates can be archived — not drafts or individual sequence instances. Archiving is reversible. Consider get_sequence first to see how many people are still actively enrolled. Returns the sequence's ext_id and its resulting is_archived state.
delete_widget
ChatGPTPermanently delete a widget from its dashboard. The widget is removed immediately and cannot be recovered. Returns the deleted widget's ext_id and deleted=true.
edit_project_enrollment
ChatGPTAdd candidates to or remove them from an existing project. Pass the project's project_ext_id (e.g. from search or get_project) plus add_person_ext_ids and/or remove_person_ext_ids (person ext_ids from search, search_people, or get_person). Returns the project_ext_id, how many were added and removed, and the skipped ext_ids. Use save_project to create the project itself or edit its name/description.
edit_sequence_enrollment
ChatGPTEnroll people into an existing outreach sequence and/or unenroll them. Pass sequence_ext_id (owned by the current user) plus add_person_ext_ids and/or remove_person_ext_ids (person ext_ids, e.g. from search or search_people). Returns how many were newly added, how many removed, a skipped list pairing each person NOT acted on with the reason, and any warnings about the people who were. Enrolling into a reusable template copies it into a new sequence, so the returned sequence_ext_id may differ from the one passed in. Use save_sequence first to create the sequence shell.
edit_sequence_stages
ChatGPTEdit one outreach stage (an email/message step) of a sequence owned by the current user — its subject, body_html (rich-text body), stage_type, and wait_days — addressed by index (use N+1 to append a new follow-up). Pass the version from get_sequence: the edit is rejected if the sequence changed since you read it, and a successful edit returns the new version to chain the next edit. An unknown merge token is rejected; text that only looks suspect comes back in warnings. Returns the affected index, a created flag, the new version, and any warnings. Use save_sequence to create the sequence first, and get_sequence to read the stages and current version.
get_application
ChatGPTLook up one application (a candidate on a specific job) by ext_id — status, stage, stage_entry, gem_status (the Talent Pipeline's computed next-step status and SLA health, e.g. NEEDS_DECISION / MISSED_TARGET; null for closed applications and for ATSes without support), source, job ref, rejection (its reason_type says whether we rejected them or they declined), and form answers: the full evaluation record behind an application. Get an ext_id from a person's applications (get_person) or from search_applications. Use fields for interviewer scorecards and the offer. The response is {found, entity} — check found before reading entity; a missing row and a no-access row both return found: false.
get_dashboard
ChatGPTLook up one dashboard by ext_id — name, owner, link, and its widgets in display order. Each widget lists the metric it reports and how it's sliced (metric, visualization, stages, breakdowns, time granularity) plus its grid size — width ("1"/"2"/"3" columns or "max" for full-bleed) and height (row span), both settable back via save_widget. Use it to see what a dashboard tracks and how it's laid out, then call query_metrics to compute those numbers. A dashboard's ext_id is what search (kind=dashboard) returns, and the id in a gem.com /dashboard/<ext_id> URL. The response is {found, entity} — check found before reading entity; a missing row and a no-access row both return found: false.
get_job
ChatGPTLook up one job by ext_id — title, status, requisition id, ATS, department/office, and link. Cross-ATS. For Gem ATS jobs also returns openings ({ext_id, name} → get_opening) and the pipeline stages ({ext_id, name, index} → search_applications's stage_ids). Use fields for the job's custom fields, its job_posts (posting descriptions), and/or its hiring_team (hiring managers, recruiters, coordinators, sourcers, each {name, email}). A job's ext_id is what search / search_jobs return, and the id in a gem.com /ats/jobs/<ext_id> URL. The response is {found, entity} — check found before reading entity; a missing row and a no-access row both return found: false.
get_metrics_catalog
ChatGPTList the metrics and dimensions this team can report on with query_metrics. Call this first to get valid metric and dimension ids. Returns groups of co-queryable metrics: metrics in the same group share a data source, so they can be combined in one query_metrics call and grouped or filtered by that group's dimensions, while metrics from different groups need separate calls. Each metric carries its id, unit, and valid aggregations; each dimension marks whether it's filterable or group-by only. Groups flagged requires_date_range take a date_range from the returned date_ranges. Also returns pipeline_stages — the team's normalized stages in order, each with an id (the STAGE_TYPE:name string) for query_metrics's stages / exclude_stages / cohort_entry_stage and a name for search_people's ats_pipeline_stage — and widget_metrics, the separate metric vocabulary save_widget accepts, each mapped to the query_metrics id it corresponds to. Pass groups to slim a large catalog to just the areas you need.
get_opening
ChatGPTLook up one opening (headcount/requisition) by ext_id — name, status, hire type, department, locations, job levels, associated jobs, target dates, and link. Use fields for its custom fields. Gem ATS only: other ATSes return found: false. ext_id is an opening id, e.g. from a gem.com URL /ats/openings/<ext_id>. The response is {found, entity} — check found before reading entity; a missing row and a no-access row both return found: false.
get_person
ChatGPTLook up one candidate by ext_id — name, current title, company, school, emails, phone numbers, and links, plus optional fields (full work history, education, custom fields, applications, activity timeline, sequence responses, and resumes — presigned download URLs valid for 7 days for the candidate's resume files, including the LinkedIn PDF imported at sourcing time). Feed an application's ext_id into get_application for its scorecards. A candidate's ext_id is what search (kind=person) and search_people return, and the id in a gem.com /candidate/<ext_id> URL. The response is {found, entity} — check found before reading entity; a missing row and a no-access row both return found: false.
get_project
ChatGPTLook up one project by ext_id — name, description, owner, link, type, privacy, archived status, and people_count (candidates in the project). Use fields for its custom fields and/or its people (the candidates in the project). A project's ext_id is what search (kind=project) returns, and the id after -- in a gem.com /projects/--<ext_id> URL. The response is {found, entity} — check found before reading entity; a missing row and a no-access row both return found: false.
get_saved_report
ChatGPTLook up one saved analytics report (Pipeline Analytics or Outreach) by ext_id — its name, type, owner, link, and a ready-to-run query_metrics payload translated from the report's saved configuration. Run that payload through query_metrics to reproduce the report's numbers. For Outreach reports the payload's metrics are the standard activity/cohort family (the report may display a subset). Check fully_reproducible/caveats: when false, the report uses a knob query_metrics can't express and the payload is a best-effort approximation. A saved report's ext_id is the reportId in a gem.com analytics report URL (e.g. /pipeline-stats?reportId=<ext_id> or /outreach-stats?reportId=<ext_id>). The response is {found, entity} — check found before reading entity; a missing row and a no-access row both return found: false.
get_sequence
ChatGPTLook up one outreach sequence by ext_id — name, status, whether it is a reusable template (is_template) and whether it is archived (is_archived), owner, link, a version (the sequence's edit version — pass it to edit_sequence_stages, which rejects edits made against a stale version), and its ordered stages (index, stage_type channel, subject, body as plain text, and days_after cadence). Pass fields for two opt-in sections: enrollment — its recipients with each one's current stage, next send time, reply status, and stop reason (capped, with the full total); and personalization — the per-person AI {gem_ai:} values with a reviewed status (capped, with the full total), where reviewed=false means the value has not yet been approved to send. A sequence's ext_id is what search (kind=sequence) returns, and the id in a gem.com /sequence/<ext_id> URL. The response is {found, entity} — check found before reading entity; a missing row and a no-access row both return found: false.
get_sequence_tokens
ChatGPTList the merge tokens available for writing a sequence stage's subject or body on this team. Call this before authoring a stage so you know which {{tokens}} you can use. Each token's key is the field name that goes inside the braces (write {{first_name}} to insert the candidate's first name), with a human label and a category: Person (the candidate's profile), Custom (the team's custom person fields), Computed (filled at send time, e.g. day_of_week), Job (recruiter_name, only when the team has a connected ATS), and AI, listed only when Gem AI is enabled for the team — a freeform per-person token: write {{gem_ai: <your instruction>}} in the body, then set each person's value with set_sequence_personalization (not pulled from a fixed field). Feed the keys into edit_sequence_stages.
get_tasks
ChatGPTList the current user's actionable to-dos: their upcoming scheduled interviews ('what interviews do I have this week?') and the scorecards they still owe. Pass kind ('interview' or 'scorecard') to filter, or omit for both; soonest first. Each task carries a title, gem_link, the candidate and job, and an application_ext_id to feed into get_application. Interview tasks also carry location, duration_minutes, video_conferencing_url (present only when Gem created the meeting), and interviewers — the full panel with each one's name, email, and response_status. Scorecard tasks also include the questions to fill out (each with text, answer_type, options, and whether it's required). This is the 'what's on my plate' tool — it needs no candidate or job id.
get_widget
ChatGPTLook up one dashboard widget by ext_id (a widget_id from get_dashboard) — its title, visualization, metric, parent dashboard, and a ready-to-run query_metrics payload translated from the widget's saved configuration. Run that payload through query_metrics to reproduce the widget's numbers. For Outreach widgets the payload's metrics are the standard activity/cohort family (the widget may display a subset). Check fully_reproducible/caveats: when false, the widget uses a knob query_metrics can't express and the payload is a best-effort approximation. TEXT widgets have no metric; they return text_content, the full authored body as HTML. get_dashboard carries only a truncated content_preview, so read the body here and pass it back as save_widget's text_content when copying a dashboard. The response is {found, entity} — check found before reading entity; a missing row and a no-access row both return found: false.
query_metrics
ChatGPTRun a recruiting-analytics query and get back an aggregated {columns, rows} table. Use this for reporting and any 'how many / what rate / trend over time' question — pipeline health, pass-through, time-in-stage, outreach, offers, hires. Call get_metrics_catalog first for the metric and dimension ids this team can use; all metrics in one call must come from the same catalog group, and Pipeline Analytics accepts only one metric per query (request candidates / time-in-stage / pass-through separately).
save_dashboard
ChatGPTCreate a new analytics dashboard or edit an existing one's metadata — name, description, emoji, visibility ('PUBLIC' for the whole team or 'PRIVATE' for owner + link), date_range (the relative time window it opens in, e.g. 'last_90_days'), and filter_terms (a JSON-string array of dashboard-wide filters applied to every widget; pass query_metrics-style {dimension_id, ids} terms and they're converted to the stored form on save, like save_widget's filter_terms). Omit dashboard_ext_id to create a fresh dashboard (new ones default to PUBLIC and the last 90 days); pass one — e.g. an ext_id from search — to update, and only the fields you include change. Returns the dashboard's ext_id, name, and a created flag (true when a new dashboard was made). This sets up the dashboard shell only; it does not add or configure widgets.
save_project
ChatGPTCreate a new sourcing project or edit an existing one's metadata (name, description, privacy). Omit project_ext_id to create; pass it to update. Returns the project's ext_id, name, privacy_type, and a created flag. Sets up the project shell only; it does not add or remove candidates.
save_sequence
ChatGPTCreate a new outreach sequence or rename an existing one. Omit sequence_ext_id to create a fresh sequence (set is_template to make it a reusable template); pass one — e.g. an ext_id from search — to rename that sequence. Returns the sequence's ext_id, name, and a created flag (true when a new sequence was made). This sets up the sequence shell only; it does not add or edit outreach stages or recipients.
save_widget
ChatGPTCreate a chart widget on a dashboard, or edit an existing one. Core config is title, metric, visualization, time_granularity, and aggregation_type; breakdowns go in group_breakdown_types and stage_types_and_names, and outreach metrics use outreach_breakdown / outreach_group_by / outreach_activities — each field's accepted values are documented on the field. filter_terms and outreach_filter_terms accept query_metrics-style {dimension_id, ids} terms (as in get_widget's query_metrics.filters) and convert them to the stored dashboard format on save; visualization_options is a JSON-string object of chart options. []/{} clears any of them. Specialized modes: text_content for a TEXT widget, benchmark_statistic_type + benchmark_categories for an industry-standard overlay, the passthrough_ fields for a PASSTHROUGH_RATE / TIME_IN_STAGE cohort, and outreach_funnel_stages for a CANDIDATE_COHORTS_ widget. Size and arrange the widget with width (1/2/3 columns or "max" for full-bleed), height (row span), and position (0-based slot among the dashboard's widgets); new widgets otherwise append in creation order at a default size, and get_dashboard reports each widget's current size and order. Omit widget_ext_id and pass dashboard_ext_id (e.g. from search or save_dashboard) to create; pass widget_ext_id to update, and only the fields you include change. Returns the widget's ext_id, its dashboard_ext_id, and a created flag.
search
ChatGPTQuick cross-type lookup of a Gem entity by name or keyword — people, projects, sequences, dashboards, or jobs. Start here when the user names something: it's the fastest way to turn that name into an ext_id, which you then feed into the get tool for that kind (person→get_person, project→get_project, sequence→get_sequence, dashboard→get_dashboard, job→get_job) or use as a filter elsewhere. Returns lightweight stubs (ext_id, display_name, gem_link). To find candidates by attribute (title, skills, location, pipeline) use search_people instead; for counts, rates, or trends use query_metrics.
search_applications
ChatGPTList the candidates in one job's pipeline. Requires job_id — a job ext_id from search or get_job. Returns shallow application summaries (ext_id, status, stage, stage_id, stage_entry, gem_status — the Talent Pipeline's computed next-step status and SLA health {status, sla_status, associated_ts_ms} for open applications; null for closed ones and for ATSes without support — candidate name/email/location with a get_person-compatible ext_id when person-linked, applied/closed dates, rejection, gem_link, and candidate_tags), newest first; active applications only by default — set include_rejected / include_hired to widen, or stage_ids to filter to stages. Filter by application_statuses (e.g. SCHEDULED, NEEDS_DECISION), sla_statuses (["MISSED_TARGET"] = stalled past the team's SLA target, auto-excluding already-scheduled candidates), or candidate_tags (whole tag names, case-insensitive; every result carries its own tags, so an unfiltered call shows which ones the job uses); with these filters total_count counts only matching applications. Page with limit/offset while has_next_page is true. Pass fields for scorecards or the offer on every row instead of calling get_application per application (limit caps at 25 with scorecards); feed an ext_id into get_application for one record's form answers. For candidates across many jobs use search_people; for pipeline counts use query_metrics.
search_jobs
ChatGPTFind jobs by criteria — turn a job name or req id into the ext_id other tools take, or browse a team's jobs. query matches job title and requisition id; omit it to list all open jobs, and filter by department or office (each with a recursive variant covering sub-departments / child locations), or set following to return only jobs you follow. Returns shallow job stubs (ext_id, title, status, requisition_id, department, offices, gem_link), best match first; page with limit/offset while has_next_page is true. Pass fields for the job's hiring_team (hiring managers, recruiters, coordinators, sourcers, each {name, email}) on every row. Feed an ext_id into get_job for the full record or search_applications for that job's candidates; for job counts or rates use query_metrics.
search_people
ChatGPTFind candidates by attribute across CRM and ATS — title, company, skills, location, years of experience, pipeline stage, scorecards, and contact recency. Filters combine with AND; page with page while has_next_page is true. By default returns only candidates not in an active pipeline and not yet hired (available for fresh outreach) — set include_open_applications to widen. Feed a result's ext_id into get_person. The result also carries a top-level gem_link, a shareable gem.com link that reopens the whole search in Gem's UI. Use search if you already know the person's name, or query_metrics to count or aggregate instead of paging here.
search_users
ChatGPTResolve a teammate to their ATS ID (used for analytics queries and filters that rely on it) and Gem ID (used for tagging in notes). Search by name or email. Each hit returns display_name, email, user_ats_id, and user_id.
set_sequence_personalization
ChatGPTSet per-person AI personalization values for a sequence's {{gem_ai: <prompt>}} tokens — the custom text each recipient sees in place of a token. Pass sequence_ext_id (owned by the current user) and personalizations, a list of {person_ext_id, prompt, value} where prompt matches a {{gem_ai: <prompt>}} token placed in a stage body via edit_sequence_stages. Returns how many were set and a skipped list. Every value is stored UNREVIEWED — it does not send until a human reviews and approves it.
submit_mcp_feedback
ChatGPTSend feedback about these Gem tools to the team at Gem that builds them — a bug, a missing capability, or confusing behavior. Say what you were trying to do and what went wrong; don't include candidate names or other personal data. Use only when the user explicitly asks to send feedback or report a problem to Gem.
whoami
ChatGPTReturn the Gem user this session is authenticated as: user_id, team, email, client id, and the team's ATS (e.g. 'Gem ATS', 'Greenhouse'). Use it to confirm whose data the other tools read, or to resolve who "me" / "my team" is before a filtered search or task lookup.
add_note_to_person
Claudearchive_project
Claudearchive_sequence
Claudedelete_widget
Claudeedit_project_enrollment
Claudeedit_sequence_enrollment
Claudeedit_sequence_stages
Claudeget_application
Claudeget_dashboard
Claudeget_job
Claudeget_metrics_catalog
Claudeget_opening
Claudeget_person
Claudeget_project
Claudeget_saved_report
Claudeget_sequence
Claudeget_sequence_tokens
Claudeget_tasks
Claudeget_widget
Claudequery_metrics
Claudesave_dashboard
Claudesave_project
Claudesave_sequence
Claudesave_widget
Claudesearch
Claudesearch_applications
Claudesearch_jobs
Claudesearch_people
Claudesearch_users
Claudeset_sequence_personalization
Claudesubmit_mcp_feedback
Claudewhoami
Claude