Skip to content

Connect ShiftCare to Claude: Sync Billing, Payments, and Compliance

Connect ShiftCare to Claude to sync billing, payments, and NDIS compliance via a managed MCP server - no custom API glue code required.

Sidharth Verma Sidharth Verma · · 18 min read
Connect ShiftCare to Claude: Sync Billing, Payments, and Compliance

If your team needs to connect ShiftCare to Claude to automate care scheduling, NDIS billing reconciliation, or compliance tracking, you need a Model Context Protocol (MCP) server. This server acts as the translation layer between Claude's tool calls and ShiftCare's REST API. 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 connecting ShiftCare to ChatGPT or explore our broader architectural overview on connecting ShiftCare to AI Agents.

Giving a Large Language Model (LLM) read and write access to a specialized healthcare and workforce management system like ShiftCare is an engineering challenge. You have to handle OAuth 2.0 or API key token lifecycles, map massive JSON schemas to MCP tool definitions, and deal with ShiftCare's domain-specific data constraints. Every time ShiftCare updates an endpoint or deprecates a field, 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 ShiftCare, connect it natively to Claude, and execute complex care management workflows using natural language.

The Engineering Reality of the ShiftCare 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 B2B APIs is painful. ShiftCare is built to manage National Disability Insurance Scheme (NDIS) compliance, complex payroll awards, and mobile care workforces. Its API reflects that complexity.

If you decide to build a custom ShiftCare MCP server, here are the specific integration challenges you will face:

NDIS Billing and Cancellation Logic ShiftCare enforces strict domain logic around cancellations and billing. For example, cancelling a shift is not just a matter of changing a status to cancelled. If you want to cancel a shift while keeping it billable, you must apply specific NDIS no-show codes to individual client ratios. An LLM cannot simply guess this payload structure. A managed MCP server exposes tools like shift_care_shifts_cancel with strictly defined schemas that explicitly guide the LLM to provide the correct charge flags.

Feature-Flagged Endpoints and Asynchronous Operations Not all endpoints in the ShiftCare API behave like standard synchronous CRUD operations. Endpoints like list_all_shift_care_account_locations are gated behind internal feature flags, meaning an LLM will throw unexpected 403 errors if it tries to list locations on an un-flagged account. Furthermore, operations like archiving a staff member (shift_care_staff_archive) are processed asynchronously in the background. Your MCP server must properly map these responses so the LLM understands the operation was queued, not instantly completed.

Complex External Reference Mapping Syncing ShiftCare to external payroll systems (like Xero or MYOB) requires utilizing ShiftCare's external_references endpoints. You cannot just pass a Xero ID in a standard user payload. You have to use bulk update endpoints like shift_care_external_references_bulk_update, which require highly specific arrays of resource_type, resource_id, service, and external_id. Truto translates these requirements into strictly typed MCP tool schemas so Claude knows exactly how to format the cross-reference payloads.

Rate Limits and Upstream Headers ShiftCare enforces rate limits to protect its infrastructure. It is critical to note that Truto does not retry, throttle, or apply backoff on rate limit errors. When the upstream ShiftCare API returns an HTTP 429 Too Many Requests, Truto passes that error directly to the caller. Truto normalizes the upstream rate limit information into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset) per the IETF spec. Your LLM framework or MCP client is completely responsible for handling the retry and exponential backoff logic.

How to Generate a ShiftCare MCP Server with Truto

Truto dynamically generates MCP tools based on ShiftCare's API documentation and your environment's integration configuration. You can spin up an MCP server for any connected ShiftCare account in seconds.

There are two ways to create your ShiftCare MCP server URL: via the Truto UI or programmatically via the API.

Method 1: Creating the Server via the Truto UI

If you are setting up an internal tool or testing Claude Desktop, the Truto UI is the fastest path.

  1. Log in to your Truto dashboard and navigate to the Integrated Accounts page.
  2. Select your connected ShiftCare account.
  3. Click on the MCP Servers tab.
  4. Click Create MCP Server.
  5. Select your desired configuration (e.g., allow read and write methods, set tag filters if needed).
  6. Copy the generated MCP server URL. It will look like https://api.truto.one/mcp/a1b2c3d4e5f6....

Method 2: Creating the Server via the API

If you are provisioning AI agents dynamically for your end-users, you should generate the MCP server programmatically. Truto scopes each MCP server to a single integrated account using a secure, hashed token.

Make a POST request to /integrated-account/:id/mcp with your desired configuration:

curl -X POST https://api.truto.one/integrated-account/<SHIFTCARE_ACCOUNT_ID>/mcp \
  -H "Authorization: Bearer YOUR_TRUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ShiftCare Billing and Compliance Agent",
    "config": {
      "methods": ["read", "write", "custom"]
    }
  }'

The API will validate the integration and return a ready-to-use URL:

{
  "id": "mcp_srv_9x8y7z6",
  "name": "ShiftCare Billing and Compliance Agent",
  "config": { "methods": ["read", "write", "custom"] },
  "expires_at": null,
  "url": "https://api.truto.one/mcp/a1b2c3d4e5f67890"
}

How to Connect the ShiftCare MCP Server to Claude

Once you have the Truto MCP URL, connecting it to Claude requires zero custom code. You can add it directly to Claude's UI or modify your desktop configuration file.

Method A: Via the Claude UI

(Note: Anthropic is actively rolling out UI support for remote MCP connectors. If your tier does not yet have the UI, use Method B below).

  1. Open Claude (Desktop or Web).
  2. Navigate to Settings -> Integrations -> Add MCP Server.
  3. Provide a name (e.g., "ShiftCare Production").
  4. Paste the Truto MCP URL you generated in the previous step.
  5. Click Add.

Claude will immediately initialize the connection, perform a handshake, and list the available ShiftCare tools.

Method B: Via Manual Configuration File

If you are using Claude Desktop and prefer manual configuration, you can inject the Truto MCP URL using the standard Server-Sent Events (SSE) transport wrapper provided by the MCP specification.

Open your Claude Desktop config file:

  • macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
  • Windows: %APPDATA%\Claude\claude_desktop_config.json

Add the following JSON configuration, replacing the URL with your Truto URL:

{
  "mcpServers": {
    "shiftcare-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-sse",
        "https://api.truto.one/mcp/a1b2c3d4e5f67890"
      ]
    }
  }
}

Save the file and restart Claude Desktop. The model now has full functional access to your ShiftCare instance.

MCP Config Guide: Scoping Claude to Billing and Payments

Most billing teams do not want Claude poking around in medical records, staff HR data, or rostering. The safer pattern is to provision a dedicated MCP server scoped exclusively to ShiftCare's billing, invoicing, and payments surface, then hand that URL to Claude.

Here is the exact end-to-end config for a billing-and-payments-only Claude connection.

Step 1: Create a billing-scoped MCP server

Use method-level and tag-level filters together so Claude only sees the invoicing and payments tools:

curl -X POST https://api.truto.one/integrated-account/<SHIFTCARE_ACCOUNT_ID>/mcp \
  -H "Authorization: Bearer YOUR_TRUTO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ShiftCare Billing and Payments (Claude)",
    "config": {
      "methods": ["read", "write", "custom"],
      "tags": ["billing", "payments", "invoicing"],
      "require_api_token_auth": true
    }
  }'

What each field does:

  • methods limits Claude to reading records and creating or updating billing entities. Drop "write" if you only want a read-only reconciliation agent.
  • tags restricts the tool list at generation time. Tools for medical records, staff archiving, or rostering are never exposed to the model.
  • require_api_token_auth forces the client to also send a Truto API token, so possession of the URL alone is not enough to hit ShiftCare.

Step 2: Add the URL as a custom connector in Claude

  1. Copy the url value from the response.
  2. In Claude, open Settings -> Connectors -> Add custom connector.
  3. Name it "ShiftCare Billing and Payments" and paste the URL.
  4. If you set require_api_token_auth: true, add your Truto API token as a Bearer credential in the connector's authentication settings.
  5. Save. Claude runs the MCP handshake and lists only the billing, invoice, and payment tools.

Step 3: Verify the tool surface

Before you trust Claude with real billing operations, ask it:

"List every tool you have access to on the ShiftCare connector, grouped by resource."

You should see tools like list_all_shift_care_invoiceable_items, shift_care_shifts_cancel, shift_care_external_references_bulk_update, and payment-related resources. If you see tools for medical notes or staff PII, revisit your tag filters.

Step 4: Sanity-check with a read-only prompt

Run one benign read call to confirm the connection and auth are wired end-to-end before you point the agent at production data:

"Fetch the five most recent invoiceable items in ShiftCare. Do not create, update, or delete anything. Just show me the raw response."

If that returns clean data, the connector is ready for the real workflows below.

Hero Tools for ShiftCare Automation

Truto maps ShiftCare's extensive API into modular, highly specific MCP tools. Instead of forcing Claude to guess REST parameters, these tools include injected schemas that explicitly guide the LLM. Here are a few high-leverage tools available on the ShiftCare MCP server.

shift_care_shifts_cancel

Cancelling shifts in healthcare scheduling is complex due to billing requirements. This custom tool allows Claude to cancel a shift either without charge (unbillable) or with charge (marking clients as absent using NDIS no-show codes while retaining billability).

"Cancel shift ID 9872. The client called to cancel at the last minute, so process this with a charge using the standard NDIS no-show code."

shift_care_clients_get_fund_balance

This tool is critical for tracking NDIS plan limits. It returns a specific client's fund balance, including both monetary totals and allocated hours, preventing over-servicing.

"Check the current fund balance for client ID 8493 on their primary NDIS support fund. How many hours do they have remaining for the month?"

create_a_shift_care_complaint

Incident reporting is a massive compliance burden. This tool creates a formal complaint record, defaulting new entries to a 'received' status and 'low' risk level, while capturing complainant details and lifecycle timestamps.

"Log a new compliance complaint for client ID 1122. A family member reported that the carer arrived 45 minutes late yesterday. Set the risk level to low and assign it to the floor manager."

list_all_shift_care_invoiceable_items

This tool fetches priced shift and non-shift line items for a specific billing period. The response is grouped per client and includes tax-exclusive totals, making it perfect for generating end-of-week billing summaries.

"Pull all invoiceable items for the billing period of October 1st through October 15th. Summarize the total tax-exclusive amounts grouped by client name."

shift_care_external_references_bulk_update

Managing payroll mapping requires linking ShiftCare staff and pay items to external HR systems. This tool allows Claude to bulk update external references across multiple supported resources in a single call.

"Update the external payroll references for staff IDs 501, 502, and 503. Map them to Xero employee IDs X-101, X-102, and X-103 respectively."

shift_care_staff_archive

When a carer leaves the organization, offboarding must be complete. This tool triggers ShiftCare's asynchronous archiving process, which removes the staff member from future shifts and updates related records in the background.

"Staff member ID 304 has resigned. Trigger the archive process to remove them from all future rosters and update their profile status."

To view the complete inventory of available operations, schemas, and required parameters, visit the ShiftCare integration page.

Workflows in Action

When you connect the ShiftCare MCP server to Claude, you graduate from simple Q&A to agentic execution. Claude can sequence multiple tools together to solve complex operational problems.

Here are three real-world workflows that compliance managers and billing administrators can execute.

Workflow 1: NDIS Fund Audit & Billing Reconciliation

Care coordinators need to ensure they do not schedule services that exceed a client's allocated NDIS funding. This workflow audits upcoming billing against remaining funds.

User Prompt:

"Audit the invoiceable items for the current week for client 'Jane Doe'. Once you have the total invoiceable hours, check her primary NDIS fund balance. If the week's billing will leave her with fewer than 5 hours remaining in her fund, draft an alert email for the care management team."

Execution Steps:

  1. list_all_shift_care_clients: Claude searches for "Jane Doe" to retrieve her unique client_id.
  2. list_all_shift_care_invoiceable_items: Claude fetches the line items for the current week, filtering the results for Jane's client_id, and calculates the total hours billed.
  3. shift_care_clients_list_funds: Claude queries the client's available funds to find the primary NDIS fund ID.
  4. shift_care_clients_get_fund_balance: Claude checks the real-time monetary and hourly balance of that specific fund.
  5. Synthesis: Claude subtracts the pending invoiceable hours from the fund balance and generates the requested alert text if the threshold is breached.
sequenceDiagram
    participant Admin as Care Coordinator
    participant Claude as Claude Desktop
    participant Truto as Truto MCP Server
    participant ShiftCare as ShiftCare API

    Admin->>Claude: "Audit invoiceable items for Jane Doe vs fund balance..."
    Claude->>Truto: tools/call (list_all_shift_care_invoiceable_items)
    Truto->>ShiftCare: GET /invoiceable_items (Proxy)
    ShiftCare-->>Truto: Return pending shift totals
    Truto-->>Claude: Standardized tool response
    Claude->>Truto: tools/call (shift_care_clients_get_fund_balance)
    Truto->>ShiftCare: GET /funds/balance (Proxy)
    ShiftCare-->>Truto: Return remaining hours
    Truto-->>Claude: Standardized tool response
    Claude-->>Admin: "Jane has 12 hours pending, leaving only 2 hours. Here is the alert draft..."

Workflow 2: Incident Reporting & Compliance Escalation

When a care incident occurs, strict documentation is required. This workflow ensures an incident is logged as a complaint and cross-referenced in the client's progress notes.

User Prompt:

"We had a safety concern today with client ID 599. A medication error was reported during the morning shift. Please create a new complaint record with a 'high' risk level assigned to manager ID 42. After creating the complaint, create a private progress note on the client's profile linking the complaint reference number."

Execution Steps:

  1. create_a_shift_care_complaint: Claude formats a payload with client_id: 599, risk_level: high, assignee_id: 42, and a detailed description of the medication error.
  2. Claude extracts the resulting reference_number from the successful complaint creation response.
  3. create_a_shift_care_client_note: Claude generates a new note for client_id: 599. It sets private: true, categorizes it as a compliance note, and injects the extracted reference_number into the message body for audit tracking.

Workflow 3: Weekly Billing and Payments Sync

Billing administrators close out the week by comparing what was billable in ShiftCare against payments received and payroll mappings pushed to external systems. This workflow lets Claude run the whole reconciliation loop with a single prompt.

User Prompt:

"For the billing period October 1 to October 15, pull every invoiceable line item grouped by client and calculate the tax-exclusive totals. Then flag any client whose total exceeds their remaining NDIS fund balance. Finally, for the staff whose shifts appear in that period, confirm each one has a valid Xero external reference. Give me a single summary table."

Execution Steps:

  1. list_all_shift_care_invoiceable_items: Claude fetches priced shift and non-shift items for the two-week window, grouped by client, with tax-exclusive totals.
  2. shift_care_clients_get_fund_balance: For each client on the invoiceable list, Claude checks the primary NDIS fund balance to identify anyone at risk of over-servicing.
  3. list_all_shift_care_staff: Claude extracts the distinct set of staff IDs from the invoiceable line items.
  4. shift_care_external_references_bulk_update (read path via list): Claude verifies each staff ID has a service: "xero" external reference mapped. Missing references are flagged so payroll does not silently drop those hours.
  5. Synthesis: Claude assembles one table with columns for client, invoiceable total, fund headroom, and payroll-mapping status - the exact artifact a billing admin needs before pressing "invoice" in the downstream accounting system.

Because the MCP server was scoped with billing and payments tags, Claude has no way to touch scheduling or clinical data during this reconciliation, even if the prompt drifts.

ShiftCare MCP Tool Schemas

When Claude sends a tools/list request to the Truto MCP URL, it receives back a list of JSON Schema tool definitions. These schemas are what actually constrain the model's tool calls at inference time. Here is what a few of the billing-relevant ShiftCare tool definitions look like in practice.

list_all_shift_care_invoiceable_items

Read-only query for a billing window. This is the workhorse for any reconciliation flow.

{
  "name": "list_all_shift_care_invoiceable_items",
  "description": "List priced shift and non-shift invoiceable items for a billing period, grouped by client, with tax-exclusive totals.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "from": {
        "type": "string",
        "description": "Start of the billing period (ISO 8601 date)."
      },
      "to": {
        "type": "string",
        "description": "End of the billing period (ISO 8601 date)."
      },
      "client_id": {
        "type": "string",
        "description": "Optional. Restrict results to a single client."
      },
      "limit": {
        "type": "string",
        "description": "The number of records to fetch"
      },
      "next_cursor": {
        "type": "string",
        "description": "The cursor to fetch the next set of records. Always send back exactly the cursor value you received (nextCursor) without decoding, modifying, or parsing it."
      }
    }
  }
}

Notice that limit and next_cursor are injected automatically for every list-type tool. The cursor description explicitly instructs the LLM to pass values back unchanged, so you never write pagination glue - Claude receives the cursor from the previous response and hands it back verbatim on the next call.

shift_care_shifts_cancel

Custom method with strict NDIS billing semantics. The schema forces the model to decide upfront whether the cancellation is billable, and to supply the no-show code and per-client absence flags when it is.

{
  "name": "shift_care_shifts_cancel",
  "description": "Cancel a shift. Set with_charge=true to keep the shift billable using NDIS no-show codes, or false to cancel without charge.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "id": {
        "type": "string",
        "description": "The id of the shift to cancel. Required."
      },
      "with_charge": {
        "type": "boolean",
        "description": "Whether to retain billability using NDIS no-show codes."
      },
      "no_show_code": {
        "type": "string",
        "description": "Required if with_charge=true. NDIS no-show reason code."
      },
      "client_ratios": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "client_id": { "type": "string" },
            "absent": { "type": "boolean" }
          }
        },
        "description": "Per-client absence flags for group shifts."
      }
    },
    "required": ["id", "with_charge"]
  }
}

shift_care_clients_get_fund_balance

Single-resource read. Truto automatically injects the id property into the schema for get, update, and delete methods, so the LLM always knows which parameter identifies the target record.

{
  "name": "shift_care_clients_get_fund_balance",
  "description": "Get a client's NDIS fund balance, including monetary total and allocated hours remaining.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "id": {
        "type": "string",
        "description": "The id of the clients to get. Required."
      },
      "fund_id": {
        "type": "string",
        "description": "Specific fund to query. Defaults to the client's primary NDIS fund."
      }
    },
    "required": ["id"]
  }
}

shift_care_external_references_bulk_update

The payload shape you would otherwise have to hand-roll for every ShiftCare-to-payroll sync. The schema makes it obvious to the model that each entry needs a resource type, a resource ID, an external service key, and the external ID.

{
  "name": "shift_care_external_references_bulk_update",
  "description": "Bulk update external references linking ShiftCare resources (staff, clients, pay items) to external systems (Xero, MYOB, etc.).",
  "inputSchema": {
    "type": "object",
    "properties": {
      "references": {
        "type": "array",
        "items": {
          "type": "object",
          "properties": {
            "resource_type": {
              "type": "string",
              "enum": ["staff", "client", "pay_item"]
            },
            "resource_id": { "type": "string" },
            "service": {
              "type": "string",
              "description": "External service key, e.g. 'xero', 'myob'."
            },
            "external_id": { "type": "string" }
          },
          "required": ["resource_type", "resource_id", "service", "external_id"]
        }
      }
    },
    "required": ["references"]
  }
}

Because these schemas are generated from Truto's per-resource documentation on every tools/list request rather than baked into a static server binary, they track the current ShiftCare API surface without you hand-writing or regenerating JSON Schema files.

End-to-End Billing Developer Guide

If you are wiring an agent up programmatically instead of clicking through Claude Desktop, here is the full loop for a billing and payments sync. This walkthrough uses Anthropic's native MCP connector in the Messages API to point Claude directly at a Truto MCP URL and drive a reconciliation.

1. Provision a scoped MCP server

Create a short-lived, billing-scoped server for the run. The TTL means the token auto-expires once the batch job finishes.

const provisionRes = await fetch(
  `https://api.truto.one/integrated-account/${SHIFTCARE_ACCOUNT_ID}/mcp`,
  {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.TRUTO_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      name: "ShiftCare Billing Sync (Claude Agent)",
      config: {
        methods: ["read", "write", "custom"],
        tags: ["billing", "payments", "invoicing"],
        require_api_token_auth: true,
      },
      expires_at: new Date(Date.now() + 24 * 60 * 60 * 1000).toISOString(),
    }),
  }
);
 
const { url: mcpUrl } = await provisionRes.json();

Because Truto schedules cleanup ahead of the expiry, both the token record and its cached auth state are torn down when the TTL elapses. You can also PATCH the resource to extend or remove the expiry.

2. Connect Claude to the MCP URL

Anthropic's Messages API accepts remote MCP servers directly via the mcp_servers parameter behind the mcp-client-2025-04-04 beta header. Pass the Truto URL and the Truto API token as the authorization token:

import Anthropic from "@anthropic-ai/sdk";
 
const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
 
const response = await anthropic.beta.messages.create(
  {
    model: "claude-sonnet-4-5",
    max_tokens: 4096,
    mcp_servers: [
      {
        type: "url",
        url: mcpUrl,
        name: "shiftcare-billing",
        authorization_token: process.env.TRUTO_API_KEY,
      },
    ],
    messages: [
      {
        role: "user",
        content:
          "Reconcile invoiceable items for October 1-15 against NDIS fund balances. Flag any client at risk of over-servicing and confirm every staff member on shift has a Xero external reference. Return a single summary table.",
      },
    ],
  },
  { headers: { "anthropic-beta": "mcp-client-2025-04-04" } }
);

Claude now calls the Truto MCP tools directly from Anthropic's infrastructure. You do not have to run a local MCP client or relay tools/call traffic through your own backend.

3. Expected tool call sequence

For a billing reconciliation prompt like the one above, Claude will typically execute this sequence:

  1. list_all_shift_care_invoiceable_items with from and to set to the billing window. If the response includes a next_cursor, Claude pages through until exhausted.
  2. For each client_id returned, shift_care_clients_get_fund_balance to check headroom against the pending invoiceable total.
  3. list_all_shift_care_staff (or a list call against the ShiftCare external references resource) to build the distinct set of staff IDs from the shift lines and inspect their existing Xero mappings.
  4. If any staff IDs are missing a service: "xero" reference, Claude constructs a shift_care_external_references_bulk_update payload and asks you to confirm before writing.
  5. A synthesized markdown table with client, invoiceable total, fund headroom, and payroll-mapping status.

Because next_cursor and pagination instructions are baked into every list-tool schema, Claude paginates correctly without any prompt engineering from your side.

4. Capture the tool trace for audit

Truto is stateless for MCP calls: it proxies each request to ShiftCare and returns the raw response wrapped in the MCP tool result envelope, along with a request_id that maps to the upstream trace ID. Persist those alongside the model's final output if you need an audit log for compliance reviews.

import { writeAuditRow } from "./audit";
 
for (const block of response.content) {
  if (block.type === "mcp_tool_use") {
    await writeAuditRow({
      kind: "tool_use",
      server: block.server_name,
      tool: block.name,
      input: block.input,
      tool_use_id: block.id,
    });
  }
  if (block.type === "mcp_tool_result") {
    await writeAuditRow({
      kind: "tool_result",
      tool_use_id: block.tool_use_id,
      is_error: block.is_error,
      content: block.content,
    });
  }
}

The request_id field inside each tool result payload is your join key back to the ShiftCare-side request in Truto's logs if you ever need to reproduce a specific call.

5. Handle rate limits and idempotency

ShiftCare returns HTTP 429 when you hit its rate limit, and Truto surfaces those directly via normalized ratelimit-limit, ratelimit-remaining, and ratelimit-reset headers without retrying on your behalf. Your agent loop needs to detect tool errors, back off, and re-issue the call:

async function runWithBackoff(prompt: string, attempt = 0): Promise<void> {
  const res = await anthropic.beta.messages.create(/* ...as above... */);
  const errored = res.content.some(
    (b) => b.type === "mcp_tool_result" && b.is_error
  );
  if (errored && attempt < 5) {
    const delayMs = Math.min(30_000, 2 ** attempt * 500);
    await new Promise((r) => setTimeout(r, delayMs));
    return runWithBackoff(prompt, attempt + 1);
  }
}

For batch jobs that write to ShiftCare (creating complaints, updating external references, cancelling shifts), wrap the loop with idempotent state on your side. Track which billing periods, client IDs, and staff IDs have already been reconciled so a mid-run failure does not double-post payments to your downstream accounting system.

That is the complete billing-and-payments loop: provision a scoped MCP server, hand Claude the URL through the Messages API, let it drive ShiftCare through Truto's proxy, and capture the tool trace for audit. No custom OAuth handling, no hand-written schema mapping, no pagination glue.

Security and Access Control

Exposing a healthcare management system to an LLM requires strict access governance. Truto's MCP server implementation provides multiple layers of security to ensure Claude only accesses what it should.

  • Method Filtering: You can restrict your MCP server to only allow read operations. If an LLM attempts to hallucinate a create or delete command, the MCP router will block the request before it ever reaches ShiftCare.
  • Tag Filtering: Limit the surface area of the integration by passing a tags array during server creation. You can configure a server to only expose tools related to billing and completely hide tools related to medical_records.
  • Expiration (TTL): When provisioning access for temporary audits or contractor agents, you can set an expires_at ISO datetime. The MCP token will automatically self-destruct once the TTL elapses, with a scheduled cleanup ahead of expiry to remove any residual state.
  • Extra Authentication Layer: By enabling require_api_token_auth: true, the MCP URL itself is no longer sufficient for access. The connecting client must also pass a valid Truto user API token in the Authorization header, binding the AI agent's actions to an authenticated user session.

Stop writing boilerplate pagination logic and battling external reference mapping schemas.

FAQ

Does Truto automatically retry rate-limited requests to ShiftCare?
No. Truto passes HTTP 429 Too Many Requests errors directly back to the caller. Truto normalizes the upstream limit info into standardized headers (ratelimit-limit, ratelimit-remaining, ratelimit-reset), but the LLM client is responsible for implementing retry and backoff logic.
How do I ensure Claude doesn't delete staff or client records in ShiftCare?
When generating the MCP server via the Truto API, you can pass a config payload with `"methods": ["read"]`. This strictly enforces read-only access at the proxy routing layer, entirely removing write tools from the LLM's context.
Can I temporarily grant an AI agent access to my ShiftCare account?
Yes. You can pass an `expires_at` datetime when creating the MCP server. Truto will automatically revoke the token and destroy the access configuration when the timestamp is reached.

More from our Blog