Most people who run a disability or aged care service ask their software the same small questions every day. Who is unrostered tomorrow? Which participants have no progress notes this week? What incidents were logged at a particular house last month? Each of those is either a report someone has to build or a screen someone has to know about.
The Model Context Protocol (MCP) gives AI assistants a standard way to ask those questions of a live system. This post looks at how MCP works, why care-sector data changes the design, and how to connect a client to a remote server. Our examples come from Rostery, Australian software for NDIS and aged care providers, which runs a remote MCP server at https://app.rostery.com.au/api/mcp.
What MCP actually is
MCP is an open protocol for connecting an AI client (Claude, ChatGPT, an IDE agent, and so on) to an external system. The server publishes a set of tools. Each tool has a name, a description and a JSON Schema for its inputs. The client lists those tools, the model decides when to call one, and the server returns structured results the model can reason over.
Under the hood it is JSON-RPC 2.0. A session starts with an initialize request, the client calls tools/list to discover what is available, and tools/call runs a tool. Remote servers usually speak the Streamable HTTP transport, which means a single HTTPS endpoint that accepts JSON-RPC over POST.
The useful idea is the split of responsibilities. The model is good at turning "who hasn't had a visit this week?" into a sensible sequence of calls. The server stays the system of record and decides what can be read, by whom, and in what shape.
Why care data changes the design
A connector for a to-do app can expose almost everything. A connector for care software can't. NDIS and aged care records hold health information, behaviour support details, incident reports and funding data, and Australian providers work under the Privacy Act and the requirements of their regulators. Three design questions come up before you write a single tool.
1. What should the assistant be able to reach at all?
It is tempting to expose the whole API and rely on permissions. Rostery took the narrower route. The connector covers operational data (clients, rosters, progress notes and incidents) and leaves money out entirely. Timesheets, invoices, payments and payroll aren't behind a permission check in the MCP tool set. They are simply absent.
That difference matters. A permission-gated tool can be misconfigured, and a role can be granted too broadly. A tool that doesn't exist can't be called. If your question is "could an assistant ever read a pay run?", "there is no tool for it" is an easier answer to defend than "only if the role allows it".
2. Whose data is this, and who agreed to share it?
In multi-tenant SaaS the worst failure is one organisation's assistant reading another organisation's records. So the connection is per-organisation, authorised with OAuth by a user from that organisation, and it acts within that user's role and permissions. Nobody pastes a long-lived API key into a chat app. It is also revocable: disconnect it in Settings and the access ends.
3. Where does the data go after the tool returns it?
Once a result reaches the model, it is part of a conversation governed by the agreement between the provider and their AI vendor. The server can't control that, so the honest thing is to say so plainly. Rostery's documentation states that the connector answers queries when asked, doesn't send data unprompted and doesn't store conversations, and it points providers to the business terms their AI vendor offers. If you are building something similar, put this in writing early. It is usually the first question a privacy officer asks.
How the authorisation flow looks from the outside
You can see most of the auth design without any credentials. An unauthenticated initialize request to Rostery's endpoint returns 401 with a WWW-Authenticate header pointing at protected resource metadata:
curl -i -X POST https://app.rostery.com.au/api/mcp \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"probe","version":"0.1"}}}'
# HTTP/2 401
# www-authenticate: Bearer resource_metadata="https://app.rostery.com.au/.well-known/oauth-protected-resource"
That metadata document names the authorisation server, the supported scope (mcp) and that bearer tokens go in the Authorization header. The authorisation server metadata at /.well-known/oauth-authorization-server then advertises:
- the authorisation code grant with refresh tokens
- PKCE with
S256 - a dynamic client registration endpoint
-
token_endpoint_auth_methods_supported: ["none"], meaning public clients with no client secret
This is the pattern the MCP authorisation spec describes, and it is why "add a URL" is all the user has to do. The client discovers the auth server, registers itself, sends the user to log in and approve access, and gets back a token tied to that user's organisation. No secret ever sits in a config file.
If you are building your own server, it is worth getting this 401 response right. A bare 401 with no WWW-Authenticate header leaves clients with no way to discover how to log in.
Adding a remote MCP server to a client
The details differ between clients and change often, so check each client's current docs. The general shapes are:
Claude (web or desktop): add a custom connector in the connector settings, paste the server URL, then complete the OAuth sign-in when prompted.
Claude Code:
claude mcp add --transport http rostery https://app.rostery.com.au/api/mcp
VS Code and other clients that use a JSON config:
{
"servers": {
"rostery": {
"type": "http",
"url": "https://app.rostery.com.au/api/mcp"
}
}
}
ChatGPT: connectors to remote MCP servers are added from the app's connector settings. Availability depends on the plan and workspace settings.
On first use the client opens a browser window to sign in. For Rostery, that means signing in with an existing Rostery account and approving access for your organisation. The connector is part of the product, not a public data source, so it is only useful to providers who already use Rostery.
Design notes if you're building one
A few things we'd suggest to anyone putting an MCP server in front of sensitive data:
- Start from questions, not endpoints. List the ten questions coordinators actually ask, then design tools around those. A small set of well-described tools beats a thin wrapper around every REST route, both for safety and for how reliably the model picks the right tool.
- Write tool descriptions for the model. The description is the prompt. Say what the tool returns, what it doesn't, and when to use it instead of a neighbouring tool.
- Return less. Page results, trim fields, and leave out identifiers the model doesn't need to answer the question. Every field you return ends up in a conversation transcript somewhere.
- Enforce tenancy below the application layer. Database-level isolation, such as row-level security, means a bug in a tool handler still can't return another tenant's rows.
- Exclude rather than gate when the risk is high. If a category of data would change the risk conversation, leave it out of the tool set and say so in your docs.
- Make revocation obvious. Users should be able to find the disconnect button without asking support.
- Log tool calls like any other access. Care providers already keep audit logs for access to participant records, and an assistant reading those records is no different.
Wrapping up
MCP makes it cheap to connect an assistant to a system of record. In regulated sectors, though, the protocol is the easy part. The real work is deciding what the assistant should never be able to reach, making consent explicit per organisation, and being clear about where data goes once it leaves your server.
If you work on software for NDIS or aged care providers and want to compare notes on connector design, you can find more about how Rostery approaches it on our site.
— Rostery Team
Top comments (1)
The care sector is such an under-served space for tooling — most off-the-shelf SaaS assumes you have a dedicated admin team, but in reality it's often one overworked manager juggling rosters, compliance, and family comms on a phone between shifts.
MCP feels like the right abstraction here because it lets the AI sit inside the existing workflow rather than demanding a new dashboard. The rostering example hits home: "who's free Tuesday?" is a trivial query for a human but historically painful to expose via API (permissions, shift rules, fatigue limits, qualification matching). Pushing that logic into the MCP server where the domain knowledge already lives — instead of trying to serialize it into a generic spec — is the pragmatic move.
Curious how you're handling the "read vs write" boundary. Letting an assistant read roster gaps is low-risk; letting it assign shifts touches labor law, union rules, and duty-of-care obligations. Are you keeping write operations behind explicit human confirmation, or baking guardrails into the server itself? (site: labagent .tech)
Some comments may only be visible to logged-in visitors. Sign in to view all comments.