Projeto IA.med Licença Apache-2.0 100% local, sem LLM v0.1.0, repositório privado

ans-mcp

Servidor MCP para consultar os dados abertos da ANS: a terminologia TUSS e o desempenho das operadoras de plano de saúde. Nenhuma das três tools usa modelo de linguagem, nem para resumir: tudo o que elas respondem está nos arquivos que a agência publica.

Antes de usar, leia

  • Não é fonte oficial para decisão regulatória nem contratual. É uma cópia local dos dados abertos da ANS, com a data da coleta em cada resposta.
  • A TUSS não é o Rol de Procedimentos. Ela diz que um código existe e está vigente, não que o procedimento tenha cobertura obrigatória: isso é outra norma.
  • A tool de operadora procura nas ativas e nas canceladas, e uma operadora pode aparecer nas duas listas no mesmo dia. Não achar uma operadora não prova que ela nunca existiu.
  • A faixa do monitoramento de garantia de atendimento vem como a ANS publica, sem tradução para boa ou ruim: o dicionário oficial não define o que cada faixa significa.

O problema

Por que este projeto existe

Quatro downloads para uma pergunta

A ANS publica muita coisa, em conjuntos separados, cada um com seu arquivo e sua periodicidade. Responder "como está a operadora X" significa abrir quatro downloads e juntar na mão, cruzando pelo registro.

O mesmo CNPJ escrito de dois jeitos

O CNPJ vem formatado num arquivo (04.518.814/0001-73) e cru no outro (19541931000125). O registro da operadora tem zero à esquerda, então é texto, e ninguém digita os zeros. Sem normalizar, o cruzamento não casa.

Dezenove tabelas, seis formatos

O zip da TUSS tem 19 arquivos que não compartilham um schema só. A tabela 63 não tem NM_TERMO, a 64 usa outra nomenclatura inteira e seu cabeçalho é publicado com uma aspa não fechada. Um parser escrito de memória lê a coluna errada.

Como funciona

Do FTP da agência ao agente, em quatro camadas

  1. 01

    Download

    Baixa os cinco conjuntos do FTP de dados abertos da ANS, incluindo o zip da TUSS. Uma fonte fora do ar não impede as outras, mas formato inesperado interrompe o sync de propósito.

  2. 02

    Parser que trava no cabeçalho

    Cada parser confere as colunas que espera e aceita só os nomes já conferidos na origem. Um formato novo levanta erro em vez de adivinhar: parser lendo a coluna errada devolve número plausível, que é pior que não devolver nada.

  3. 03

    DuckDB em formato longo

    IDSS, garantia e glosas viram tabelas longas. O IDSS vem largo da ANS, com uma coluna por indicador e par de anos, e os nomes dos indicadores já mudaram duas vezes: longo sobrevive à próxima troca sem migração.

  4. 04

    Troca atômica da base

    O sync constrói a base nova ao lado e troca as duas por rename no fim. Quem está consultando não é interrompido, e a cópia sai compactada: sem isso o arquivo passava de 120 MB sem ganhar uma linha.

Não há camada de modelo de linguagem em nenhum ponto. As três tools leem a base e devolvem o que está nela, o que também significa que elas não interpretam, não resumem e não ordenam por relevância semântica.

O que ele lê

Sete tabelas de dados abertos

Contagens lidas da base real em 12/10/2026. Cada uma saiu de um count(*), não de estimativa. A base inteira ocupa 62 MB em disco.

  • Terminologia TUSS 67.884 termos 18 tabelas de domínio, das 19 do zip. Procedimentos, medicamentos, materiais e OPME, diárias e as tabelas de domínio menores.
  • Operadoras ativas 1.106 operadoras Cadastro com registro na ANS, CNPJ, razão social, nome fantasia, modalidade e município. Só as ativas.
  • Operadoras canceladas 3.078 operadoras Com data e motivo do cancelamento.
  • Histórico do IDSS 43.724 notas Formato longo, uma linha por operadora, indicador e ano. Anos-base de 2015 a 2024.
  • Garantia de atendimento 33.025 posições 35 competências trimestrais, com a faixa como a ANS publica.
  • Painel de glosas 48.184 valores Quatro indicadores em formato longo: tempo médio de pagamento, glosa inicial, glosa final e guias sem retorno.
  • Regimes especiais 118 resoluções Resoluções de direção técnica, de 77 operadoras.

A ponte com a Anvisa é uma normalização, não uma junção: 61.573 dos 67.884 termos trazem o registro na Anvisa, e os de materiais e OPME trazem também classe de risco e nome técnico. O servidor não lê a base da Anvisa: devolve o registro na forma que ela aceita, e quem cruza é o cliente, chamando a tool do outro servidor.

As ferramentas

Três tools MCP, nenhuma com LLM

O modelo chama estas funções durante a conversa. Toda resposta traz total, retornados e truncado: conte pelo total, nunca pelo tamanho da lista. Os retornos abaixo são saídas reais de 11/10/2026, com as listas longas cortadas, e não foram regravados em 12/10/2026.

consultar_tuss

Termo da TUSS por código TISS ou por nome, nas 18 tabelas de domínio. Um código exato traz aquele termo direto; um nome busca por texto, e termo genérico casa com muita coisa ("stent coronário" casa com 4.311). Por padrão só os vigentes, que é o que DT_FIM_VIGENCIA vazio significa no dicionário da ANS. Para conferir guia antiga, use apenas_vigentes=False. Devolve o registro na Anvisa em dois formatos: o publicado pela agência e o que serve para consultar a Anvisa.

consultar_tuss(
    termo_ou_codigo: str,
    apenas_vigentes: bool = True,
    limite: int = 20,   # 1 a 200
)
{
  "termo_consultado": "stent coronário",
  "total": 4311,
  "retornados": 2,
  "truncado": true,
  "resultados": [
    {
      "cd_termo": "71220577",
      "tabela": "tabela_19_materiais_e_opme",
      "nm_termo": "STENT CORONÁRIO CHROMA",
      "ds_termo": null,
      "dt_inicio_vigencia": "2016-10-01",
      "dt_fim_vigencia": null,
      "dt_fim_implantacao": "2016-12-31",
      "registro_anvisa": "80102511360",
      "fabricante": "VR MEDICAL IMPORTADORA E DISTRIBUIDORA DE PRODUTOS MÉDICOS LTDA",
      "classe_risco": "IV",
      "nome_tecnico": "STENT PARA ARTÉRIAS CORONÁRIAS"
    }
  ],
  "aviso": "Terminologia Unificada da Saúde Suplementar, dos dados abertos da ANS. O código e a vigência valem para troca de informações no padrão TISS, e não dizem se o procedimento tem cobertura obrigatória: isso é o Rol de Procedimentos, que é outra norma. Casaram 4311 termos e estão aqui os 2 primeiros..."
}
Saída real de 11/10/2026, cortada em um resultado

consultar_operadora

Cadastro, notas do IDSS por ano, faixa de garantia de atendimento por trimestre, indicadores de glosa e regimes especiais, juntos, cruzados pelo registro na ANS. Procura nas operadoras ativas e nas canceladas. Aceita registro com ou sem os zeros à esquerda, CNPJ formatado ou cru, razão social e nome fantasia. O visto_na_ultima_coleta avisa quando a operadora não veio no arquivo mais recente, ou seja, saiu da lista de ativas.

consultar_operadora(
    nome_registro_ou_cnpj: str,
    limite: int = 10,   # 1 a 50
)
{
  "termo_consultado": "417548",
  "total": 1,
  "retornados": 1,
  "truncado": false,
  "resultados": [
    {
      "registro_operadora": "417548",
      "cnpj": "03033006000153",
      "razao_social": "CAIXA DE ASSISTÊNCIA OSWALDO CRUZ",
      "nome_fantasia": "FIOSAÚDE",
      "modalidade": "Autogestão",
      "uf": "RJ",
      "cidade": "Rio de Janeiro",
      "data_registro_ans": "2010-09-21",
      "visto_na_ultima_coleta": true,
      "idss": [
        { "indicador": "IDSS", "ano_divulgacao": 2025, "ano_base": 2024, "nota": 0.7232 },
        { "indicador": "IDQS", "ano_divulgacao": 2025, "ano_base": 2024, "nota": 0.8918 }
      ],
      "garantia_atendimento": [
        { "competencia": "4º Trim./2024", "dt_inicio": "2024-10-01", "dt_fim": "2024-12-31", "posicao": "FAIXA 3" }
      ],
      "glosas": [
        { "indicador": "tempo_medio_pagamento", "periodo": "2025-02", "valor": 10.68, "porte": "Pequeno" },
        { "indicador": "percentual_glosa_final", "periodo": "2025-02", "valor": 3.37, "porte": "Pequeno" }
      ]
    }
  ],
  "aviso": "Dados abertos da ANS, cruzados pelo registro da operadora. Cada bloco vem de um conjunto diferente, com periodicidade própria..."
}
Saída real de 11/10/2026, com as listas cortadas: a completa trouxe 40 notas de IDSS, 12 competências e 24 valores de glosa

consultar_por_registro_anvisa

A ponte com a Anvisa em sentido reverso: dado um registro na Anvisa, quais itens da TUSS o citam. Aceita registro com 9, 11 e 13 dígitos. Não consulta a base da Anvisa: normaliza o registro e devolve os itens da TUSS que o citam. O cruzamento com a resposta do anvisa-mcp fica com o cliente.

Onde ele falha

O que as tools não dizem

Cada item abaixo foi conferido baixando o arquivo ou consultando a base, não deduzido de documentação. São as coisas que fazem alguém tirar a conclusão errada de uma resposta certa.

A TUSS não é o Rol de Procedimentos

Ela é terminologia para troca de informações no padrão TISS. Dizer que um código existe e está vigente não é dizer que o procedimento tem cobertura obrigatória, e essa confusão é a mais fácil de cometer aqui. O Rol é outra norma, e a ANS não o publica como dado aberto: das 53 pastas do FTP, nenhuma é o Rol.

Uma operadora pode aparecer nas duas listas no mesmo dia

Em 11/10/2026 a 423122 foi cancelada em 09/10 e ainda constava no arquivo de ativas coletado em 10/10. A tool mostra os dois fatos em vez de escolher um vencedor que a agência não escolheu. Ela procura nas ativas e nas canceladas.

Regime especial não tem data de fim

O conjunto tem seis campos e nenhum diz quando o regime acabou. A leitura certa é "teve regime especial em tal data", nunca "está em regime hoje".

A faixa de garantia não é traduzida

A tool devolve FAIXA 0, FAIXA 3 e assim por diante, como a ANS publica. O dicionário oficial não define o que cada faixa significa, então traduzir para boa ou ruim seria interpretação nossa apresentada como dado.

Glosa inicial e final vêm iguais na maior parte dos casos

Quem vê os dois indicadores com o mesmo valor pensa em erro de parser. Não é: é o que os dois arquivos da ANS trazem. Lido em 12/10/2026, de 81% a 90% dos pares operadora e semestre têm glosa inicial igual à final, dependendo do semestre. Em 2019-01 (conferido em 11/10/2026) a FIOSAÚDE tem 3,33 e 3,51, valores diferentes, o que mostra que a coluna lida é a certa.

Uma tabela da TUSS fica inteira de fora

A base tem 18 das 19 tabelas do zip. A 64 é um mapa de código para grupo de envio, não terminologia: suas 67.759 linhas vêm com descrição e grupo vazios em todas elas, conferido em 11/10/2026. Um termo sem nome e sem descrição não serve para consulta, então ela não entra. Com ela, o campo TP_ENVIO também fica fora.

Um dos cinco arquivos de glosa não é coletado

A ANS publica cinco indicadores de glosa; este servidor carrega quatro. Falta o percentual de valor das guias sem retorno. Onde a origem marca o dado como inconsistente, com um traço, o valor entra como nulo em vez de zero.

periodo é ano e semestre, não ano e mês

O campo periodo das glosas vem como 2025-02, que pelo dicionário oficial da ANS quer dizer segundo semestre de 2025. Ler isso como fevereiro erra por meio ano.

A ponte com a Anvisa é normalização, não junção

O TUSS publica o registro de medicamento com 13 dígitos (o registro de 9 mais o código de apresentação) e a base da Anvisa guarda 9. Dos 13.390 registros de medicamento que o TUSS cita, 1 casa pelo valor publicado e 13.388 casam pelos 9 primeiros dígitos (lido em 12/10/2026). Quem encadeava as duas consultas à mão recebia "não encontrado" para quase todo medicamento, sem sinal de que a culpa era do formato. Este servidor não lê a base da Anvisa: devolve o registro na forma que ela aceita, e quem cruza é o cliente.

Como rodar

Local, por stdio, sem serviço hospedado

Não há conector hospedado nem versão remota deste servidor. Ele roda na sua máquina e fala stdio com o cliente MCP. Precisa de Python 3.12+, uv e cerca de 62 MB de disco para a base (tamanho lido em 12/10/2026).

O repositório é privado na v0.1.0: não há link público para clonar. Os passos abaixo valem para quem já tem acesso ao código.

# 1. na pasta do projeto: instalar e configurar
uv sync
cp .env.example .env

# 2. montar a base (baixa ~25 MB da ANS, cerca de 2 min)
uv run ans-cli sync --publicar

# 3. conferir quantas linhas entraram em cada tabela
uv run ans-cli estado

# 4. registrar o servidor MCP (stdio) no Claude Code
claude mcp add --scope user ans -- uv --directory /caminho/do/ans-mcp run ans-mcp
Comandos conferidos contra a CLI da v0.1.0. No Claude Code, passe caminhos absolutos.

Manutenção e consulta direta

Para manter a base atualizada sem sessão aberta há um timer systemd no projeto, que roda a coleta com --publicar todo dia de madrugada, com atraso aleatório. O atraso importa: horário fixo resolveria a concorrência numa máquina só, mas faria todas as instalações baterem no servidor da ANS no mesmo minuto.

# uma fonte só, quando a ANS republica apenas aquela
uv run ans-cli sync --fonte tuss

# consultar da linha de comando, sem cliente MCP
uv run ans-cli tuss "stent coronário"
uv run ans-cli operadora 417548

Só saem da sua máquina as requisições ao FTP de dados abertos da ANS. Não há chamada a modelo, nem local nem remoto, e nenhum termo consultado é registrado em log.