CareerGenius is preparing an API and an MCP server for AI agents that act for one person who asked for help with their own job search. Neither is open yet. This page describes how agents will connect, so you can plan; it will say when the API opens.
Coming soon Coming soon: the API and MCP server are not open yet, and calls to the addresses below do not work until they open.
https://api.careergenius.org/mcphttps://api.careergenius.org/api/agent/v1/The MCP tools and the REST operations take the same input and return the same output.
careergenius_keyword_gapComing soonKeywords the posting asks for that the resume shows / doesn't show
REST: POST https://api.careergenius.org/api/agent/v1/keyword-gap
Deterministic, no AI. Not a score and not a prediction.
| Field | Type | Notes |
|---|---|---|
posting_text | string | at least 40 characters; at most 30,000 characters |
job_url | string | at most 2,048 characters; uri; Public http(s) job page on port 80/443. Greenhouse, Lever, Ashby, SmartRecruiters, Workday and pages with schema.org JobPosting read best. LinkedIn links are not fetched: send posting_text. |
on_behalf_of required | object | You confirm a person asked for this, and the resume is theirs (or they are authorised to use it). |
on_behalf_of.human_requested required | true | |
on_behalf_of.resume_is_theirs required | true | |
resume | object | Structured resume. Send only what the person has really done; every output is checked against it. |
resume.name | string | at most 120 characters |
resume.headline | string | at most 120 characters |
resume.summary | string | at most 3,000 characters |
resume.experience | array of objects | at most 15 items |
resume.experience[].title | string | at most 120 characters |
resume.experience[].employer | string | at most 120 characters |
resume.experience[].location | string | at most 120 characters |
resume.experience[].start_date | string | at most 20 characters |
resume.experience[].end_date | string | at most 20 characters |
resume.experience[].current | boolean | |
resume.experience[].bullets | array of string | at most 15 items |
resume.education | array of objects | at most 8 items |
resume.education[].degree | string | |
resume.education[].field | string | |
resume.education[].school | string | |
resume.education[].start_date | string | |
resume.education[].end_date | string | |
resume.education[].details | array of string | |
resume.skills | array of string | at most 80 items |
resume.sections | array of objects | at most 6 items |
resume.sections[].title | string | |
resume.sections[].items | array of string | at most 15 items |
resume_text | string | at least 40 characters; at most 30,000 characters |
keywords | array of string | at most 30 items; Extra keywords to check (the posting's named tools and credentials are found automatically). |
| Field | Type | Notes |
|---|---|---|
request_id | string | uuid |
api_version | string | |
operation | "keyword_gap" | |
posting | object | |
posting.title | string | null | |
posting.company | string | null | |
posting.source | string | posting_text, or how the link was read (ats-api, json-ld, embedded-json, generic) |
keywords | object | |
keywords.asked_for | array of string | |
keywords.shown_on_resume | array of string | |
keywords.not_shown_on_resume | array of string | |
keywords.found_in_posting | integer | |
keywords.supplied_by_caller | integer | |
method | string | |
notes | array of string |
careergenius_tailor_resumeComing soonReword the summary and job bullets for one posting (fact-checked)
REST: POST https://api.careergenius.org/api/agent/v1/tailor
One AI call, then the CareerGenius Suggest fact check on every line. Lines that fail keep their original wording and are listed in held_back by field, index and reason code. Their text is never returned. Counts against the allowance only when at least one suggestion is delivered.
| Field | Type | Notes |
|---|---|---|
posting_text | string | at least 40 characters; at most 30,000 characters |
job_url | string | at most 2,048 characters; uri; Public http(s) job page on port 80/443. Greenhouse, Lever, Ashby, SmartRecruiters, Workday and pages with schema.org JobPosting read best. LinkedIn links are not fetched: send posting_text. |
on_behalf_of required | object | You confirm a person asked for this, and the resume is theirs (or they are authorised to use it). |
on_behalf_of.human_requested required | true | |
on_behalf_of.resume_is_theirs required | true | |
resume required | object | Structured resume. Send only what the person has really done; every output is checked against it. |
resume.name | string | at most 120 characters |
resume.headline | string | at most 120 characters |
resume.summary | string | at most 3,000 characters |
resume.experience | array of objects | at most 15 items |
resume.experience[].title | string | at most 120 characters |
resume.experience[].employer | string | at most 120 characters |
resume.experience[].location | string | at most 120 characters |
resume.experience[].start_date | string | at most 20 characters |
resume.experience[].end_date | string | at most 20 characters |
resume.experience[].current | boolean | |
resume.experience[].bullets | array of string | at most 15 items |
resume.education | array of objects | at most 8 items |
resume.education[].degree | string | |
resume.education[].field | string | |
resume.education[].school | string | |
resume.education[].start_date | string | |
resume.education[].end_date | string | |
resume.education[].details | array of string | |
resume.skills | array of string | at most 80 items |
resume.sections | array of objects | at most 6 items |
resume.sections[].title | string | |
resume.sections[].items | array of string | at most 15 items |
| Field | Type | Notes |
|---|---|---|
request_id | string | uuid |
api_version | string | |
operation | "tailor" | |
suggestions | array of objects | |
suggestions[].field | string | |
suggestions[].original | string | |
suggestions[].suggested | string | |
suggestions[].items | array of objects | |
suggestions[].items[].index | integer | |
suggestions[].items[].original | string | |
suggestions[].items[].suggested | string | |
held_back | array of objects | |
held_back[].field | string | |
held_back[].index | integer | |
held_back[].reasons | array of objects | |
held_back[].reasons[].code | string | |
held_back[].reasons[].why | string | |
notes | array of string |
careergenius_cover_letterComing soonA cover letter or hiring-manager letter, every sentence checked against the resume
REST: POST https://api.careergenius.org/api/agent/v1/cover-letter
The CareerGenius letter pipeline: draft, check every sentence, at most one rewrite, clean. Unsupported or off-topic sentences are removed and counted by reason (their text is not returned). If what remains is not a letter grounded in this resume, the answer is 422 LETTER_HELD with no text and nothing is charged.
| Field | Type | Notes |
|---|---|---|
posting_text | string | at least 40 characters; at most 30,000 characters |
job_url | string | at most 2,048 characters; uri; Public http(s) job page on port 80/443. Greenhouse, Lever, Ashby, SmartRecruiters, Workday and pages with schema.org JobPosting read best. LinkedIn links are not fetched: send posting_text. |
on_behalf_of required | object | You confirm a person asked for this, and the resume is theirs (or they are authorised to use it). |
on_behalf_of.human_requested required | true | |
on_behalf_of.resume_is_theirs required | true | |
resume | object | Structured resume. Send only what the person has really done; every output is checked against it. |
resume.name | string | at most 120 characters |
resume.headline | string | at most 120 characters |
resume.summary | string | at most 3,000 characters |
resume.experience | array of objects | at most 15 items |
resume.experience[].title | string | at most 120 characters |
resume.experience[].employer | string | at most 120 characters |
resume.experience[].location | string | at most 120 characters |
resume.experience[].start_date | string | at most 20 characters |
resume.experience[].end_date | string | at most 20 characters |
resume.experience[].current | boolean | |
resume.experience[].bullets | array of string | at most 15 items |
resume.education | array of objects | at most 8 items |
resume.education[].degree | string | |
resume.education[].field | string | |
resume.education[].school | string | |
resume.education[].start_date | string | |
resume.education[].end_date | string | |
resume.education[].details | array of string | |
resume.skills | array of string | at most 80 items |
resume.sections | array of objects | at most 6 items |
resume.sections[].title | string | |
resume.sections[].items | array of string | at most 15 items |
resume_text | string | at least 40 characters; at most 30,000 characters |
kind | "cover-letter" | "hiring-manager-letter" | default "cover-letter" |
applicant_name | string | at most 120 characters |
job_title | string | at most 120 characters; Recommended; otherwise read from the posting. |
company_name | string | at most 120 characters; Recommended; otherwise read from the posting. |
| Field | Type | Notes |
|---|---|---|
request_id | string | uuid |
api_version | string | |
operation | "cover_letter" | |
kind | string | |
letter | string | |
removed | array of objects | at most 20 items |
removed[].reason | "unsupported_claim" | "off_topic" | |
removed[].why | string | at most 160 characters |
reworded | array of objects | at most 20 items |
reworded[].reason | "stretched_wording" | |
reworded[].now_reads | string | |
reworded[].why | string | |
added_from_resume | array of string | |
attempts | integer | 1 to 2 |
notes | array of string |
careergenius_interview_prepComing soonLikely interview questions for a posting, with answer outlines built only from the resume
REST: POST https://api.careergenius.org/api/agent/v1/interview-prep
Same resume and posting inputs as tailor-resume-pdf (no template / page_size). One AI call with a fixed prompt; the posting and resume are fenced as data and instructions inside them are ignored. A question is kept only if it is a short question about this posting. Every answer point must cite one resume line (summary or an experience bullet) and pass the CareerGenius fact check against that line: a point that adds a tool, number, result, title or employer is removed and listed by reason code. One paid call (allowance + AI cap) when at least one question is delivered. Scope: interview_prep. Idempotency-Key supported.
| Field | Type | Notes |
|---|---|---|
resume | object | Structured resume. Send only what the person has really done; every output is checked against it. |
resume.name | string | at most 120 characters |
resume.headline | string | at most 120 characters |
resume.summary | string | at most 3,000 characters |
resume.experience | array of objects | at most 15 items |
resume.experience[].title | string | at most 120 characters |
resume.experience[].employer | string | at most 120 characters |
resume.experience[].location | string | at most 120 characters |
resume.experience[].start_date | string | at most 20 characters |
resume.experience[].end_date | string | at most 20 characters |
resume.experience[].current | boolean | |
resume.experience[].bullets | array of string | at most 15 items |
resume.education | array of objects | at most 8 items |
resume.education[].degree | string | |
resume.education[].field | string | |
resume.education[].school | string | |
resume.education[].start_date | string | |
resume.education[].end_date | string | |
resume.education[].details | array of string | |
resume.skills | array of string | at most 80 items |
resume.sections | array of objects | at most 6 items |
resume.sections[].title | string | |
resume.sections[].items | array of string | at most 15 items |
resume_text | string | at most 30,000 characters; Pasted plain text. Read by a fixed layout parser (no AI). Headings such as Summary, Experience, Education, Skills help. |
resume_file | object | |
resume_file.format required | "pdf" | "docx" | |
resume_file.content_base64 required | string | At most 1.5 MB decoded. PDFs need a text layer (scans are refused: FILE_UNREADABLE). |
resume_file.filename | string | at most 200 characters |
contact | object | |
contact.name | string | at most 120 characters |
contact.email | string | at most 254 characters |
contact.phone | string | at most 40 characters |
contact.location | string | at most 120 characters |
links | array of objects | at most 5 items |
links[].label | string | at most 40 characters |
links[].url required | string | at most 300 characters |
posting_text | string | at least 40 characters; at most 30,000 characters |
job_url | string | at most 2,048 characters; uri; Public http(s) job page on port 80/443. Greenhouse, Lever, Ashby, SmartRecruiters, Workday and pages with schema.org JobPosting read best. LinkedIn links are not fetched: send posting_text. |
on_behalf_of required | object | You confirm a person asked for this, and the resume is theirs (or they are authorised to use it). |
on_behalf_of.human_requested required | true | |
on_behalf_of.resume_is_theirs required | true |
| Field | Type | Notes |
|---|---|---|
request_id | string | uuid |
api_version | string | |
operation | "interview_prep" | |
questions | array of objects | at most 8 items |
questions[].question | string | |
questions[].answer_outline | array of objects | at most 4 items |
questions[].answer_outline[].text | string | |
questions[].answer_outline[].from | string | The resume line it restates, e.g. experience[0].bullets[2] or summary. |
questions[].answer_outline[].resume_line | string | |
held_back | array of objects | |
held_back[].question | integer | |
held_back[].point | integer | |
held_back[].reasons | array of objects | |
notes | array of string |
careergenius_render_resume_pdfComing soonLay out a structured resume as a clean, single-column, ATS-readable PDF (no AI)
REST: POST https://api.careergenius.org/api/agent/v1/resume-pdf
Real selectable text with embedded fonts (Liberation Sans / Serif, SIL OFL), single column, no images, no tables, no clickable links (web addresses are printed as text), no scripts, actions or form fields. Letter or A4; templates classic (serif, centred header) and modern (sans-serif, left-aligned). At most 3 pages: a longer resume is refused with 422 TOO_MANY_PAGES. Text is printed exactly as sent (no rewording, no fact check), after removing control, zero-width and bidi-override characters. Characters the fonts cannot print (scripts other than Latin, Greek and Cyrillic) are refused with 400 UNSUPPORTED_CHARACTER and the field. The file is returned in the response as base64 and is never stored (no download link). Idempotency-Key is ignored here: a retry is a new call. One render at a time per key (429 CONCURRENCY); the server renders in a small worker pool with a queue (429 RENDER_BUSY when full) and stops a render after 5 s (503 RENDER_TIMEOUT). Counts one call of the monthly allowance when the file is delivered. Scope: render_resume.
| Field | Type | Notes |
|---|---|---|
on_behalf_of required | object | You confirm a person asked for this, and the resume is theirs (or they are authorised to use it). |
on_behalf_of.human_requested required | true | |
on_behalf_of.resume_is_theirs required | true | |
resume required | object | Closed schema at every level (an unknown field is 400 UNKNOWN_FIELD). At most 40,000 characters of JSON. |
resume.contact required | object | |
resume.contact.name required | string | at most 120 characters |
resume.contact.headline | string | at most 160 characters |
resume.contact.email | string | at most 254 characters |
resume.contact.phone | string | at most 40 characters |
resume.contact.location | string | at most 120 characters |
resume.links | array of objects | at most 5 items; http(s) only, no user name or password. Printed as text without the scheme, never as a clickable link. |
resume.links[].label | string | at most 40 characters |
resume.links[].url required | string | at most 300 characters |
resume.summary | string | at most 2,000 characters; Line breaks start new paragraphs. |
resume.experience | array of objects | at most 15 items |
resume.experience[].title required | string | at most 160 characters |
resume.experience[].employer | string | at most 160 characters |
resume.experience[].location | string | at most 120 characters |
resume.experience[].start_date | string | at most 25 characters; Printed as sent |
resume.experience[].end_date | string | at most 25 characters |
resume.experience[].current | boolean | Prints "Present"; do not also send end_date. |
resume.experience[].bullets | array of string | at most 12 items |
resume.education | array of objects | at most 8 items |
resume.education[].school required | string | at most 160 characters |
resume.education[].degree | string | at most 160 characters |
resume.education[].field | string | at most 160 characters |
resume.education[].location | string | at most 120 characters |
resume.education[].start_date | string | at most 25 characters |
resume.education[].end_date | string | at most 25 characters |
resume.education[].details | array of string | at most 6 items |
resume.skills | array of string | at most 80 items |
resume.certifications | array of objects | at most 20 items |
resume.certifications[].name required | string | at most 200 characters |
resume.certifications[].issuer | string | at most 160 characters |
resume.certifications[].date | string | at most 25 characters |
template | "classic" | "modern" | default "classic" |
page_size | "letter" | "a4" | default "letter" |
| Field | Type | Notes |
|---|---|---|
request_id | string | uuid |
api_version | string | |
format required | "pdf" | "docx" | |
template required | "classic" | "modern" | |
page_size required | "letter" | "a4" | |
pages required | integer | null | 1 to 3; PDF page count; null for docx. |
bytes required | integer | |
sha256 required | string | SHA-256 of the file bytes (hex). |
filename required | string | |
content_type required | string | |
data_base64 required | string | The file. Decode and save it: nothing is kept on our side. |
careergenius_tailor_resume_pdfComing soonOne call: job posting + resume (text, PDF, DOCX or JSON) -> tailored, fact-checked PDF + what changed
REST: POST https://api.careergenius.org/api/agent/v1/tailor-resume-pdf
1. Reads the posting (posting_text, or job_url through the job-import engine: public addresses only, redirects re-checked, size and time limits). 2. Reads the resume: structured JSON; or plain text / a PDF or DOCX file (base64, at most 1.5 MB, needs a text layer) read by a fixed layout parser (no AI; every value is the resume's own words; a field it cannot find stays empty). Files are parsed in an isolated worker with a time and memory limit. 3. Lists the keywords the posting asks for and which the resume shows (not a score). 4. Rewords the summary and job bullets for this posting (one AI call) and runs every rewording through the CareerGenius fact check. ONLY rewordings that pass are applied; the others keep the original wording and are listed in held_back by field, index and reason code (their text is never returned). 5. Lays out the tailored resume as a single-column, ATS-readable PDF (as resume-pdf) and returns it with the summary. Nothing is stored; Idempotency-Key is ignored (a retry is a new call). Counts one call of the monthly allowance when the PDF is delivered; the AI cost counts against the key's AI cap. One request at a time per key. Scope: tailor_resume_pdf.
| Field | Type | Notes |
|---|---|---|
resume | object | Structured resume. Send only what the person has really done; every output is checked against it. |
resume.name | string | at most 120 characters |
resume.headline | string | at most 120 characters |
resume.summary | string | at most 3,000 characters |
resume.experience | array of objects | at most 15 items |
resume.experience[].title | string | at most 120 characters |
resume.experience[].employer | string | at most 120 characters |
resume.experience[].location | string | at most 120 characters |
resume.experience[].start_date | string | at most 20 characters |
resume.experience[].end_date | string | at most 20 characters |
resume.experience[].current | boolean | |
resume.experience[].bullets | array of string | at most 15 items |
resume.education | array of objects | at most 8 items |
resume.education[].degree | string | |
resume.education[].field | string | |
resume.education[].school | string | |
resume.education[].start_date | string | |
resume.education[].end_date | string | |
resume.education[].details | array of string | |
resume.skills | array of string | at most 80 items |
resume.sections | array of objects | at most 6 items |
resume.sections[].title | string | |
resume.sections[].items | array of string | at most 15 items |
resume_text | string | at most 30,000 characters; Pasted plain text. Read by a fixed layout parser (no AI). Headings such as Summary, Experience, Education, Skills help. |
resume_file | object | |
resume_file.format required | "pdf" | "docx" | |
resume_file.content_base64 required | string | At most 1.5 MB decoded. PDFs need a text layer (scans are refused: FILE_UNREADABLE). |
resume_file.filename | string | at most 200 characters |
contact | object | |
contact.name | string | at most 120 characters |
contact.email | string | at most 254 characters |
contact.phone | string | at most 40 characters |
contact.location | string | at most 120 characters |
links | array of objects | at most 5 items |
links[].label | string | at most 40 characters |
links[].url required | string | at most 300 characters |
posting_text | string | at least 40 characters; at most 30,000 characters |
job_url | string | at most 2,048 characters; uri; Public http(s) job page on port 80/443. Greenhouse, Lever, Ashby, SmartRecruiters, Workday and pages with schema.org JobPosting read best. LinkedIn links are not fetched: send posting_text. |
on_behalf_of required | object | You confirm a person asked for this, and the resume is theirs (or they are authorised to use it). |
on_behalf_of.human_requested required | true | |
on_behalf_of.resume_is_theirs required | true | |
template | "classic" | "modern" | default "classic" |
page_size | "letter" | "a4" | default "letter" |
| Field | Type | Notes |
|---|---|---|
request_id | string | uuid |
api_version | string | |
operation | "tailor_resume_pdf" | |
posting | object | |
resume_source | "structured" | "text" | "pdf" | "docx" | |
parse_notes | array of string | |
keywords | object | Lists, not a score. |
keywords.asked_for | array of string | |
keywords.shown_before | array of string | |
keywords.shown_after | array of string | |
keywords.newly_shown | array of string | |
keywords.not_shown_after | array of string | |
changes | array of objects | Applied rewordings (same items as tailor's suggestions). |
held_back | array of objects | Rewordings that failed the fact check: field, index, reason codes. Never their text. |
pdf | object | |
pdf.template | string | |
pdf.page_size | string | |
pdf.pages | integer | |
pdf.bytes | integer | |
pdf.sha256 | string | |
pdf.filename | string | |
pdf.content_type | "application/pdf" | |
pdf.data_base64 | string | |
notes | array of string |
careergenius_render_resume_docxComing soonThe same resume layout as an editable Word (.docx) file (no AI)
REST: POST https://api.careergenius.org/api/agent/v1/resume-docx
Same input, rules and limits as resume-pdf. Plain paragraphs and a bullet list; no hyperlinks, fields, images or macros; fonts referenced by name (Times New Roman / Arial). pages is null (a Word file has no fixed page count until it is opened). Scope: render_resume.
| Field | Type | Notes |
|---|---|---|
on_behalf_of required | object | You confirm a person asked for this, and the resume is theirs (or they are authorised to use it). |
on_behalf_of.human_requested required | true | |
on_behalf_of.resume_is_theirs required | true | |
resume required | object | Closed schema at every level (an unknown field is 400 UNKNOWN_FIELD). At most 40,000 characters of JSON. |
resume.contact required | object | |
resume.contact.name required | string | at most 120 characters |
resume.contact.headline | string | at most 160 characters |
resume.contact.email | string | at most 254 characters |
resume.contact.phone | string | at most 40 characters |
resume.contact.location | string | at most 120 characters |
resume.links | array of objects | at most 5 items; http(s) only, no user name or password. Printed as text without the scheme, never as a clickable link. |
resume.links[].label | string | at most 40 characters |
resume.links[].url required | string | at most 300 characters |
resume.summary | string | at most 2,000 characters; Line breaks start new paragraphs. |
resume.experience | array of objects | at most 15 items |
resume.experience[].title required | string | at most 160 characters |
resume.experience[].employer | string | at most 160 characters |
resume.experience[].location | string | at most 120 characters |
resume.experience[].start_date | string | at most 25 characters; Printed as sent |
resume.experience[].end_date | string | at most 25 characters |
resume.experience[].current | boolean | Prints "Present"; do not also send end_date. |
resume.experience[].bullets | array of string | at most 12 items |
resume.education | array of objects | at most 8 items |
resume.education[].school required | string | at most 160 characters |
resume.education[].degree | string | at most 160 characters |
resume.education[].field | string | at most 160 characters |
resume.education[].location | string | at most 120 characters |
resume.education[].start_date | string | at most 25 characters |
resume.education[].end_date | string | at most 25 characters |
resume.education[].details | array of string | at most 6 items |
resume.skills | array of string | at most 80 items |
resume.certifications | array of objects | at most 20 items |
resume.certifications[].name required | string | at most 200 characters |
resume.certifications[].issuer | string | at most 160 characters |
resume.certifications[].date | string | at most 25 characters |
template | "classic" | "modern" | default "classic" |
page_size | "letter" | "a4" | default "letter" |
| Field | Type | Notes |
|---|---|---|
request_id | string | uuid |
api_version | string | |
format required | "pdf" | "docx" | |
template required | "classic" | "modern" | |
page_size required | "letter" | "a4" | |
pages required | integer | null | 1 to 3; PDF page count; null for docx. |
bytes required | integer | |
sha256 required | string | SHA-256 of the file bytes (hex). |
filename required | string | |
content_type required | string | |
data_base64 required | string | The file. Decode and save it: nothing is kept on our side. |
Replace the placeholder with the person's key. Until the API opens, these calls do not work.
curl -sS -X POST 'https://api.careergenius.org/api/agent/v1/keyword-gap' \
-H 'Authorization: Bearer <your CareerGenius API key>' \
-H 'Content-Type: application/json' \
-d '{"on_behalf_of":{"human_requested":true,"resume_is_theirs":true},"resume_text":"Jordan Example. Data analyst since 2021: weekly sales reports in SQL and Tableau.","posting_text":"Data Analyst. You will build reports for the sales team with SQL, Python and Tableau."}'curl -sS -X POST 'https://api.careergenius.org/mcp' \
-H 'Authorization: Bearer <your CareerGenius API key>' \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-H 'MCP-Protocol-Version: 2025-06-18' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"careergenius_keyword_gap","arguments":{"on_behalf_of":{"human_requested":true,"resume_is_theirs":true},"resume_text":"Jordan Example. Data analyst since 2021: weekly sales reports in SQL and Tableau.","posting_text":"Data Analyst. You will build reports for the sales team with SQL, Python and Tableau."}}}'In claude_desktop_config.json, through the mcp-remote bridge (the key stays in an environment variable):
{
"mcpServers": {
"careergenius": {
"command": "npx",
"args": [
"-y",
"mcp-remote",
"https://api.careergenius.org/mcp",
"--header",
"Authorization:${CAREERGENIUS_AUTH}"
],
"env": {
"CAREERGENIUS_AUTH": "Bearer <your CareerGenius API key>"
}
}
}
}claude mcp add --transport http careergenius https://api.careergenius.org/mcp --header "Authorization: Bearer <your CareerGenius API key>"ChatGPT's app connectors sign in with OAuth, which CareerGenius does not offer yet. Agents built on the OpenAI Responses API can pass the key in the MCP tool's authorization field:
{
"type": "mcp",
"server_label": "careergenius",
"server_url": "https://api.careergenius.org/mcp",
"authorization": "<your CareerGenius API key>",
"require_approval": "always"
}Included with CareerGenius Premium. Agent access has no separate price. Premium: $29.99 a month, renewing until you cancel; $119.94 every 6 months, renewing until you cancel. See pricing.