Skip to main content
Glama

revisor-notas-mcp

Servidor MCP que confere notas clínicas no formato SOAP (F/S/O/A/P): checa se os campos obrigatórios estão preenchidos e usa um LLM local para apontar incoerências entre queixa, exame e conduta. Roda inteiramente na sua máquina, o texto da nota não sai dela.

⚠️ Não substitui o julgamento clínico

  • Isto não é um software de apoio à decisão clínica. Não foi validado clinicamente, não foi avaliado por nenhum órgão regulador e não é um dispositivo médico.

  • A checagem semântica é probabilística. Ela é feita por um LLM lendo texto livre: erra para os dois lados. Ausência de avisos não atesta que a nota está correta, e um aviso pode ser falso positivo.

  • A responsabilidade pela nota continua sendo de quem assina. A ferramenta aponta o que pode ter faltado; ela não sabe do paciente nada além do que está escrito.

  • O projeto foi escrito em torno de um template específico de telemedicina. Se o seu formato for outro, as regras determinísticas precisam ser ajustadas.

Requisitos

O quê

Versão

Para quê

Python

3.12+

runtime

uv

recente

dependências e venv

Um LLM local com API OpenAI-compatible

-

checagem semântica (opcional)

Sem banco de dados, sem sync e sem timer systemd: este projeto não persiste nada e só roda quando o cliente MCP chama uma tool.

Related MCP server: soapnoteapi-mcp

Instalação

A distribuição é por clone + uv (não há pacote no PyPI).

git clone https://github.com/fabianofilho/revisor-notas-mcp.git
cd revisor-notas-mcp
uv sync
cp .env.example .env

Configuração

Variável

Padrão

Observação

QWEN_ENDPOINT

http://127.0.0.1:8080/v1

llama.cpp. Ollama: :11434/v1. LM Studio: :1234/v1

QWEN_MODEL

local-model

llama.cpp e LM Studio aceitam qualquer nome

TIMEOUT_CHECAGEM_SEMANTICA_SEGUNDOS

15

curto de propósito: a checagem não pode travar a resposta

O endpoint precisa ser localhost. Qualquer outro host é recusado com exceção, não com aviso, ver Privacidade.

uv run revisor-cli llm                        # confirma o LLM local
uv run revisor-cli validar nota.txt           # ou cole a nota no stdin
uv run revisor-cli validar nota.txt --sem-llm # só as regras determinísticas
uv run revisor-cli anotar nota.txt            # nota com anotações inline

Ligando ao Claude Code

claude mcp add revisor-notas --scope user \
  -e QWEN_ENDPOINT=http://127.0.0.1:8080/v1 \
  -e QWEN_MODEL=local-model \
  -- uv --directory /caminho/para/revisor-notas-mcp run revisor-notas-mcp

Uso

validar_nota_soap(texto_nota: str)

Lista os problemas encontrados, cada um com seção, severidade, sugestão e a origem (regra ou semantica).

{
  "total_erros": 0,
  "total_avisos": 2,
  "checagem_semantica_feita": true,
  "problemas": [
    {
      "secao": "F, S, A, P",
      "severidade": "aviso",
      "descricao": "A queixa é dor torácica irradiando para o braço esquerdo, com hipertensão e tabagismo, o que sugere etiologia cardíaca. A hipótese final é dor muscular e a conduta é analgésico simples.",
      "origem": "semantica"
    },
    {
      "secao": "S",
      "severidade": "aviso",
      "descricao": "Sinais de alarme esperados que não aparecem como investigados: sudorese, dispneia, náuseas.",
      "origem": "semantica"
    }
  ]
}

Esse exemplo é a saída real de uma nota sintética de teste. Note que total_erros é zero: a nota está formalmente correta, as regras determinísticas passam limpo. O que a camada semântica aponta é clínico, e é exatamente o que regra não pega.

sugerir_correcoes(texto_nota: str)

A mesma nota com os problemas de validar_nota_soap inseridos como linhas <<ERRO: ...>> ou <<AVISO: ...>>. Não reescreve o texto original: nenhuma linha da nota é alterada, e quem decide o que mudar é quem assina.

  • Cada problema aparece uma única vez, no fim da seção a que se refere. Um achado da camada semântica que cita várias seções vai para a primeira delas que existe na nota, com as seções entre colchetes, por exemplo <<AVISO [F, A, P]: ...>>.

  • O que não tem onde ficar (cabeçalho ausente, seção ausente ou vazia sem marcador, seção fora do padrão) vai para um bloco <<PROBLEMAS NO DOCUMENTO>> no topo.

  • total_anotacoes é o número de problemas, igual ao número de linhas <<...>> fora o título do bloco.

<<PROBLEMAS NO DOCUMENTO>>
    <<ERRO [O]: Seção -O: ausente ou vazia. → Preencha a seção -O: conforme o template.>>
#TELEMEDICINA#
-F: Paciente refere cefaleia. Sem sinais de alarme.
...
-A: Cefaleia tensional (CID: R51).
-P:
1. Dipirona 500mg via oral se dor.
...
Atendimento realizado via telemedicina, não sendo possível aferição de sinais vitais.
    <<AVISO: Plano sem os itens numerados [2, 4, 5]. → O template prevê os itens 1 a 5, sendo o 5 o do atestado.>>

Saída real (sem LLM) de uma nota sintética de teste, com linhas omitidas.

As duas camadas

Regras determinísticas (rules/) rodam sempre, sem LLM: cabeçalho, as cinco seções, CID em formato válido, itens numerados do plano, item de sinais de alarme, rodapé fixo, e os campos do subjetivo (medicações em uso, antecedentes, alergia, hábitos).

Checagem semântica (llm/) olha coerência entre queixa, exame e conduta; e sinais de alarme típicos do diagnóstico que não aparecem como investigados (negativa explícita conta como investigado).

Se o LLM local estiver fora do ar (ou der timeout, ou devolver algo que não é JSON), a validação por regras responde sozinha: checagem_semantica_feita vem false e motivo_semantica_pulada diz o porquê. As regras nunca ficam bloqueadas pelo modelo.

Os prompts do LLM estão em src/revisor_notas_mcp/prompts/ e fazem parte do pacote.

Limitações conhecidas

O parser espera um template específico. Ele tolera variação de formatação (marcador com ou sem hífen, caixa baixa, espaço sobrando), mas as regras de conteúdo (quais campos são obrigatórios, qual rodapé, quais itens no plano) foram escritas para um template de telemedicina. Adaptar para outro formato significa mexer em rules/checklist.py.

A checagem semântica depende de um modelo pequeno. Rodando local, ela custa alguns segundos e a qualidade varia com o modelo. Um modelo fraco vai gerar falso positivo.

A validação de CID é sintática, não semântica. Ela confere o formato (letra + dois dígitos, com subcategoria opcional), não se o código corresponde ao diagnóstico escrito.

Nada é cacheado. Cada chamada reprocessa a nota do zero, porque cachear significaria guardar o texto, e isso o projeto não faz.

Privacidade

Este é o ponto central do projeto, e ele está em código e em teste, não só aqui:

  • Nenhuma chamada de rede além de localhost. O cliente do LLM recusa com exceção (EndpointNaoLocal) um endpoint que aponte para qualquer outro host. Configuração perigosa estoura em vez de degradar em silêncio.

  • Nada é gravado. Sem banco, sem cache em disco, sem log do conteúdo. O processamento é em memória, por chamada. Há um teste que confere que nenhum trecho da nota aparece em log, inclusive quando a chamada ao LLM falha.

  • Fixtures de teste são sintéticas, nunca dado real, nem anonimizado.

  • Sem telemetria, sem analytics.

O que sai da sua máquina: nada. O que vai para o seu LLM local: o texto da nota, pelo localhost.

Segurança

Veja SECURITY.md para reportar uma vulnerabilidade. As mudanças por versão estão no CHANGELOG.md.

Contribuindo

Veja CONTRIBUTING.md. A regra mais importante e sem exceção: nenhuma fixture pode conter dado real de paciente, nem anonimizado.

Licença e atribuição

Apache License 2.0: escolhida por o projeto tocar em dado de paciente, onde a cláusula explícita de patente é mais protetiva.

Construído no contexto do IA.med.

Available Tools

2 tools
sugerir_correcoesA

Devolve a nota com anotações inline do que precisa ser ajustado.

Não reescreve o texto original: cada problema de validar_nota_soap vira uma linha <<ERRO: ...>> ou <<AVISO: ...>>, uma única vez, no fim da seção a que se refere. O que não tem seção na nota (cabeçalho, seção ausente) vai para um bloco <> no topo. Quem decide o que mudar é o médico.

Args: texto_nota: a nota completa a ser anotada.

Inputs: texto_nota (required). Returns: A nota com anotações inline, sem reescrever o texto original.

validar_nota_soapA

Valida uma nota clínica no formato #TELEMEDICINA# (F/S/O/A/P).

Checa campos obrigatórios, CID, numeração do plano e rodapé por regras determinísticas, e usa o LLM local para conferir coerência entre queixa, exame e conduta, além de sinais de alarme não investigados. A parte do LLM é probabilística e vem marcada como tal; se ele estiver fora do ar, as regras respondem sozinhas e motivo_semantica_pulada diz por que a semântica não rodou.

O texto processado não sai da máquina nem é gravado em lugar nenhum.

Args: texto_nota: a nota completa, como seria colada no prontuário.

Inputs: texto_nota (required). Returns: Resultado da validação de uma nota.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

Loading tool schema changelog…

    TDQS

    A4.4/5.0

    Scored across 2 tools

    Disambiguation4/5

    The two tools are clearly related but serve distinct output purposes: one produces a validation report, the other an annotated version of the note. Descriptions explicitly differentiate them, though an agent might briefly hesitate about which to call for a given user request.

    Naming Consistency5/5

    Both tool names follow the same verb_noun pattern in Portuguese, using snake_case: validar_nota_soap and sugerir_correcoes. The convention is consistent and the verbs accurately describe the actions.

    Tool Count4/5

    With only two tools, the server is on the smaller side, but they cover the two core operations for a note reviewer: validate and suggest corrections. The count feels reasonable rather than thin because each tool is substantial and has a clear purpose.

    Completeness4/5

    The domain is clinical note review, and the pair covers validation (including semantic checks) and actionable inline suggestions. There are no obvious dead ends, though a tool for a structured list of errors separately from annotation is already covered by validar_nota_soap.

    Maintenance

    ActivityMaintained
    ResponsivenessOutdated data

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      C
      maintenance
      Enables coding assistants to check code for common health-data mistakes locally without an account, and, with a configured core service, de-identify clinical text, restore placeholders, and append tamper-evident audit log entries.
      1
      6 npm
      MIT
    • A
      license
      Not graded
      quality
      A
      maintenance
      Enables AI assistants to query authoritative medical sources such as FDA, WHO, PubMed, RxNorm, and ClinicalTrials.gov from a local, key-free server. Provides drug searches, health statistics, graded medical literature, clinical guidelines, pediatric resources, and built-in health monitoring without sending data to the cloud.
      83 npm
      ISC