A especificação de autorização do MCP (versão 2026-07-28) já trata o servidor MCP como resource server OAuth 2.1, exige metadata de recurso protegido (RFC 9728), amarra o token ao servidor com resource (RFC 8707) e recomenda (SHOULD) devolver 403 com scope= quando falta permissão. É a mesma fundação do SMART App Launch 2.2.0 do HL7. O que ainda falta copiar da saúde são três coisas: uma gramática de escopo comum, um contexto de lançamento que diz “este paciente, este atendimento”, e um caminho padrão pra agente que roda sem ninguém na frente da tela.
O que o SMART on FHIR resolveu na saúde
Antes do SMART, cada prontuário eletrônico tinha seu jeito de deixar um app entrar. Quem escrevia um app clínico escrevia uma integração por fornecedor. O projeto começou em Harvard e no Boston Children’s em 2010, adotou o FHIR em 2013 e foi descrito no JAMIA em 2016 (Mandel et al.). A ideia era escrever o app uma vez e rodar sem mudança em qualquer sistema.
A solução não inventou protocolo. Pegou OAuth 2.0 e fixou as partes que ficavam soltas:
- Escopo com gramática.
patient/Observation.rsquer dizer ler e buscar Observation do paciente em contexto. Prefixopatient/,user/ousystem/, recurso FHIR, e as letrasc r u d s. - Contexto de lançamento. O prontuário abre o app com
isselaunch. O app devolve olaunchna autorização e recebe, junto com o token, opatiente oencounterque estavam na tela. - Token preso ao servidor certo. O parâmetro
audé obrigatório e, segundo a spec, existe pra não vazar um token legítimo pra um servidor falso. - Acesso sem usuário. O perfil Backend Services cobre serviço que roda sozinho: client credentials, autenticação com chave assimétrica, escopos
system/e token curto.
A versão publicada hoje é a 2.2.0, de 30/04/2024. A 1.0.0 saiu em 13/11/2018.
Peça por peça: SMART App Launch e autorização do MCP
| Problema | SMART App Launch 2.2.0 | MCP, spec 2026-07-28 |
|---|---|---|
| Papel do servidor | Servidor FHIR protegido por OAuth | Servidor MCP é resource server OAuth 2.1; quem emite token é o servidor de autorização |
| Descoberta | .well-known/smart-configuration |
Protected Resource Metadata (RFC 9728), obrigatório |
| Token preso ao servidor | aud obrigatório |
resource obrigatório (RFC 8707) e validação de audiência |
| Gramática de escopo | patient/Recurso.cruds, igual em todo servidor |
Livre. O exemplo da spec é files:read |
| Contexto de lançamento | launch, launch/patient, fhirContext |
Não existe |
| Recusa por escopo | Servidor concede menos que o pedido | 403 insufficient_scope com scope= e step-up |
| Sem humano | Backend Services, escopos system/ |
Client credentials permitido; identidade de agente está no roadmap |
A metade de baixo da tabela é onde a coisa pega. O MCP fez bem a parte de OAuth. A parte clínica do SMART, que é dizer sobre quem e com qual gramática, ainda não tem par.
Os próprios mantenedores dizem isso
No post do roadmap de 22/08/2026, os mantenedores do MCP escreveram: “MCP authorization today is built around a person approving access in a browser”. E completaram que cada vez mais quem chama são agentes rodando como carga de nuvem, com identidade própria, em nome de um usuário que não está presente. A saída que eles apontam é Workload Identity Federation e token exchange. A saúde passou por isso com o Backend Services. O desenho está lá pra ser lido.
A prova curta: escopo SMART por ferramenta MCP
Na demo 05 do repositório do projeto NursIA (PPGINFOS/UFSC, bolsa FAPESC), montei um servidor MCP com duas ferramentas e mapeei cada uma pra um escopo SMART v2. O mapa é a ideia inteira:
TOOL_SCOPES = {
"read_patient": "patient/Patient.r",
"create_observation": "patient/Observation.c",
}
Rodei em 15/09/2026 com o SDK oficial do MCP em Python, versão 1.27.0, e dado sintético. Quatro chamadas, duas recusadas:
| Chamada | Escopos do token | Resultado |
|---|---|---|
| read_patient | nenhum | 401 com resource_metadata |
| read_patient | patient/Patient.r | 200 |
| create_observation | patient/Patient.r | 403 com scope="patient/Observation.c" |
| create_observation | patient/Patient.r patient/Observation.c | 200 |
O header da recusa saiu assim:
HTTP 403
WWW-Authenticate: Bearer error="insufficient_scope", scope="patient/Observation.c", resource_metadata="http://127.0.0.1:8000/.well-known/oauth-protected-resource/mcp"
Funciona. Mas deu trabalho que não devia dar. O SDK só conhece required_scopes pro servidor inteiro, sem gancho por ferramenta. A recusa por ferramenta são 36 linhas minhas que leem o corpo JSON-RPC. E o 403 do próprio SDK põe o escopo faltante dentro do error_description, em texto, e não no scope= que a spec diz que o servidor deveria mandar. O passo a passo completo está em escopos MCP com FHIR na prática.
O que a analogia não cobre
Tese boa tem borda. Essa tem cinco.
App SMART é código fixo. Agente decide na hora.
O SMART autoriza um app que faz o que foi programado pra fazer. Um agente com o mesmo escopo escolhe o que chamar a partir de texto que entra no contexto, inclusive texto malicioso. Escopo limita o que o agente pode. Não diz nada sobre o que ele vai fazer dentro desse limite.
Ferramenta não é recurso
Escopo FHIR fala de dado: Patient, Observation. Ferramenta MCP fala de ação. Uma ferramenta “resumir internação” pode ler cinco tipos de recurso. Ou você lista todos os escopos dela, ou cria um escopo de ação que nenhum servidor FHIR entende.
Sem paciente em contexto
Em SMART, patient/ vale pro paciente que veio no lançamento. Na demo 05 o patient_id é argumento da ferramenta. Nada impede o token de ler outro paciente. É a lacuna mais séria, e o MCP não tem onde pendurar esse contexto hoje.
Agente chamando servidor que chama servidor
A spec do MCP proíbe repassar token: o servidor “MUST NOT accept or transit any other tokens”. Então o servidor MCP precisa do próprio token pra falar com o servidor FHIR. O SMART não resolve essa cadeia. Token exchange resolve, e ainda não está fechado no MCP.
Escopo não é consentimento
Escopo concedido não é base legal na LGPD. O SMART nunca prometeu isso, e copiar a gramática não muda o fato.
Limites desta tese
- A demo usa token estático. Não tem servidor de autorização, login nem consentimento.
- Hierarquia de escopo não está implementada. A spec do MCP diz que o servidor deve considerar que um escopo amplo implica os estreitos.
- O gate por ferramenta mexe no objeto da rota depois que o SDK a monta. Não é API pública e pode quebrar na próxima versão.
- Autorização do MCP só vale em transporte HTTP. Em stdio o token é sempre vazio e nada disso roda.
Quando não usar esse modelo
- Servidor MCP local em stdio, um usuário só. A spec diz pra pegar credencial do ambiente e não seguir o fluxo OAuth. Não monte OAuth ali.
- Agente que roda sozinho, sem ninguém pra aprovar no navegador. Não force o fluxo de app com usuário. O modelo certo é o do Backend Services: client credentials e escopo
system/, até o MCP fechar identidade de agente. - Ferramenta que não toca dado pessoal. Gramática SMART ali é cerimônia.
O que eu faria hoje num servidor MCP clínico
- Um escopo por ferramenta, escrito na gramática SMART v2 quando a ferramenta toca recurso FHIR.
- 403 com
scope=no header, não em texto. Cliente faz step-up lendo esse parâmetro. - Paciente vindo do token ou da sessão, nunca só do argumento que o modelo escreveu.
- Servidor MCP com token próprio pro FHIR, nunca o do usuário repassado.
Fonte e como reproduzir
git clone https://github.com/rogeriorrodrigues/nursia-research-lab
cd nursia-research-lab/demos/05-mcp-scopes-smart-on-fhir
pip install -r requirements.txt
python3 -m pytest tests -q -s
python3 demo.py
- Demo 05: nursia-research-lab/demos/05-mcp-scopes-smart-on-fhir (headers crus em
docs/evidence-2026-09-15.md) - MCP, especificação de autorização 2026-07-28: modelcontextprotocol.io/specification/2026-07-28/basic/authorization
- The New MCP Roadmap, 22/08/2026: blog.modelcontextprotocol.io/posts/mcp-roadmap
- HL7 SMART App Launch 2.2.0, escopos e contexto: hl7.org/fhir/smart-app-launch/scopes-and-launch-context.html
- HL7 SMART App Launch 2.2.0, lançamento: hl7.org/fhir/smart-app-launch/app-launch.html
- HL7 SMART Backend Services: hl7.org/fhir/smart-app-launch/backend-services.html
- Mandel JC et al. SMART on FHIR: a standards-based, interoperable apps platform for electronic health records. JAMIA 2016;23(5):899-908. DOI 10.1093/jamia/ocv189
- RFC 6750 §3.1, RFC 8707, RFC 9728.
In English
MCP authorization (spec 2026-07-28) already mirrors the OAuth half of SMART App Launch 2.2.0: resource server role, protected resource metadata, audience binding and 403 insufficient_scope with step-up. What it lacks is the clinical half: a shared scope grammar, launch context that pins the patient, and a standard path for agents running without a user. A small demo maps SMART v2 scopes to MCP tools; the gaps are listed above.
Última revisão em 07/10/2026.

