MCP reference / Catalogue
Catalogue tools
Seven tools covering treatment chairs, locations, the service catalogue and patient tags — the lists that appointments, invoices and patient records pick their values from.
How to read this
Each tool below lists its arguments exactly as the input schema declares them: the type, whether it is required, the permitted values where the schema fixes them, and what the schema says the argument means. None of it is written here. An amount in cents, a default that applies when a field is left out, which action needs which id: those sentences come from the tool itself.
practiceId is never an argument. It comes from your token, and the write paths strip it if a client sends one anyway.
A tool that writes shows one example per action, because what an action needs is not what the input schema marks required: the schema requires action and leaves the rest to the action. Every example is a complete tools/call request whose arguments are checked, when this page is built, against the same object the handler parses. Errors come back inside a 200 response with isError set: the MCP overview has that envelope, and the full catalogue lists every tool at a glance.
Catalogue
Chairs, locations, services and tags — the lists the rest of the product picks from.
list_chairs
List the treatment chairs (bookable resources).
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_chairs",
"arguments": {}
}
}Result
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": { "...": "the requested records" },
"content": [{ "type": "text", "text": "<the same JSON>" }]
}
}Errors
| Code | Status | When |
|---|---|---|
| plan_feature_required | 403 | The practice's plan does not include this. MCP needs Complete. |
list_locations
List the practice's locations (branches) with their names and addresses, and whether locations take effect.
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_locations",
"arguments": {}
}
}Result
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": { "...": "the requested records" },
"content": [{ "type": "text", "text": "<the same JSON>" }]
}
}Errors
| Code | Status | When |
|---|---|---|
| plan_feature_required | 403 | The practice's plan does not include this. MCP needs Complete. |
list_services
List the service catalogue. Pass isPublic=true for services offered on the public booking page.
Arguments
| Tool | Type | Required? | What it means |
|---|---|---|---|
| visibility | string: public | hidden | Optional | Omit this to list the whole catalogue, which is almost always what you want. "public" lists only the services offered on the public booking page; "hidden" lists only the ones that are not. |
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_services",
"arguments": {}
}
}Result
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": { "...": "the requested records" },
"content": [{ "type": "text", "text": "<the same JSON>" }]
}
}Errors
| Code | Status | When |
|---|---|---|
| validation_failed | 400 | An argument is missing, of the wrong type, or outside its allowed values. |
| plan_feature_required | 403 | The practice's plan does not include this. MCP needs Complete. |
list_tags
List all tags defined for the practice.
Example call
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "list_tags",
"arguments": {}
}
}Result
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": { "...": "the requested records" },
"content": [{ "type": "text", "text": "<the same JSON>" }]
}
}Errors
| Code | Status | When |
|---|---|---|
| plan_feature_required | 403 | The practice's plan does not include this. MCP needs Complete. |
write_chair
Create, update or delete a treatment chair. update and delete require chairId. Deleting one cancels nothing: the bookings on it keep their time and their patient and are left with no chair.
Arguments
| Tool | Type | Required? | What it means |
|---|---|---|---|
| action | string: create | update | delete | Required | |
| chairId | string | Optional | The chair to update or delete. |
| title | string | Optional | The chair's display name, e.g. "Surgery 1". Required for action=create. |
| doctorName | string | Optional | Optional note for the team about who works this chair. Not shown to patients. A member's usual chair is usualChairId on list_practice_members. |
| color | string | Optional | Six-digit hex colour with a leading #, e.g. "#1a2b3c". Shorthand ("#abc") and colour names ("red") are rejected. |
| isPublic | boolean | Optional | Whether this chair is bookable from the practice's public booking page. Defaults to false. |
| position | integer | Optional | Sort order in the calendar. Lower comes first. Defaults to 0. |
Example call
action=create
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_chair",
"arguments": {
"action": "create",
"title": "Chair 1",
"color": "#1f5eff",
"isPublic": true
}
}
}action=update
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_chair",
"arguments": {
"action": "update",
"chairId": "6f708192-2d3e-4f80-9b4c-5d6e7f8091a2",
"title": "Chair 2"
}
}
}action=delete
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_chair",
"arguments": {
"action": "delete",
"chairId": "6f708192-2d3e-4f80-9b4c-5d6e7f8091a2"
}
}
}Result
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": { "...": "the written record" },
"content": [{ "type": "text", "text": "<the same JSON>" }]
}
}Errors
| Code | Status | When |
|---|---|---|
| validation_failed | 400 | An argument is missing, of the wrong type, or outside its allowed values. |
| not_found | 404 | The id does not exist in your practice. A malformed id looks identical. |
| plan_limit_reached | 403 | action=create past the chairs the plan includes. The refusal says the limit and what is in use. |
| forbidden | 403 | The caller is not an owner of the practice. |
| plan_feature_required | 403 | The practice's plan does not include this. MCP needs Complete. |
| subscription_read_only | 403 | The subscription has lapsed, so the practice is read-only and nothing may be written. |
write_service
Create, update or delete a service, or seed the vertical pack's default catalogue with action=seed_defaults. update and delete require serviceId.
Arguments
| Tool | Type | Required? | What it means |
|---|---|---|---|
| action | string: create | update | delete | seed_defaults | Required | |
| serviceId | string | Optional | The service to update or delete. |
| name | string | Optional | The service's name. Required for action=create. |
| priceMinor | integer | Optional | The service's price. Required for action=create. In MINOR currency units (cents): 4500 means 45.00, not 4500.00. |
| durationMinutes | integer | Optional | How long the service takes, used to pre-fill appointment length. Optional. |
| isPublic | boolean | Optional | Whether the service is offered on the public booking page. Defaults to false. |
Example call
action=create
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_service",
"arguments": {
"action": "create",
"name": "Check-up",
"priceMinor": 4500,
"durationMinutes": 30,
"isPublic": true
}
}
}action=update
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_service",
"arguments": {
"action": "update",
"serviceId": "5e6f7081-1c2d-4e9f-8a3b-4c5d6e7f8091",
"priceMinor": 5000
}
}
}action=delete
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_service",
"arguments": {
"action": "delete",
"serviceId": "5e6f7081-1c2d-4e9f-8a3b-4c5d6e7f8091"
}
}
}action=seed_defaults
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_service",
"arguments": {
"action": "seed_defaults"
}
}
}Result
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": { "...": "the written record" },
"content": [{ "type": "text", "text": "<the same JSON>" }]
}
}Errors
| Code | Status | When |
|---|---|---|
| validation_failed | 400 | An argument is missing, of the wrong type, or outside its allowed values. |
| not_found | 404 | The id does not exist in your practice. A malformed id looks identical. |
| forbidden | 403 | The caller is not an owner of the practice. |
| plan_feature_required | 403 | The practice's plan does not include this. MCP needs Complete. |
| subscription_read_only | 403 | The subscription has lapsed, so the practice is read-only and nothing may be written. |
write_tag
Create, update or delete a patient tag. update and delete require tagId. Deleting a tag removes it from every patient carrying it.
Arguments
| Tool | Type | Required? | What it means |
|---|---|---|---|
| action | string: create | update | delete | Required | |
| tagId | string | Optional | The tag to update or delete. |
| title | string | Optional | The tag's label. Required for action=create. Unique per practice, case-insensitively. |
| color | string | Optional | The tag's colour. Required for action=create. Six-digit hex with a leading #, e.g. "#1a2b3c". |
Example call
action=create
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_tag",
"arguments": {
"action": "create",
"title": "Recall due",
"color": "#1f5eff"
}
}
}action=update
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_tag",
"arguments": {
"action": "update",
"tagId": "70819203-3e4f-4091-8c5d-6e7f8091a2b3",
"title": "Recall sent"
}
}
}action=delete
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "write_tag",
"arguments": {
"action": "delete",
"tagId": "70819203-3e4f-4091-8c5d-6e7f8091a2b3"
}
}
}Result
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"structuredContent": { "...": "the written record" },
"content": [{ "type": "text", "text": "<the same JSON>" }]
}
}Errors
| Code | Status | When |
|---|---|---|
| validation_failed | 400 | An argument is missing, of the wrong type, or outside its allowed values. |
| not_found | 404 | The id does not exist in your practice. A malformed id looks identical. |
| plan_feature_required | 403 | The practice's plan does not include this. MCP needs Complete. |
| subscription_read_only | 403 | The subscription has lapsed, so the practice is read-only and nothing may be written. |
Common questions
Patient records are encrypted, both where they are stored and on their way to your screen. Files are private, and a link to one stops working after a short time. Changes to patient records are recorded, with who made them and when. There is no shared practice password: everyone has their own account. On the Complete plan, the practice owner can also require two-step sign-in for the whole team.
Yes. The practice owner can export the patient list, the reports and the activity log to a spreadsheet file (CSV) from the app, and anyone in the practice can download its files at any time. Your practice data belongs to you, and there is no export fee or waiting period. That holds on either plan, during the trial, and after you cancel.
HyperCRM is paid software. Every practice starts with a 30-day free trial of the Complete plan, with no card needed. After that, Essential starts at €19 a month and Complete at €34, VAT included. The price depends on how many practitioners you have. Every price is on the pricing page, so you never need a sales call.