Skip to main content
Glama

radar-cfm-mcp

Servidor MCP que consulta e monitora resoluções do CFM (Conselho Federal de Medicina) sobre inteligência artificial, telemedicina e prontuário eletrônico. Mantém uma cópia local pesquisável e sempre devolve o link do documento oficial.

⚠️ Não é fonte oficial

  • Não substitui a consulta ao portal do CFM. Este projeto lê o que o portal publica e guarda uma cópia local, que pode estar defasada.

  • Um trecho extraído não é "a posição do CFM". Toda resposta traz a ementa e a URL do PDF oficial justamente para você conferir antes de citar.

  • A extração de PDF pode falhar ou truncar. Quando isso acontece o registro é marcado com metadados_incompletos, mas leia sempre o documento original.

  • Sem validação jurídica. Isto é uma ferramenta de busca, não uma interpretação normativa.

Requisitos

O quê

Versão

Para quê

Python

3.12+

runtime

uv

recente

dependências e venv

Espaço em disco

~200 MB

base DuckDB + PDFs cacheados

Este projeto não usa LLM: a busca é full-text sobre a base local.

Related MCP server: cfm_estabelecimento

Instalação

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

Configuração

Variável

Padrão

Observação

CRAWLER_DELAY_SEGUNDOS

2

intervalo entre requisições ao portal

PALAVRAS_CHAVE

IA, telemedicina, prontuário eletrônico, algoritmo

separadas por vírgula

DUCKDB_PATH

./data/cfm.duckdb

base local

SYNC_HORA_LOCAL

02:00

horário fixo do sync agendado

uv run cfm-cli sync --max-paginas 3    # teste rápido
uv run cfm-cli sync                    # varredura completa (~8 min com delay de 2s)
uv run cfm-cli consultar telemedicina
uv run cfm-cli novas --dias 90
uv run cfm-cli schema

Ligando ao Claude Code

claude mcp add radar-cfm --scope user \
  -e DUCKDB_PATH=/caminho/para/radar-cfm-mcp/data/cfm.duckdb \
  -- uv --directory /caminho/para/radar-cfm-mcp run radar-cfm-mcp

Uso

consultar_resolucao_cfm(tema: str, apenas_vigentes=True)

{
  "tema": "inteligência artificial",
  "total": 1,
  "resultados": [
    {
      "identificador": "2454/2026",
      "ementa": "Normatiza o uso da inteligência artificial na medicina.",
      "vigente": true,
      "revogada_por": null,
      "trecho_relevante": "…Normatiza o uso da inteligência artificial na medicina. O CONSELHO FEDERAL DE MEDICINA…",
      "url_origem": "https://sistemas.cfm.org.br/normas/visualizar/resolucoes/BR/2026/2454",
      "texto_completo_disponivel": true
    }
  ]
}

Ordena por relevância (BM25 do FTS do DuckDB) e depois por data. Revogadas vêm com vigente: false e o número da que substituiu.

monitorar_novas_resolucoes(dias=30, filtrar_tema=True)

O que foi publicado na janela, filtrado pelos temas configurados.

Como a fonte funciona

O portal de busca de normas renderiza os resultados no navegador a partir de uma variável resultadoBuscaJson embutida no HTML. O crawler lê esse JSON em vez de raspar tabela: é mais estável, e já vem com o campo de revogação.

Confirmado em 20/09/2026: 2.457 resoluções, 10 por página, 246 páginas.

Dois detalhes que moldaram o desenho:

  • A busca textual por URL é ignorada pelo portal (o total não muda com busca=), então o filtro por palavra-chave é aplicado localmente sobre a ementa.

  • A página de detalhe é um visualizador PDF.js, não texto. O PDF real segue o padrão sistemas.cfm.org.br/normas/arquivos/resolucoes/BR/{ano}/{numero}_{ano}.pdf.

Respeito ao portal

É o site de um conselho profissional, não uma API feita para volume:

  • intervalo configurável entre requisições (padrão 2s);

  • o mesmo PDF nunca é baixado duas vezes (cache por hash da URL);

  • PDF só é baixado quando a ementa casa com alguma palavra-chave. Baixar as 2.457 seria abusivo, e a ementa já basta para a triagem.

Limitações conhecidas

O corpus relevante é pequeno, e isso é do CFM, não do projeto. Das 2.457 resoluções, apenas 5 ementas mencionam os temas padrão: a 2.454/2026 (IA), a 2.314/2022, as 2.227/2018 e 2.228/2019 (revogadas) e a 1.643/2002. Se você espera dezenas de resultados, o problema é a expectativa.

O filtro age sobre a ementa, não sobre o texto completo. Uma resolução que trate de IA no corpo sem dizer isso na ementa não terá o PDF baixado. Ajuste PALAVRAS_CHAVE se o seu tema for outro.

A vigência vem do portal, não de análise jurídica. O campo reflete o que o CFM marca como revogado. Revogação parcial ou alteração por outra resolução não aparece como tal.

O parser depende do formato da página. Se o portal mudar, o crawler falha com uma mensagem explícita (resultadoBuscaJson não encontrado) em vez de devolver vazio em silêncio — mas vai falhar.

A busca cai para LIKE sem o FTS. A extensão full-text do DuckDB é baixada na primeira execução. Sem rede, a busca continua respondendo, mais lenta e sem ranking.

Privacidade

  • Sai da máquina: requisições ao portal.cfm.org.br e ao sistemas.cfm.org.br, para a busca e os PDFs públicos.

  • Não sai: os temas que você consulta. A busca roda contra a base local.

  • Sem LLM, sem telemetria, sem analytics.

Contribuindo

Veja CONTRIBUTING.md. Não rode o crawler em loop nem reduza o delay.

Licença e atribuição

Apache License 2.0 — escolhida por o projeto tocar em regulação de conduta médica.

Construído no contexto do IA.med.

Available Tools

2 tools
consultar_resolucao_cfmA

Consulta resoluções do CFM relacionadas a um tema.

Devolve as resoluções mais relevantes, com número, ano, data, ementa, o trecho em volta do termo buscado e sempre a URL de origem. Resoluções revogadas vêm com vigente=false e o número da que as substituiu.

Nunca trate um trecho como "a posição do CFM" sem abrir a fonte: a ementa e o link vêm justamente para isso.

Args: tema: assunto a buscar, por exemplo "telemedicina" ou "inteligência artificial". apenas_vigentes: quando True, omite as resoluções já revogadas.

ParametersJSON Schema
NameRequiredDescriptionDefault
temaYes
apenas_vigentesNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
temaYes
avisoNo
totalYes
resultadosYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations, the description carries the burden of behavioral disclosure. It explains what is returned (fields, excerpt, source URL) and how revoked resolutions are marked, and it adds a caution about not treating excerpts as official CFM positions. It could be slightly more explicit about read-only/no side effects, but the 'Consulta' verb plus the output behavior are sufficient.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the purpose, then the return behavior, then a practical caution, then a compact Args block. Every sentence adds information; no filler or repetition.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a two-parameter search tool with an output schema, the description is complete: it tells the agent when to use it, what topic to provide, what the output includes, and how revocations are represented. Nothing critical is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, so the description must define both parameters. It does so clearly: 'tema' with concrete examples and 'apenas_vigentes' with its filtering behavior.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb and resource: consulting CFM resolutions by theme. It also defines the search scope and outputs, which clearly distinguishes it from the sibling monitorar_novas_resolucoes.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives clear context: it is the search tool for existing CFM resolutions on a topic, with examples of valid temas. It does not explicitly name the sibling as the alternative for monitoring new resolutions, so it misses an explicit when-not-to-use statement.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

monitorar_novas_resolucoesA

Resoluções do CFM publicadas nos últimos dias.

Args: dias: tamanho da janela, em dias, a contar de hoje. filtrar_tema: quando True, devolve só as que mencionam os temas configurados (IA, telemedicina, prontuário eletrônico, algoritmo).

ParametersJSON Schema
NameRequiredDescriptionDefault
diasNo
filtrar_temaNo

Output Schema

ParametersJSON Schema
NameRequiredDescription
diasYes
avisoNo
totalYes
resultadosYes

TDQS

A3.5/5.0
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

No annotations are provided, so the description carries full responsibility for behavioral disclosure. It does not mention whether the operation is read-only, any rate limits, pagination, or what happens if no results are found. While the tool is clearly a read operation, the description lacks explicit transparency about its behavior.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is exceptionally concise, with the purpose in a single sentence and parameter details in two bullet points. It is front-loaded with the core function, contains no fluff, and every sentence earns its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the tool's simplicity, two parameters are fully documented, and an output schema exists (not shown), so return values need not be explained. The description covers the tool's core behavior and filtering logic, though it omits edge cases like empty results or access requirements. It is nearly complete for a monitoring tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 0%, and the description fully compensates by explaining both parameters: 'dias' as the window size in days from today, and 'filtrar_tema' as a filter for configured themes (IA, telemedicina, prontuário eletrônico, algoritmo). This adds meaningful context beyond the bare schema types and defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool monitors CFM resolutions published in recent days, with a specific verb ('monitorar') and resource ('novas resoluções'). It distinguishes itself from the sibling tool by focusing on recent/new items rather than a specific query, though it does not explicitly name the sibling.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

No guidance is provided on when to use this tool versus the sibling consultar_resolucao_cfm. The description gives parameter details but no explicit context for selecting this tool over alternatives, leaving the agent to infer the distinction.

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.

  1. 2 tool updatesv0.1.0
    • First observedconsultar_resolucao_cfm
    • First observedmonitorar_novas_resolucoes

TDQS

A4/5.0

Scored across 2 tools

Disambiguation5/5

consultar_resolucao_cfm targets historical thematic search across CFM resolutions, while monitorar_novas_resolucoes targets recency-based detection of new publications. Their overlap is limited by the monitor's time window and preconfigured theme filter, so an agent can reliably choose based on temporal versus thematic intent.

Naming Consistency5/5

Both tool names follow the same verb_object pattern in snake_case: consultar_resolucao_cfm and monitorar_novas_resolucoes. The singular/plural difference is minor and does not create naming inconsistency.

Tool Count3/5

Two tools is on the thin side and below the typical well-scoped range, though each tool maps to a distinct action: searching and monitoring. The count is not excessive, but the server would feel more complete with a direct resolution lookup.

Completeness4/5

The read-only domain is covered at the core level: thematic consultation and monitoring of new resolutions both return metadata, validity status, and source URLs. The main gap is the lack of a fetch-by-number tool, but agents can usually work around it through the returned links or a topic search.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    C
    maintenance
    MCP server for querying Brazilian Federal Council of Medicine (CFM) registration data from official sources. It provides a read-only tool to consult medical registrations via natural language.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables querying health establishment data from the Brazilian Federal Council of Medicine (CFM), providing read-only access to official information.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables querying official Brazilian Federal Accounting Council records for accounting professionals and companies, providing read-only consultation through natural language.
    MIT