mcp-health-server
The mcp-health-server is a health domain MCP server for managing synthetic patient data, with strict validation, audit logging, and human-in-the-loop confirmation for consequential write operations. Here's what you can do:
Search patients (
search_patients): Find patients by name or medical condition, returning lean summaries (ID, name, age).Get patient details (
get_patient): Retrieve full demographics and active clinical conditions for a specific patient by ID.List appointments (
list_appointments): View a patient's scheduled appointments, with optional date range filtering.Book appointments (
book_appointment): Schedule a new appointment by specifying date/time and reason — a consequential write action requiring explicit user confirmation.Record lab observations (
record_observation): Log laboratory results for patients with LOINC code validation — also a consequential write action requiring confirmation.Run cohort reports: Start long-running reports based on conditions (e.g., count patients with diabetes) and retrieve their results.
Access patient lab results via a dedicated URI (
patient://{patient_id}/labs).Read full FHIR R4 patient records via a FHIR URI (
fhir://Patient/{patient_id}).View appointment confirmation UI via a rendered HTML URI (
ui://appointment/confirm/{patient_id}).Generate structured triage summaries for patients using a built-in prompt template.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-health-serverSearch for patients with diabetes."
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mcp-health-server
Um servidor Model Context Protocol (MCP) compatível com Claude que expõe ferramentas de um domínio de saúde sobre dados 100% sintéticos, construído com o rigor que um domínio regulado exige: validação estrita no servidor, log de auditoria com PII redigida, autorização OAuth 2.1 com escopos por ferramenta, tracing sem PII e uma suíte de red-team que prova, no CI, que os guardrails seguram. A ação de escrita é marcada como consequente, então o host pede confirmação ao usuário.
Qualquer host MCP — Claude Desktop, Cursor, VS Code, o MCP Inspector — conecta por stdio (local) ou Streamable HTTP (remoto).
O que isto faz, na prática
Um modelo de IA, sozinho, consegue falar sobre um paciente, mas não consegue consultá-lo, verificar uma consulta nem marcar uma — ele não tem mãos. O MCP é o padrão que dá mãos a ele: um servidor publica um conjunto de ações tipadas ("tools"), e qualquer assistente compatível com MCP (Claude Desktop, Cursor, VS Code…) consegue descobrir e chamar essas ações no meio de uma conversa.
Este projeto é esse servidor, para uma pequena fatia de saúde — rodando inteiramente sobre dados de paciente inventados. Ele permite que um assistente:
encontre pacientes por nome ou condição, e puxe seus dados demográficos, condições, consultas e resultados de exames;
marque uma consulta ou registre um resultado de exame — ações que alteram dados;
rode um relatório de coorte (ex.: "quantos pacientes têm diabetes?") como tarefa em segundo plano;
leia o prontuário de um paciente em FHIR, o formato que sistemas hospitalares reais trocam entre si.
O ponto não são as funcionalidades de saúde em si — é o quão cuidadosamente elas são feitas. Num campo regulado, deixar uma IA tocar em registros só é aceitável com guardrails, então toda ação aqui é validada antes de rodar, registrada com os dados pessoais mascarados, protegida por login e permissões e — para tudo que altera dados — sinalizada para que o app pergunte ao humano "tem certeza?" antes. E esses guardrails não são só afirmados: uma suíte de ataques simulados roda a cada build e reprova o build se algum guardrail vazar.
Um passo a passo concreto
Um clínico, conversando com o Claude, pede: "Resuma o paciente p-001 para triagem."
O Claude escolhe o prompt
triage_summary, que o instrui a reunir os dados do jeito certo.Ele chama
get_patient("p-001")elist_appointments("p-001"), e lê o resource de exames. Nos bastidores, o servidor confere que o token de acesso do chamador tem a permissãopatients:read, valida cada argumento e escreve uma linha de auditoria com o nome mascarado (R****** A******).O Claude redige o resumo e sugere marcar um retorno. Marcar é uma escrita, então é marcada como consequente — o host pausa e pede a confirmação do clínico antes de o
book_appointmentrealmente rodar (e essa chamada exige a permissão mais forte,appointments:write).Se o Claude tentasse registrar um exame com um código médico inventado, o servidor rejeitaria em vez de deixar um código fabricado entrar no registro.
Para quem é
É uma implementação de portfólio / referência: uma demonstração de como construir uma integração MCP do jeito que um domínio regulado (saúde, finanças, jurídico) de fato exige — segurança, auditabilidade e supervisão humana tratadas como primeira classe, não como remendo. Não é um produto médico e nunca deve ser apontado para dados de paciente reais.
Related MCP server: FHIRfly MCP Server
Por que este projeto existe
O MCP é a forma padrão de conectar modelos de IA a sistemas reais (doado à Linux Foundation em dez/2025; ~10 mil servidores públicos; adoção em produção pelos principais hosts). A habilidade escassa é fazer isso bem onde o erro custa caro. Este repo demonstra integração MCP com a disciplina de um domínio regulado — segurança como primitiva, e verificável, não apenas afirmada. Ele mira exatamente onde o ecossistema é fraco: só ~8,5% dos servidores MCP implementam o OAuth 2.1 obrigatório, e ataques de tool poisoning têm mais de 60% de sucesso mundo afora.
É a metade operacional de uma história de dois repos: llm-guardrails governa o que o
modelo responde; este servidor governa o que o modelo pode executar via ferramentas.
O que ele expõe
Primitiva | Nome | Escopo | Observação |
Tool (leitura) |
|
| Busca por nome ou condição. |
Tool (leitura) |
|
| Dados demográficos e condições. |
Tool (leitura) |
|
| Faixa de data opcional. |
Tool (escrita) |
|
| Consequente — o host confirma. |
Tool (escrita) |
|
| Consequente; código LOINC validado (anti-alucinação). |
Tool (task) |
|
| Agregado de longa duração via o padrão Tasks. |
Resource |
|
| Resultados de exames, endereçáveis por URI. |
Resource |
|
| Paciente como Bundle FHIR R4. |
Resource |
|
| Confirmação HTML renderizada no servidor (precursor de MCP App). |
Prompt |
| — | Template estruturado de triagem. |
Como rodar
Local (stdio, sem auth) — um comando
python -m venv .venv
# Windows: .venv\Scripts\activate | macOS/Linux: source .venv/bin/activate
pip install -e ".[dev]"
python -m mcp_health_serverRemoto (Streamable HTTP, Resource Server OAuth 2.1)
MCP_TRANSPORT=streamable-http python -m mcp_health_serverEle imprime um token bearer de dev (leitura+escrita) no stderr e serve em
http://127.0.0.1:8000/mcp. Requisições sem token válido recebem HTTP 401. O enforce
é real:
curl -s -o /dev/null -w "%{http_code}\n" -X POST http://127.0.0.1:8000/mcp \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}'
# => 401A configuração vem do ambiente:
Variável | Padrão | Finalidade |
|
|
|
|
| Endereço de bind do HTTP. |
|
| Caminho do dataset sintético. |
|
| Verbosidade do log de auditoria. |
| desligado | Liga o enforce de escopo por ferramenta (o HTTP liga sozinho). |
| padrões de dev | Issuer e audience do OAuth (RFC 8707). |
|
| Exportador de tracing: |
O token de dev é emitido por um Authorization Server mock em processo, só para dev/CI. Um deploy real valida contra o JWKS de um issuer real e nunca usa o mock.
Ajustes extras de HTTP: MCP_HTTP_STATELESS=1 roda o servidor sem sessão
(Mcp-Session-Id), para que ele possa ficar atrás de um load balancer round-robin simples
— a direção que a spec de 2026-07-28 formaliza.
Container (Docker)
docker compose up # só o servidor, tracing no console
docker compose --profile observability up # servidor + coletor OTLPO container roda o transporte Streamable HTTP como usuário não-root e imprime um token bearer de dev nos logs ao subir.
Conectar pelo MCP Inspector
npx @modelcontextprotocol/inspector python -m mcp_health_serverConectar pelo Claude Desktop
Adicione em claude_desktop_config.json (Settings → Developer → Edit Config):
{
"mcpServers": {
"health": { "command": "python", "args": ["-m", "mcp_health_server"] }
}
}Como book_appointment é anotada como consequente, o host pede confirmação.
Segurança e conformidade — o coração do repo
Validação estrita no servidor em toda ferramenta. O modelo nunca é confiável. Paciente inexistente, id malformado, strings de injeção e faixa de data invertida devolvem erros limpos, não exceções cruas.
Log de auditoria de toda invocação, com PII redigida. Nomes mascarados (
Rafaela Almeida→R****** A******), data de nascimento →****-**-**. Os logs vão para o stderr (o stdout é o canal JSON-RPC no stdio).Config e segredos vêm só do ambiente — nunca de schema de tool ou payload de resource.
.envestá no gitignore.A ferramenta de escrita é consequente (
destructiveHint=True) — human-in-the-loop.OAuth 2.1 como Resource Server. Validação local de JWT RS256, enforce de
aud(RFC 8707, anti-replay) e escopos por ferramenta (patients:readvsappointments:write) — menor privilégio nos dois sentidos.Observabilidade sem PII. Um span OpenTelemetry por chamada, registrando nome da ferramenta, escopo, resultado e latência — nunca argumentos ou resultado.
Guardrails verificáveis. Uma suíte de red-team (
tests/redteam/) reproduz tool poisoning, escalação de autorização e vazamento de PII. Ela roda como gate no CI: qualquer ataque bem-sucedido reprova o build. Um meta-teste prova que o gate é load-bearing (afrouxá-lo inverte o resultado).
Mapeamento para ISO/IEC 42001 + HIPAA + LGPD
Controle | Como o servidor atende |
HIPAA — trilha de auditoria de todo acesso a PHI |
|
HIPAA — mínimo necessário | Escopos por ferramenta; |
HIPAA — controle de acesso | Resource Server OAuth 2.1, enforce de escopo por ferramenta. |
LGPD — minimização e finalidade | Redação de PII em logs/traces; dado sintético; escopo por ferramenta. |
ISO/IEC 42001 — supervisão humana (A.9.2) | Escrita consequente (HITL) + gate de red-team. |
ISO/IEC 42001 — segurança do sistema (B.6.2.6) | Auth, validação estrita, resistência a poisoning verificada no CI. |
Ilustrativo de uma postura de controles alinhada à ISO/IEC 42001, não uma certificação formal. Não existe "IA certificada HIPAA" — conformidade é um estado operacional, que é exatamente o que os controles em volta do modelo demonstram.
Dados sintéticos
Tudo em data/patients.json é inventado — seis pacientes fictícios
com consultas e exames. Nunca aponte MCP_HEALTH_DATA_PATH para dados reais.
Testes
pytest # suíte completa (cliente in-memory, sem transporte)
pytest tests/redteam -q # o gate de segurança adversarial, isoladoCobertura: o servidor responde com os modelos esperados; entrada ruim é rejeitada em vez de quebrar; a linha de auditoria mascara o nome do paciente; a verificação de token rejeita audience errada, token expirado, issuer errado e token forjado; escopos por ferramenta impõem menor privilégio; e a suíte de red-team prova resistência a poisoning/escalação/ vazamento de PII.
Decisões de design e trade-offs
Veja DESIGN.md — camada fina, transportes, segurança como primitiva verificável, auth de Resource Server, dado só sintético e a decisão de versão do SDK, cada uma com o seu "por que não do outro jeito".
Realismo FHIR e conceitos de v2 (construídos)
FHIR (v1.5):
fhir://Patient/{id}retorna um Bundle FHIR R4 (Patient + Conditions + Observations). A ferramenta de escritarecord_lab_observationvalida o código LOINC contra um conjunto conhecido e rejeita códigos fabricados — o controle nomeado de anti-alucinação para IA clínica. O dado continua sintético;data.pyé a única costura que um backend FHIR/EHR real substituiria.HTTP stateless (v2):
MCP_HTTP_STATELESS=1— real, usando ostateless_httpdo SDK.Padrão Tasks (v2):
start_cohort_reportdevolve um handle;get_cohort_reportfaz o poll, usando as próprias strings de status do protocolo (working/completed/…).Precursor de MCP App (v2):
ui://appointment/confirm/{id}serve um card HTML de confirmação sem PII.
Nota de honestidade sobre a v2. O SDK v2 do MCP (núcleo stateless nativo, Tasks nativas, MCP Apps renderizadas no servidor) ainda não foi publicado — este repo fixa a linha estável v1 (
mcp>=1.28,<2.0). Os itens acima implementam os conceitos da v2 sobre o SDK estável; a migração nativa é um passo futuro deliberado, quando a v2 sair. O caminho de HITL interativo suportado hoje é elicitation (Context.elicit); Apps nativas chegam com a v2.
Ainda futuro (não construído)
Migrar para o SDK v2 do MCP quando publicado (núcleo stateless / Tasks / MCP Apps nativos).
Coordenação multi-agente (agent-to-agent).
Backend FHIR/EHR real atrás da costura
data.py; Authorization Server / IdP externo real; JWKS buscado+cacheado de um issuer ao vivo em vez do mock em processo.
Available Tools
4 toolsbook_appointmentBDestructive
Book a new appointment for a patient.
CONSEQUENTIAL WRITE: this changes state. Marked destructive so the MCP host prompts the user for confirmation before it runs.
| Name | Required | Description | Default |
|---|---|---|---|
| when | Yes | ||
| reason | Yes | ||
| patient_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | |
| when | Yes | Appointment date and time (ISO 8601). |
| reason | Yes | Reason for the visit. |
| patient_id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true, so the description's 'CONSEQUENTIAL WRITE' adds minimal new behavioral information. No additional side effects, authorization needs, or post-conditions are disclosed, so the description does not significantly extend beyond the structured annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short (two sentences). The first sentence clearly states the purpose. The second sentence, while redundant with annotations, is not excessively long. No structural issues, but could be slightly more efficient by omitting the redundant note.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite having three required parameters with no schema descriptions and an output schema (whose content is unknown), the description provides no parameter details or return value expectations. The agent lacks sufficient context to use the tool correctly without external knowledge.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, meaning the input schema provides no parameter descriptions. The tool description fails to explain any of the three required parameters (patient_id, when, reason), leaving the agent without essential semantic context to pass correct values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly says 'Book a new appointment for a patient,' providing a specific verb (book) and resource (appointment). It clearly distinguishes from sibling tools like get_patient, list_appointments, and search_patients, which are read/query operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description does not provide explicit guidance on when to use this tool versus alternatives. It states the basic action but lacks context about prerequisites, availability constraints, or exclusion criteria. Usage is implied by the tool name and sibling contrast.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_patientARead-only
Return a patient's demographics and conditions by id.
| Name | Required | Description | Default |
|---|---|---|---|
| patient_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| id | Yes | Stable synthetic patient identifier, e.g. 'p-001'. |
| name | Yes | Patient full name. PII — redacted in audit logs. |
| birth_date | Yes | Date of birth. PII — redacted in audit logs. |
| conditions | No | Active clinical conditions (free-text labels). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description aligns with the readOnlyHint annotation, indicating a read operation. However, it adds no extra behavioral details (e.g., response format, performance constraints) beyond what annotations already convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, front-loaded with key action and resource, no extraneous words. Highly efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Output schema exists to define return values, and the description covers the basic purpose. However, missing usage guidelines and parameter details reduce completeness for a tool with 0% schema description coverage.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, yet the description does not elaborate on the patient_id parameter beyond 'by id'. No format, source, or constraints are provided, leaving the agent with minimal guidance.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool returns patient demographics and conditions by ID, using a specific verb ('Return') and resource. It effectively distinguishes from sibling tools like book_appointment and search_patients.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives like search_patients. The context implies use when a patient ID is known, but no exclusions or conditions are stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_appointmentsARead-only
List appointments for a patient, optionally filtered to a date range.
| Name | Required | Description | Default |
|---|---|---|---|
| to_date | No | ||
| from_date | No | ||
| patient_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already provide readOnlyHint=true, indicating non-destructive behavior. The description adds no additional behavioral traits beyond what annotations convey, such as pagination, ordering, or response limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence with no wasted words. Every word adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
While the description covers the core purpose, it lacks details on pagination, sorting, or result limits. Given the existence of an output schema (context signal) and the relatively low complexity (3 params, 1 required), the description is adequate but not fully complete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description adds minimal meaning: it mentions patient and optional date range but does not clarify the required patient_id, date formats, or default values beyond what the schema names imply.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb (list), resource (appointments), and scope (for a patient, optionally filtered by date range). It distinguishes itself from siblings such as book_appointment, get_patient, and search_patients.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage (list appointments with optional date filter) but does not provide explicit guidance on when to use this tool versus alternatives, nor does it specify when not to use it.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
search_patientsARead-only
Search synthetic patients by name or condition. Returns lean summaries.
| Name | Required | Description | Default |
|---|---|---|---|
| query | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, so the description adds value by clarifying the output is 'lean summaries' and that patients are synthetic, which helps the agent understand result nature and data domain. However, it doesn't mention potential pagination or result limits.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences front-load the action and key information without any unnecessary words. Every sentence earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple single-parameter search tool, the description covers the main purpose and output nature. It doesn't discuss edge cases or response structure, but the presence of an output schema (not shown) might supplement this. Overall adequate.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With 0% schema description coverage, the description compensates by explaining the 'query' parameter accepts names or conditions. This adds meaning beyond the raw schema, though it lacks details on format or examples.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'Search', the resource 'synthetic patients', and the criteria 'by name or condition'. It distinguishes this tool from siblings like 'get_patient' (single patient) and 'list_appointments' (appointments) by its search nature and focus on patients.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies the tool is for searching patients by input terms but provides no explicit guidance on when to use it versus alternatives (e.g., 'get_patient' for exact ID lookup). It lacks exclusions or contextual cues for decision-making.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
4 tool updates
v0.1.0- First observed
book_appointment - First observed
get_patient - First observed
list_appointments - First observed
search_patients
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose: patient search, patient retrieval, appointment booking, and appointment listing with no functional overlap.
All tool names follow a consistent verb_noun snake_case pattern (book_appointment, get_patient, list_appointments, search_patients).
With 4 tools covering core patient and appointment operations, the count is well-scoped for a health management MCP server.
The set covers basic patient retrieval and appointment booking, but misses common operations like updating or canceling appointments and adding patient conditions.
Maintenance
Related MCP Connectors
Hosted MCP server exposing US hospital procedure cost data to AI assistants
Hosted MCP server for Cliniko — patients, appointments, availability, and invoices for AI agents.
Hosted MCP server for the Healthie EHR & telehealth API: patients, appointments, charting, tasks.
Hosted MCP endpoint with realistic fake data for prototyping agents. 12 tools, no setup.
Related MCP Servers
- AlicenseNot gradedqualityNot gradedmaintenanceA production-grade MCP server that enables AI assistants to securely manage healthcare data through clinical tools for patient vitals, lab results, and medication ordering. It prioritizes security and compliance with features like HIPAA-ready audit logging, PII redaction, and role-based access control.-

FHIRfly MCP Serverofficial
AlicenseNot gradedqualityBmaintenanceMCP server for connecting Claude Desktop to FHIRfly healthcare reference data APIs, enabling lookup of drugs, providers, clinical codes, and more.126 npmMIT- AlicenseNot gradedqualityDmaintenanceAn MCP server that brings AI-powered search and conversation to your FHIR clinical documents.1MIT
- FlicenseNot gradedqualityCmaintenanceA healthcare MCP demo server exposing clinical resources, tools, and prompts over SSE with authentication, integrated with Pydantic AI and Gemini for natural language patient record updates.-