MCP endpoint
HollyHR exposes a universal Model Context Protocol endpoint:
Code
The endpoint derives the organisation from the authenticated API-key or OAuth
principal; callers cannot select it in a tool argument. Tenant-origin endpoints
at https://{workspace}.hollyhr.com/api/mcp remain available for server-side
integrations. Both forms are framing layers over the same public API substrate
and use the same public IDs, generated contracts, request logs, rate limits,
idempotency and ETags.
OAuth connector-directory submission is in progress with a read-only initial listing. Governed writes remain scope- and environment-gated and are not included in the directory actor, discovery or reviewer prompts.
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.
The initial directory connector is read-only. While
HOLLYHR_MCP_WRITE_MODE=disabled, the server omits write tools, write prompts
and write scopes from discovery rather than merely rejecting their execution.
For a separately approved write-capable integration, grant mcp:write in
addition to the relevant data write scope, for example people:write or
time_off:write, and enable the global write mode. A key with REST write scopes
but without mcp:write remains read-only.
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.
The universal endpoint's issuer, JWKS, audience, actor claims, dynamic client registration and fixed synthetic reviewer flow have been smoke-tested in production. Anthropic and OpenAI directory submission is in progress; a working custom connector or completed portal draft is not the same as a submitted or approved public listing.
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 preferred protocol is 2026-07-28. The same endpoint also accepts
stateless 2025-11-25 initialize clients through the official SDK's
compatibility path. Both eras use one server factory and exactly the same
tools, resources, prompts, authentication and data controls.
The server is stateless for Vercel/serverless compatibility. Modern clients use
protocol-native per-request envelopes; legacy clients do not need to preserve
an MCP-Session-Id. Browser clients must use the same origin or a configured
trusted Origin; server-to-server clients normally omit the Origin header.
Authenticated legacy GET /api/mcp returns 405 Method Not Allowed because
session SSE is not part of the hosted surface.
Tools
The read-only directory surface includes contract-aware discovery tools:
list_api_operationsget_api_operationcall_api_operation
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. When the separately
governed write mode is enabled, the server additionally registers
prepare_api_write and commit_api_write. Those tools are absent from the
initial provider listing.
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 and HR data-handling policy, plus prompts for planning safe read-only lookups. The safe-write resource and write-review prompt are registered only when write mode is enabled. Resources and prompts contain public guidance only; tenant data is available through scoped tools, not static resources.
Optional Write Safety
The public directory submission is read-only. The following contract applies only to separately approved integrations for which write discovery is enabled.
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 returns a protocol-native
input_required approval request before committing. This requires a modern
2026-07-28 host. Stateless 2025 clients can read and prepare a frozen write,
but commit fails closed because that era cannot carry durable host approval
across per-request exchanges. If the host cannot provide approval, if the
response is invalid, or if the user declines, the write fails closed. Approval
never replaces the signed frozen token, principal binding, scope checks, ETag
or idempotency controls.
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:<legacy|modern>:<tool_name> and source set to mcp. This records
content-free adoption telemetry without storing arguments or results. 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. It connects once with each supported protocol era:
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
modern input_required approval and the production write-mode gate is
intentionally enabled. Stateless legacy clients fail closed at commit.
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.