Connect ClayHR to Claude: Automate Recruiting, Expenses & PTO
Learn how to connect ClayHR to Claude using a managed MCP server. Automate recruiting, timesheets, expenses, and PTO workflows without writing integration code.
If you need to connect ClayHR to Claude to automate recruiting pipelines, process employee expense reports, manage timesheets, or handle PTO balances, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's AI tool calls and ClayHR's REST APIs. You can either build and maintain this infrastructure yourself, or use a managed integration platform like Truto to dynamically generate a secure, authenticated MCP server URL. If your team uses ChatGPT, check out our guide on /connect-clayhr-to-chatgpt-manage-employee-lifecycle-time/ or explore our broader architectural overview on /connect-clayhr-to-ai-agents-orchestrate-projects-performance/.
Giving a Large Language Model (LLM) read and write access to a sprawling Human Capital Management (HCM) platform like ClayHR is an engineering challenge. You must handle complex authorization lifecycles, map massive human resources JSON schemas to MCP tool definitions, and deal with strict state transitions for entities like timesheets and expense reports. Every time ClayHR updates an endpoint or changes a required field for performance reviews, you have to update your server code, redeploy, and test the integration.
This guide breaks down exactly how to use Truto to generate a secure, managed MCP server for ClayHR, connect it natively to Claude Desktop, and execute complex HR workflows using natural language.
The Engineering Reality of the ClayHR API
A custom MCP server is a self-hosted integration layer. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against specialized HR and operations APIs is painful. ClayHR is built to manage everything from applicant tracking to project timesheets and financial compensation. Its API reflects that complexity.
If you decide to build a custom ClayHR MCP server, here are the specific integration challenges you will face:
Strict State Transitions for Expenses and Timesheets
Entities in ClayHR do not follow simple CRUD patterns. Expense management, for example, requires strict sequencing. You cannot just pass a payload to an endpoint and expect a fully submitted expense report. An LLM must first create individual expense items (create_a_clay_hr_expense_item) defining amounts and currency codes, then create an expense report shell (create_a_clay_hr_expense_report), link the items, and finally submit the report (clay_hr_expense_reports_submit) with the correct status flag. If your MCP tools do not explicitly define these constraints in their JSON Schemas, Claude will attempt invalid operations and fail.
Nested Human Resources Data Models
Employee records in ClayHR are deeply nested arrays of data. A single user profile contains relations to organizational units, custom fields, compensation history, skills, and emergency contacts. When an AI agent needs to update an employee's profile, simple PATCH operations are often insufficient. The clay_hr_users_upsert endpoint is powerful but dangerous - if the LLM hallucinating a schema sends a partial payload, it can inadvertently overwrite or drop nested arrays for addresses or employment history. You must strictly bound the schemas exposed to the LLM to prevent destructive writes.
Pagination and Cursor Handling in Lists
When retrieving timesheets, projects, or user lists, ClayHR returns paginated results. An LLM cannot inherently guess how a specific API implements pagination. A custom MCP server must inject specific limit and next_cursor properties into the tool schema and explicitly instruct the LLM to pass cursor values back unchanged on subsequent calls. Otherwise, the model will hallucinate offset integers or get trapped in pagination loops.
Architecture: How Truto Generates the ClayHR MCP Server
Truto abstracts away the complexity of the ClayHR API by turning the connected integration directly into an MCP-compatible tool server. Rather than manually coding tool definitions, Truto generates them dynamically based on the integration's resource definitions and documentation records.
When Claude connects to the Truto MCP server, it requests a list of available tools. Truto iterates over the configured ClayHR resources, checks for available documentation schemas, and instantly compiles them into an array of JSON-RPC 2.0 tools. If a ClayHR endpoint lacks a documentation record, it is intentionally excluded from the MCP server. This acts as a strict quality gate, ensuring Claude only sees tools with properly defined inputs, descriptions, and required fields.
A Note on Rate Limits and Execution:
When Claude executes a tool (e.g., list_all_clay_hr_users), the request routes through Truto's proxy API layer. Truto translates the flat JSON-RPC arguments into the correct query parameters and request body structure for ClayHR.
Crucially, Truto does not retry, throttle, or apply backoff on rate limit errors. If your agent triggers ClayHR's rate limits, ClayHR returns an HTTP 429 Too Many Requests error. Truto passes this error directly back to Claude, normalizing the upstream rate limit data into standard IETF headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset). The caller (your AI agent or Claude Desktop) is entirely responsible for reading these headers and executing its own backoff logic.
How to Create the ClayHR MCP Server
Every MCP server in Truto is scoped to a single integrated account (a specific tenant's connected ClayHR instance). You can generate the server URL via the Truto UI or programmatically via the API.
Method 1: Via the Truto UI
If you are setting up an internal tool or testing locally, the UI is the fastest path:
- Navigate to the Integrated Accounts page in the Truto dashboard.
- Select your connected ClayHR account.
- Click the MCP Servers tab.
- Click Create MCP Server.
- Configure your server (assign a name, filter by specific methods like
readorwrite, and set an optional expiration date). - Copy the generated MCP server URL (e.g.,
https://api.truto.one/mcp/a1b2c3d4e5f6...).
Method 2: Via the REST API
For production workflows where you deploy AI agents programmatically, you can generate MCP servers on the fly via the Truto API. This creates a secure, hashed token in Truto's infrastructure and returns the connection URL.
curl -X POST https://api.truto.one/integrated-account/{integrated_account_id}/mcp \
-H "Authorization: Bearer YOUR_TRUTO_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "ClayHR Recruitment & PTO Agent",
"config": {
"methods": ["read", "write", "custom"],
"tags": ["recruitment", "hr_admin"]
},
"expires_at": "2026-12-31T23:59:59Z"
}'Truto validates that the integration has available tools, hashes the token for secure storage, and returns the ready-to-use URL.
How to Connect the MCP Server to Claude
Once you have your Truto MCP server URL, you must connect it to your LLM client.
Method A: Via the Claude or ChatGPT UI
If you are using Claude Desktop or ChatGPT Enterprise, you can add the server directly through the application settings.
For Claude Desktop/Web:
- Open Settings -> Integrations (or Connectors).
- Click Add MCP Server.
- Paste your Truto MCP URL.
- Click Add. Claude will immediately handshake with the server and discover the ClayHR tools.
For ChatGPT:
- Open Settings -> Apps -> Advanced settings.
- Enable Developer mode.
- Under Custom connectors, click Add new server.
- Provide a name (e.g., "ClayHR Tools") and paste the Truto MCP URL.
Method B: Via Manual Config File
If you are managing Claude Desktop via configuration files, you can add the server to your claude_desktop_config.json. Because Truto exposes the server over Server-Sent Events (SSE), you will use the official @modelcontextprotocol/server-sse transport.
Add the following to your configuration file (typically located at ~/Library/Application Support/Claude/claude_desktop_config.json on macOS or %APPDATA%\Claude\claude_desktop_config.json on Windows):
{
"mcpServers": {
"clayhr-truto": {
"command": "npx",
"args": [
"-y",
"@modelcontextprotocol/server-sse",
"https://api.truto.one/mcp/YOUR_TRUTO_TOKEN"
]
}
}
}Restart Claude Desktop. The application will initialize the connection and load the ClayHR tools.
ClayHR Hero Tools for Claude
Truto exposes the full surface area of the ClayHR API to Claude. Here are the highest-leverage tools for automating HR, recruitment, and financial operations.
clay_hr_users_upsert
Creates a new user or updates an existing one if a match is found based on email. This tool is highly versatile, allowing the LLM to save addresses, education, employment history, and custom field values in a single call.
"We just hired Jane Doe as a Senior Engineer. Her email is jane.doe@example.com. Upsert her profile in ClayHR and set her basic employment history details."
create_a_clay_hr_pto_balance
Adds a Paid Time Off (PTO) balance to a specific user. This requires the LLM to know the user's ID and the specific PTO policy ID, making it ideal for automated annual leave resets or manual adjustments.
"Find the user ID for John Smith, check his current PTO policies, and add 40 hours of balance to his 'Annual Leave' policy id."
clay_hr_timesheets_save
Creates or updates a timesheet entry. The LLM must supply the date, project ID, and elapsed time. This is critical for agents acting as AI project managers or time-tracking assistants.
"Log 4.5 hours for today on the 'Q3 Website Redesign' project timesheet for my account."
create_a_clay_hr_expense_item
Creates a discrete expense item specifying the amount, currency code, date, remarks, and expense type. This is the first step in the expense reporting workflow.
"I spent $45.50 on a client lunch today. Create a new expense item in USD categorized under 'Meals and Entertainment' and add a remark about the Acme Corp meeting."
clay_hr_expense_reports_submit
Submits an existing expense report for approval. Once items are linked to a report, the LLM uses this tool to transition the report status.
"Take expense report ID 8492, which contains this week's travel expenses, and submit it for manager approval."
create_a_clay_hr_candidate
Creates a new candidate in the recruitment pipeline. Ideal for AI agents monitoring a shared inbox for incoming resumes and automatically parsing them into the Applicant Tracking System (ATS).
"Parse the details from this email and create a new candidate profile in ClayHR for Sarah Connor applying for the Data Scientist role."
clay_hr_performance_reviews_bulk_launch
Launches performance reviews in bulk based on a template. This allows an AI agent to execute company-wide or department-wide review cycles autonomously.
"Launch the 'Q4 Annual Review' template for all users in the Engineering department."
To see the full list of available tools, query parameters, and required schemas, view the ClayHR integration page.
Workflows in Action
When Claude is equipped with ClayHR tools, it can orchestrate multi-step workflows that would normally require manual data entry across several screens. Here are two real-world examples.
Scenario 1: End-to-End Expense Reporting
Sales representatives frequently accumulate receipts on the road. An AI assistant can process raw text or receipt data and fully construct the expense report in ClayHR.
"I have three receipts from my trip to London: $120 for the hotel on Monday, $45 for a taxi on Tuesday, and $60 for dinner on Tuesday. Create expense items for all three, bundle them into a new expense report called 'London Sales Trip', and submit the report for approval."
Execution Steps:
- Claude calls
create_a_clay_hr_expense_itemthree separate times, applying the correct amounts, dates, and currency codes. - Claude calls
create_a_clay_hr_expense_reportwith the name "London Sales Trip" and retrieves the new report ID. - Claude (depending on ClayHR's exact linking requirements) updates the items to attach to the report.
- Claude calls
clay_hr_expense_reports_submitpassing the report ID and thesubmitstatus.
sequenceDiagram participant User as User participant Claude as Claude Desktop participant MCP as Truto MCP Server participant ClayHR as ClayHR API User->>Claude: "Process London trip expenses..." Claude->>MCP: Call create_a_clay_hr_expense_item (x3) MCP->>ClayHR: POST /expense/items ClayHR-->>MCP: Returns item IDs MCP-->>Claude: JSON-RPC Result Claude->>MCP: Call create_a_clay_hr_expense_report MCP->>ClayHR: POST /expense/reports ClayHR-->>MCP: Returns Report ID MCP-->>Claude: JSON-RPC Result Claude->>MCP: Call clay_hr_expense_reports_submit MCP->>ClayHR: POST /expense/reports/submit ClayHR-->>MCP: Success status MCP-->>Claude: JSON-RPC Result Claude-->>User: "Expense report 'London Sales Trip' submitted successfully."
Scenario 2: Employee Onboarding & Initial PTO Setup
HR administrators can ask Claude to execute the administrative tasks required when a new employee signs their offer letter.
"We just finalized the hire of Michael Scott as Regional Manager. Upsert his profile with his basic details, then assign him his initial 80 hours of PTO under the standard policy."
Execution Steps:
- Claude calls
clay_hr_users_upsertwith Michael's name, email, and job title. - Claude calls
list_all_clay_hr_pto_policiesto find the ID for the "standard policy". - Claude extracts Michael's new user ID from the upsert response and the policy ID from the list response.
- Claude calls
create_a_clay_hr_pto_balanceutilizing both IDs to credit the 80 hours.
Security and Access Control
When exposing HR and payroll systems to AI agents, security is paramount. Truto provides several configuration layers to restrict what an MCP server can do:
- Method Filtering: Configure the server to only allow
readoperations (blockingcreate,update,delete). If an LLM attempts to mutate data on a read-only server, Truto intercepts the call and returns an error before it reaches ClayHR. - Tag Filtering: Restrict tools to specific functional domains. You can configure a server to only expose tools tagged with
recruiting, hiding sensitivepayrollorperformanceendpoints from the agent. - Require API Token Auth: By setting
require_api_token_auth: trueduring creation, the MCP URL alone is not enough to execute tools. The client must also pass a valid Truto API token in theAuthorizationheader, adding a second layer of identity verification. - Ephemeral Servers: Use the
expires_atfield to create temporary MCP servers. Once the timestamp passes, Cloudflare KV drops the token and a cleanup alarm deletes the record, instantly revoking the AI's access to ClayHR.
Connect ClayHR to Claude Today
Building a custom integration layer for ClayHR requires deep knowledge of its nested schemas, pagination logic, and strict state transitions. By using Truto to generate a managed MCP server, you eliminate the need to write and maintain TypeScript mapping code, handle token refreshes, or manually define tool schemas for your LLM.
You can deploy secure, strictly-scoped AI tools in minutes and let your agents get straight to work managing timesheets, recruiting pipelines, and expense reports.
FAQ
- How does Truto handle ClayHR API rate limits?
- Truto does not retry, throttle, or apply backoff on rate limit errors. When ClayHR returns an HTTP 429 Too Many Requests, Truto passes that error directly to the caller, normalizing the upstream data into standard IETF headers. The caller must handle retries and backoff.
- Can I restrict Claude to only read data from ClayHR?
- Yes. When creating the MCP server via the Truto API or UI, you can pass a configuration object with `methods: ["read"]`. This drops all write, update, and delete tools from the generated server, ensuring the LLM cannot mutate HR records.
- How do I connect the Truto MCP URL to Claude Desktop?
- You can connect the server by navigating to Claude Desktop's settings, selecting Integrations or Connectors, clicking Add MCP Server, and pasting the Truto URL. Alternatively, you can edit the `claude_desktop_config.json` file to use the `@modelcontextprotocol/server-sse` transport.
- What happens if a ClayHR endpoint lacks documentation in Truto?
- Truto uses documentation records as a quality gate. If an endpoint does not have a documentation record defining its description and schemas, Truto will skip it during tool generation. This ensures Claude only interacts with well-defined tools.