# Rippling MCP access for HR team: read, not run

> Rippling MCP access for HR team members, scoped in Claude: reads shared, termination and payroll-run tools blocked, and an audit trail that names the account reached.

**TL;DR** Elaichi gives an HR team Rippling reads inside Claude through one organization-wide MCP endpoint, then blocks the termination and payroll-run tools with rules targeted at the HR role. Block rules match the tool name or the pinned operation, so renaming a tool does not reopen it. The audit trail records one entry per tool-call attempt, succeeded or failed, and names the Rippling account actually reached. Restriction changes take about two minutes to take effect.

## What the HR team is asking for

HR opens Claude and asks who reports to whom, which hires start on the first, how many people are on leave in March. The answers sit in Rippling. Nobody in the room wants a model one token away from running payroll. Rippling MCP access for HR team members has one shape that survives review: reads shared, the termination and payroll-run tools blocked outright, and an audit trail that shows nobody ran one.

MCP (Model Context Protocol) is the standard way an AI assistant calls tools in other apps Elaichi serves Rippling's tools through one organization-wide MCP endpoint, `POST /mcp`, behind OAuth (the sign-in flow that hands a client a scoped grant instead of a password). Claude is pointed at that single address through its own admin console. There are no per-toolbox URLs and no tokens pasted into a config file. Rippling is one of 450+ connectors Elaichi authors, maintains and serves from its own infrastructure.

## How to scope Rippling MCP access for HR team members

Connect Rippling once, give the HR people one role, then write block rules against that role. The order matters, because a rule written before the connection exists has nothing to pin against.

1. Connect the Rippling account. Credentials never live in Elaichi. A separate credential service holds per-account secrets, AES-256-GCM at rest, and owns refresh. A failed refresh marks the connection `needs_reauth` rather than failing quietly.
2. Share the connection with the HR team, with `use`. Sharing is one building block: a grant of `view`, `use` or `edit` to a user, a team or the whole organization. A member sees only what they own or what was explicitly shared with them, and no organization-level permission widens that listing, owners and admins included.
3. Check the role. Every member carries exactly one role, enforced by a unique index, so the HR role is a complete persona rather than a bolt-on. Members need `tool:execute`, which gates the whole endpoint ahead of every other check. Without it, `tools/list` comes back empty and a call returns an in-band error naming the permission.
4. Write the restrictions. A restriction is a rule about which connectors and which individual tools a target may reach. Targets are `role` or `user` only. restriction targets are role or user only; the organization default is the absence of a rule, which means allow everything: the default is the absence of any rule, which means allow-all.
5. Point Claude at `POST /mcp` from the Claude admin console and have the HR team sign in.

If the HR group already exists in your identity provider, SCIM v2 can provision the members and map that group to the HR role, so step 3 stops being a manual task.

One caution on step 4. A user-targeted rule replaces role rules entirely instead of layering on top of them. If you later write a rule for one HR manager, the role's blocks stop applying to that person. Write the exception as a copy of the role rules plus the change, or leave it at the role.

## Why block the payroll tools instead of allowlisting the reads

Block rules are the right shape here because the allowlist stage engages on the presence of an allow rule, not its contents, so an allow rule that names nothing denies everything. Add one allow rule naming three read tools and every other tool on the connector disappears, including the reads you forgot. An allow rule naming nothing denies everything, which is the strictest rule the system can express and a real trap.

Blocks and allows both union within the winning layer, and blocks always beat allows. A block list is therefore additive and safe to extend as the catalog grows.

There is a second reason for HR specifically. A block matches on the tool name or on the pinned canonical operation, while an allow matches on the pinned operation only. A tool's advertised name can be changed by whoever edits the connector's documentation, so the name is a token the governed party controls. Blocking catches both the label and the operation underneath it. The [name versus pinned operation asymmetry](/blog/block-matches-name-allow-matches-operation/) is worth reading before you write a long rule set.

The OAuth scope ladder is a second constraint on the same call. A connected tool whose method is a delete needs `mcp:destructive`, and a tool classified `forbidden` is reachable under no scope at all.

## Does HR see the blocked tools in the Claude tool list?

No. Enforcement runs at four points against the same resolver, browse, connect, advertise and execute, plus a final check on the fully substituted outbound URL, plus a final check on the fully-substituted outbound URL. A tool withheld by a restriction is never advertised, so the model does not know it exists and cannot be talked into asking for it.

The list HR does see is shorter than the raw tool count for a second reason. Past a threshold of 30 tools, the connected tools collapse behind two meta-tools, `search_tools` and `execute_tool`. The threshold counts catalog operations and connected tools together, and the control-plane catalog alone is dozens of operations, so one connected app is normally enough to trip it. Collapse is the normal case.

Two details keep this honest. Tools withheld by a restriction are excluded from the count, because they were handed to nobody. And `execute_tool` is only a naming indirection: it unwraps to the same name and arguments and falls through the identical gates, with no separate execution path and no privilege in it.

Search ranking is purely lexical, over tool name, description and connector label, with a relevance floor. A tool has to account for at least half the query's own IDF-weighted mass to be returned at all. Without a floor a search always returns something, and something from an app you did not ask about is worse than nothing, because the model calls it. The [reasoning behind the floor](/blog/search-tools-ranking-floor-idf/) is written up separately.

## Freezing the arguments HR should not get to choose

Frozen parameters fix an argument before the model ever sees it. They are a per-entry map over the tool's flattened argument space, with two effects. Frozen keys are stripped from the advertised schema, so the model cannot supply them. Frozen values are merged over caller arguments at execution, so passing the key anyway cannot un-freeze it.

The full precedence is entry defaults, then caller and model arguments, then frozen parameters. For an HR setup the usual use is a filter you want held constant on every read, so a question about one population cannot quietly return another. Freeze it once on the toolbox entry, which is the saved set of connected tools a client is pointed at, and the model only ever sees the arguments you left open.

## Proving nobody ran a termination or payroll tool

The audit trail records one entry per tool-call attempt, succeeded or failed, and both name the account. The recorded connection is the account actually reached, taken from the execution rather than from the intent. That is the first thing you want when an unexpected change shows up in a second Rippling environment.

Per call, the record carries the operation and tool, the connection, the classification, whether it was approved, the outcome, and an error code only. Argument names and counts are logged. Argument values never are.

`actor_kind` is a field, not an inference. Its values include `user`, `system`, `staff`, `scim`, `api_token` and `ai_assistant`, so whether an action was taken by an AI is recorded at the point of action rather than guessed later from a user agent. That turns "did an assistant run payroll" into a filter instead of an argument.

Two design details matter when the log leaves the product. There is one log tenant per organization, enforced in the type system rather than by a WHERE clause, because a dropped clause leaks while a wrong tenant simply returns nothing. And two error strings exist per failed call. The one returned to the caller comes from the third party's response body. The one written to the trail is never derived from the request or the response, because audit records are org-visible and get fanned out to whatever SIEM you configure.

To produce the evidence: filter the trail by connection, action kind and time range. It is append-only, newest-first, cursor-paginated and filterable by free text, category and actor. A departed member renders as "Former member" rather than vanishing. Give the reviewer the Auditor role, a free read-only seat that lacks `tool:execute`, so no tool call is possible from it. Export forwards the trail to your own destination; Datadog is implemented, while Splunk HEC and Microsoft Sentinel are accepted but not yet delivering. The trail is eventually consistent, so pull the report after the fact rather than mid-call.

## Does the employee data stay in the EU?

It depends on the region, and the region is chosen once at organization creation from `eu`, `us` and `apac`. The `eu` and `us` regions are hard residency, a jurisdiction-pinned store where compute and storage both stay put. The `apac` region is a placement hint only. It is best-effort, and not a residency guarantee, so do not write it into a works council commitment.

Region also selects which regional log instance the organization's audit trail lands in. For an HR rollout that matters as much as the connection itself, because the trail carries employee-adjacent metadata even though it never carries argument values.

## What this setup does not prove

The restriction governs the MCP path and nothing else. Someone who signs into Rippling's own web application and runs payroll there leaves a record in Rippling, not in Elaichi. If your control objective is "nobody ran payroll", you need both trails. If it is "no AI client ran payroll", the Elaichi trail answers it on its own.

The prompt-injection write gate lives in the Elaichi agent window and does not apply to a raw tool call. What does hold on the endpoint: permissions per operation, the `forbidden` classification, output redaction, OAuth scope limits and full audit logging.

Timing is the fact most often stated wrongly. A role or restriction change takes effect within about two minutes, through a 60 second cache plus edge propagation, on MCP, console and REST alike. Only grant revocation, member removal and suspension are effective on the next call. Tell the HR lead two minutes.

## When a control plane is not worth it yet

If you have one HR person, one Rippling login and no other connected app, none of this earns its maintenance. A shared browser session managed in a password manager is a smaller problem than a control plane nobody owns. The same holds when the AI client only needs a read-only handbook and touches nothing that can change state.

The case for [holding off on a gateway](/blog/when-you-dont-need-an-mcp-gateway/) is real, and worth reading before a rollout rather than after. Governance starts paying when a second system joins, when more than one person holds the credential, or when someone outside HR has to be able to answer what the assistant did.

## The day someone leaves the HR team

removing or suspending a member revokes every live grant in the same transaction as the membership change, and `revoked_at` is re-read from the organization store on every single call. For removal and suspension, the next call fails.

Removal also runs a preflight. Personal connections referenced by a toolbox entry must be resolved first, transferred to the organization, a team or another member, or deleted, or the removal is refused. Unreferenced personal connections are cleaned up. A private connection is not transferable at all: a credential only its owner could ever use does not become somebody else's because its owner left. Delegated toolbox entries surface as a non-blocking warning, and re-pinning is the fix rather than a credential decision.

A move sideways, from HR into a narrower role, is a role change. Budget about two minutes for it rather than the next call.

For the equivalent setup on the revenue side, see [how a sales team gets scoped Salesforce access in ChatGPT](/blog/sales-team-chatgpt-salesforce-accounts/). For the harder version of the same offboarding question, read the [contractor access walkthrough](/blog/shadow-ai-contractor-offboarding/). The full catalog is at [/connectors/](/connectors/), and the other eleven teams are mapped at [/use-cases/](/use-cases/).

## FAQ

### Can an HR team read Rippling records in Claude without getting payroll tools?

Yes. In Elaichi, the Rippling connection is shared with the HR team, and block rules targeted at the HR role withhold the termination and payroll-run tools. A withheld tool is never advertised to the client, so the model does not see it in the tool list and cannot call it. Blocks always beat allows, and a block matches either the advertised tool name or the pinned canonical operation underneath it.

### How long does a restriction or role change take to apply?

about two minutes. Role membership and restrictions in Elaichi resolve through a 60 second cache plus edge propagation, and that applies on every surface, MCP, console and REST alike. Only three changes are effective on the very next call: grant revocation, member removal and suspension, because the revocation flag is re-read from the organization store on every single call.

### What is the smallest scope a restriction can target?

No. Restriction targets in Elaichi are a role or a user only. restriction targets are role or user only; the organization default is the absence of a rule, which means allow everything. The organization default is the absence of any rule, which means allow-all, so scoping is done by writing rules against roles and then, where needed, against individual users. A user-targeted rule replaces the role rules entirely rather than layering on top of them.

### Does the audit log show which Rippling account an AI client reached?

Yes. Elaichi writes one entry per tool-call attempt, succeeded or failed, and both name the account. The recorded connection is the account actually reached, taken from the execution rather than from the intent. Each record carries the operation and tool, the classification, whether it was approved, the outcome, an error code, and an actor_kind field whose values include ai_assistant. Argument names and counts are logged; argument values never are.

### Does a compliance reviewer need a paid seat to read the audit trail?

No. The Auditor role in Elaichi is a free, read-only seat and is excluded from the billable seat count, along with Guest and Billing Admin. Auditor lacks the tool:execute permission, so the MCP tool list comes back empty for that member and no tool call is possible from the seat.

## Read next

- [NetSuite MCP access for finance team in Claude](/blog/finance-team-claude-netsuite-ledger/) — NetSuite MCP access for finance team work: read-only analysts, journal posting behind a user override, and an audit entry naming the subsidiary account reached.
- [HubSpot MCP access for marketing team, safely](/blog/marketing-team-chatgpt-hubspot-campaigns/) — How to set up HubSpot MCP access for marketing team use in ChatGPT: reads allowed, list deletion and bulk email send blocked, the portal frozen, every attempt logged.
- [Salesforce MCP access for sales team, done right](/blog/sales-team-chatgpt-salesforce-accounts/) — Salesforce MCP access for sales team, set up so reps see only their own accounts. Bulk update and mass delete are restricted at the operation, the owner field is frozen, and an audit query proves it.
