Koskamo

Sanovia MCP

Official MCP server for Sanovia, a cloud practice management system for Italian healthcare professionals. It enables AI agents to search for doctors by specialty and city, retrieve profile details, visit prices, and available booking slots up to 14 days in advance. It also supports initiating booking requests that send confirmation emails to patients.

Endpoint and access

No sign-in to connect and list tools. Individual tools may still need a vendor account, credentials, or permissions; check the documented prerequisites.

Sanovia MCP logo, by SanoXvia LTDVendor evidenceStreamable HTTPNo sign-inEndpoint checked 2026-11-07Operated by SanoXvia LTD
MCP endpoint (Streamable HTTP)
https://sanovia.app/api/v1/mcp
Vendor documentation

What its tools do

5 tools, grouped by the hints the server advertises. Hints are self-declared, not verified behavior.

Can change data (1)

5 of 5 have a description · 5 of 5 declare behavior hints · 5 of 5 with parameters document them all

Checks and signals

Each line is separate evidence, not a trust score.

  • Passed Endpoint answered the live check ·
  • Passed Official MCP Registry namespace is tied to sanovia.app ·
  • Passed Endpoint is on the registry namespace domain ·
  • Availability 1 of 1 checks passed in 30 days

What you can do with it

  • Search for healthcare professionals by specialty and city
  • Retrieve doctor profiles, visit prices, and availability
  • Initiate booking requests for free time slots

Source and maintenance

Vendor evidenceRegistry 1.0.0

Protocol and capabilities

Server
sanovia 1.1.0
MCP protocol negotiated in check
2025-11-25
Tools
5 advertised
Resources
Not advertised
Resource templates
Not advertised
Prompts
Not advertised
Server-advertised capabilities
{
  "tools": {
    "listChanged": false
  }
}

Server-provided instructions

Untrusted server output shown for inspection. It is not Koskamo guidance and is excluded from knowledge search.

Sanovia è un gestionale per studi e professionisti della salute in Italia. Questi strumenti leggono solo dati che i professionisti hanno scelto di rendere pubblici: chi sono, dove ricevono, cosa offrono, quanto costa e quando sono liberi. Con request_booking puoi inviare una richiesta di prenotazione per un orario libero: il paziente riceve un'email e conferma lui stesso dalla pagina Sanovia; senza la sua conferma non viene prenotato nulla. In alternativa dai al paziente il booking_url. Chiedi solo nome, cognome ed email; non chiedere né inviare mai dati sanitari del paziente. / Sanovia is practice-management software for practices and health professionals in Italy. These tools only read data practitioners chose to publish. With request_booking you can send a booking request for a free time: the patient receives an email and confirms on the Sanovia page themselves; nothing is booked without that confirmation. Otherwise give the patient the booking_url. Ask only for first name, last name and email; never ask for or send the patient's health data.

Tools

5 advertised

search_doctors — Cerca professionisti / Search practitioners
Advertised by the server during the last successful anonymous check.
Advertised read-only

Cerca medici e professionisti sanitari italiani iscritti a Sanovia per specialità e/o città. Elenca solo chi ha la pagina di prenotazione online e un sito pubblicato: il proprio, oppure quello della struttura (poliambulatorio, centro) in cui riceve — in quel caso site_url è il sito della struttura. Non prenota: restituisce il link di prenotazione. / Search Italian doctors and health practitioners on Sanovia by specialty and/or city. Lists only practitioners with an online booking page and a published website: their own, or that of the structure (clinic) they practise in — then site_url is the structure's site. Does not book; returns the booking link.

search_doctors input schema
{
  "type": "object",
  "properties": {
    "city": {
      "type": "string",
      "description": "Città della sede, es. «Bologna». / City of the practice."
    },
    "limit": {
      "type": "integer",
      "maximum": 20,
      "minimum": 1,
      "description": "Massimo risultati (default 10, max 20). / Max results."
    },
    "specialty": {
      "type": "string",
      "description": "Specialità o professione, in italiano: la disciplina («Cardiologia», «Odontoiatria», «Medicina Generale», «Fisioterapia», «Osteopatia») oppure il professionista («cardiologo», «dentista», «medico di base», «fisioterapista», «osteopata»). / Specialty or profession, in Italian: the discipline (e.g. «Cardiologia») or the practitioner noun (e.g. «cardiologo»)."
    }
  },
  "additionalProperties": false
}
search_doctors output schema
{
  "type": "object",
  "required": [
    "doctors",
    "truncated"
  ],
  "properties": {
    "doctors": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "code",
          "name",
          "specialty",
          "practice_name",
          "profession_types",
          "online_booking",
          "booking_url",
          "site_url",
          "cities"
        ],
        "properties": {
          "code": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "cities": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "site_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "specialty": {
            "type": [
              "string",
              "null"
            ]
          },
          "booking_url": {
            "type": [
              "string",
              "null"
            ]
          },
          "practice_name": {
            "type": [
              "string",
              "null"
            ]
          },
          "online_booking": {
            "type": "boolean"
          },
          "profession_types": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      }
    },
    "truncated": {
      "type": "boolean"
    }
  }
}
search_doctors annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_doctor_profile — Profilo del professionista / Practitioner profile
Advertised by the server during the last successful anonymous check.
Advertised read-only

Profilo pubblico di un professionista: specialità, iscrizione all'Albo, sedi, orari, prestazioni con durata e prezzo (null = prezzo non indicato o non mostrato online), valutazione verificata, link al suo sito e alla prenotazione. Non prenota. / Public profile: specialty, professional registration, locations, opening hours, services with duration and price (null = price not stated or not shown online), verified rating, links to their website and booking page. Does not book.

get_doctor_profile input schema
{
  "type": "object",
  "required": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "string",
      "description": "Codice pubblico del medico restituito da search_doctors (campo `code`). / The doctor's public code from search_doctors (`code`)."
    }
  },
  "additionalProperties": false
}
get_doctor_profile output schema
{
  "type": "object",
  "required": [
    "code",
    "name",
    "specialty",
    "practice_name",
    "profession_types",
    "online_booking",
    "booking_url",
    "site_url",
    "registration",
    "locations",
    "opening_hours",
    "services",
    "rating",
    "external_site_url"
  ],
  "properties": {
    "code": {
      "type": [
        "string",
        "null"
      ]
    },
    "name": {
      "type": "string"
    },
    "rating": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "count": {
          "type": "number"
        },
        "average": {
          "type": "number"
        }
      }
    },
    "services": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "duration_min",
          "price_eur",
          "remote",
          "description"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "remote": {
            "type": "boolean"
          },
          "price_eur": {
            "type": [
              "number",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "duration_min": {
            "type": [
              "number",
              "null"
            ]
          }
        }
      }
    },
    "site_url": {
      "type": [
        "string",
        "null"
      ]
    },
    "locations": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "online_booking"
        ],
        "properties": {
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "address": {
            "type": [
              "string",
              "null"
            ]
          },
          "location_ref": {
            "type": "number"
          },
          "online_booking": {
            "type": "boolean"
          }
        }
      }
    },
    "specialty": {
      "type": [
        "string",
        "null"
      ]
    },
    "booking_url": {
      "type": [
        "string",
        "null"
      ]
    },
    "registration": {
      "type": [
        "object",
        "null"
      ],
      "properties": {
        "number": {
          "type": "string"
        },
        "province": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "opening_hours": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "location",
          "day",
          "from",
          "to"
        ],
        "properties": {
          "to": {
            "type": "string"
          },
          "day": {
            "type": [
              "string",
              "null"
            ]
          },
          "from": {
            "type": "string"
          },
          "location": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    },
    "practice_name": {
      "type": [
        "string",
        "null"
      ]
    },
    "online_booking": {
      "type": "boolean"
    },
    "profession_types": {
      "type": "array",
      "items": {
        "type": "string"
      }
    },
    "external_site_url": {
      "type": [
        "string",
        "null"
      ]
    }
  }
}
get_doctor_profile annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_visit_types — Tipi di visita e prezzi / Visit types and prices
Advertised by the server during the last successful anonymous check.
Advertised read-only

Tipi di visita prenotabili online da un professionista, con durata, prezzo in euro (null = prezzo non indicato o non mostrato online, NON gratuito) e se il pagamento è online. Non prenota. / Visit types bookable online, with duration, price in EUR (null = price not stated or not shown online, NOT free) and whether payment is online. Does not book.

get_visit_types input schema
{
  "type": "object",
  "required": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "string",
      "description": "Codice pubblico del medico restituito da search_doctors (campo `code`). / The doctor's public code from search_doctors (`code`)."
    },
    "location_ref": {
      "type": "integer",
      "maximum": 50,
      "minimum": 1,
      "description": "Opzionale: numero della sede (location_ref) da get_doctor_profile. Senza, la sede principale. / Optional location number (location_ref) from get_doctor_profile; defaults to the primary location."
    }
  },
  "additionalProperties": false
}
get_visit_types output schema
{
  "type": "object",
  "required": [
    "location",
    "visit_types",
    "booking_url"
  ],
  "properties": {
    "location": {
      "type": "object",
      "required": [
        "location_ref",
        "name",
        "city"
      ],
      "properties": {
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "name": {
          "type": "string"
        },
        "location_ref": {
          "type": "number"
        }
      }
    },
    "booking_url": {
      "type": "string"
    },
    "visit_types": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "name",
          "duration_min",
          "price_eur",
          "requires_online_payment",
          "description"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "price_eur": {
            "type": [
              "number",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "duration_min": {
            "type": [
              "number",
              "null"
            ]
          },
          "requires_online_payment": {
            "type": "boolean"
          }
        }
      }
    }
  }
}
get_visit_types annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
get_availability — Orari liberi / Free time slots
Advertised by the server during the last successful anonymous check.
Advertised read-only

Orari di inizio liberi per la prenotazione online di un professionista, giorno per giorno (massimo 14 giorni). Mostra solo gli orari liberi, mai chi ha prenotato. Indica visit_type per avere solo gli orari in cui quella visita ci sta. Non prenota: per l'orario scelto dai al paziente il link di booking_urls di quel giorno (pagina di prenotazione con sede, giorno, orario e tipo di visita già scelti; il paziente inserisce i suoi dati e conferma), altrimenti booking_url. / Free start times for online booking, day by day (max 14 days). Shows free times only, never who booked. Pass visit_type to get only the times that visit fits. Does not book: for the chosen time give the patient that day's booking_urls link (the booking page with location, day, time and visit type preselected; the patient enters their details and confirms), otherwise booking_url.

get_availability input schema
{
  "type": "object",
  "required": [
    "code"
  ],
  "properties": {
    "code": {
      "type": "string",
      "description": "Codice pubblico del medico restituito da search_doctors (campo `code`). / The doctor's public code from search_doctors (`code`)."
    },
    "days": {
      "type": "integer",
      "maximum": 14,
      "minimum": 1,
      "description": "Numero di giorni (default 7, max 14). / Number of days."
    },
    "from": {
      "type": "string",
      "format": "date",
      "description": "Primo giorno AAAA-MM-GG (default oggi, fuso Europe/Rome). / First day YYYY-MM-DD (default today, Europe/Rome)."
    },
    "visit_type": {
      "type": "string",
      "description": "Opzionale ma consigliato: il nome esatto di un tipo di visita da get_visit_types (stessa sede). Con il nome, solo gli orari in cui quella visita (con la sua durata) è prenotabile. / Optional but recommended: the exact visit type name from get_visit_types (same location); only start times where a visit of that length fits are returned."
    },
    "location_ref": {
      "type": "integer",
      "maximum": 50,
      "minimum": 1,
      "description": "Opzionale: numero della sede (location_ref) da get_doctor_profile. Senza, la sede principale. / Optional location number (location_ref) from get_doctor_profile; defaults to the primary location."
    }
  },
  "additionalProperties": false
}
get_availability output schema
{
  "type": "object",
  "required": [
    "location",
    "other_locations",
    "from",
    "days",
    "free_slots",
    "booking_url"
  ],
  "properties": {
    "days": {
      "type": "number"
    },
    "from": {
      "type": "string"
    },
    "location": {
      "type": "object",
      "required": [
        "location_ref",
        "name",
        "city"
      ],
      "properties": {
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "name": {
          "type": "string"
        },
        "location_ref": {
          "type": "number"
        }
      }
    },
    "free_slots": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "date",
          "slots",
          "booking_urls"
        ],
        "properties": {
          "date": {
            "type": "string"
          },
          "slots": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "booking_urls": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          }
        }
      }
    },
    "visit_type": {
      "type": "object",
      "required": [
        "name",
        "duration_min"
      ],
      "properties": {
        "name": {
          "type": "string"
        },
        "duration_min": {
          "type": [
            "number",
            "null"
          ]
        }
      }
    },
    "booking_url": {
      "type": "string"
    },
    "other_locations": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "location_ref",
          "name",
          "city"
        ],
        "properties": {
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "name": {
            "type": "string"
          },
          "location_ref": {
            "type": "number"
          }
        }
      }
    }
  }
}
get_availability annotations
{
  "readOnlyHint": true,
  "openWorldHint": false,
  "idempotentHint": true,
  "destructiveHint": false
}
request_booking — Richiesta di prenotazione / Booking request
Advertised by the server during the last successful anonymous check.
Open-world

Invia una richiesta di prenotazione per un orario libero. Non prenota subito: Sanovia manda al paziente un'email con un link valido 30 minuti; la visita esiste solo quando il paziente la conferma dalla pagina Sanovia (accetta Termini e Privacy e, se previsto, paga online). L'orario non è bloccato fino alla conferma. Chiedi al paziente SOLO nome, cognome ed email: non inviare mai dati sanitari, sintomi, telefono o codice fiscale. Usa un time di free_slots da get_availability per la stessa sede e lo stesso visit_type. / Sends a booking request for a free time. It does not book: Sanovia emails the patient a link valid for 30 minutes; the visit exists only once the patient confirms on the Sanovia page (accepting Terms and Privacy and, when required, paying online). The time is not held until then. Ask the patient ONLY for first name, last name and email: never send health data, symptoms, phone number or tax code. Use a time from get_availability's free_slots for the same location and visit_type.

request_booking input schema
{
  "type": "object",
  "required": [
    "code",
    "date",
    "time",
    "first_name",
    "last_name",
    "email"
  ],
  "properties": {
    "code": {
      "type": "string",
      "description": "Codice pubblico del medico restituito da search_doctors (campo `code`). / The doctor's public code from search_doctors (`code`)."
    },
    "date": {
      "type": "string",
      "format": "date",
      "description": "Giorno AAAA-MM-GG (fuso Europe/Rome), come in free_slots. / Day YYYY-MM-DD (Europe/Rome), as in free_slots."
    },
    "time": {
      "type": "string",
      "pattern": "^([01][0-9]|2[0-3]):[0-5][0-9]$",
      "description": "Orario di inizio HH:MM, uno di free_slots per quel giorno. / Start time HH:MM, one of that day's free_slots."
    },
    "email": {
      "type": "string",
      "format": "email",
      "description": "Email del paziente: riceverà il link di conferma. / Patient's email: the confirmation link goes there."
    },
    "language": {
      "enum": [
        "it",
        "en"
      ],
      "type": "string",
      "description": "Lingua dell'email (default it). / Email language (default it)."
    },
    "last_name": {
      "type": "string",
      "maxLength": 60,
      "description": "Cognome del paziente (solo lettere). / Patient's last name (letters only)."
    },
    "first_name": {
      "type": "string",
      "maxLength": 60,
      "description": "Nome del paziente (solo lettere). / Patient's first name (letters only)."
    },
    "visit_type": {
      "type": "string",
      "description": "Il nome esatto di un tipo di visita da get_visit_types (stessa sede). Obbligatorio se il medico ne pubblica. / The exact visit type name from get_visit_types (same location). Required when the doctor publishes any."
    },
    "location_ref": {
      "type": "integer",
      "maximum": 50,
      "minimum": 1,
      "description": "Opzionale: numero della sede (location_ref) da get_doctor_profile. Senza, la sede principale. / Optional location number (location_ref) from get_doctor_profile; defaults to the primary location."
    }
  },
  "additionalProperties": false
}
request_booking output schema
{
  "type": "object",
  "required": [
    "status",
    "expires_in_min",
    "slot_held",
    "date",
    "time",
    "location",
    "visit_type",
    "price_eur",
    "requires_online_payment",
    "requires_approval"
  ],
  "properties": {
    "date": {
      "type": "string"
    },
    "time": {
      "type": "string"
    },
    "status": {
      "type": "string"
    },
    "location": {
      "type": "object",
      "required": [
        "location_ref",
        "name",
        "city"
      ],
      "properties": {
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "name": {
          "type": "string"
        },
        "location_ref": {
          "type": "number"
        }
      }
    },
    "price_eur": {
      "type": [
        "number",
        "null"
      ]
    },
    "slot_held": {
      "type": "boolean"
    },
    "visit_type": {
      "type": "string"
    },
    "expires_in_min": {
      "type": "number"
    },
    "requires_approval": {
      "type": "boolean"
    },
    "requires_online_payment": {
      "type": "boolean"
    }
  }
}
request_booking annotations
{
  "readOnlyHint": false,
  "openWorldHint": true,
  "idempotentHint": false,
  "destructiveHint": false
}

Prompts

Not advertised

No prompt definitions available.

Resources

Not advertised

No resource definitions available.

30-day availability

Aggregated from read-only remote checks; this is not a tool-execution or security guarantee.

Successful checks
1 of 1 (100%)
Average latency
832 ms
95th percentile latency
832 ms

Maintenance history

Public check and source-refresh events. Editorial and ownership records remain private.

  • · probe · passed · 832 ms · metadata changed · 5 tool(s)

Connect from your client

Each snippet registers the same endpoint; pick the client you use.

This server is operated by the named third party. Listing and endpoint checks are not an endorsement or a security audit. Review the operator's permissions, terms, and data handling before connecting. How listings are checked and corrected.

Claude Code

Run this once in a terminal. It registers the remote server. Use --scope project to write .mcp.json for the repo.
Claude Code configuration
claude mcp add --transport http sanovia-mcp https://sanovia.app/api/v1/mcp

Codex

Run this once. Codex stores MCP servers in ~/.codex/config.toml (or .codex/config.toml in a trusted project).
Codex configuration
codex mcp add sanovia-mcp --url https://sanovia.app/api/v1/mcp

Cursor

Merge this server into .cursor/mcp.json in your project, then enable sanovia-mcp in your MCP settings.
Cursor configuration
{
  "mcpServers": {
    "sanovia-mcp": {
      "url": "https://sanovia.app/api/v1/mcp"
    }
  }
}

Cline

Merge this into cline_mcp_settings.json (Cline → MCP Servers → Configure).
Cline configuration
{
  "mcpServers": {
    "sanovia-mcp": {
      "type": "streamableHttp",
      "url": "https://sanovia.app/api/v1/mcp",
      "disabled": false
    }
  }
}

VS Code

Merge this server into .vscode/mcp.json. Use MCP: List Servers to start sanovia-mcp and inspect its tools.
VS Code configuration
{
  "servers": {
    "sanovia-mcp": {
      "type": "http",
      "url": "https://sanovia.app/api/v1/mcp"
    }
  }
}

Gemini CLI

Run this once. It writes .gemini/settings.json in the current project; pass --scope user for ~/.gemini/settings.json.
Gemini CLI configuration
gemini mcp add --transport http sanovia-mcp https://sanovia.app/api/v1/mcp

Claude Desktop

Open Claude Settings > Connectors > Add custom connector, enter this server URL and enable it for the conversation. This is a manual remote-connector handoff, not a desktop JSON configuration.
Claude Desktop configuration
https://sanovia.app/api/v1/mcp

Windsurf

Merge this into ~/.codeium/windsurf/mcp_config.json, then refresh MCP in Cascade. Windsurf remote servers use serverUrl, not url.
Windsurf configuration
{
  "mcpServers": {
    "sanovia-mcp": {
      "serverUrl": "https://sanovia.app/api/v1/mcp"
    }
  }
}

Let your agent find its tools

Find servers like Sanovia MCP from your agent. Add Koskamo once to search the index for endpoints, access requirements, and client setup. Public discovery needs no key.

Do you run Sanovia MCP?

Prove ownership with a DNS record, a well-known file, or your Official MCP Registry entry, and your edits publish immediately. Proofs are re-checked weekly; admins can still hide or remove a listing.

Claim this listing