Connect Greenhouse to ChatGPT: Manage Jobs and Candidate Pipelines
A complete engineering guide to connecting Greenhouse to ChatGPT using a managed MCP server. Automate job postings, candidate screening, and scorecards.
If you need to connect Greenhouse to ChatGPT to automate hiring pipelines, audit interview scorecards, or draft offer letters, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between ChatGPT's tool calls and the complex, deeply nested REST APIs provided by Greenhouse. You can either spend engineering cycles building and maintaining this infrastructure yourself, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL—much like the workflow used to connect Zendesk to ChatGPT for customer support automation.
If your team uses Claude, check out our guide on connecting Greenhouse to Claude or explore our broader architectural overview on connecting Greenhouse to AI Agents.
Giving a Large Language Model (LLM) read and write access to an enterprise Applicant Tracking System (ATS) is a massive engineering challenge. You have to handle OAuth 2.0 or API key lifecycles, map massive JSON schemas to MCP tool definitions, and deal with highly specific permission models. Every time a recruiter adds a custom demographic field, your data model shifts. This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for Greenhouse, connect it natively to ChatGPT, and execute complex recruiting workflows using natural language.
The Engineering Reality of the Greenhouse API
A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against vendor APIs is painful. If you decide to build a custom MCP server for Greenhouse, you own the entire API lifecycle.
Greenhouse is not a simple CRUD application. It is a highly customized enterprise workflow engine. Here are the specific integration challenges that break standard REST assumptions when working with Greenhouse:
The 'Job' vs 'Job Post' Dichotomy In Greenhouse, a "Job" is an internal requisition. It contains the hiring team, the approval flow, and internal custom fields. A "Job Post" is the external-facing listing that lives on a job board. If you tell an LLM to "list all jobs", it will pull internal requisitions. If the LLM tries to find the public description or the required application questions in that payload, it will fail and hallucinate. Your MCP server must explicitly distinguish between these objects in its tool descriptions.
Nested Scorecards and Interview Kits
Candidates do not have scorecards; Applications have scorecards attached to Interviews. To get feedback on a candidate, an LLM cannot just query the candidate endpoint. It must resolve the Candidate ID, fetch the associated Application ID, find the Scheduled Interview, and then retrieve the Scorecard. The scorecard itself is a deeply nested array of attributes, ratings, and questions. Exposing this cleanly to an LLM requires exact JSON schema generation.
The Site Admin vs Job Admin Permission Trap
Greenhouse has a notoriously complex permission model. For example, if you query the list_all_greenhouse_job_permissions endpoint to see what a user has access to, it behaves counter-intuitively. This endpoint is only intended for Job Admin or Interviewer roles. If the user is a Site Admin (who has access to everything), the API returns an empty array. If your AI agent relies on this array to verify access, it will falsely assume the Site Admin has zero permissions.
Rate Limits and 429 Exhaustion
Greenhouse enforces strict concurrency and rate limits. If your AI agent gets stuck in a loop trying to summarize 5,000 candidate profiles, Greenhouse will reject the requests with an HTTP 429 error. Truto does not retry, throttle, or absorb these rate limit errors. When the upstream Greenhouse API returns a 429, Truto passes that error directly to the caller. Truto normalizes the upstream rate limit information into standardized IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). It is entirely the responsibility of the caller (your multi-agent framework or ChatGPT client) to read these headers and implement exponential backoff, a critical step when handling third-party API rate limits in AI-driven workflows.
How to Generate a Managed MCP Server for Greenhouse
Instead of writing custom connection logic and JSON schemas for all 50+ Greenhouse endpoints, you can use Truto to generate an MCP server dynamically. Truto translates your authenticated Greenhouse connection into an MCP-compliant endpoint that exposes the API as tools. This follows our recommended strategy of using auto-generated MCP tools for AI agents to scale integration capabilities without manual upkeep.
There are two ways to generate this server.
Method 1: Via the Truto UI
If you are setting this up for internal use or a single tenant, the UI is the fastest path.
- Navigate to the integrated account page for your active Greenhouse connection in the Truto dashboard.
- Click the MCP Servers tab.
- Click Create MCP Server.
- Select your configuration options (Name, Allowed Methods, Tags, and Expiration).
- Copy the generated MCP Server URL (e.g.,
https://api.truto.one/mcp/a1b2c3d4...).
Method 2: Via the Truto API
If you are building an AI product and need to programmatically provision MCP servers for your customers as soon as they connect their Greenhouse instance, use the Truto API.
Make a POST request to /integrated-account/:id/mcp using the ID of the connected Greenhouse account.
POST https://api.truto.one/integrated-account/ia_12345abcde/mcp
Authorization: Bearer <YOUR_TRUTO_API_KEY>
Content-Type: application/json
{
"name": "Greenhouse Recruiting Agent Server",
"config": {
"methods": ["read", "write", "custom"]
},
"expires_at": null
}The API responds with a secure, hashed MCP token URL. This URL contains everything ChatGPT needs to authenticate and discover tools.
{
"id": "mcp_789xyz",
"name": "Greenhouse Recruiting Agent Server",
"config": {
"methods": ["read", "write", "custom"]
},
"expires_at": null,
"url": "https://api.truto.one/mcp/f7a8b9c0d1e2..."
}How to Connect the Greenhouse MCP Server to ChatGPT
Once you have the Truto MCP URL, you need to route ChatGPT's tool calls to it. You can do this visually through the ChatGPT interface, or via a configuration file if you are using an enterprise setup or developer framework.
Method 1: Via the ChatGPT UI
If you are using ChatGPT Plus, Team, or Enterprise, you can add the server directly.
- Open ChatGPT and navigate to Settings -> Apps -> Advanced settings.
- Toggle Developer mode on (Custom MCP connectors are gated behind this setting).
- Under MCP servers / Custom connectors, click Add new.
- Give the connector a name (e.g., "Greenhouse ATS").
- Paste the Truto MCP Server URL into the Server URL field.
- Click Add.
ChatGPT will immediately ping the server, complete the JSON-RPC handshake, and ingest the tool schemas for Greenhouse.
Method 2: Via Manual Configuration File
If you are connecting an agent framework, Cursor, or a local instance that uses the standard MCP configuration format, you can connect to the remote Truto server using the official Server-Sent Events (SSE) transport wrapper.
Add the following to your mcp.json or framework config:
{
"mcpServers": {
"greenhouse": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sse",
"https://api.truto.one/mcp/f7a8b9c0d1e2..."
]
}
}
}This instructs the MCP client to route all standard local tool requests over the network to Truto, which then translates them into authenticated Greenhouse REST requests.
Hero Tools: High-Leverage Greenhouse Operations
Truto exposes every documented Greenhouse resource as an LLM tool. However, throwing 50+ tools at an LLM wastes token context and degrades reasoning. You should restrict your AI agents to high-leverage operations. Here are the core hero tools for Greenhouse.
list_all_greenhouse_candidates
This is the primary discovery tool for sourcing agents. It returns an array of candidates, including their personal details, associated tags, and most importantly, their custom_fields and nested applications.
Usage Note: Greenhouse candidate payloads are heavy. If you run a broad list operation, the LLM will hit context limits quickly. Always instruct the LLM to use query parameters like created_after or filter by specific tags to narrow the response.
"Fetch all candidates added in the last 7 days who have the tag 'Senior Backend' and summarize their current companies and titles."
get_single_greenhouse_candidate_by_id
Once an agent identifies a candidate of interest, it uses this tool to pull the full, unabridged profile. This includes complete education histories, employment histories, and all attached application states.
Usage Note: The candidate ID is globally unique across your Greenhouse instance. The LLM must extract this ID from a previous list operation or webhook payload before calling this tool.
"Get the full candidate profile for ID 8472910. Extract their complete employment history and list all custom fields associated with their profile."
list_all_greenhouse_jobs
This tool retrieves internal requisitions. It returns the job ID, requisition ID, status, department, assigned hiring team, and current openings.
Usage Note: This returns internal data, not the public job description. Agents use this tool to answer operational questions about pipeline capacity or hiring manager assignments.
"List all active jobs in the Engineering department. Tell me who the designated Hiring Manager and Recruiter are for the 'Staff Data Engineer' role."
get_single_greenhouse_application_by_id
In Greenhouse, an Application is the bridge between a Candidate and a Job. This tool returns the specific status of a candidate for a specific role, including their current stage, answers to application questions, and prospect details.
Usage Note: Candidates can have multiple applications (e.g., they applied for Sales in 2024 and Marketing in 2025). Always pivot on the Application ID, not just the Candidate ID, when assessing pipeline progress.
"Retrieve application ID 9928374. Tell me exactly what stage the application is currently in and summarize the answers they provided to the demographic questionnaire."
list_all_greenhouse_scorecards
This is the most critical tool for hiring velocity. It returns interview feedback, including overall recommendations (e.g., "Definitely Not", "Yes", "Strong Yes"), attribute ratings, and raw text notes from interviewers.
Usage Note: Scorecards are tied to Applications. To prevent the LLM from hallucinating feedback, explicitly instruct it to query this tool using the application_id parameter.
"List all scorecards submitted for application ID 9928374. Create a summary table showing each interviewer's name, their overall recommendation, and a one-sentence summary of their technical feedback."
list_all_greenhouse_offers
This tool retrieves the financial and logistical details of an extended offer, including the offer version, status (e.g., "resolved", "sent"), start dates, and custom compensation fields.
Usage Note: Because offers often contain sensitive compensation data, ensure your MCP server configuration uses method filtering if you do not want standard agents accessing this endpoint.
"Find the active offer for candidate ID 8472910. Check if the status is 'resolved' and tell me the agreed-upon start date."
To view the complete inventory of available tools, including detailed query and body schemas for departments, tags, emails, and EEOC data, visit the Greenhouse integration page.
Workflows in Action
Raw tools are only useful when chained together. Here is how a multi-step recruiting workflow executes using the Truto MCP server.
Scenario 1: The Automated Interview Debrief
A Hiring Manager asks ChatGPT: "Can you summarize the interview feedback for Alex Chen for the DevOps role, and tell me if we have consensus to move to offer?"
- Tool Call 1:
list_all_greenhouse_candidates- The LLM searches for candidates named "Alex Chen". It parses the JSON, finds the correct candidate ID, and notes the attachedapplication_idsfor active jobs. - Tool Call 2:
get_single_greenhouse_application_by_id- The LLM inspects the application to verify it is for the "DevOps" job and checks the current stage. - Tool Call 3:
list_all_greenhouse_scorecards- Passing theapplication_id, the LLM retrieves all submitted feedback. - The Output: ChatGPT synthesizes the JSON arrays into a natural language briefing: "Alex Chen has 4 submitted scorecards for the DevOps role. You have 3 'Strong Yes' recommendations and 1 'Yes'. The primary strengths noted were Kubernetes orchestration and CI/CD automation. You have consensus to move to the Offer stage."
Scenario 2: Pipeline Stagnation Audit
A VP of Talent asks ChatGPT: "Which active engineering roles have candidates stuck in the 'Executive Interview' stage for more than 14 days?"
- Tool Call 1:
list_all_greenhouse_jobs- The LLM fetches all active jobs in the Engineering department, extracting thejob_idarray. - Tool Call 2:
list_all_greenhouse_applications- The LLM loops through the job IDs, querying applications filtered bycurrent_stagematching "Executive Interview" andlast_activity_beforeset to 14 days ago. - The Output: ChatGPT responds with a targeted report: "You currently have 3 candidates stuck in the Executive Interview stage for the 'Backend Engineer' role without any activity in the last two weeks. Their application IDs are 10293, 10294, and 10301. Would you like me to draft an email pinging the assigned hiring managers?"
Security and Access Control
Exposing an ATS to an LLM requires strict governance. Truto MCP servers support configuration parameters that limit what an agent can see and do.
- Method Filtering: Set
config.methods: ["read"]during server creation. This drops allcreate,update, anddeletetools from the MCP server. The LLM physically cannot modify a candidate or alter an offer. - Tag Filtering: Set
config.tags: ["candidate_read"]. The MCP server will only generate tools for Greenhouse endpoints explicitly tagged with that label in the Truto integration config, completely hiding sensitive endpoints like EEOC data or Offers. - Require API Token Auth: By setting
require_api_token_auth: true, possession of the MCP URL is no longer enough. The client must also pass a valid Truto API token in theAuthorizationheader, binding the LLM's actions to an authenticated developer session. - Time-to-Live (TTL): Set an
expires_atISO datetime when creating the server. Truto uses Cloudflare KV expiration and Durable Object alarms to permanently destroy the server and its hashed token at the exact timestamp, ideal for temporary agent sessions.
Architecting for Agentic Recruiting
AI agents are only as smart as the APIs they can access. If you force an LLM to rely on stale CSV exports or rigid iPaaS workflows, it cannot act as a true partner to your recruiting team.
By leveraging the Model Context Protocol and a managed infrastructure layer, you bypass the boilerplate of OAuth token refreshes, schema maintenance, and pagination handling. You give ChatGPT secure, structured access to Greenhouse's raw data model, allowing it to navigate custom fields and nested scorecards just like a human recruiter would.
Stop writing custom integration code to parse ATS data.
FAQ
- How does the MCP server handle Greenhouse API rate limits?
- Truto does not retry or absorb rate limits. When the upstream Greenhouse API returns a 429 error, Truto passes it directly to the caller while normalizing the rate limit information into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). The calling agent must handle its own exponential backoff.
- Can I restrict the AI agent to only read candidate data?
- Yes. When generating the MCP server via the Truto API or UI, you can apply method filtering (e.g., config.methods: ["read"]). This prevents any write, update, or delete tools from being exposed to the LLM.
- How do AI agents handle Greenhouse's custom demographic fields?
- Truto passes the raw Greenhouse data model directly to the LLM through the Proxy API. Custom fields are exposed as JSON arrays in the candidate or application object schemas, allowing the LLM to inspect and parse them dynamically.
- Why does the LLM need to query Applications to get interview feedback?
- In the Greenhouse data model, Scorecards are not attached directly to Candidate objects. They are tied to an Interview, which belongs to an Application. The LLM must use the application ID to accurately retrieve interview feedback.