MCP endpoint
HollyHR exposes a hosted Model Context Protocol endpoint at your tenant app origin:
Code
The endpoint is a framing layer over the same public API substrate documented in this developer portal. It uses organisation-scoped API keys, the Pro API entitlement, public API scopes, public IDs, generated contracts, request logs, rate limits, idempotency, and ETags.
For client-specific setup, see Claude and ChatGPT. For a repeatable deployment check, see the MCP smoke test.
Agent-readable discovery is available at:
Code
That document summarizes the current access mode, PRM URL, MCP endpoint, scope surface, and write-safety posture for human readers and agent tooling.
Authentication
Use a HollyHR public API key as a bearer token:
Code
The MCP endpoint derives the organisation from the API key. Do not provide a tenant ID or workspace ID to any tool.
For write tools, grant mcp:write in addition to the relevant data write scope,
for example people:write or time_off:write. A key with REST write scopes but
without mcp:write can still use read tools, but write preparation and commit
tools reject it. HollyHR also keeps MCP writes disabled by default unless the
tenant environment has HOLLYHR_MCP_WRITE_MODE=enabled.
OAuth protected-resource metadata is available under:
Code
The endpoint returns a WWW-Authenticate challenge on unauthenticated requests
with the same resource_metadata URL, so capable MCP clients can discover the
protected-resource metadata automatically. The challenge also includes a narrow
read-scope hint for the first useful MCP connection:
Code
The metadata scopes_supported list advertises only scopes used by executable
MCP operations with explicit output projections. Excluded public API surfaces
such as personal profiles, payroll exports, provider mappings, and webhook
management are intentionally not advertised as MCP scopes.
The initial /api/mcp/.well-known/oauth-protected-resource route remains
available as a compatibility alias, but it is not the primary discovery path.
Bearer API-key auth is HollyHR's first supported developer-preview access mode.
When OAuth is enabled for a tenant, the MCP endpoint also accepts
issuer-verified OAuth access tokens whose audience is the tenant /api/mcp
resource and whose claims bind the token to a real active HollyHR API-key actor
row. When an authorization server issues HollyHR data scopes, those scopes must
be part of the executable MCP surface and are intersected with that API-key
actor's scopes. WorkOS/AuthKit currently issues identity-scoped MCP tokens
(openid profile email) plus resource and custom consent claims, so HollyHR
derives data access from the selected API-key actor profile filtered to the
MCP-safe scope surface. OAuth cannot grant broader access than the underlying
HollyHR integration actor.
For WorkOS/AuthKit, configure:
HOLLYHR_OAUTH_ISSUER_URLto the AuthKit issuer;HOLLYHR_OAUTH_JWKS_URLonly when the JWKS endpoint is non-standard; otherwise HollyHR deriveshttps://<authkit-domain>/oauth2/jwks;HOLLYHR_OAUTH_AUDIENCEonly when the AuthKit resource indicator differs from the tenant MCP URL;HOLLYHR_OAUTH_ORG_ID_CLAIMandHOLLYHR_OAUTH_API_KEY_ID_CLAIMwhen custom claim names differ fromhollyhr_org_idandhollyhr_api_key_id.WORKOS_API_KEYandHOLLYHR_OAUTH_CONNECT_API_KEY_NAMEfor Standalone Connect Login URI completion.
HollyHR advertises authorization_servers in protected-resource metadata only
when the issuer is HTTPS and the JWKS verification URL is usable. For older MCP
or OAuth clients that look at the resource origin, HollyHR also proxies:
Code
to the configured authorization server metadata.
Connector-gallery support remains a GA launch gate until the tenant's issuer, JWKS, audience, actor claims, client registration, and compliance approvals are configured and smoke-tested in production.
This is API-key-backed OAuth resource-server mode, not true delegated-user
OAuth. Per-user consent, user-role intersection, OAuth app records, grant
revocation, and user-attributed audit are a separate future architecture phase.
Do not treat an empty authorization_servers array as a broken preview
endpoint; it means the tenant is currently using API-key bearer auth only.
Transport
The hosted endpoint uses MCP Streamable HTTP:
Code
The server runs in stateless mode for Vercel/serverless compatibility. Browser
clients must use the same origin or a configured trusted Origin; server-to-server
clients normally omit the Origin header. Authenticated GET /api/mcp returns
405 Method Not Allowed because GET/SSE session streaming is not part of the
first hosted surface. The server does not require clients to preserve an
MCP-Session-Id.
Tools
The endpoint includes contract-aware discovery tools:
list_api_operationsget_api_operationcall_api_operationprepare_api_writecommit_api_write
It also includes workflow-shaped read tools for common HR work:
whoamisearch_peopleget_personget_person_contextlist_time_offget_time_offlist_reference
call_api_operation executes read operations only. Mutations require
prepare_api_write followed by commit_api_write.
Stable tools publish output schemas and return MCP structuredContent so
clients can validate common results without parsing freeform text.
whoami includes a catalogue_version fingerprint. Treat it as the current
server-side MCP tool/catalogue contract version for compatibility checks.
Resources And Prompts
The server exposes read-only MCP resources for the developer guide, OpenAPI reference, safe-write workflow, and HR data-handling policy. It also exposes prompts for planning safe read-only lookups and reviewing prepared writes before commit. These resources and prompts contain public guidance only; tenant data is available through scoped tools, not static resources.
Write Safety
Writes use a two-step flow:
- Call
prepare_api_writewith the operation ID, path parameters, query parameters, and body. - Review the frozen payload and confirmation token returned by the server.
- Call
commit_api_writewith the confirmation token.
The confirmation token is signed by HollyHR, tied to the API key and organisation, expires quickly, and contains a server-generated idempotency key. For conditional updates, the server captures the current ETag during preparation. The model cannot change the write body, ETag, or idempotency key between preparation and commit.
When writes are enabled, commit_api_write also asks the MCP host for user
approval through form elicitation before committing. If the initialized client
does not advertise form elicitation, if the host cannot provide approval, or if
the user declines, the write fails closed.
Data Handling
MCP output is projected and sanitized before it is returned to clients. Each operation has a positive MCP output projection, so newly added upstream public API fields are omitted from MCP until they are deliberately reviewed and added to that projection:
- bearer tokens, API keys, webhook secrets, and secret-like values are redacted;
- links and document/download URLs are redacted;
- document filenames are redacted and document categories are bucketed;
- payroll, bank, tax/government, compensation, and home-address fields are redacted;
- absence category labels are bucketed to
Absenceby default, and time-off category IDs are omitted from MCP output to prevent category-label joins; - time-off balance category names and category IDs are also bucketed/omitted so
composite tools such as
get_person_contextkeep the same projection ceiling.
Webhook management operations are intentionally excluded from the MCP tool surface while the secret-returning and DPIA gates are open.
Debugging
Every MCP tool call writes a public API request-log row with a route shaped like
mcp:<tool_name> and source set to mcp. Budgeted HR-data reads also record
pii_row_count.
HollyHR enforces a rolling daily MCP HR-data row ceiling per organisation. The
default is 500 rows per 24 hours unless the tenant environment sets
HOLLYHR_MCP_DAILY_PII_ROW_LIMIT. If a tool call would exceed the remaining
budget, it fails closed with a rate-limit error before returning the rows.
Public API service calls still return structured errors that MCP tools surface as tool errors rather than protocol errors, so agents can correct missing scopes, validation mistakes, ETag preconditions, and rate-limit issues without losing the session.
Smoke Testing
Use the repository smoke harness with a disposable tenant API key when validating a deployment:
Code
When validating a tenant that should have OAuth enabled, add:
Code
The smoke covers protected-resource metadata, authorization-server metadata
when OAuth is expected, unauthenticated discovery, the authenticated
GET/SSE-disabled 405 response, SDK initialization, tools/list, whoami,
and safe write preparation. Write commits are tested only when the host supports
MCP form elicitation and the production write-mode gate is intentionally
enabled.
For WorkOS/AuthKit connector readiness, run the provider smoke as well:
Code
It checks WorkOS authorization-server metadata, DCR, PKCE S256, that WorkOS
accepts the default identity scopes, and that the tenant MCP resource is
accepted by WorkOS before an interactive reviewer login. HollyHR data
authorization is then enforced from the selected backing API-key actor profile,
not custom WorkOS data scopes. For diagnostic custom-scope probes, operators can
set HOLLYHR_WORKOS_CONNECT_ALLOW_CUSTOM_SCOPES=1 and
HOLLYHR_WORKOS_CONNECT_SCOPES, but that is not the normal WorkOS setup path
unless WorkOS begins advertising those scopes.
For an API + MCP time-to-first-call check, use
pnpm developer:ttfc:smoke from Sandbox and TTFC.