---
title: How to Connect ShiftCare to Claude for Billing and Payments (With Code)
slug: how-to-connect-shiftcare-to-claude-for-billing-and-payments-with-code
date: 2026-08-24
author: Riya Sethi
categories: ["AI & Agents", Guides, By Example]
excerpt: "Learn how to connect Claude to ShiftCare via an MCP server. Handle Basic Auth, OAuth 2.0, NDIS state machines, rate limits, and billing workflows with code."
tldr: "Connecting Claude to ShiftCare requires an MCP server to translate natural language into strict JSON payloads, manage complex split authentication, and handle IETF rate limits."
canonical: https://truto.one/blog/how-to-connect-shiftcare-to-claude-for-billing-and-payments-with-code/
---

# How to Connect ShiftCare to Claude for Billing and Payments (With Code)


If you need to connect Claude to ShiftCare to automate National Disability Insurance Scheme (NDIS) billing, reconcile care worker payments, or programmatically manage invoices, you must build a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's natural language tool calls and ShiftCare's highly structured REST APIs.

Giving a Large Language Model (LLM) read and write access to a specialized healthcare and workforce management system is a significant engineering challenge. That server has to handle Basic Auth for the standard API, OAuth 2.0 for the newer HR endpoints, NDIS-specific state constraints, and rate limit headers. You can either engineer and maintain this middleware yourself, or use a managed integration platform to generate a signed, authenticated MCP URL and skip the boilerplate entirely.

This is a developer-focused walkthrough for B2B SaaS engineering leads automating NDIS invoicing, shift-to-invoice reconciliation, and payment flows. If you are looking for a broader architectural view before diving into the code, check out our guide on [Connect ShiftCare to AI Agents: Sync Workforce Data and Client Funds](https://truto.one/connect-shiftcare-to-ai-agents-sync-workforce-data-and-client-funds/), or the OpenAI variant in [Connect ShiftCare to ChatGPT: Manage Care Shifts and Client Notes](https://truto.one/connect-shiftcare-to-chatgpt-manage-care-shifts-and-client-notes/). For a sibling piece focused on organizational data, read [Connect ShiftCare to Claude: Sync Billing, Payments, and Compliance](https://truto.one/connect-shiftcare-to-claude-sync-billing-payments-and-compliance/).

> [!NOTE]
> **TL;DR:** MCP is the transport standard, ShiftCare's authentication split (Basic Auth vs OAuth 2.0) is the primary trap, and rate limits are entirely your responsibility. A managed MCP layer removes the token, schema, and hosting burden—but you still own the retry and idempotency logic.

## The Engineering Reality of the ShiftCare API

A [custom MCP server](https://truto.one/how-to-build-a-custom-mcp-server-for-claude-to-access-saas-apis/) is essentially a self-hosted API gateway. While the open MCP standard provides a predictable way for models to discover tools, the reality of implementing it against specialized B2B APIs is painful. ShiftCare isn't a generic CRM. It's a workforce and care management platform built around NDIS rules, shift-based payroll awards, and client fund tracking. Wiring an LLM into it means respecting constraints that don't exist in most REST APIs.

Here are three specific hurdles you will hit when writing custom code:

### 1. Split Authentication: Basic Auth vs OAuth 2.0

The ShiftCare public API uses HTTP Basic Authentication for standard resources (clients, shifts, invoices), but newer HR and payroll endpoints require OAuth 2.0 with short-lived JWT tokens.

The most common integration bug developers make when accessing the standard API is placing the API key in the `username` field. The correct format requires the Account ID as the username and the API key as the password:

```text
Authorization: Basic base64(<account_id>:<api_key>)
```

Get this wrong, and every request returns a `401 Unauthorized` with no useful error body. Conversely, for HR endpoints, your infrastructure must constantly monitor token expiration and execute refresh flows before the 15-minute JWT window closes, or your LLM's API calls will fail mid-generation.

### 2. Strict State Machines

ShiftCare enforces strict operational constraints to prevent billing anomalies. You cannot simply `POST` a new invoice and expect it to be valid. Invoices must be linked to verified client profiles, tied to specific approved shift records, and compliant with NDIS pricing arrangements. 

You can't invoice a shift that hasn't been marked complete. You can't edit a locked pay period. You can't create a duplicate booking on the same time block for the same worker. These aren't documented as validation errors in a single place—you discover them one HTTP 422 at a time. Your MCP server must be designed to fetch context, validate state, and guide the LLM through a multi-step billing sequence.

### 3. Domain-Heavy JSON Payloads

A single `shift` object references clients, workers, services, funding sources, pay items, mileage, expenses, notes, and NDIS line items. Mapping that massive JSON schema to MCP tool definitions means either dumping the entire schema into Claude's context window (expensive and noisy) or hand-curating a subset (brittle and incomplete). Neither scales past a handful of endpoints.

## Why Claude Needs a Model Context Protocol (MCP) Server

Anthropic positions MCP as the open standard—effectively the "USB-C"—for connecting AI assistants to data sources. It replaces fragmented custom integrations with a universal JSON-RPC format.

The momentum is real. Gartner predicts that by 2026, more than 30% of the increase in demand for APIs will come from AI and tools using Large Language Models. Furthermore, industry adoption data from Nevermined shows that 58% of MCP builders are creating wrappers around existing REST APIs rather than building entirely new greenfield backends. That is exactly the ShiftCare shape: a mature REST API that needs an LLM-native façade.

Without an MCP server, connecting Claude to ShiftCare means one of two ugly options:

*   **Copy-paste hell:** A human pulls invoice JSON from ShiftCare, pastes it into Claude, and copies the response back into a payment flow. There is no audit trail, no idempotency, and no scale.
*   **Bespoke function calling:** You hand-write brittle scripts that manually fetch data, format it into a prompt, send it to the LLM, parse the text response, deploy a serverless bridge, and reimplement it the moment ShiftCare ships a spec change.

MCP standardizes this. When Claude connects to an MCP server, the server exposes a list of available tools (e.g., `create_shiftcare_invoice`, `get_client_billing_history`). Claude decides when to use these tools based on the prompt, and the MCP server executes the underlying HTTP requests.

```mermaid
sequenceDiagram
    participant Claude as Claude LLM
    participant App as Your Application
    participant Truto as Managed MCP Layer
    participant ShiftCare as ShiftCare API

    Claude->>App: Tool Call: create_invoice
    App->>Truto: POST /mcp/execute (Tool Payload)
    Truto->>ShiftCare: POST /api/v2/invoices (Basic Auth)
    ShiftCare-->>Truto: 429 Too Many Requests
    Truto-->>App: 429 with IETF Ratelimit Headers
    Note over App: App reads headers & waits
    App->>Truto: Retry POST /mcp/execute
    Truto->>ShiftCare: POST /api/v2/invoices (Basic Auth)
    ShiftCare-->>Truto: 201 Created + invoice_id
    Truto-->>App: Tool Result (Success)
    App-->>Claude: Return Invoice ID
```

## Handling ShiftCare Rate Limits and API Errors

When you give an LLM the ability to query an API, it will often execute multiple requests in rapid succession to gather context. When Claude drives a bulk operation—reconciling a fortnight of shifts, or generating end-of-month invoices for 400 clients—you will hit account-level rate limits. This aggressive querying frequently triggers HTTP 429 (Too Many Requests) errors from upstream providers like ShiftCare.

A common anti-pattern in managed integration platforms is attempting to silently mask these errors. Masking 429s leads to unpredictable latency spikes, hanging LLM generations, and silent data loss in billing workflows. This is a far worse failure mode than a visible retry.

Truto takes a deterministic approach. Truto does not automatically retry, throttle, or apply backoff on rate limit errors. When ShiftCare returns an HTTP 429, the error is passed straight through to your caller. To make handling these errors predictable, Truto normalizes the upstream rate limit information into standardized headers per the IETF specification:

*   `ratelimit-limit`: The maximum number of requests permitted in the current window.
*   `ratelimit-remaining`: The number of requests remaining in the current window.
*   `ratelimit-reset`: The time at which the rate limit window resets.

**The architectural takeaway:** The caller (your application) is entirely responsible for reading these headers and implementing exponential backoff. 

Here is a minimal backoff wrapper concept in TypeScript:

```typescript
async function callWithBackoff(fn: () => Promise<Response>, maxRetries = 5) {
  for (let attempt = 0; attempt <= maxRetries; attempt++) {
    const res = await fn();
    if (res.status !== 429) return res;
    const reset = Number(res.headers.get('ratelimit-reset') ?? 1);
    const jitter = Math.random() * 250;
    await new Promise(r => setTimeout(r, reset * 1000 + jitter));
  }
  throw new Error('Rate limit retries exhausted');
}
```

## Step-by-Step: Connecting ShiftCare to Claude with Code

To build a reliable integration, you need to map ShiftCare's API to Claude's tool calling interface. Below is an end-to-end developer tutorial demonstrating how to execute a billing workflow using a managed MCP server approach. For more context on formatting technical documentation, see [How to Build a Runnable, Step-by-Step Developer Tutorial with Code Samples](https://truto.one/how-to-build-a-runnable-step-by-step-developer-tutorial-with-code-samples/).

### Phase 1: Infrastructure Setup

First, create an integrated account in your managed platform with your ShiftCare credentials. The platform stores the credential securely and injects it on every proxied call—your code never sees the raw secret at runtime.

```bash
curl -X POST https://api.truto.one/integrated-account \
  -H "Authorization: Bearer $TRUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "integration": "shiftcare",
    "tenant_id": "tenant_123",
    "authentication": {
      "account_id": "YOUR_SHIFTCARE_ACCOUNT_ID",
      "api_key": "YOUR_SHIFTCARE_API_KEY"
    }
  }'
```

Next, request a scoped MCP URL for that integrated account. The URL is signed, expires, and only exposes the tools you allow-list.

```bash
curl -X POST https://api.truto.one/mcp/server \
  -H "Authorization: Bearer $TRUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "integrated_account_id": "ia_abc123",
    "tools": [
      "list_clients",
      "list_shifts",
      "create_invoice",
      "record_payment"
    ]
  }'
```

### Phase 2: Application Implementation

Now, set up your Node.js environment and initialize the HTTP client that will communicate with your managed MCP server. We will implement the backoff strategy discussed earlier.

```javascript
import fetch from 'node-fetch';
import Anthropic from '@anthropic-ai/sdk';

const TRUTO_API_KEY = process.env.TRUTO_API_KEY;
const MCP_SERVER_URL = process.env.TRUTO_SHIFTCARE_MCP_URL;
const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });

// Helper to execute MCP tools
async function executeMcpTool(toolName, parameters) {
  return await fetch(`${MCP_SERVER_URL}/execute`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${TRUTO_API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      jsonrpc: '2.0',
      method: 'tools/call',
      params: { name: toolName, arguments: parameters },
      id: crypto.randomUUID()
    })
  });
}

// Backoff wrapper reading IETF headers
async function callToolWithBackoff(toolName, parameters, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const response = await executeMcpTool(toolName, parameters);
    
    if (response.status === 429) {
      const resetTime = response.headers.get('ratelimit-reset');
      const waitSeconds = resetTime ? Math.max(0, resetTime - Math.floor(Date.now() / 1000)) : Math.pow(2, attempt);
      
      console.warn(`Rate limited by ShiftCare. Retrying in ${waitSeconds} seconds...`);
      await new Promise(resolve => setTimeout(resolve, waitSeconds * 1000));
      continue;
    }
    
    if (!response.ok) throw new Error(`API Error: ${response.status} - ${await response.text()}`);
    return await response.json();
  }
  throw new Error('Max retries exceeded for ShiftCare API.');
}
```

### Phase 3: Execute the Billing Workflow

Now you can wire this up to Claude. In this scenario, we instruct Claude to generate an invoice for a specific client based on their recent approved shifts.

```javascript
async function processBillingPrompt(userPrompt) {
  const message = await anthropic.messages.create({
    model: 'claude-3-5-sonnet-20241022',
    max_tokens: 1024,
    tools: [{
      name: 'create_invoice',
      description: 'Creates a new NDIS-compliant invoice in ShiftCare',
      input_schema: {
        type: 'object',
        properties: {
          client_id: { type: 'string' },
          amount: { type: 'number' },
          description: { type: 'string' },
          date: { type: 'string', format: 'date' }
        },
        required: ['client_id', 'amount', 'date']
      }
    }],
    messages: [{ role: 'user', content: userPrompt }]
  });

  if (message.stop_reason === 'tool_use') {
    const toolCall = message.content.find(block => block.type === 'tool_use');
    console.log(`Claude is calling ${toolCall.name} with params:`, toolCall.input);
    
    try {
      const result = await callToolWithBackoff(toolCall.name, toolCall.input);
      console.log('Invoice successfully created in ShiftCare:', result);
      return result;
    } catch (error) {
      console.error('Billing workflow failed:', error);
      throw error;
    }
  }
  return message.content;
}

processBillingPrompt("Create a $450 invoice for client ID 'CL-9938' for weekend care services provided on 2023-10-28.");
```

### Phase 4: Handle Payment Recording with Idempotency

After the customer pays, Claude can call a `record_payment` tool. 

> [!WARNING]
> Always implement idempotency keys when creating financial records. If a network timeout occurs between your application and ShiftCare, an idempotency key ensures that a retry does not result in a duplicate invoice or payment being generated.

```json
{
  "tool": "record_payment",
  "arguments": {
    "invoice_id": "inv_9982",
    "amount": 1450.00,
    "method": "bank_transfer",
    "idempotency_key": "pay-2026-11-15-inv9982"
  }
}
```

The idempotency key survives retries, network failures, and Claude re-planning the same action twice—which happens more than you'd think.

## Managed MCP Infrastructure vs. Self-Hosting

Building the code above is only half the battle. If you self-host your MCP server, you are responsible for maintaining the infrastructure, securing the API keys, handling OAuth callbacks, and updating the tool schemas every time ShiftCare deprecates a field.

Economic uncertainty and complex billing requirements are pushing organizations to adopt LLMs and automation to prevent revenue leakage. According to McKinsey, 65% of aftermarket and service executives see a risk of margin compression, driving the need for automated, AI-driven billing workflows. The catch: the automation only pays off if the integration layer under it is reliable.

| Concern | Self-Hosted MCP | Managed MCP (Truto) |
|---|---|---|
| Basic Auth + OAuth split | You implement both | Handled |
| 15-min JWT refresh | You schedule refresh jobs | Platform schedules work ahead of token expiry |
| Rate limit headers | You parse vendor-specific formats | Normalized to IETF `ratelimit-*` |
| 429 retry logic | You write it | **You still write it** |
| Schema drift | You patch and redeploy | Absorbed upstream |
| Adding Xero or QuickBooks | New server, new code | Same MCP surface, new tools |

Be honest about the trade-off. A managed layer removes hosting, auth plumbing, and schema maintenance, but it doesn't remove your responsibility for retry policy, idempotency keys, or writing prompts that respect ShiftCare's state machine. 

Compare that to heavyweight platforms like MuleSoft, which solve integration comprehensively but require significant upfront investment and specialized training. For teams that just need Claude talking to ShiftCare (and Xero, and maybe QuickBooks next quarter), the heavyweight iPaaS approach is overkill. A unified API approach means the exact same infrastructure used for ShiftCare can instantly connect Claude to accounting platforms without writing new authentication logic.

## Where to Go From Here

If you're evaluating this seriously, the fastest path to production is:

1.  **Provision a sandbox:** Connect a ShiftCare test account to a managed integration platform.
2.  **Start read-only:** Generate an MCP URL scoped to read-only tools first (`list_clients`, `list_shifts`).
3.  **Validate the round trip:** Wire it into Claude Desktop or the Anthropic SDK and validate the prompt-to-API flow.
4.  **Add write operations:** Add write tools (`create_invoice`, `record_payment`) with strict idempotency keys once read flows are stable.
5.  **Layer observability:** Add your own 429 backoff and observability around the MCP calls.

Do the read-only pass end-to-end before you touch anything that moves money. The engineering realities of ShiftCare—split auth, state machines, NDIS constraints—don't disappear because Claude is calling the API instead of your backend. They just move up the stack. By leveraging MCP and a managed integration layer, engineering teams can bypass the boilerplate and focus on building intelligent billing workflows that actually drive business value.

> Stop wasting engineering cycles on API maintenance. Use Truto to dynamically generate secure MCP servers for ShiftCare, Xero, QuickBooks, and hundreds of other SaaS platforms.
>
> [Talk to us](https://cal.com/truto/partner-with-truto)
