Skip to main content
Glama
fabianofilho

protocolos-pcdt-mcp

by fabianofilho

protocolos-pcdt-mcp

Servidor MCP que consulta os PCDTs (Protocolos Clínicos e Diretrizes Terapêuticas) do Ministério da Saúde/Conitec e resume a conduta recomendada para um contexto clínico específico, usando um LLM local. Toda resposta traz o link do PDF oficial.

⚠️ Não substitui o protocolo nem o julgamento clínico

  • Não é fonte oficial. O projeto lê o que a Conitec publica e guarda uma cópia local, que pode estar defasada em relação ao portal.

  • O resumo é gerado por LLM e é uma ajuda de leitura. Protocolos têm exceções, populações específicas e notas de rodapé que um resumo de seis linhas não carrega.

  • A citação literal é conferida, mas a interpretação não. Ver Limitações conhecidas — há um exemplo real de citação correta com conclusão clínica errada.

  • Sem validação clínica. Não foi avaliado por nenhum órgão e não é dispositivo médico.

  • Para conduta, leia o protocolo completo. O link vem em toda resposta.

Requisitos

O quê

Versão

Para quê

Python

3.12+

runtime

uv

recente

dependências e venv

Um LLM local com API OpenAI-compatible

resumo direcionado

Espaço em disco

~1 GB

base DuckDB + PDFs cacheados (protocolos são grandes)

Related MCP server: Manual RAG — SIH/SUS Query System

Instalação

git clone https://github.com/fabianofilho/protocolos-pcdt-mcp.git
cd protocolos-pcdt-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

DUCKDB_PATH

./data/pcdt.duckdb

base local

COLETA_DELAY_SEGUNDOS

1

intervalo entre downloads de PDF

SYNC_HORA_LOCAL

02:40

horário fixo da coleta agendada

uv run pcdt-cli llm                 # confirma o LLM local
uv run pcdt-cli sync --max-pdfs 5   # teste rápido
uv run pcdt-cli sync                # coleta (20 PDFs por execução, por padrão)
uv run pcdt-cli consultar asma
uv run pcdt-cli resumir "asma" "paciente gestante"

A coleta baixa no máximo --max-pdfs protocolos por execução: são ~130 PDFs grandes, e a ideia é a base completar ao longo de algumas noites em vez de sobrecarregar o portal numa única. O texto já coletado é preservado entre execuções.

Ligando ao Claude Code

claude mcp add protocolos-pcdt --scope user \
  -e DUCKDB_PATH=/caminho/para/protocolos-pcdt-mcp/data/pcdt.duckdb \
  -e QWEN_ENDPOINT=http://127.0.0.1:8080/v1 \
  -e QWEN_MODEL=local-model \
  -- uv --directory /caminho/para/protocolos-pcdt-mcp run protocolos-pcdt-mcp

Uso

consultar_protocolo(doenca_ou_condicao: str)

Busca pelo nome da condição; se não achar, procura no texto completo — uma condição pode ser tratada dentro do PCDT de outra. Devolve todos os protocolos relacionados.

{
  "termo": "acidentes ofídicos",
  "total": 1,
  "resultados": [
    {
      "identificador": "acidentes ofídicos",
      "condicao": "Acidentes Ofídicos",
      "status": "Conitec",
      "portaria": "Portaria SECTICS/MS nº 83 - 07/10/2025",
      "url_pdf": "https://www.gov.br/conitec/pt-br/midias/protocolos/pcdt_acidentes_ofidicos_final.pdf/@@display-file/file",
      "secoes_disponiveis": ["introducao", "classificacao", "diagnostico", "tratamento", "monitoramento"],
      "texto_completo_disponivel": true
    }
  ]
}

resumir_conduta(pcdt_id: str, contexto_clinico: str)

Extrai do protocolo a parte que responde ao contexto, em vez de devolver o documento inteiro.

{
  "condicao": "Acidentes Ofídicos",
  "resumo": {
    "resumo": "O paciente deve receber soroterapia antiveneno específica para o tipo de envenenamento.",
    "secao_origem": "1.3. Acesso a soroterapia antiveneno",
    "citacao_literal": "…é necessário utilizar a soroterapia antiveneno específica, correspondente ao tipo de envenenamento…",
    "citacao_confere": true,
    "fracao_citacao_verificada": 1.0
  },
  "url_pdf": "https://www.gov.br/conitec/..."
}

A citação é conferida, não só pedida

O prompt exige a citação literal do trecho que sustenta o resumo. Um modelo pequeno às vezes "cita" parafraseando — ou, pior, costura frases reais de partes diferentes do documento num único bloco de aspas. Então o código confere:

Campo

O que significa

citacao_confere

a citação existe inteira e contígua no protocolo

fracao_citacao_verificada

quanto dela existe, frase a frase (0 a 1)

Fração alta com citacao_confere: false é o caso mais traiçoeiro: parece legítimo na leitura e não é. Isso aconteceu no primeiro teste real deste projeto, com o PCDT de Acidentes Ofídicos, e é por isso que os dois campos existem.

Limitações conhecidas

Conferir a citação não pega erro de interpretação. Num teste com "paciente picado por cascavel", o modelo local devolveu uma citação real e contígua do protocolo e mesmo assim classificou o caso como envenenamento botrópico, quando cascavel é crotálico. A citação estava certa; o raciocínio em cima dela, errado. Esta é a limitação mais importante do projeto.

O protocolo é truncado antes de ir para o modelo. Protocolos passam de 200 mil caracteres; o recorte prioriza a vizinhança das palavras do contexto perguntado, mas pode cortar fora a parte relevante.

A segmentação por seções é heurística. A estrutura dos PCDTs varia entre protocolos antigos e novos. Quando os títulos não são reconhecíveis, secoes_disponiveis vem vazio e só o texto corrido fica disponível — de propósito, para não inventar estrutura.

A base começa quase vazia. Por causa do teto de PDFs por execução, os primeiros syncs trazem a listagem completa mas pouco texto. texto_completo_disponivel diz quais já têm.

PDFs digitalizados não têm camada de texto. Nesses casos o registro fica com extracao_incompleta: true e só os metadados.

As URLs das fontes podem mudar. Estão em coleta/listagem.py, confirmadas em 20/09/2026. Observação prática: os links .csv que o portal de dados abertos exibe estão desatualizados e devolvem 403; os que funcionam terminam em .zip.

Privacidade

  • Sai da máquina: requisições ao gov.br/conitec e ao bucket de dados abertos do Ministério da Saúde, para a listagem e os PDFs públicos.

  • Não sai: a condição e o contexto clínico que você consulta ficam entre a base local e o seu LLM local.

  • Sem telemetria, sem analytics.

Atenção: o contexto_clinico que você digita vai para o seu LLM. Se ele estiver hospedado fora da sua máquina, o texto vai junto — este projeto não impede isso, ao contrário do revisor-notas-mcp.

Contribuindo

Veja CONTRIBUTING.md. Não rode a coleta em loop contra o portal.

Licença e atribuição

Apache License 2.0 — escolhida por o projeto tocar em conduta clínica.

Construído no contexto do IA.med.

Available Tools

2 tools
consultar_protocoloA

Consulta o PCDT vigente do Ministério da Saúde para uma doença ou condição.

Devolve nome da condição, status, portaria, link do PDF completo e do PCDT resumido, e quais seções foram extraídas. Se houver mais de um protocolo relacionado, devolve todos — a escolha é de quem pergunta.

Args: doenca_ou_condicao: nome da doença ou condição, por exemplo "asma".

ParametersJSON Schema
NameRequiredDescriptionDefault
doenca_ou_condicaoYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
avisoNo
termoYes
totalYes
resultadosYes

TDQS

A3.7/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 and mostly delivers: it lists what is returned (nome, status, portaria, PDF links, extracted sections) and the multiplicity behavior (returns all protocols when several exist). It does not mention error cases, freshness guarantees, or auth/rate limits, but for a read-only lookup it is considerably more transparent than a generic 'updates settings' description.

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 compact: a purpose sentence, a return-behavior paragraph, and an Args block, all in Portuguese with no filler. The most informative content (returned fields and multi-protocol behavior) comes before the parameter details.

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?

For a one-parameter read-only tool with an output schema present, the description covers the query concept, the input semantics, the returns, and an edge case (multiple protocols). The main gap is the absence of any relationship to the sibling tool and of failure/ambiguity behavior, which keeps it slightly short of fully complete.

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

Parameters4/5

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

The schema only provides type and title, but the description adds a dedicated Args section defining doenca_ou_condicao as the disease or condition name and giving the concrete example 'asma'. This compensates for the 0% schema description coverage.

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 first sentence names the action ('Consulta') and the resource ('PCDT vigente do Ministério da Saúde') and specifies the target ('doença ou condição'). However, it never mentions the sibling resumir_conduta, so the agent isn't given an explicit way to tell them apart beyond the verb.

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?

The description gives no guidance on when to choose consultar_protocolo over resumir_conduta or any alternatives, and it states no exclusions or prerequisites. The only contextual clue is the behavior of returning multiple protocols with the choice left to the questioner, which is not an explicit usage rule.

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

resumir_condutaA

Resume a conduta de um PCDT para um contexto clínico específico.

Em vez de devolver o protocolo inteiro, extrai a parte que responde ao contexto — por exemplo "paciente com contraindicação a metformina". A resposta traz sempre a citação literal do trecho que sustenta o resumo, e diz se essa citação foi de fato encontrada no protocolo.

É ajuda de leitura, não substitui o protocolo: o link do PDF vem junto.

Args: pcdt_id: identificador devolvido por consultar_protocolo. contexto_clinico: a situação concreta sobre a qual se quer a conduta.

ParametersJSON Schema
NameRequiredDescriptionDefault
pcdt_idYes
contexto_clinicoYes

Output Schema

ParametersJSON Schema
NameRequiredDescription
avisoNo
resumoNo
url_pdfNo
condicaoYes
identificadorYes
contexto_clinicoYes

TDQS

A4.5/5.0
Behavior4/5

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

With no annotations provided, the description carries the burden. It discloses key behaviors: it always returns the literal citation, states whether the citation was found, includes the PDF link, and clarifies it is reading aid, not a substitute. This is substantial transparency for a read-only summarization tool.

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

Conciseness4/5

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

The description is well-structured with a clear purpose statement, an explanatory paragraph, and an Args list. It is slightly verbose but every sentence adds value, and the main purpose is front-loaded. The structure aids scanning.

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?

Given the tool's simplicity (2 params) and the presence of an output schema, the description covers all essential aspects: what it returns (citation, found flag, link), its limitation (not a substitute), and the workflow (uses id from sibling). Nothing an agent needs to call it correctly 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?

The schema provides zero description coverage, so the description must compensate. It does so effectively: pcdt_id is explained as 'identificador devolvido por consultar_protocolo', and contexto_clinico is defined with an example. This adds meaning beyond the schema's type-only definitions.

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 clearly states the tool's purpose: 'Resume a conduta de um PCDT para um contexto clínico específico' – a specific verb, resource, and scope. It distinguishes itself from the sibling by explicitly contrasting with returning the whole protocol ('Em vez de devolver o protocolo inteiro'), making the differentiation clear.

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 explains the intended use case: it extracts the part relevant to a specific clinical context, not the full protocol. It implies that pcdt_id should come from consultar_protocolo, giving a workflow hint. However, it does not explicitly state when not to use it or name the alternative tool directly, though the contrast is implicit.

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_protocolo
    • First observedresumir_conduta

TDQS

A3.9/5.0

Scored across 2 tools

Disambiguation5/5

The two tools serve clearly different functions: one searches and retrieves protocol information, the other summarizes clinical conduct based on a specific context. There is no overlap or ambiguity in their purposes.

Naming Consistency5/5

Both tool names follow the verb_noun pattern (consultar_protocolo, resumir_conduta) and are in Portuguese, consistent and predictable.

Tool Count3/5

With only 2 tools, the server feels thin, though the scope is narrow. It is bordering on inadequate but still minimally functional for its stated purpose of querying and summarizing PCDTs.

Completeness3/5

While the two tools cover querying and summarizing, there is no way to list all available protocols or discover them without knowing a specific disease. This is a notable gap for a medical reference server.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers