Skip to content

MCP reference / Website

Website builder tools

Ten tools covering the practice's public site and its blog. Writes affect a draft; publishing is the single tool here that changes what the public can see, and it takes effect immediately.

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.

Website builder

The practice's public marketing site. Writes affect a draft until published; publishing is the one tool here that changes what the public sees.

get_site

Read-onlyAny member

Read the site with its pages, modules and FAQs. Returns null if no site has been created.

Example call

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "get_site",
    "arguments": {}
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the requested records" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
plan_feature_required403The practice's plan does not include this. MCP needs Complete.

list_site_page_modules

Read-onlyAny member

Read the content modules and FAQs of one page.

Arguments

ToolTypeRequired?What it means
pageIdstringOptionalPage ids come from get_site.
pagestringOptionalThe page by name: its navLabel as the practice wrote it, or its kind. Case and accents are ignored.

Example call

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_site_page_modules",
    "arguments": {}
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the requested records" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
validation_failed400An argument is missing, of the wrong type, or outside its allowed values.
not_found404The id does not exist in your practice. A malformed id looks identical.
plan_feature_required403The practice's plan does not include this. MCP needs Complete.

check_site_slug_available

Read-onlyOwner only

Check whether a slug is valid and free. Returns availability plus a reason when it is not.

Arguments

ToolTypeRequired?What it means
slugstringRequiredLowercase letters, numbers and hyphens, starting and ending with a letter or number. Becomes the site's public subdomain.

Example call

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "check_site_slug_available",
    "arguments": {
      "slug": "..."
    }
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the requested records" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
validation_failed400An argument is missing, of the wrong type, or outside its allowed values.
forbidden403The caller is not an owner of the practice.
plan_feature_required403The practice's plan does not include this. MCP needs Complete.

write_site

WritesCan deleteReaches outsideOwner only

action=create sets up the site; update edits settings; publish PUSHES THE CURRENT DRAFT LIVE to the public internet, immediately visible to anyone.

Arguments

ToolTypeRequired?What it means
actionstring: create | update | publishRequired
slugstringOptionalThe site's public subdomain. Required for action=create. Lowercase letters, numbers and hyphens; check it first with check_site_slug_available.
localestring: en | elOptionalLanguage the public site is written in. Required for action=create.
templateIdstringOptionalOptional layout template id. Leave unset for the default.
brandColorstringOptionalThe site's accent colour.
fontPairingstringOptionalOptional named font pairing. Leave unset for the default.
logoFileIdstring | nullOptionalAn already-uploaded image to use as the logo, or null to remove the logo, after which the site's header shows the practice name as text. Files are uploaded through the dashboard, not over MCP.
heroFileIdstring | nullOptionalAn already-uploaded image for the hero, or null to remove it.
metaTitlestringOptionalSite-wide SEO title. 70 characters or fewer.
metaDescriptionstringOptionalSite-wide SEO description. 160 characters or fewer.
showServicePricesbooleanOptionalWhether service prices are shown to the public.

Example call

action=create

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_site",
    "arguments": {
      "action": "create",
      "slug": "smile-dental",
      "locale": "el"
    }
  }
}

action=update

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_site",
    "arguments": {
      "action": "update",
      "brandColor": "#1f5eff",
      "metaTitle": "Smile Dental, Athens",
      "showServicePrices": true
    }
  }
}

action=publish

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_site",
    "arguments": {
      "action": "publish"
    }
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the written record" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
validation_failed400An argument is missing, of the wrong type, or outside its allowed values.
not_found404The id does not exist in your practice. A malformed id looks identical.
forbidden403The caller is not an owner of the practice.
plan_feature_required403The practice's plan does not include this. MCP needs Complete.
subscription_read_only403The subscription has lapsed, so the practice is read-only and nothing may be written.

update_site_page

WritesOwner only

Edit one page's metadata — title, slug, SEO.

Arguments

ToolTypeRequired?What it means
pageIdstringRequiredPage ids come from get_site.
enabledbooleanOptionalWhether the page exists on the public site at all. Disabling removes it from the nav and 404s its URL.
navLabelstringOptionalWhat the page is called in the site navigation.
navOrderintegerOptionalPosition in the navigation. Lower comes first.
metaTitlestringOptionalSEO title for this page. 70 characters or fewer.
metaDescriptionstringOptionalSEO description for this page. 160 characters or fewer.

Example call

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "update_site_page",
    "arguments": {
      "pageId": "03142536-6172-43c4-9f80-91a2b3c4d5e6",
      "enabled": true,
      "navLabel": "Services",
      "navOrder": 2
    }
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the written record" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
validation_failed400An argument is missing, of the wrong type, or outside its allowed values.
not_found404The id does not exist in your practice. A malformed id looks identical.
forbidden403The caller is not an owner of the practice.
plan_feature_required403The practice's plan does not include this. MCP needs Complete.
subscription_read_only403The subscription has lapsed, so the practice is read-only and nothing may be written.

write_site_module

WritesCan deleteOwner only

action=create adds a content module to a page (requires pageId); update and delete require moduleId. Changes affect the draft until the site is published. On update, `content` replaces the module's content whole rather than merging, so read it first and send it back complete.

Arguments

ToolTypeRequired?What it means
actionstring: create | update | deleteRequired
pageIdstringOptionalThe page to add to. Required for action=create.
moduleIdstringOptionalThe module to update or delete.
typestring: hero | intro | services_teaser | team_teaser | why_us | testimonials | hours_map | cta | faq | service_grid | insurance_payment | story | team_grid | credentials | gallery | address_map | hours | contact_form | access_parking | booking_widget | service_detailOptionalWhich preset module to add. Required for action=create, and not changeable afterwards.
positionintegerOptionalOrder on the page. Lower comes first.
enabledbooleanOptionalWhether the module renders. Disabling hides it without deleting it.
contentobjectOptionalShape depends on `type`, and is validated strictly — an unrecognised key is rejected. hero: { heading (required, <=120 chars), subheading, imageFileId, ctaLabel, ctaHref }. intro and story: { heading, body } where body is required rich text. why_us, credentials, insurance_payment, access_parking: { heading, points: [{ title, body }] } with 1-6 points. testimonials: { heading, items: [{ quote, attribution }] } with 1-12 items. gallery: { heading, images: [{ fileId, alt }] } with 1-24 images. cta: { heading (required), body, label (required), href (required) }. The data-driven modules (services_teaser, service_grid, service_detail, team_teaser, team_grid, hours_map, address_map, hours, contact_form, booking_widget, faq) take { heading } and nothing else — their body comes from the practice's own services, team, hours and FAQs. Read get_site to see the current content of any module.

Example call

action=create

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_site_module",
    "arguments": {
      "action": "create",
      "pageId": "03142536-6172-43c4-9f80-91a2b3c4d5e6",
      "type": "hero",
      "position": 0,
      "content": {
        "heading": "Dentistry in the centre of Athens"
      }
    }
  }
}

action=update

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_site_module",
    "arguments": {
      "action": "update",
      "moduleId": "14253647-7283-44d5-8091-a2b3c4d5e6f7",
      "enabled": false
    }
  }
}

action=delete

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_site_module",
    "arguments": {
      "action": "delete",
      "moduleId": "14253647-7283-44d5-8091-a2b3c4d5e6f7"
    }
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the written record" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
validation_failed400An argument is missing, of the wrong type, or outside its allowed values.
not_found404The id does not exist in your practice. A malformed id looks identical.
forbidden403The caller is not an owner of the practice.
plan_feature_required403The practice's plan does not include this. MCP needs Complete.
subscription_read_only403The subscription has lapsed, so the practice is read-only and nothing may be written.

write_site_faq

WritesCan deleteOwner only

action=create adds an FAQ to a page (requires pageId); update and delete require faqId.

Arguments

ToolTypeRequired?What it means
actionstring: create | update | deleteRequired
pageIdstringOptionalThe page to add to. Required for action=create.
faqIdstringOptionalThe FAQ to update or delete.
questionstringOptionalRequired for action=create. Plain text, 300 characters or fewer.
answerstringOptionalRequired for action=create, and must be non-empty. A limited HTML subset (h2/h3, bold, italic, links, lists, blockquote); anything else is stripped on save. Plain text is fine.
positionintegerOptionalOrder within the page's FAQ list. Lower comes first.

Example call

action=create

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_site_faq",
    "arguments": {
      "action": "create",
      "pageId": "03142536-6172-43c4-9f80-91a2b3c4d5e6",
      "question": "Do you see children?",
      "answer": "Yes, from the age of three.",
      "position": 0
    }
  }
}

action=update

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_site_faq",
    "arguments": {
      "action": "update",
      "faqId": "25364758-8394-45e6-91a2-b3c4d5e6f708",
      "answer": "Yes, from the age of three. The first visit is a look and a chat."
    }
  }
}

action=delete

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_site_faq",
    "arguments": {
      "action": "delete",
      "faqId": "25364758-8394-45e6-91a2-b3c4d5e6f708"
    }
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the written record" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
validation_failed400An argument is missing, of the wrong type, or outside its allowed values.
not_found404The id does not exist in your practice. A malformed id looks identical.
forbidden403The caller is not an owner of the practice.
plan_feature_required403The practice's plan does not include this. MCP needs Complete.
subscription_read_only403The subscription has lapsed, so the practice is read-only and nothing may be written.

list_blog_posts

Read-onlyAny member

List the practice's blog posts — drafts and published alike — with their slugs, status and bodies.

Example call

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_blog_posts",
    "arguments": {}
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the requested records" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
plan_feature_required403The practice's plan does not include this. MCP needs Complete.

list_blog_categories

Read-onlyAny member

List the categories a post can be filed under. Call this before writing a post if you intend to set one: the id must belong to this site.

Example call

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "list_blog_categories",
    "arguments": {}
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the requested records" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
plan_feature_required403The practice's plan does not include this. MCP needs Complete.

write_blog_post

WritesCan deleteOwner only

Write, edit or remove a blog post. create needs title, slug and body; update and delete need postId. A post is created as a DRAFT. The blog is the one exception to publishing: on a site that is already published, setting a post to published puts it in front of patients at once, and deleting a published post takes it down at once. A practice may also have a weekly schedule that writes posts by itself, so posts you did not create can appear.

Arguments

ToolTypeRequired?What it means
actionstring: create | update | deleteRequired
postIdstringOptionalThe post to update or delete.
titlestringOptionalRequired for action=create. Plain text.
slugstringOptionalRequired for action=create. Lowercase letters, numbers and hyphens; it becomes the post's address and must be unique on this site.
excerptstringOptionalA short teaser for the blog index. Plain text.
bodystringOptionalRequired for action=create. A limited HTML subset (h2/h3, bold, italic, links, lists, blockquote, images); anything else is stripped on save. Do not include an h1 — the page supplies the title.
categoryIdstring | nullOptionalOne of list_blog_categories' ids, or null to clear. A category from another site is refused.
authorMembershipIdstring | nullOptionalA practice member to credit, or null for no named author — in which case the practice itself is the author.
statusstring: draft | publishedOptionalDefaults to draft on create. On a site that has been published, moving a post to published puts it live immediately; it does not wait for the next site publish.
metaTitlestringOptionalOptional search-result headline. Falls back to the title.
metaDescriptionstringOptionalOptional search-result summary, around 110-160 characters. Falls back to the excerpt.

Example call

action=create

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_blog_post",
    "arguments": {
      "action": "create",
      "title": "What to expect at your first visit",
      "slug": "first-visit",
      "body": "We start with a look, an X-ray if you need one, and a plan you agree to.",
      "status": "draft"
    }
  }
}

action=update

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_blog_post",
    "arguments": {
      "action": "update",
      "postId": "36475869-94a5-46f7-a2b3-c4d5e6f70819",
      "status": "published"
    }
  }
}

action=delete

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "write_blog_post",
    "arguments": {
      "action": "delete",
      "postId": "36475869-94a5-46f7-a2b3-c4d5e6f70819"
    }
  }
}

Result

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "structuredContent": { "...": "the written record" },
    "content": [{ "type": "text", "text": "<the same JSON>" }]
  }
}

Errors

CodeStatusWhen
validation_failed400An argument is missing, of the wrong type, or outside its allowed values.
not_found404The id does not exist in your practice. A malformed id looks identical.
forbidden403The caller is not an owner of the practice.
plan_feature_required403The practice's plan does not include this. MCP needs Complete.
subscription_read_only403The 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.