Corpus para desenvolvedores
O índice do corpus, campo a campo
O corpus do saude.capital é publicado como um único arquivo estático, /normas.json — o mesmo que o Verificador carrega no navegador. Esta página documenta o que há dentro dele, como consumi-lo e como reproduzir a lógica de correspondência do Verificador, sem servidor no meio.
O que é o normas.json
É o índice de metadados verificados das 19 normas do corpus: número, título, órgão, data, status de vigência, peso normativo, endereço da fonte oficial, casos de uso mapeados e os termos de busca. Não contém o texto das normas — o texto está nas fontes oficiais, para as quais cada registro aponta pelo campo url.
O arquivo é gerado do repositório-fonte do corpus (arquivos Markdown com um cabeçalho de metadados verificados na fonte oficial), nunca editado à mão, e publicado na mesma origem do site. O Verificador o consulta direto do navegador: o que a pessoa digita não sai da máquina dela.
Recorte, contagem e data
- Contagem: 19 normas — o campo
totale o tamanho denormassão conferidos um contra o outro a cada publicação. - Recorte declarado (campo
cobertura): proteção de dado sensível de saúde, sigilo profissional, exercício da medicina e inteligência artificial na medicina. - Data de geração (campo
atualizado_em): é a data em que o índice foi regerado do corpus-fonte, gravada pelo próprio gerador. Não há número de versão: a data no arquivo é a referência, e o histórico correspondente está em O que mudou no corpus. - Procedência (campo
gerado_de): identifica o repositório-fonte de onde o índice saiu.
A cobertura é um recorte declarado, não a legislação brasileira inteira. Uma norma ausente do índice é uma norma não indexada neste corpus — nunca uma norma inexistente. Essa ressalva de cobertura vale para qualquer produto construído sobre este arquivo, e pedimos que seja repassada a quem lê o resultado.
Esquema
O documento é um objeto JSON com cinco campos na raiz. Todos são sempre emitidos.
gerado_de— texto, obrigatório. Procedência do índice: o repositório-fonte e a nota de que os metadados foram verificados em fonte oficial.cobertura— texto, obrigatório. O recorte temático declarado, na mesma redação usada no site.total— inteiro, obrigatório. Quantidade de registros emnormas. É igual ao tamanho da lista por construção; se divergir, a publicação falha.normas— lista de objetos, obrigatório. Um registro por norma, no esquema abaixo. Ordem: alfabética pelo nome do arquivo-fonte — não a trate como significativa.atualizado_em— textoAAAA-MM-DD, obrigatório. Data da geração do índice.
Cada registro de normas
id— texto, obrigatório. Identificador estável, em letras minúsculas com hífens (ex.:res-cfm-2454-2026-ia-medicina). É a chave de junção e a URL da ficha:/normas/<id>.html.titulo— texto, obrigatório. Título como indexado, com número e ano.tipo— texto, obrigatório. Rótulo da espécie normativa, de vocabulário fechado. Valores em uso:Lei federal,Emenda constitucional,Resolução CFM,Resolução ANPD,Resolução CNS,Portaria MS,Enunciado ANPD,Guia/estudo técnico. Um tipo fora dessa lista faz a geração falhar — nunca entra em silêncio.orgao— texto, obrigatório. Órgão emissor por extenso, com a sigla entre parênteses quando houver (ex.:Conselho Federal de Medicina (CFM)).data— textoAAAA-MM-DD, obrigatório. Data do ato, não a da publicação nem a do início de vigência.status— texto, obrigatório. Vocabulário fechado em quatro valores:vigente,vigencia_futura,revogadaerevogada_parcialmente. É o status verificado na fonte, não um rótulo de exibição — ver status declarado × status efetivo.peso— texto, obrigatório. Vocabulário fechado em dois valores:vinculante(ato com poder regulamentar próprio) eorientativo_nao_vinculante(guia, estudo técnico, recomendação sem força cogente). Não equipare os dois.url— texto, obrigatório. Endereço da fonte oficial. Restrito por lista de domínios oficiais na geração: um endereço fora dela faz a publicação falhar, para que o link "texto oficial" nunca aponte para fora do órgão emissor.ucs— lista de textos, obrigatório (pode vir vazia). Códigos dos casos de uso mapeados, no formatoUC-NN, deUC-01aUC-14. Cada código tem página própria: UC-01, UC-02, UC-03, UC-04, UC-05, UC-06, UC-07, UC-08, UC-09, UC-10, UC-11, UC-12, UC-13 e UC-14. Lista vazia significa norma ainda não mapeada a nenhum caso de uso, não norma irrelevante.aliases— lista de textos, obrigatório. Formas de citação já normalizadas (minúsculas, sem acento, pontuação convertida em espaço) contra as quais a consulta é comparada: variações numéricas geradas do número e do ano, mais os apelidos declarados no corpus-fonte (lgpd,telemedicina). Ordenada alfabeticamente. Serve à correspondência, não à exibição.temas— lista de textos, obrigatório. Assuntos da norma, normalizados como os aliases. Alimentam a busca por tema e as facetas do Verificador.ementa— texto, opcional. Transcrição literal da ementa oficial, quando conferida — nunca resumo editorial. Ausente quando ainda não foi transcrita; a ficha e a referência ABNT simplesmente a omitem.vigencia_inicio— textoAAAA-MM-DD, opcional. Data em que a norma passa a produzir efeitos, quando difere da data do ato. Obrigatória quandostatusévigencia_futura.revogada_por— texto, opcional. Identificador da norma que revogou esta. Previsto no gerador e ainda sem ocorrência no índice publicado: nenhuma norma do recorte atual está revogada. Trate-o como campo que pode aparecer.
Campo ausente e campo vazio significam coisas diferentes. Os campos opcionais só aparecem quando o corpus-fonte os declara — o índice não carrega chave vazia para fingir completude. Trate a ausência como "não declarado", nunca como "não existe".
Um registro real, abreviado
{
"gerado_de": "sciereli-legal-mcp/sources (front-matter verificado em fonte oficial)",
"cobertura": "Proteção de dado sensível de saúde, sigilo profissional, exercício da medicina e inteligência artificial na medicina",
"total": 19,
"normas": [
{
"id": "res-cfm-2454-2026-ia-medicina",
"titulo": "Resolução CFM nº 2.454/2026 — uso de inteligência artificial na medicina",
"tipo": "Resolução CFM",
"orgao": "Conselho Federal de Medicina (CFM)",
"data": "2026-02-11",
"status": "vigente",
"peso": "vinculante",
"url": "https://sistemas.cfm.org.br/normas/arquivos/resolucoes/BR/2026/2454_2026.pdf",
"ucs": [],
"aliases": ["2454/2026", "cfm 2454", "resolucao cfm 2454/2026", "ia na medicina", "…"],
"temas": ["inteligencia artificial", "ia", "risco algoritmico"],
"ementa": "Normatiza o uso da inteligência artificial na medicina.",
"vigencia_inicio": "2026-08-26"
}
],
"atualizado_em": "2026-09-14"
}
As reticências marcam o corte feito aqui: no arquivo real a lista de aliases vem inteira, e há mais 18 registros irmãos.
Status declarado × status efetivo
O campo status é um dado verificado na fonte oficial; o rótulo que o leitor vê é função desse campo e da data da consulta. Quem consome o índice não deve reescrever o campo: deve derivar o rótulo na hora de exibir. Para quem vai citar a norma, e não consumir o índice, a mesma disciplina está resumida em Como citar normas de saúde digital.
No Verificador essa derivação é a função statusInfo(norma, hojeISO) de /matching.js. Para vigente ela devolve "vigente". Para vigencia_futura devolve "publicada · vigência a partir de" mais a data de vigencia_inicio por extenso e, quando a interface informa a data de hoje e faltam 30 dias ou menos, acrescenta a contagem regressiva ("entra em vigor em 12 dias", "entra em vigor hoje"). Para revogada e revogada_parcialmente há rótulos próprios, com destaque visual distinto.
vigencia_futura— norma publicada cujos efeitos ainda não começaram.statusInfo()devolve "publicada · vigência a partir de" mais a data devigencia_iniciopor extenso e, quando a interface informa a data de hoje e faltam 30 dias ou menos, acrescenta a contagem regressiva.vigente— único estado que recebe selo na ficha.revogada_parcialmente— rótulo e destaque próprios: parte do texto continua produzindo efeitos.revogada— estado final: nenhuma transição sai dele. Quando o corpus-fonte declararevogada_por, a ficha mostra a linha "Revogada por" e, se a norma revogadora também estiver no corpus, o valor vira link para a ficha dela.- Como se entra — uma norma entra no corpus já no estado verificado na fonte,
vigenteouvigencia_futura; a entrada e cada troca posterior ficam registradas em O que mudou no corpus. - A seta curva à direita — revogação total a partir de
vigente, sem passar por revogação parcial. - Transição nenhuma é automática — a troca acontece no corpus-fonte, conferida na fonte oficial, e só então chega ao índice; ver a ressalva do parágrafo abaixo.
quatro estados · o vocabulário fechado do campo status · nenhum estado fora desta lista
Limite declarado: statusInfo() não promove sozinha a "vigente" uma norma cuja vigencia_inicio já passou. Essa correção pertence ao corpus-fonte, onde a mudança é conferida na fonte oficial antes de entrar — e é cobrada a cada regeneração do índice, que emite aviso quando encontra uma data de início vencida com status não atualizado. Alinhar a derivação em tempo de execução ao cálculo do servidor MCP é trabalho previsto e ainda não feito; até lá, vigencia_futura com data passada significa "flip pendente de verificação", não "vigente".
Linha do tempo global
As normas do corpus, pela data do ato, agrupadas por órgão emissor. Só marcos estruturados: data do ato (campo data, todas as normas) e início de vigência (campo vigencia_inicio, hoje declarado em 4 delas) — publicação no Diário Oficial, retificações e suspensões de dispositivos não são campos do corpus e por isso não aparecem aqui; quando verificadas, constam em nota de texto na ficha de cada norma. Entrada de normas e alterações de metadados têm o próprio registro cronológico em O que mudou no corpus.
- Congresso Nacional
- CFM
- ANPD
- CNS
- Ministério da Saúde
- marcador vazado, ligado por traço — início de vigência declarado, quando diferente da data do ato.
Download e licença
O arquivo é servido pela mesma origem do site, sem CDN de terceiro, sem chave e sem cadastro: https://saude.capital/normas.json (cerca de 17 KB, UTF-8, JSON indentado). Não há serviço de consulta, paginação nem limite de requisições — é um arquivo estático, e a forma educada de consumi-lo é baixá-lo uma vez e guardar em cache.
O que já está resolvido, e o que não está
- As normas em si são livres. São atos oficiais e, como tais, não são objeto de proteção por direito autoral (art. 8º, IV, da Lei 9.610/98 — distinto de "domínio público", que é o art. 45 da mesma lei). O texto delas está nas fontes oficiais para as quais o campo
urlaponta. - A compilação é outra coisa. A seleção, a verificação e a organização destes metadados são protegidas como compilação/base de dados (art. 7º, XIII, e art. 87 da Lei 9.610/98) — a proteção recai sobre o arranjo, não sobre as normas.
- A licença dessa compilação ainda não foi declarada. Enquanto não for, o uso do arquivo é o que os Termos de Uso já permitem: uso profissional livre, inclusive por escritórios de advocacia e healthtechs no curso normal do trabalho, com atribuição quando citado publicamente, vedada a extração sistemática para constituir produto concorrente.
- Quando houver decisão, a licença será declarada nesta página, com a data. Até lá não afirmamos licença alguma — inclusive porque afirmar uma licença aberta e recuá-la depois seria pior do que não afirmar nada.
Ao citar o corpus publicamente, a atribuição que pedimos é simples: nome do produto, endereço do arquivo e a data de atualizado_em do índice que você usou — a mesma disciplina de proveniência que aplicamos às normas.
Exemplo de consumo
No navegador, em JavaScript sem dependência:
const resp = await fetch('https://saude.capital/normas.json');
const dados = await resp.json();
console.log(dados.total, dados.atualizado_em, dados.cobertura);
// Resoluções do CFM vigentes, com o endereço da fonte oficial
dados.normas
.filter(n => n.tipo === 'Resolução CFM' && n.status === 'vigente')
.forEach(n => console.log(n.id, n.data, n.url));
Na linha de comando, com curl e jq:
curl -s https://saude.capital/normas.json \
| jq '{total, atualizado_em, cobertura}'
# uma norma pelo id, só os campos que interessam
curl -s https://saude.capital/normas.json \
| jq '.normas[] | select(.id == "res-cfm-2454-2026-ia-medicina")
| {titulo, status, peso, vigencia_inicio, url}'
Reproduzir a correspondência do Verificador
A lógica de busca não está presa à página: vive em /matching.js, um script clássico que funciona das duas formas — como <script src> no navegador (as funções ficam no escopo global) e como require() no Node, sem transpilação. É o mesmo arquivo que a suíte de testes exercita.
// navegador: <script src="https://saude.capital/matching.js"></script>
const achados = buscar('Resolução CFM nº 2.454, de 11 de fevereiro de 2026', dados);
achados.forEach(n => console.log(n.titulo, '—', statusInfo(n, '2026-09-14').label));
// Node, a partir de uma cópia local do arquivo
const m = require('./matching.js');
m.buscar('lgpd', dados).map(n => n.id);
buscar(consulta, dados) recebe o texto digitado e o objeto inteiro do índice, e devolve as normas correspondentes ordenadas por pontuação. Antes de comparar, normaliza a consulta — minúsculas, sem acento, pontuação convertida em espaço — de modo que "Lei nº 13.709/2018", "lei 13709/2018" e "LGPD" chegam à mesma forma; também reconhece data por extenso ("de 11 de fevereiro de 2026"). A comparação é feita contra aliases e temas com limite de palavra, para que "cfm 2454" não case dentro de outro número. É correspondência textual, não busca por sentido: a função não interpreta a pergunta e não pondera relevância jurídica. Lista vazia quer dizer "não encontrada neste corpus" — e é assim que deve ser apresentada a quem lê.
statusInfo(norma, hojeISO) traduz o campo status no rótulo de exibição, como descrito acima. O segundo argumento é opcional e existe para que a função não leia o relógio por conta própria: quem chama informa que dia é hoje, o que torna o resultado determinístico e testável. Devolve { label, cls, selo } — o texto, uma classe de severidade (ok, info, crit) e se cabe o selo de vigência. Use o label; não exiba o token cru do JSON.
Não há promessa de interface estável. matching.js é o código do Verificador publicado abertamente, não uma biblioteca com versão própria: nomes de função e formato de retorno podem mudar numa rodada do site. O esquema do normas.json é o que tem estabilidade declarada, e a declaração é a data em atualizado_em: mudanças de conteúdo do corpus — norma nova, mudança de status, correção de metadado — entram em O que mudou no corpus e no feed Atom, que é a forma de acompanhar sem cadastro. Mudança de campo do esquema é registrada no changelog do repositório do site e anunciada nesta página.
Servidor MCP e plugin do Claude Code
O mesmo corpus existe como servidor MCP — Model Context Protocol, o padrão aberto de conexão entre assistentes de IA e fontes de dados —, empacotado junto com três comandos para o Claude Code. Serve a quem quer o corpus dentro do próprio fluxo de trabalho, em vez de consumir o JSON na mão.
As ferramentas do servidor
listar_corpus()— identificadores, títulos e status de tudo que está indexado.ficha_norma(id)— metadados completos de uma norma.buscar_norma(consulta)— busca por citação, sigla ou tema, com a mesma disciplina de normalização do Verificador.normas_por_tema(tema)— a faceta temática.comparar_normas(ids)— metadados lado a lado.citacao_abnt(id, data_acesso?)— referência NBR 6023 composta só de campos verificados.verificar_citacao(texto)— audita uma minuta ou parecer colado: citações reconhecidas no corpus × não encontradas, cada uma com status.mudancas_recentes(limite?)— acompanhamento normativo, lido do feed Atom público do site.
Mais dois guias embarcados, que o assistente pode ler: a ressalva de cobertura e as regras de como citar uma norma do corpus.
O que sai pela rede
O servidor roda na máquina de quem o instala e as consultas ao corpus não passam por servidor da Sciereli; o que trafega para o provedor de IA é o que o próprio usuário já envia ao seu assistente. O único acesso à rede feito pelo servidor é a leitura do feed público /feed.xml, em mudancas_recentes() — e mesmo essa tem cache local e degrada dizendo que degradou.
O texto auditado em verificar_citacao() é processado localmente e não é enviado a lugar nenhum pelo servidor.
Os três comandos do plugin
/saude-capital:radar [n]— últimas mudanças do corpus, cada uma com ficha, status e referência ABNT das normas reconhecidas./saude-capital:verificar-citacao <arquivo ou texto>— auditoria das citações de uma minuta ou parecer. Só a pessoa invoca; o assistente não o dispara por conta própria./saude-capital:ficha <número, nome ou tema>— ficha verificada de uma norma, com fonte oficial e referência ABNT.
Instalação
No Claude Code, com uv instalado na máquina — o repositório é o seu próprio marketplace de plugins:
/plugin marketplace add Sciereli/sciereli-legal-mcp
/plugin install saude-capital@sciereli
O plugin sobe o servidor MCP sozinho, sem ambiente virtual nem caminho absoluto. Para usar o servidor fora do Claude Code — em Claude Desktop ou em qualquer outro cliente MCP —, o pacote roda por uvx, com transporte padrão de entrada e saída:
uvx --from git+https://<token>@github.com/Sciereli/sciereli-legal-mcp sciereli-legal-mcp
A partir de um clone local, a alternativa é pip install -r requirements.txt seguido de python server.py. Requisitos: Python 3.11 ou mais recente.
O repositório é privado. Os comandos acima estão prontos e corretos, mas só funcionam para quem já tem acesso de leitura ao repositório no GitHub — acesso concedido a escritório cliente e a escritório parceiro com contrato em vigor. Por isso esta página não linka o repositório: publicar um endereço que devolve "não encontrado" seria pior do que dizer o motivo. A data de abertura ao público ainda não foi definida. Para pedir acesso, escreva para capital@saude.dev.
Encontrou um erro?
Metadado errado em um registro — data, número, status, endereço da fonte — é defeito, e queremos saber. Escreva para capital@saude.dev com o id do registro e o endereço oficial que contradiz o que está publicado. A correção entra pelo corpus-fonte, é verificada, e aparece no acompanhamento com data.
Como citar normas de saúde digital · O que mudou no corpus · Feed Atom do acompanhamento · Índice das 19 normas · Os 14 casos de uso · Glossário: corpus · Kit do escritório parceiro · Termos de Uso