FEATURE_MCP_CONNECTOR=true and the public origin in
MCP_ISSUER_URL.
Separately, this documentation site serves its own public MCP endpoint — see
Two MCP servers for which one to connect.
Two MCP servers
An installation is reachable over MCP at two independent endpoints. They serve different content under different authorization, and an assistant can be connected to either or both.
The rest of this page documents the connector. The documentation server is
described directly below and needs no setup.
The documentation server
The documentation site is a Mintlify site, and Mintlify serves an MCP endpoint for it at/mcp. It is generated from the published
pages, so it is always as current as the site, and it exposes three tools:
Add it to Claude Code with:
docs/customers/<customer>/ and are never part
of this site, so they are not reachable through this server either.
Answers are only as good as the page behind them, and the guides are currently English-only — a
German or French question is answered from the translated What’s new pages
or from an English guide.
Endpoints
Rules a client must follow:
- PKCE with
S256on every authorization request;plainis refused. - The
resourceparameter (RFC 8707) must equal the canonical MCP URL,<issuer>/api/mcp, on both the authorization and the token request. - Refresh tokens rotate on every use; reusing a rotated token revokes the whole token family.
- Dynamic registrations are public clients (
token_endpoint_auth_method: "none"); an installation may instead create a confidential client by hand and hand its id and secret to the assistant’s advanced settings. - Every unauthenticated call to
/api/mcpanswers401with aWWW-Authenticate: Bearerchallenge carrying theresource_metadataURL.
Scopes
A grant never widens: a refresh or a later consent carries at most the scopes
first approved. A person’s role is re-read from the database on every call, so
a role change or deactivation takes effect on the next request.
Limits and records
- 60 calls per minute per connection; the HR overview additionally 6 per hour; writes (commit, withdraw, cancel) 20 per day per connection.
- A daily allowance of distinct person records per connection (installation setting, default 1 000). Reads beyond it are refused until the next UTC day.
- Every list returns at most 50 rows; search at most 25.
- Every call writes an audit row: assistant, connection, tool, argument names (free text as length and hash only), the records touched, result count and outcome. A connection that touches 50 or more different people in a day is additionally recorded as an export.
- Writes are two steps. A
prepare_*tool computes the request on the server (days deducted, balance after, approver; derived hours; days covered) and returns a preview plus a single-usepreviewIdbound to the connection; the matchingcommit_*tool takes only that id and files the stored preview — nothing the assistant says in between changes what is written. Previews expire after 15 minutes and a retried commit replays the first result. For an HR write the caller’s authority over the record — the approval scope, the HR scope, the recruiting scope — is checked again at the commit, so a reporting line, an assignment or a position role that changed inside those 15 minutes is honoured. A self-service write takes no free text at all (no reason, note or description). An HR write takes only the text that is the record — a rejection note, a task title, an application note — and it is taken at the prepare step, so the person approves the exact wording before the commit files it. An application note is always filed as a shared one: the read side never returns private HR notes, so the connector never writes one. - A stage move names, before it happens, every automatic task the destination stage fires — flagging the ones that e-mail the candidate and whether the stage marks them as hired — because none of that is undoable. The compliance override that bypasses a stage’s blocking-task gate is not offered over the connector at all: a move the gate blocks is refused, and releasing it stays a person’s job inside HR Easy.
Tool catalog
The catalog below is generated from the server’s tool registry (npm run gen:mcp-catalog); a drift check in CI keeps it identical to what
tools/list returns. Each tool declares its scope, the permission the role
must hold, MCP annotations (read tools and previews are read-only; commit,
withdraw and cancel are marked destructive so a client asks first), and JSON
Schemas for its arguments and its result.
mcp-tools.json
The machine-readable catalog: 36 tools with input and output schemas, plus the resource template
and the prompts.
Resources and prompts
The same documents are served as MCP resources underhr-easy://documents/{slug} (text/markdown). resources/list returns only
the documents the connected person’s role may read; resources/read applies
the same rule and writes an audit row like a tool call. Documents are the
installation’s own texts — handbook chapters, policies — authored under
Settings → AI connections → Documents in German with optional English and
French translations; a reader without a translation gets the German original.
An audience of all employees, managers and above or HR staff and above
governs who may read each one.
Two prompts are offered to the roles that may use them:
Both are rendered in the person’s language and end with the ADR-006 guard rail:
no ratings, no comparison between people, no speculation about health or
private matters.
Every HR-scope tool description ends with the same sentence: never use this to
rank, score or compare people against each other. HR Easy does not support
rankings; see the product’s design principles.