
Greenhouse now gives an AI agent two doors into a recruiting pipeline: an official MCP server in open beta, and the Harvest v3 API that just replaced v1/v2 API keys with OAuth. They overlap on reading jobs, candidates, applications and scorecards, and they diverge on deletes, attachments, event delivery, high-stakes actions like rejecting or hiring, and whose permissions an action runs under. This guide compares what each path lets an agent do, the credential each one puts you on, and how to run either across many customer organizations in production.
Your agent needs to work inside your customers' Greenhouse accounts: find the candidates who have sat in the same interview stage for 14 days, flag scorecards that interviewers never submitted, log a recruiter note, move a candidate to the next stage, or attach the resume a sourcing tool just found. Greenhouse now hosts an official Model Context Protocol (MCP) server that Claude, ChatGPT, Copilot Studio, Glean, and other clients connect to with OAuth. Greenhouse also has the Harvest API, which just went through a forced migration from v1/v2 API keys to v3 with OAuth. They overlap on reading the pipeline. They diverge on deletes, attachments, event delivery, high-stakes actions like rejecting or hiring, and whose permissions an action runs under. Here's how to pick.
Greenhouse MCP is a remote server hosted by Greenhouse, and the support article states that it "is currently in open beta." Greenhouse's setup guide lists two endpoints: https://mcp.greenhouse.io/mcp for Claude on the web and Google Antigravity, and https://mcp.us.greenhouse.io/mcp for Claude Code and ChatGPT. Claude Code connects with claude mcp add greenhouse --transport http https://mcp.us.greenhouse.io/mcp. The product page is dated July 2026 and describes it as "a governed way to connect approved AI tools to Greenhouse."
Clients authenticate with OAuth 2.0 Authorization Code with PKCE and Dynamic Client Registration (DCR), and users sign in at auth.greenhouse.io with their normal Greenhouse credentials. A Site Admin sets the ceiling in Dev Center > MCP Access. Greenhouse's security FAQ says the server exposes a subset of the Harvest v3 API and that "not all API endpoints may be exposed." Greenhouse doesn't publish a tool-by-tool list. It describes the coverage as jobs, candidates, applications, scorecards, and interview stages.
Before the official server, the community filled the gap with self-hosted servers. One example is open-greenhouse-mcp, an MIT-licensed local server that runs over stdio and uses Greenhouse API credentials that you manage. Servers like this aren't maintained by Greenhouse, and any of them written against v1/v2 API keys broke at the v1/v2 cutoff.
Greenhouse has several APIs. The one agents care about is Harvest, the read and write API for candidates, applications, jobs, openings, offers, interviews, scorecards, notes, attachments, users, and custom fields. Harvest v3 lives at https://harvest.greenhouse.io/v3 and takes a JWT bearer token from https://auth.greenhouse.io/token. The v1/v2 reference states "The Harvest v1/v2 API is deprecated and will be removed on August 31, 2026." Those versions used Basic auth with an API key as the username, and every POST, PATCH, and DELETE needed an On-Behalf-Of header naming the Greenhouse user "for auditing purposes."
The other APIs sit beside Harvest. The Job Board API at https://boards-api.greenhouse.io/v1/boards/, keyed by each company's board token, serves public job data without auth, and only application submission needs a Job Board API key. The Onboarding API is GraphQL-only at https://onboarding-api.greenhouse.io/graphql, with Basic-auth keys that grant access to all company data and cannot be scoped. Neither one is part of the MCP server or this comparison.
The pattern is deliberate. Greenhouse built its MCP server for a person in a chat, with guardrails on the actions that change a candidate's outcome. Its default scopes are read-only, so AI tools cannot create, edit, or delete data until an admin enables more. The API is built for systems that run without anyone watching. The same reject call that MCP stops for a human confirmation is a single request on Harvest.
Answering "which Engineering candidates have been in Onsite for more than 10 days, and whose scorecards are still drafts" on raw Harvest is a join across four resources. You resolve the job IDs, list each job's interview stages, list applications in that stage, pull stage history for time in stage, then list scorecards filtered by status=draft for each application. Every list call pages through per_page results of up to 500, and each page lands in the model's context.
The MCP server keeps that inside a conversation the recruiter already trusts. The user connects once, Greenhouse applies their role, and a client like Claude chains the reads. Greenhouse's own example use cases are exactly this kind of work: pipeline dashboards, stalled-candidate flags, scorecard completion checks, and offer approval bottlenecks. Nobody on your team writes a schema. Writing the schema is the hard part. Not the API call.
The tradeoff is that Greenhouse owns the surface. The server is in open beta, Greenhouse says its functionality "may change over time," and it publishes no tool changelog. When a Site Admin adds or removes scopes, every connected user is signed out and must reconnect before new scopes apply. An agent tuned against today's tool behavior can change without a release on your side.
On the MCP path, auth is browser OAuth with PKCE, and the client is a public client with no secret. Greenhouse layers three controls: the Site Admin's scope ceiling in Dev Center > MCP Access, the user's own consent screen where they can deselect data categories, and the user's Greenhouse role, because the tool acts under the user's own token. Access tokens expire after one hour, and refresh tokens "remain valid until there have been 14 consecutive days of inactivity." Claude, Claude Code, ChatGPT, Amazon Q, Glean, Grok AI, and Google Antigravity are pre-approved. Any other client, including your own gateway, needs a redirect URL pattern added in the Clients tab of MCP Access before users can connect.
On the direct API path, Harvest v3 gives you two OAuth grants, per Greenhouse's authentication guide. Custom integrations use Client Credentials: an admin creates "Harvest v3 (OAuth)" credentials under Dev Center > API Credential Management, picks endpoints and scopes, and gets a client secret that is shown once and can be rotated. The token request can carry an optional sub with a Greenhouse user_id; omit it and calls run as an integration service user. Partner integrations must use Authorization Code. The partner OAuth guide requires a signed Greenhouse partnership agreement, sends users to https://auth.greenhouse.io/authorize, and uses space-separated scopes such as harvest:candidates:list and harvest:job_posts:list. Authorization codes expire in 1 minute, access tokens in 1 hour, and refresh tokens in 24 hours. Each refresh returns a new refresh token, and if the refresh token goes unused for 24 hours, "the user must repeat the entire authorization flow."
The On-Behalf-Of header is gone in v3. The acting user now comes from the token: the sub you request with Client Credentials, or the user who authorized the partner app. Greenhouse's partner guide ties codes and refresh tokens to that user, and requests fail once that user is disabled.
Then comes the line that shapes every multi-tenant Greenhouse agent. Greenhouse states that "all list endpoints require authorization by a Greenhouse user with Site Admin privileges," and list calls with a non-Site Admin's token return HTTP 403. An agent built on the partner path therefore holds a Site Admin's grant for each customer. What the user can't do, the agent can't do: on MCP, Greenhouse enforces that for every recruiter and hiring manager. On the API, the grant reflects a Site Admin's reach, and the line between what a hiring manager may see and what a recruiting ops lead may see is yours to draw.
In a multi-tenant B2B agent, MCP gives you a credential per user and the direct API gives you a credential per user. In neither case does the path itself solve storage, rotation, or revocation; those are infrastructure problems regardless of which path you choose.
Greenhouse moves where the boundary sits. On the API path, the natural unit is the customer's Greenhouse organization, connected once by a Site Admin, and that connected account can list every candidate in the org. Your app has to bind each connected account to exactly one customer, then filter by job_ids, department_ids, or the hiring team when an ordinary hiring manager asks a question, because Harvest will answer for the whole organization. Candidate data is personal data, so a cross-tenant mistake here is a privacy incident, not just a bug. On the MCP path, each recruiter connects separately, which matches Greenhouse's permission model but multiplies the sessions you track.
Recommended reading: access control for multi-tenant AI agents
On the MCP path, Greenhouse hosts the server, owns the tool schemas, enforces the user's role, and writes mcp_access events to its audit log. You own each user's OAuth session inside a client you may not control, and the reconnect step every time a Site Admin changes scopes. You also own the gaps. MCP tools only run inside a conversation someone starts, so nothing happens when a candidate moves stages. Files can't be read or uploaded through it. Greenhouse hosts the server on US infrastructure only, which matters for EU customers with data residency requirements.
On the API path, you own schemas, pagination, retries, and the token lifecycle. Harvest v3 pagination is cursor-based: you put filters and per_page (1 to 500) on the first request, then follow the opaque cursor in the Link header, which "must be the only query parameter" on later requests. v3 returns only a next link, no prev or last. Rate limits apply on a fixed window that "resets at the end of each 30-second interval," the token endpoint has its own 60-second window, and custom and partner integrations are limited separately. Greenhouse doesn't publish the quota; you read X-RateLimit-Limit and X-RateLimit-Remaining from each response and wait out Retry-After on a 429.
The fixed window bites multi-tenant agents. A nightly backfill that pages through 40,000 applications in one customer's org can burn the window in seconds, and a 24-hour refresh token means a connected account that goes quiet over a long weekend may need a Site Admin to consent again on Monday. Refresh rotation adds a race: each refresh hands you a new refresh token to persist, so two workers refreshing the same grant at once can leave you holding the stale one.
Webhooks are how the API path learns about changes. Greenhouse sends events such as new_candidate_application, candidate_stage_change, reject_candidate, hire_candidate, offer_approved, and job_post_updated, each signed with HMAC-SHA256 over the whole body in a Signature header of the form sha256 <hex digest>. Each delivery carries a unique Greenhouse-Event-ID. Greenhouse makes up to 7 attempts over about 15 hours on a timeout or non-200 response, then stops, and a webhook whose configuration ping fails stays disabled until someone re-enables it.
Use Greenhouse MCP when:
Use the Greenhouse API when:
Both paths hand you a Greenhouse credential per user. Neither hands you a vault. A multi-tenant agent serving 60 customer organizations holds 60 Site Admin grants on the partner API path, each with an access token that expires every hour and a refresh token that expires after 24 hours unused and rotates on every refresh. Behind them sits your Greenhouse partner OAuth app, with a client secret issued by Greenhouse Partner Support. Every token must be stored encrypted, kept out of logs and LLM context, refreshed before it expires, discarded when the authorizing admin is deactivated, and replaced through a fresh consent when the 24-hour window closes.
The MCP path changes the count, not the problem. Per-recruiter OAuth sessions match Greenhouse's permission model better, but 60 organizations with 12 recruiters and hiring managers each is 720 sessions living in chat clients, and Greenhouse notes that a password change or SSO sign-out does not invalidate them. The tempting shortcut on the API path is asking each customer's admin to create Client Credentials for you. That gives you a long-lived client secret per customer, calls that run as an integration service user unless you pass sub, and a secret with org-wide endpoint access sitting in your database. Fewer consent flows, larger blast radius per secret.
Scalekit's greenhouse connector handles the Greenhouse OAuth flow, token storage, and refresh for every connected account, so the MCP vs API decision doesn't change your auth infrastructure. Your agent passes an identifier; credentials never touch the agent runtime or the LLM context.
Recommended reading: how to handle token refresh for AI agents
Scalekit's greenhouse connector is an API-path connector built by Scalekit with 90 tools: 46 read, 32 write, and 12 destructive. It covers candidates, prospects, applications and stage history, jobs, openings, job posts, hiring teams, interview stages, interviews and interviewers, scorecards, offers, notes, attachments, tags, education and employment history, custom fields, sources, referrers, rejection reasons, email templates, departments, offices, and users. It authenticates with OAuth 2.0: each user signs in to Greenhouse once, and Scalekit stores and refreshes the tokens.
In the Scalekit dashboard, go to AgentKit > Connections, create a Greenhouse connection, and copy its redirect URI. The name you give the connection is the connection_name your code passes, and the string must match the dashboard exactly. This is the most common integration error.
Greenhouse connections use your own OAuth app. Harvest partner OAuth requires a signed Greenhouse partnership agreement: you submit Greenhouse's integration request form, and Greenhouse Partner Support issues the Client ID and Client Secret and handles scope changes. Register the Scalekit redirect URI with that app and request the Harvest scopes your tools need; each tool's entry in the connector docs lists its inputs. Paste the Client ID and Client Secret into the Greenhouse connection. Copy SCALEKIT_ENVIRONMENT_URL, SCALEKIT_CLIENT_ID, and SCALEKIT_CLIENT_SECRET from Developers > API Credentials into .env.
get_or_create_connected_account returns the connected account for an identifier. If it is not ACTIVE, get_authorization_link returns a link to Greenhouse's consent screen for your app. Because Harvest list endpoints return 403 unless a Site Admin authorized the token, the person who clicks it should be a Site Admin of the customer's Greenhouse organization. Scalekit exchanges the code and stores the tokens; the agent never sees them. Here the identifier is your customer's ID, because the grant covers the whole Greenhouse organization.
This is not a catalog load. The agent asks for the tools this connected account is authorized to call, then narrows them to the six a pipeline-review agent needs. Loading all 90 Greenhouse tools would put greenhouse_candidate_delete, greenhouse_application_reject, and greenhouse_application_hire in front of a model whose job is to report stalled candidates. None of the six below changes anything in Greenhouse.
The loop runs until the model stops requesting tools. Every call executes with this customer's Site Admin grant, so the system prompt pins the agent to one department's jobs; Harvest would otherwise answer for the whole organization.
For pipelines, skip the model. execute_tool runs one tool with a fixed input and returns data plus an execution_id you can log. This handler runs when your webhook endpoint receives a candidate_stage_change event. It verifies the Signature header, reads the application, checks for scorecards still in draft, and if any exist, logs an admin-only note on the candidate naming the interviewers who haven't submitted.
The webhook itself is not a connector tool. It is configured inside each customer's Greenhouse account with your endpoint URL and a secret key, and the secret belongs in your own store, per customer. Because Greenhouse retries up to 7 times, deduplicate on the Greenhouse-Event-ID header before calling the handler. The Greenhouse MCP server has no equivalent for either step.
Two other writes show where the API path earns its place. greenhouse_application_move takes a from_stage_id that must match the application's current stage, so a pipeline acting on a stale read fails instead of moving the wrong candidate. greenhouse_application_reject can schedule a templated rejection email to the candidate. Neither belongs in a model's default tool set. Both fit a pipeline with a recruiter approval step in front of them, which is the same guardrail Greenhouse's MCP server enforces with its human confirmation rule.
The greenhouse connector has 90 tools. At roughly 200 tokens each, that is about 18,000 tokens of tool definitions before the agent does any work. A model choosing among greenhouse_applications_list, greenhouse_application_stages_list, greenhouse_job_interview_stages_list, and greenhouse_prospect_pool_stages_list picks the wrong stage tool more often than a model holding only the one it needs, and the docs warn that stage IDs from one won't match filters on another. Overreach is the bigger risk: a scorecard chaser that also holds greenhouse_application_reject and greenhouse_candidate_delete can end a candidacy on a bad inference. The fix is not better prompting. It is surface reduction. A Scalekit virtual MCP server declares exactly which tools an agent role can see, and session tokens keep each run bound to one customer's connected accounts. Docs: set up a virtual MCP server.
One server definition serves every customer. Before each run, check that the customer's accounts are active and mint a short-lived session token scoped to them. With Greenhouse's 24-hour refresh window, this check is where a lapsed grant surfaces as an authorization link for the Site Admin, not as a 401 halfway through a run. Any MCP client that speaks Streamable HTTP can connect; this example uses langchain-mcp-adapters (pip install langchain-mcp-adapters) and passes the token as a Bearer header.
The agent sees five tools instead of 90. The endpoint is static; the identity is per customer. Unlike Greenhouse's own MCP server, this endpoint can include tools Greenhouse MCP blocks, such as greenhouse_candidate_delete for a data retention role that should hold it, and leave them out of every other role.
Every execute_tool call returns an execution_id, and every execution is attributed to a connected account, which maps to one of your customers. When a recruiting lead asks which agent run logged 30 notes overnight or moved a candidate out of Onsite on Saturday, the answer is a lookup, not an investigation.
Attribution is also where the paths differ. Greenhouse MCP writes mcp_access events to the audit log with the user, the OAuth client_id, the endpoint, and the parameters, but its UI Change Log shows MCP writes under the user's name, with no indicator that an AI tool was involved. On the API path, writes run under the Greenhouse user tied to the grant, usually the Site Admin who authorized it, so your execution log is the only record of which of your users asked for the action. One more Greenhouse detail: greenhouse_note_create accepts a user_id to record as the note's author, so keep that parameter out of the model's control unless you want it choosing who appears to have written a note. A shared credential across customers breaks attribution entirely: one grant reaching several Greenhouse orgs means every action looks the same, and a leak exposes every candidate in all of them. Shared credentials work for one user. They do not survive a second user.
Recommended reading: audit trails for agent auth
If your agent is a recruiting team's assistant in Claude, ChatGPT, or Copilot Studio, answering pipeline questions, summarizing scorecards, and moving candidates with a person watching, Greenhouse's official MCP server is a good fit: it is hosted, it enforces each user's Greenhouse permissions, and it puts a human confirmation in front of rejects and hires. Plan for open-beta changes and Core, Plus, or Pro eligibility. If your agent runs unattended, reacts to candidate_stage_change and hire_candidate webhooks, handles resumes and offer documents, or manages jobs and openings across many customer organizations, build against Harvest v3, where you choose the scopes and the operations. Either way, you hold an OAuth grant per Greenhouse organization or per recruiter, with hourly access tokens and refresh tokens that lapse after a day of silence on the partner path, and that's what needs production-grade infrastructure.
Yes. Greenhouse hosts a remote MCP server in open beta at https://mcp.greenhouse.io/mcp, with https://mcp.us.greenhouse.io/mcp for Claude Code and ChatGPT. It exposes a subset of the Harvest v3 API, runs as the signed-in user, ships with read-only default scopes, and is limited to Greenhouse Recruiting Core, Plus, and Pro tiers. A Site Admin sets the scope ceiling under Dev Center > MCP Access.
It permanently blocks every DELETE endpoint, returns attachment metadata and a 7-day download link but never file content or uploads, has no event triggers, and makes the AI client get explicit human confirmation before rejecting, hiring, merging, or anonymizing a candidate. Greenhouse publishes no tool-by-tool list and says the server's functionality may change during the beta.
Greenhouse set August 31, 2026 as the removal date for Harvest v1/v2 and their Basic-auth API keys. Harvest v3 uses OAuth 2.0 only: Client Credentials for custom integrations an admin creates in Dev Center, and Authorization Code for partner apps, where access tokens last 1 hour and refresh tokens expire after 24 hours unused. The On-Behalf-Of header is gone; the acting user comes from the token.
Greenhouse states that all Harvest list endpoints require authorization by a user with Site Admin privileges, and list calls with a non-Site Admin token return HTTP 403. On the partner OAuth path the grant your agent holds is therefore an admin's, covering the whole organization, so recruiter-level and hiring-manager-level restrictions are yours to enforce by filtering on jobs, departments, or hiring teams.
When it runs without a person in the loop: reacting to candidate_stage_change or hire_candidate webhooks, chasing draft scorecards, uploading resumes with greenhouse_attachment_create, creating jobs and openings, scheduling interviews, or deleting candidates for data retention. Each of those is either blocked or undocumented on the MCP server.
Through the greenhouse connector, which exposes 90 tools over Harvest v3 and runs the OAuth flow, token storage, and refresh through your own Greenhouse partner OAuth app. A Site Admin at each customer authorizes once, Scalekit stores and refreshes the tokens, a virtual MCP server narrows the 90 tools to the ones an agent role needs, and every execution returns an execution_id attributed to that customer's connected account.
Browse the Scalekit Greenhouse connector and the Greenhouse connector docs with the full tool list. See Scalekit pricing, or talk to us.