# MCP Compras.gov.br

> Preços, atas, contratos e sanções das APIs públicas de compras do governo brasileiro

- name: io.github.opedrosoares/mcp-compras
- version: 0.4.0
- connection class: R0 (autonomous)
- trust: 94/100
- quality: 79/100 (good)
- owner: not claimed
- descriptor: https://api.protogrid.dev/v1/servers/io.github.opedrosoares%2Fmcp-compras
- tools: https://api.protogrid.dev/v1/servers/io.github.opedrosoares%2Fmcp-compras/tools

**An agent can connect right now, no human step.** Remote endpoint, no authentication, reachable on the last probe.

## Connection (mcpServers)

```json
{
  "mcpServers": {
    "mcp-compras": {
      "type": "http",
      "url": "https://mcp-compras.up.railway.app/mcp"
    }
  }
}
```


## Trust

- hygiene: 100
- liveness: 100
- freshness: 85
- provenance: 90
- drivers: +repository +namespace-matches-repo +website +reachable +uptime-100% ~updated-41d-ago
- Derived from observable signals (official registry feed and our own credential-free probes); no code audit performed.

## Quality 79/100 (good)

### protocol: 75 (weight 25)

- warn `protocol.modern`: newest supported version is 2025-11-25; 2026-07-28 not supported, older versions are deprecated until 2027-07-28
- n/a `protocol.stateless`: only applies to 2026-07-28 servers
- pass `protocol.transport`: streamable HTTP
- n/a `protocol.list_ttl`: only applies to 2026-07-28 servers

### authorization: n/a (weight 15)

- n/a `auth.prm`, `auth.as_metadata`, `auth.cimd`: no remote uses OAuth
- n/a `auth.secret_in_url`: no templated URL

### tool hygiene: 79 (weight 30)

- pass `tools.descriptions`: every tool has a description
- warn `tools.description_length`: 8 tools have descriptions over 1,024 characters, which crowds the context
- pass `tools.schemas`: every tool has an object input schema
- pass `tools.annotations`: 100 of 100 tools declare readOnlyHint or destructiveHint
- pass `tools.directory_hints`: every tool declares readOnlyHint, destructiveHint, idempotentHint and openWorldHint
- fail `tools.token_cost`: about 29,887 tokens to load every tool, a large share of an agent's context
- pass `tools.api_dump`: tools are not a one-to-one API dump

### stability: 100 (weight 15)

- pass `stability.changes`: no tool changes in 30 days
- pass `stability.rug_pull`: no tool changed its meaning under the same name

### dependencies: 67 (weight 15)

- fail `deps.known_vulns`: 2 advisories to act on (malicious, or rated high or critical with a fix available): GHSA-rww4-4w9c-7733 in fastmcp@2.14.7 (direct, fixed in 3.2.0), GHSA-vv7q-7jx5-f767 in fastmcp@2.14.7 (direct, fixed in 3.2.0); 2 more of lower severity or without a fix
- pass `deps.mcp_sdk_version`: mcp 1.30.0, no known advisory
- pass `deps.resolvable`: compras-mcp@0.4.0 resolved: 81 packages

- tools: 100, about 29,887 tokens to load them all
- tool set hash: 1e165cd7a3f77e9e7be4bd41054179a8
- badge: [![protogrid quality](https://protogrid.dev/badge/io.github.opedrosoares/mcp-compras.svg)](https://protogrid.dev/servers/io.github.opedrosoares/mcp-compras)
- Checks run on what our credential-free, read-only probes observe; tools are never called and no code audit is performed.

### Tool changes

_No tool definition changes recorded._

## Dependencies

- pypi compras-mcp@0.4.0: resolved, 80 dependencies, MCP SDK mcp 1.30.0
  - GHSA-vv7q-7jx5-f767 (critical) in `` fastmcp@2.14.7 ``, direct, fixed in `` 3.2.0 ``, advisory summary: "FastMCP OpenAPI Provider has an SSRF & Path Traversal Vulnerability" https://osv.dev/vulnerability/GHSA-vv7q-7jx5-f767
  - GHSA-rww4-4w9c-7733 (high) in `` fastmcp@2.14.7 ``, direct, fixed in `` 3.2.0 ``, advisory summary: "FastMCP: Missing Consent Verification in OAuth Proxy Callback Facilitates Confused Deputy Vulnerabilities" https://osv.dev/vulnerability/GHSA-rww4-4w9c-7733
  - GHSA-m8x7-r2rg-vh5g (moderate) in `` fastmcp@2.14.7 ``, direct, fixed in `` 3.2.0 ``, advisory summary: "FastMCP has a Command Injection vulnerability - Gemini CLI" https://osv.dev/vulnerability/GHSA-m8x7-r2rg-vh5g
  - GHSA-w8v5-vhqr-4h9v (moderate) in `` diskcache@5.6.3 ``, indirect, no fix yet, advisory summary: "DiskCache has unsafe pickle deserialization" https://osv.dev/vulnerability/GHSA-w8v5-vhqr-4h9v

Dependency graphs from deps.dev; advisories from OSV.dev, including the GitHub Advisory Database and the PyPI Advisory Database; all CC BY 4.0.

## Remotes

- https://mcp-compras.up.railway.app/mcp (streamable-http, auth none, reachable true, uptime30d 1)

## Packages

- pypi compras-mcp@0.4.0 secrets: TRANSPARENCIA_API_KEY, REDIS_URL

## Tools (100)

- `compras_aggregate_contratacoes_por_periodo`: Série temporal de contratações no PNCP por bucket.

**Modo `count` (recomendado para tendência)**: 1 chamada por bucket
lendo apenas `totalRegistros`. Janelas grandes (até 5 anos) são viáveis.

**Modo `valor_*`**: varre todas as páginas de cada bucket para somar.
Mais lento; limita-se a `MAX_PAGES_PER_BUCKET=25` páginas (× 500 itens =
12.500 registros máx por bucket). Sinaliza `truncado=true` quando bate
o teto.

Concurrency interna: 4 calls simultâneas. Cache 30 min.
- `compras_arp_adesoes_item`: Lista adesões (caronas) já realizadas a uma ARP.

Endpoint Dados Abertos `/modulo-arp/5_consultarAdesoesItem`. Mostra
quem aderiu e com que quantidade — indica nível de demanda e quanto
ainda resta no limite legal de adesões.

Cache 15 min.
- `compras_arp_buscar_por_objeto`: Busca ARPs vigentes cujo `objeto` contém uma palavra-chave.

Resolve a limitação do endpoint `/modulo-arp/1.2_consultarARP_FimVigencia`,
que não aceita filtro por texto: pagina internamente até `max_paginas_varridas`
e filtra client-side por presença de `palavra_chave` (case-insensitive,
com normalização de acentos). Curto-circuita quando atinge `max_resultados`.

O servidor faz o trabalho que antes era pedido ao LLM — sem isso, o
roteiro `oportunidades_carona_arp` esbarrava em 169k ARPs vigentes e
339 páginas. Achado da bateria A v0.3.5.

**Limitação conhecida**: o schema upstream de ARP **não traz UF** no
item — só `nomeOrgao` e `nomeUnidadeGerenciadora`. Para filtrar por
UF, cruze os matches com `compras_uasg_consultar` usando
`codigoUnidadeGerenciadora` e compare `unidade.uf`. Não tentamos esse
cruzamento aqui para manter a tool barata e previsível.

Output:
    {
      "resultado": [<ARPs que casaram>],
      "total_examinadas": int,
      "matches": int,
      "paginas_varridas": int,
      "curto_circuitou": bool,
      "_filtro_objeto": {...}
    }

Cache 15 min por (palavra_chave + janela + caps).
- `compras_arp_consultar`: Consulta uma ARP específica pelo identificador PNCP.

Endpoint Dados Abertos `/modulo-arp/1.1_consultarARP_Id`. Devolve o
cabeçalho completo da ata (vigência, modalidade, gerenciadora, valores).

Quando o `numero_controle_pncp_ata` vem no formato de **compra** (sem
o sufixo `-NNNNNN` que numera a ata), a tool detecta e devolve
diagnóstico explícito em vez de propagar `encontrada=false` silencioso.

Cache 15 min.
- `compras_arp_itens_listar`: Lista itens de ARPs na janela de vigência informada.

Endpoint Dados Abertos `/modulo-arp/2_consultarARPItem`. O upstream
exige `dataVigenciaInicialMin/Max` (janela ≤365 dias). Use filtros
opcionais para localizar atas com um item específico.

Cache 15 min.
- `compras_arp_listar`: Lista Atas de Registro de Preço (ARPs) por janela de início de vigência.

Endpoint Dados Abertos `/modulo-arp/1_consultarARP`. O upstream exige
janela `dataVigenciaInicialMin/Max` (≤ 365 dias). Para listar atas
próximas do vencimento, use `compras_arp_por_fim_vigencia`.

Cache 15 min.
- `compras_arp_por_fim_vigencia`: Lista ARPs cuja vigência termina dentro do intervalo informado.

Endpoint Dados Abertos `/modulo-arp/1.2_consultarARP_FimVigencia`.
Permite ao gestor identificar atas próximas do vencimento.

Cache 15 min.
- `compras_arp_saldo_item`: Devolve o **saldo** (quantidade ainda disponível) por item da ARP.

Endpoint Dados Abertos `/modulo-arp/4_consultarEmpenhosSaldoItem`.
**Crítico para adesão**: a ata pode estar vigente mas com saldo
zerado. Sem saldo, não há como aderir.

**Estrutura do payload**: o upstream retorna **1 linha por
(numeroItem, unidade, tipo)** — onde `tipo` pode ser `GERENCIADORA`,
`PARTICIPANTE` etc. O mesmo `numeroItem` aparece várias vezes quando
há múltiplas unidades alocadas (carona ou rateio). **Não é
duplicação** — são alocações distintas dentro da mesma ata.

Para evitar confusão (achado bateria A v0.3.5), além do `resultado`
cru, anexamos `resumo_por_item`: dicionário agregando por
`numeroItem` com soma das quantidades registradas/empenhadas e
saldo total — pronto para decisão de adesão.

Cache 15 min (saldo muda ao longo do dia).
- `compras_arp_unidades_item`: Lista UGs participantes (potenciais caronas) de um item da ARP.

Endpoint Dados Abertos `/modulo-arp/3_consultarUnidadesItem`. Determina
quais unidades podem usar a ata como carona (adesão).
Cache 15 min.
- `compras_buscar_contratacoes_similares`: Federa Dados Abertos + PNCP buscando contratações similares.

Composição: consulta os **itens** de contratações 14.133 no Dados Abertos
(`/modulo-contratacoes/2_`, filtrando por `codItemCatalogo` e só itens com
resultado) + publicações PNCP do período, deduplica pelo número de controle
PNCP e devolve os `max_resultados` mais recentes. Insumo para mapear
benchmarks de outros órgãos.

O recorte por CATMAT/CATSER vale para a perna Dados Abertos. A perna PNCP é
best-effort por modalidade e não aceita filtro por item de catálogo — por
isso `amostra_dados_abertos` e `amostra_pncp` vêm separadas no payload.

**Atenção latência**: chama o PNCP em 3 modalidades (Pregão, Dispensa,
Concorrência) em paralelo. Cada chamada PNCP costuma levar 30-60s — o
tempo total da composta tende a 60-90s quando o cache está frio. Com
Redis configurado as chamadas seguintes voltam em <1s.
- `compras_catmat_buscar`: Busca itens CATMAT.

**⚠️ Não existe busca por substring nesta API.** O contrato do
`/modulo-material/4_consultarItemMaterial` oferece `descricaoItem`, que é
**match exato**: `descricaoItem='CADEIRA'` devolve zero registros, embora o
catálogo tenha milhares de itens começando por "CADEIRA ESCRITÓRIO...".
Não é um filtro degradado — é um filtro de igualdade, e o termo livre que o
usuário digita quase nunca casa com a descrição inteira do item.

Por isso o `termo` **não** é enviado ao upstream: mandá-lo faria a chamada
retornar o universo inteiro (~340 mil itens) sem nenhum aviso. Ele é usado
para ordenar e marcar os resultados do recorte estrutural, e a filtragem
real vem de `codigo_grupo`, `codigo_classe` e `codigo_pdm`.

**Workflow recomendado**:
1. `compras_catmat_listar_grupos()` → escolher o grupo (ex.: 71=Mobiliários).
2. `compras_catmat_listar_classes(codigo_grupo=71)` → a classe (ex.: 7110).
3. `compras_catmat_listar_pdms(codigo_classe=7110)` → o PDM do material.
4. `compras_catmat_buscar(termo='cadeira', codigo_pdm=...)`.

Esta tool emite `_aviso_filtro` no payload quando o recorte informado é
largo demais para ser útil.

Cache 24h por (termo + filtros + página).
- `compras_catmat_consultar`: Consulta detalhes de um item CATMAT específico pelo código.

Devolve nome do item, PDM, grupo, classe, características, NCM e
unidades de fornecimento. Útil para confirmar o código antes de
fazer pesquisa de preços ou listar contratações similares.

Cache de 24h.
- `compras_catmat_listar_classes`: Lista as classes do CATMAT, opcionalmente filtradas por grupo.

Classes são o segundo nível da hierarquia (ex.: dentro do grupo 71
Mobiliário, a classe 7110 é "Mobiliário de escritório").

Cache de 24h.
- `compras_catmat_listar_grupos`: Lista os grupos do CATMAT (Catálogo de Materiais).

Grupos são o nível mais alto da hierarquia CATMAT (ex.: 10=ARMAMENTO,
11=MATERIAIS BÉLICOS NUCLEARES). Use esta tool para enquadrar a
contratação no grupo correto antes de descer para classes/PDM/itens.

Cache de 24h: os grupos mudam muito raramente. Total atual ~79 grupos.
- `compras_catmat_listar_pdms`: Lista os PDMs (Padrão Descritivo de Material) do CATMAT.

Endpoint `/modulo-material/3_consultarPdmMaterial`. É o terceiro nível da
hierarquia do catálogo: grupo → classe → **PDM** → item.

O PDM é o que dá nome à família do material ("CADEIRA ESCRITÓRIO",
"MICROCOMPUTADOR"), enquanto o item é uma variação específica dela. Como a
API não faz busca por substring, descer até o PDM é a forma prática de
localizar o material certo antes de pedir os itens.

Uma classe devolve suas dezenas de PDMs nomeados em **uma** chamada — a
classe 7110 (Mobiliário de escritório) tem 98 PDMs. A alternativa seria
varrer milhares de itens e deduplicar `codigoPdm` client-side.

**Isto é navegação hierárquica, não busca**: o endpoint não tem filtro
textual. Combine com `compras_catmat_listar_grupos` e
`compras_catmat_listar_classes` para descer a hierarquia, e depois passe o
`codigo_pdm` para `compras_catmat_buscar`.

Cache 24h.
- `compras_catser_consultar`: Consulta detalhes de um item CATSER pelo código.

Devolve nome do serviço, descrição, seção/divisão/grupo/classe e
unidades de medida. Use para confirmar o código antes de pesquisar
preços ou contratações similares.

Cache de 24h.
- `compras_catser_listar_classes`: Lista as classes CATSER, opcionalmente filtradas por grupo.

Cache de 24h.
- `compras_catser_listar_secoes`: Lista as seções do CATSER (Catálogo de Serviços).

Seções são o nível mais alto da hierarquia CATSER (baseada no CPC ONU).
Use para enquadrar a contratação de serviços em uma seção antes de
descer para divisões/grupos/classes/itens.

Cache de 24h.
- `compras_checar_sancoes_fornecedor`: Consolida sanções de um fornecedor (CEIS + CNEP + CEPIM + leniência + impedimentos).

Composição: chama em paralelo as listas do Portal da Transparência e os
impedimentos do Comprasnet. Retorna um veredito booleano + lista
consolidada de sanções ativas.

Levanta `ComprasAuthError` se `TRANSPARENCIA_API_KEY` não estiver configurada.
Sempre use antes de homologar pregões/contratos. Cache 10 min.
- `compras_comparar_periodos_contratacoes`: Compara dois períodos lado a lado para a mesma modalidade.

Wrapper sobre `compras_aggregate_contratacoes_por_periodo` chamado duas
vezes (granularidade='ano' implícita — soma todo o período em 1 bucket).

Retorna totais de A e B + delta absoluto + delta percentual.

Caso de uso típico: _"Houve antecipação de licitações em Jun/2024 (ano
eleitoral) comparado a Jun/2025?"_ Ou _"As dispensas em Dez/2024 foram
maiores que Dez/2023 no mesmo órgão?"_.
- `compras_contratacoes_14133_consultar`: Consulta uma contratação 14.133 pelo identificador.

Endpoint `/modulo-contratacoes/1.1_consultarContratacoes_PNCP_14133_Id`.
Devolve detalhes completos: objeto, valor estimado, modalidade,
instrumento convocatório, status no PNCP.

Aceita os dois identificadores do PNCP. Use `tipo_identificador='idCompra'`
com o campo `idCompra` das listagens, ou `'numeroControlePNCPCompra'` com o
número de controle que aparece no edital (ex.: `10673078000120-1-000021/2025`).

Cache 15 min.
- `compras_contratacoes_14133_itens_listar`: Lista itens de contratações 14.133 incluídos no período.

Endpoint `/modulo-contratacoes/2_consultarItensContratacoes_PNCP_14133`.

**Uso principal — pesquisa de preço por item.** Com `cod_item_catalogo`
(CATMAT/CATSER) cada linha traz, junto, `quantidade`,
`valorUnitarioEstimado`, `valorUnitarioResultado`, `valorTotalResultado`,
`nomeFornecedor` e `unidadeMedida` — ou seja, estimado *versus* homologado
por item, insumo direto do mapa de preços do ETP.

**Higiene da amostra**: passe `tem_resultado=True` (ou `situacao_item='2'`,
Homologado) antes de calcular média ou mediana. Item deserto, fracassado ou
cancelado não é preço praticado.

Sem nenhum filtro além das datas, a resposta é "tudo que o Brasil incluiu no
PNCP nessa janela" — quase sempre grande demais para ser útil.

Cache 15 min.
- `compras_contratacoes_14133_itens_por_contratacao`: Lista itens de uma contratação 14.133 específica.

Endpoint `/modulo-contratacoes/2.1_consultarItensContratacoes_PNCP_14133_Id`.
Aceita `idCompra` ou número de controle PNCP, conforme `tipo_identificador`.
- `compras_contratacoes_14133_listar`: Lista contratações da Lei 14.133 publicadas no PNCP (via Dados Abertos).

Endpoint `/modulo-contratacoes/1_consultarContratacoes_PNCP_14133`.
Cobre pregões eletrônicos, dispensas, inexigibilidades e demais
modalidades da Nova Lei de Licitações no governo federal.

**Atenção semântica**: o filtro `codigo_modalidade_dados_abertos` usa a
tabela de modalidade do SIASG/Dados Abertos, NÃO o cheat sheet PNCP de
`compras_pncp_modalidades`. Os payloads retornam ambos os campos
(`codigoModalidade` do Dados Abertos e `modalidadeIdPncp` do PNCP) — use
`modalidadeNome` para o nome amigável.

Cache 15 min.
- `compras_contratacoes_14133_resultados_listar`: Lista resultados (homologações) de itens 14.133 no período.

Endpoint `/modulo-contratacoes/3_consultarResultadoItensContratacoes_PNCP_14133`.
Devolve fornecedor vencedor, valor adjudicado e quantitativo homologado —
fonte primária de preço praticado para o ETP.

**Due diligence de fornecedor**: `ni_fornecedor` (CNPJ/CPF) levanta tudo que
um fornecedor ganhou na janela.

**Auditoria por materialidade**: `valor_total_min` monta a fila de
homologações acima de um patamar — combine com uma janela curta, já que o
filtro de data é obrigatório.

Para recortar por item de catálogo, use
`compras_contratacoes_14133_itens_listar(cod_item_catalogo=...)`: esta rota
**não** oferece filtro por CATMAT/CATSER.

Cache 15 min.
- `compras_contratacoes_14133_resultados_por_contratacao`: Lista resultados (homologações) de uma contratação 14.133 específica.

Endpoint `/modulo-contratacoes/3.1_consultarResultadoItensContratacoes...`.
Aceita `idCompra` ou número de controle PNCP, conforme `tipo_identificador`.
- `compras_contrato_comprasnet_consultar`: Consulta detalhe completo de um contrato no Comprasnet (/api/contrato/id/{id}).

Devolve contrato com sub-recursos embutidos. CPFs mascarados por LGPD.
Cache 15 min.
- `compras_contrato_comprasnet_por_uasg`: Lista contratos de uma UASG no Comprasnet.

**Atenção**: o upstream `/api/contrato/ug/{uasg}` não suporta paginação —
devolve a lista completa em uma resposta única (pode passar de 1 MB). Esta
tool fatia o resultado client-side conforme `pagina + tamanho_pagina` para
evitar inundar o LLM.

Cache 15 min do payload completo; fatiamento por chamada é barato.
- `compras_contrato_cronograma`: Lista cronograma financeiro (/api/contrato/{id}/cronograma).

Paginação client-side — alguns contratos têm 200+ entradas mensais.
Cache 15 min.
- `compras_contrato_empenhos`: Lista empenhos do contrato (/api/contrato/{id}/empenhos).

Paginação client-side. Cache 15 min.
- `compras_contrato_faturas`: Lista NFs/faturas (/api/contrato/{id}/faturas).

Paginação client-side. Cache 15 min. **Atenção LGPD**: o campo
`infcomplementar` (texto livre) pode conter nome de servidor + matrícula
SIAPE não estruturados — o mascaramento LGPD só cobre CPFs em campos
nominais (cpf, niResponsavel, etc.).
- `compras_contrato_garantias`: Lista garantias contratuais (/api/contrato/{id}/garantias).

Paginação client-side. Cache 15 min.
- `compras_contrato_historico_aditivos`: Lista aditivos do contrato (/api/contrato/{id}/historico).

Paginação client-side (upstream não pagina). Cache 15 min do payload completo.
- `compras_contrato_ocorrencias`: Lista ocorrências/penalidades (/api/contrato/{id}/ocorrencias).

Indicador-chave da confiabilidade do fornecedor. Paginação client-side.
Cache 15 min.
- `compras_contrato_publicacoes`: Lista publicações DOU (/api/contrato/{id}/publicacoes).

Paginação client-side. Cache 15 min.
- `compras_contrato_responsaveis`: Lista fiscais/gestores (/api/contrato/{id}/responsaveis).

CPFs mascarados por LGPD (`123.***.***-45`). Paginação client-side. Cache 15 min.
- `compras_contratos_consultar`: Consulta um contrato no Dados Abertos (endpoint 1.1).

O upstream exige `codigo + tipo`. Tipos aceitos pela API:
`idCompra` e `numeroControlePncpContrato`.

Cache 15 min.
- `compras_contratos_item_consultar`: Lista os itens de um contrato específico, pelo identificador.

Endpoint `/modulo-contratos/2.1_consultarContratosItem_Id`.

Use quando você já tem o contrato em mãos e quer só os itens dele.
`compras_contratos_itens_listar` exige órgão mais janela de vigência e
devolve os itens de todos os contratos do recorte — chegar a um contrato
específico por ali significa paginar centenas de linhas irrelevantes.

O `codigo` aceita o `idCompra` numérico (padrão) ou o número de controle
PNCP do contrato, conforme `tipo_identificador`. Qualquer outro valor de
tipo faz o upstream devolver HTTP 500.

**Atenção ao somar valores**: pode haver mais de uma linha por item, uma
por versão/alteração contratual. Confira o campo de exclusão antes de
agregar.

Cache 15 min.
- `compras_contratos_itens_listar`: Lista itens de contratos (endpoint 2).

Upstream exige `codigoOrgao + dataVigenciaInicialMin/Max`. Cache 15 min.
- `compras_contratos_listar`: Lista contratos federais (Dados Abertos /modulo-contratos/1).

O upstream exige `codigoOrgao` + janela `dataVigenciaInicialMin/Max`
(≤ 365 dias). Para sub-recursos detalhados (garantias, faturas,
ocorrências), use `compras_contrato_*` que consulta o Comprasnet.

Cache 15 min.
- `compras_contratos_listar_por_fim_vigencia`: Lista contratos com vencimento na janela informada (endpoint 1.2).

Inventário do que precisa renovar. Upstream exige `codigoOrgao` +
`dataVigenciaFinalMin/Max` (≤ 365 dias). Cache 15 min.
- `compras_detalhar_preco_material`: Lista as compras individuais de um item CATMAT — **sem valor de preço**.

Endpoint: `/modulo-pesquisa-preco/2_consultarMaterialDetalhe`.

**⚠️ Esta tool não devolve preço.** Até a v0.3.12 a docstring prometia
"valor unitário homologado"; auditoria de 2026-08-05 mostrou que o DTO
upstream (`FtPesqPrecoCompraMaterialDetalheDTO`) tem exatamente 7 campos
e nenhum deles é valor:

    idCompra, idItemCompra, numeroItemCompra, codigoItemCatalogo,
    objetoCompra, descricaoDetalhadaItem, dataAtualizacaoFato

Confirmado nos dois sentidos: chamada crua ao upstream (fora da camada
do MCP) devolve as mesmas 7 chaves, e o contrato OpenAPI oficial
declara as mesmas 7. Ou seja: **não somos nós que filtramos** — o campo
nunca existiu nesta rota. A rota 4 (serviço detalhe) tem DTO idêntico.

**Para preço unitário de material use `compras_pesquisar_preco_material`**,
que devolve `precoUnitario`, `quantidade`, `dataCompra` e fornecedor por
compra — é a fonte correta para a amostragem da IN SEGES/ME 65/2021.

Use esta tool apenas para: descrição detalhada do item como comprado,
objeto da compra e rastreio do `idCompra` para cruzar com outras bases.

Cache 10 min.
- `compras_detalhar_preco_servico`: Lista as compras individuais de um serviço CATSER — **sem valor de preço**.

Endpoint: `/modulo-pesquisa-preco/4_consultarServicoDetalhe`.

**⚠️ Esta tool não devolve preço** (verificado 2026-08-05): o DTO
upstream é idêntico ao da rota 2 — idCompra, idItemCompra,
numeroItemCompra, codigoItemCatalogo, objetoCompra,
descricaoDetalhadaItem, dataAtualizacaoFato. Nenhum campo de valor.

**Para preço unitário de serviço use `compras_pesquisar_preco_servico`**,
que devolve `precoUnitario` e fornecedor por compra.

Cache 10 min.
- `compras_fornecedor_cnpj_receita`: Dados públicos do CNPJ na Receita Federal (via BrasilAPI/MinhaReceita).

Retorna razão social, nome fantasia, situação cadastral, CNAE primário e
secundários, QSA (sócios), capital social, natureza jurídica, porte,
endereço e datas de início de atividade e da situação cadastral.

**Quando usar**: complemento do `compras_perfil_fornecedor_completo`
para due diligence (avaliar porte, sócios, CNAEs vs objeto da licitação).
Os dados são da Receita; este MCP **não** consulta sanções aqui — para
isso use as tools de sanção (CEIS/CNEP/CEPIM/CEAF).

Cache 24h. Em caso de 404 ou erro upstream, retorna `encontrado=false`
com diagnóstico em `_erro` em vez de propagar exception.
- `compras_fornecedor_consultar`: Consulta cadastro de um fornecedor pelo CNPJ ou CPF.

Endpoint Dados Abertos `/modulo-fornecedor/1_consultarFornecedor`.
Devolve razão social, CNAE, porte da empresa, natureza jurídica.

Cache 1h.
- `compras_fornecedor_contratos_por_item`: Lista contratos e empenhos por itens (CATMAT/CATSER) no Comprasnet.

Endpoint `POST /api/comprasnet/contratosempenhos`. Útil para descobrir
quem fornece esses itens hoje no governo (potenciais participantes em
novos certames).

Cache 1h.
- `compras_fornecedor_impedimentos_por_itens`: Consulta impedimentos no Comprasnet por lista de itens (CATMAT/CATSER).

Endpoint `POST /api/comprasnet/compras/impedimentos`. Retorna fornecedores
impedidos de participar de contratações dos itens informados (sanções
aplicadas no SICAF). Essencial antes de homologar pregões eletrônicos.

Cache 1h.
- `compras_fornecedor_listar`: Lista fornecedores no Compras.gov.br com filtros estruturais.

Endpoint Dados Abertos `/modulo-fornecedor/1_consultarFornecedor`. Use
para mapear fornecedores potenciais por porte/CNAE — ex.: levantar
todas as MEs com CNAE de TI.

Cache 1h.
- `compras_healthcheck`: Diz, em ~30 segundos, o que está de pé neste servidor **agora**.

Estende `compras_versao`: além de versão e configuração, dispara um
probe paralelo (timeout curto) contra as rotas upstream reais e
devolve a situação por módulo funcional.

Por que existe: em 04/08/2026 a tool de pesquisa de preço de material
estava quebrada havia semanas e ninguém sabia — a SEGES trocou a
assinatura da rota sem versionar. A descoberta veio de um analista
tentando usar a ferramenta. Antes de uma demonstração ou de instruir
processo, rode isto: o objetivo é que a descoberta aconteça aqui, não
no palco.

Args:
    profundidade: `basico` responde só versão/config (instantâneo);
        `rotas` (padrão) executa o probe upstream.
    modulo: restringe o probe a um módulo (ex.: `pesquisa_preco`,
        `atas`, `pncp`). Sem isso, testa todos.

Situação por módulo:
    - `ok`: todas as rotas responderam com os campos esperados.
    - `degradado`: alguma rota caiu, ou respondeu 200 **sem** os campos
      do contrato (ex.: rota de preço sem `precoUnitario`) — o modo de
      falha silencioso que só o contrato de campos pega.
    - `fora`: todas as rotas testáveis do módulo falharam.
    - `pulado`: faltou credencial (ex.: TRANSPARENCIA_API_KEY).

Rota que estoura o relógio é reexecutada em série antes de virar
`fora`: com dezenas de rotas em paralelo, uma rota apenas lenta seria
reportada como quebrada. Quando passa na segunda tentativa, o campo
`problemas` do módulo registra "lenta sob carga" em vez de escondê-lo.

O campo `pronto_para_uso` é o resumo honesto: `False` quando existe
qualquer módulo fora ou degradado.
- `compras_indicadores_consolidados`: Métricas operacionais consolidadas da API Dados Abertos.

Endpoint `/modulo-indicadores/1_consultarIndicadoresConsolidados`.
Retorna: total de serviços disponíveis, total de requisições no
período, percentual de sucesso, latência média (ms), volume total
e médio de download (GB). Útil para diagnóstico/observabilidade,
**não** para indicadores de mercado público (ver docstring do módulo).

Cache 1h.
- `compras_indicadores_por_periodo`: Métricas operacionais da API por período (ano/mês).

Endpoint Dados Abertos `/modulo-indicadores/2_consultarIndicadoresPorPeriodo`.
Retorna métricas de USO da API (requisições, latência, downloads),
não dados de compras. Útil para análise temporal de disponibilidade
do upstream.

Cache 1h.
- `compras_legado_compras_sem_licitacao`: Lista compras sem licitação (dispensa/inexigibilidade) do regime legado.

Endpoint `/modulo-legado/5_consultarComprasSemLicitacao`. **Upstream
exige `dt_ano_aviso`** (ano inteiro, ex.: 2024) — não janela de datas.
- `compras_legado_itens_licitacao_listar`: Lista itens de licitações legado (`/modulo-legado/2_consultarItemLicitacao`).

Upstream exige `modalidade` obrigatório. Filtros opcionais: `uasg`,
`numero_aviso`, `codigo_item_material/servico`, `cnpj_fornecedor`.
- `compras_legado_itens_pregao_listar`: Lista itens de pregões do regime legado (Lei 8.666), com a cadeia de preço.

Endpoints `/modulo-legado/4_consultarItensPregoes` (por período de
homologação) e `/modulo-legado/4.1_consultarItensPregoes_Id` (quando
`id_compra` é informado).

**É a única fonte, em todo o MCP, da cadeia completa de formação de preço
por item**: `valor_estimado_item` → `menor_lance` → `valor_negociado` →
`valor_homologado_item`. Serve para medir o desconto real obtido em certame
e para instruir negociação.

Traz também `situacao_item`, que revela itens desertos e fracassados —
invisíveis para quem só olha preço homologado, e relevantes para justificar
revisão de estimativa.

Informe `id_compra` **ou** o par de datas de homologação. As duas datas
precisam ser diferentes entre si (restrição do upstream).

Série histórica: use para contratações anteriores à Lei 14.133. Para 2022 em
diante, prefira `compras_contratacoes_14133_itens_listar`.

Cache 15 min.
- `compras_legado_itens_sem_licitacao_listar`: Lista itens de contratações diretas do regime legado (dispensa/inexigibilidade).

Endpoints `/modulo-legado/6_consultarCompraItensSemLicitacao` (por ano do
aviso) e `/modulo-legado/6.1_consultarItensComprasSemLicitacao_Id` (quando
`id_compra` é informado).

**É o único caminho para contratação direta em nível de item no período
anterior ao PNCP (2019-2021)** — justamente a janela das dispensas
emergenciais da pandemia, para a qual as rotas da Lei 14.133 retornam vazio.
Traz `vr_estimado`, fornecedor vencedor e a descrição detalhada do item.

Informe `id_compra` **ou** `ano_aviso`.

CPF de fornecedor pessoa física vem mascarado por padrão (LGPD).

Cache 15 min.
- `compras_legado_licitacao_consultar`: Consulta uma licitação legado pelo id_compra.

Endpoint `/modulo-legado/1.1_consultarLicitacao_Id`. Upstream exige
`id_compra` (string), não um `id` numérico.
- `compras_legado_licitacoes_listar`: Lista licitações do regime legado (Lei 8.666/93).

Endpoint `/modulo-legado/1_consultarLicitacao`. **Bug upstream
confirmado**: o filtro `uasg`, embora documentado no swagger oficial,
retorna HTTP 400 ("Erro ao efetuar a consulta") porque o atributo não
existe no modelo Hibernate da view (`TbVwLicitacao`). Por isso este
parâmetro foi removido da assinatura.

Workaround se você precisar filtrar por UASG: liste sem filtro, depois
filtre client-side pelo campo `uasg` do resultado.
- `compras_legado_pregoes_listar`: Lista pregões eletrônicos do regime legado.

Endpoint `/modulo-legado/3_consultarPregoes`. **Bug upstream
confirmado**: os filtros `co_uasg` e `co_orgao`, embora documentados
no swagger, retornam HTTP 400 com erro Hibernate
`Could not resolve attribute 'TbVwPregaoId.coUasg'` porque os atributos
não existem no modelo da view. Por isso ambos foram removidos da
assinatura.

Workaround para filtrar por UASG: chame sem filtro e filtre client-side
pelos campos `coUasg`/`coOrgao` do resultado.
- `compras_legado_rdc_listar`: Lista contratações pelo RDC (Regime Diferenciado de Contratações).

Endpoint `/modulo-legado/7_consultarRdc`. **Upstream usa
`data_publicacao_min/max`** (note `min`/`max`, não `inicial`/`final`).
RDC foi usado principalmente para obras dos megaeventos e da Copa —
relevância residual hoje.
- `compras_listar_prompts`: Lista os MCP Prompts disponíveis com nome, descrição e argumentos.

Tools de descoberta para clientes (como o Claude.ai web) que ainda
não expõem UI para prompts. Em Claude Desktop / Cursor / MCP Inspector,
prompts aparecem em UI dedicada — esta tool é um caminho alternativo,
não substituto.

Use depois `compras_obter_prompt(nome, argumentos)` para renderizar
um prompt específico.

Retorno:
    {
      "total": int,
      "prompts": [
        {
          "nome": str,
          "descricao": str,
          "tags": [str, ...],
          "argumentos": [
            {"nome": str, "descricao": str | None, "obrigatorio": bool},
            ...
          ]
        },
        ...
      ]
    }
- `compras_listar_resources`: Lista os MCP Resources disponíveis com URI, nome e mime-type.

Tools de descoberta para clientes que não expõem UI de attachment de
resources (como o Claude.ai web). Em Claude Desktop / Cursor / MCP
Inspector, resources aparecem em picker dedicado.

Resources contêm dados de referência estáticos (tabelas de domínio,
glossário, metadados do servidor). Use `compras_obter_resource(uri)`
para ler o conteúdo.

Retorno:
    {
      "total": int,
      "resources": [
        {"uri": str, "nome": str, "descricao": str, "mime_type": str, "tags": [str,...]},
        ...
      ]
    }
- `compras_montar_dossie_arp`: Dossiê completo de uma ARP em uma chamada.

Composição: cabeçalho via `/modulo-arp/1.1` (id PNCP) e — se `numero_item`
informado — saldo (4), adesões (5) e unidades participantes (3) em
paralelo. Os 3 últimos endpoints usam a chave composta
`numeroAta + unidadeGerenciadora`.

Os 3 IDs vêm naturalmente do retorno de `compras_arp_listar` ou
`compras_arp_itens_listar` (campos: `numeroControlePncpAta`,
`numeroAta`, `unidadeGerenciadora`, `numeroItem`). Cache 10 min.

Quando `numero_controle_pncp_ata` vem no formato de **compra** (sem
sufixo `-NNNNNN`), devolvemos diagnóstico explícito antes de bater
no upstream — caminho que retornava `cabecalho: null` silencioso.
- `compras_obter_prompt`: Renderiza um MCP Prompt e devolve o texto pronto.

O texto retornado é o conteúdo da `PromptMessage[0]` — tipicamente um
roteiro que orienta o LLM a executar um fluxo usando as tools deste
servidor. Depois de obter o texto, o LLM normalmente segue as
instruções dele, chamando outras tools conforme indicado.

Retorno:
    {
      "nome": str,
      "texto": str,  # conteúdo renderizado pronto para usar
      "argumentos_usados": dict,
    }

Se o prompt não existir ou faltar argumento obrigatório, retorna
`_erro` com diagnóstico em vez de propagar exception.
- `compras_obter_resource`: Lê o conteúdo de um MCP Resource pela URI.

Retorna o conteúdo bruto (texto/JSON-string conforme o mime-type
registrado) e os metadados do resource.

Retorno:
    {
      "uri": str,
      "nome": str,
      "mime_type": str,
      "conteudo": str,
    }

Se a URI não existir, retorna `_erro` em vez de propagar exception.
- `compras_orgao_consultar`: Consulta um órgão específico pelo código.

Devolve nome, sigla, CNPJ, esfera, poder e quantitativos.
Cache 24h.
- `compras_orgao_listar`: Lista órgãos cadastrados no Compras.gov.br.

Endpoint Dados Abertos `/modulo-uasg/2_consultarOrgao`. Inclui órgãos
do SISG (Sistema de Serviços Gerais), com código numérico, nome,
esfera, poder e CNPJ.

**✅ Restaurada em 2026-08-05**: faltava o parâmetro obrigatório
`statusOrgao` — mesma causa do 404 em `compras_uasg_listar`.

**`nome`, `esfera` e `poder` são aplicados aqui, client-side.** Nenhum
dos três consta do contrato desta rota, e esta API ignora chave
desconhecida em silêncio — mandá-los devolvia os ~11,9 mil órgãos
ativos com cara de resultado filtrado (reconfirmado em 2026-09-07 com
parâmetro de controle). Desde 2026-09-07 eles não são mais enviados: o
recorte é feito sobre a página trazida, e o payload traz
`_filtro_client_side` dizendo quantos sobraram. Consequência prática:
o filtro só enxerga a página atual, então varra as páginas ou use
`codigo_orgao` em `compras_orgao_consultar` quando souber o código.

Cache 24h.
- `compras_perfil_fornecedor_completo`: Perfil consolidado do fornecedor (cadastro + Receita + sanções + impedimentos).

Composição em paralelo:
- **cadastro**: Dados Abertos `/modulo-fornecedor/1_consultarFornecedor`
  pelo CNPJ (razão social, CNAE, porte, natureza jurídica);
- **receita_federal**: BrasilAPI / MinhaReceita — QSA, capital social,
  atividades secundárias, data de início, situação cadastral (RF).
  Provider configurável via `CNPJ_PROVIDER` (default `brasilapi`);
- **sanções**: Portal da Transparência (CEIS+CNEP+CEPIM) pelo CNPJ;
- **impedimentos Comprasnet**: `/api/comprasnet/compras/impedimentos`.

**Não inclui lista de contratos** porque os endpoints upstream
`/modulo-contratos/1` (Dados Abertos) e `/v1/contratos` (PNCP) exigem
`codigoOrgao` como filtro obrigatório — não é possível listar contratos
de um fornecedor sem saber em qual órgão ele tem contrato. Se você já
souber o órgão, use `compras_contratos_listar(codigo_orgao=X, ni_fornecedor=Y, ...)`.

Sanções dependem de `TRANSPARENCIA_API_KEY` — se não configurada ou se
o WAF da CGU bloquear, o bloco retorna aviso e o restante segue.

Cache 10 min.
- `compras_pesquisar_preco_material`: Pesquisa preços praticados em compras de material (CATMAT) pelo governo.

Endpoint Dados Abertos: `/modulo-pesquisa-preco/1_consultarMaterial`.
Para visão consolidada estatística (média/mediana no padrão IN 65/2021),
use a tool composta `compras_pesquisar_precos_para_etp`.

Cada item da resposta traz `precoUnitario`, `quantidade`, `dataCompra`,
`niFornecedor`/`nomeFornecedor` e a UASG compradora — é **esta** a tool
que devolve valor unitário para material. A `compras_detalhar_preco_material`
NÃO devolve preço (ver a docstring dela).

**⚠️ Quebra upstream corrigida em 2026-08-05**: entre ~2026-07 e
2026-08-05 esta tool respondia "Recurso nao encontrado" (HTTP 404). A
SEGES trocou a assinatura de query da rota sem versionar: o parâmetro
`codigoItemCatalogo` foi substituído pelo par `tipo` (enum
`codigoItemCatalogo` | `codigoPdm`) + `codigo`. Como a API responde
**404** — e não 400 — a parâmetros obrigatórios ausentes, a quebra se
disfarçou de "rota removida". A rota nunca saiu do swagger oficial.
Corrigido na v0.3.13; a assinatura de `compras_pesquisar_preco_servico`
(rota 3) não mudou.

Se voltar a devolver 404, a tool não levanta exception: devolve
`_erro_upstream` com diagnóstico e alternativas.

Cache 10 min.
- `compras_pesquisar_preco_servico`: Pesquisa preços praticados em compras de serviço (CATSER).

Endpoint: `/modulo-pesquisa-preco/3_consultarServico`. Para visão
consolidada (mediana, média, desvio no padrão IN 65/2021), use a tool
composta `compras_pesquisar_precos_para_etp` com tipo='servico'.
- `compras_pesquisar_precos_para_etp`: Agrega preços praticados aplicando metodologia IN SEGES/ME 65/2021.

Composição: percorre `compras_pesquisar_preco_material` ou `_servico`
em até `max_paginas`, agrega os valores unitários e calcula:
mediana, média, desvio padrão, mínimo, máximo, quartis (Q1, Q3) e
descarte de outliers por IQR (1.5×IQR — Tukey).

Saída pronta para colagem em ETP: lista detalhada + sumário estatístico
+ amostra recomendada (sem outliers). Cache 10 min.
- `compras_pgc_agregacao`: Resumo agregado do PGC de um órgão num ano (totais por categoria).

Endpoint Dados Abertos `/modulo-pgc/3_consultarPgcAgregacao`. Retorna
contagens e valores totais por categoria/grupo, útil para diagnóstico
rápido do volume planejado pelo órgão.

Cache 1h.
- `compras_pgc_listar`: Lista itens de PGC (Plano de Gestão de Contratações) do governo federal.

Endpoint Dados Abertos `/modulo-pgc/1_consultarPgcDetalhe`. Cada linha
representa um item planejado: descrição, quantidade, valor unitário
estimado, mês previsto de início e categoria de item.

Cache 1h.
- `compras_pgc_listar_csv`: Versão CSV de `compras_pgc_listar` (mesmo dataset, formato planilha).

Endpoint `/modulo-pgc/1.1_consultarPgcDetalhe_CSV`. Útil para colar no
ETP ou planilhar localmente. Retorna o CSV no campo `csv` da resposta.
- `compras_pgc_por_catalogo`: Lista todos os PGCs que incluem determinado item de catálogo (CATMAT/CATSER).

Endpoint Dados Abertos `/modulo-pgc/2_consultarPgcDetalheCatalogo`.
Útil para responder: "Quais órgãos planejaram comprar esse item este ano?
Em que quantidade?". Insumo para ETP e benchmarking de quantitativos.

**Corrigida em 2026-09-07.** A tool mandava `tipo=M`/`tipo=S` e o enum
upstream é `[Material, Servico]` — **toda** chamada devolvia HTTP 500
("Failed to convert ... EnumPgcDetalheCatalogo ... for value [M]"). A
interface `M`/`S` foi mantida e a tradução passou a ser feita aqui.
Mesma classe de defeito do `tipo=C` das tools de contratações.

Cache 1h.
- `compras_pncp_ata_arquivos`: Lista os ARQUIVOS de uma Ata de Registro de Preços no PNCP (ata + aditivos).

Endpoint `/v1/orgaos/{cnpj}/compras/{anoCompra}/{sequencialCompra}/atas/{sequencialAta}/arquivos`
da API pública de arquivos do PNCP (`/api/pncp`, sem chave).

Aditivos de reequilíbrio/prorrogação aparecem como documentos adicionais
do tipo `Ata de Registro de Preços` — diferencie por `titulo` e
`dataPublicacaoPncp`. Download: GET simples na `url` de cada item.

Cache 15 min.
- `compras_pncp_atas_listar`: Lista atas registradas no PNCP no período (federal + estadual + municipal).

Endpoint PNCP `/v1/atas`. Permite encontrar atas de qualquer ente da
federação — mais amplo que Dados Abertos (só federal SISG).

Cache 15 min.
- `compras_pncp_contratacao_arquivos`: Lista os ARQUIVOS anexos de uma contratação no PNCP (Edital, TR, ETP...).

Endpoint `/v1/orgaos/{cnpj}/compras/{ano}/{sequencial}/arquivos` da API
pública de arquivos do PNCP (host `/api/pncp`, sem chave — diferente de
`/api/consulta`, que exige `chave-api-dadosabertos` e não expõe anexos).

Cada item traz `url` (download direto do PDF/ZIP), `sequencialDocumento`,
`titulo`, `tipoDocumentoNome` (Edital, Termo de Referência, Projeto
Básico, Estudo Técnico Preliminar...). Atenção: o arquivo do Edital vem
frequentemente como ZIP (por vezes ZIP dentro de ZIP) contendo o TR.
Baixe com GET simples na `url` — não é necessário navegador.

Cache 15 min.
- `compras_pncp_contratacao_item_resultados`: Lista resultados (vencedores) de um item específico de contratação no PNCP.

Endpoint `/v1/orgaos/{cnpj}/compras/{ano}/{sequencial}/itens/{n}/resultados`.
Cache 15 min.
- `compras_pncp_contratacao_itens`: Lista itens de uma contratação no PNCP.

Endpoint `/v1/orgaos/{cnpj}/compras/{ano}/{sequencial}/itens`.
Cache 15 min.
- `compras_pncp_contratacao_por_orgao`: Consulta uma contratação específica pelo CNPJ + ano + sequencial.

Endpoint `/v1/orgaos/{cnpj}/compras/{ano}/{sequencial}`. Devolve
cabeçalho completo da contratação.

Cache 15 min.
- `compras_pncp_contratacoes_atualizacao`: Lista contratações alteradas no período (PNCP).

Endpoint `/v1/contratacoes/atualizacao`. Útil para monitoramento:
descobrir editais que sofreram retificações/republicações. Aceita
filtro `esfera` client-side.

Cache 15 min.
- `compras_pncp_contratacoes_proposta`: Lista contratações com prazo de proposta aberto no PNCP.

Endpoint `/v1/contratacoes/proposta`. Útil para mapear oportunidades
abertas para fornecedores ou para identificar contratações em curso
em órgãos similares. Filtro `esfera` opcional client-side.

Cache 15 min.
- `compras_pncp_contratacoes_publicacao`: Lista contratações publicadas no PNCP no período.

Endpoint `/v1/contratacoes/publicacao`. Cobre todos os entes da
federação. Modalidades comuns: 6=Pregão Eletrônico, 8=Dispensa,
9=Inexigibilidade, 4=Concorrência Eletrônica.

O filtro `esfera` (federal/estadual/municipal/distrital) é aplicado
client-side sobre a página retornada. Janela máxima por consulta: ~30
dias. Cache 15 min.
- `compras_pncp_contrato_por_orgao`: Consulta um contrato específico no PNCP.

Endpoint `/v1/orgaos/{cnpj}/contratos/{ano}/{sequencial}`. Cache 15 min.
- `compras_pncp_contratos_listar`: Lista contratos publicados no PNCP no período.

Endpoint `/v1/contratos`. Cache 15 min.
- `compras_pncp_modalidades`: Cheat sheet local: códigos de modalidade de contratação do PNCP.

Tool local (não chama upstream). Fonte: tabela oficial PNCP (Lei 14.133).

**ATENÇÃO — duas tabelas em circulação no ecossistema Compras**:
- `codigo` aqui (PNCP) é o usado em TODAS as tools `compras_pncp_*` e
  em `modalidadeIdPncp` no payload de retorno.
- O Dados Abertos / SIASG usa uma enumeração diferente em
  `compras_contratacoes_14133_listar(codigo_modalidade_dados_abertos)`:
  campo `equivalente_dados_abertos` abaixo, ou None se a modalidade
  não estiver disponível naquele endpoint.
- `compras_pncp_orgao_unidades`: Lista unidades administrativas de um órgão no PNCP.

Endpoint PNCP `/v1/orgaos/{cnpj}/unidades`. Útil para descobrir códigos
de unidade antes de filtrar contratações/contratos do órgão.

Cobre estados e municípios (não só federal). Cache 24h.

**Tratamento de 404**: nem todo CNPJ está indexado no PNCP. Em vez de
levantar exception, esta tool retorna `_erro_upstream` informativo
com lista de alternativas (mesmo padrão das tools `compras_uasg_*` /
`compras_orgao_*` quando o `/modulo-uasg/*` retorna 404).
- `compras_pncp_pca_atualizacao`: Lista PCAs atualizados num período (PNCP).

Endpoint PNCP `/v1/pca/atualizacao`. Útil para monitoramento: descobrir
quais órgãos revisaram seu PCA recentemente.

Cache 1h.
- `compras_pncp_pca_listar`: Lista PCAs (Planos Anuais de Contratações) no PNCP.

Endpoint PNCP `/v1/pca/`. Diferente do PGC, o PCA da Lei 14.133 cobre
federais + estaduais + municipais. Filtra por categoria do item
(`codigo_classificacao_superior` é obrigatório no upstream).

Cache 1h.
- `compras_pncp_pca_por_classificacao_superior`: Lista itens de PCA filtrados por categoria superior do item.

Endpoint PNCP `/v1/pca/` com `codigoClassificacaoSuperior`. Permite
agregar planejamentos por categoria (ex.: todos os itens de TI
planejados para o ano).

Cache 1h.
- `compras_pncp_pca_por_usuario`: Lista PCAs vinculados a um usuário/sistema integrador específico.

Endpoint PNCP `/v1/pca/usuario`. Uso menos comum — geralmente o
analista prefere `compras_pncp_pca_listar` com `cnpj_orgao`.

Cache 1h.
- `compras_sancao_acordos_leniencia`: Lista acordos de leniência firmados com a CGU.

Endpoint `/api-de-dados/acordos-leniencia`. Empresas com acordo ativo
estão sob compromisso de compliance reforçado — informação útil para
análise de risco em contratações de alto valor.

Cache 1h.
- `compras_sancao_ceaf`: Consulta CEAF — Cadastro de Expulsões da Administração Federal.

Endpoint `/api-de-dados/ceaf`. Servidores expulsos do serviço público
federal. Útil quando se identifica responsável/preposto suspeito.

CPFs mascarados por LGPD (`123.***.***-45`). Cache 1h.
- `compras_sancao_ceis`: Consulta CEIS — Cadastro de Empresas Inidôneas e Suspensas.

Endpoint `/api-de-dados/ceis`. Empresas com sanção ativa não podem
contratar com a administração pública. Use **sempre** antes de
homologar pregões e contratos.

Cache 1h.
- `compras_sancao_cepim`: Consulta CEPIM — Entidades Privadas Sem Fins Lucrativos Impedidas.

Endpoint `/api-de-dados/cepim`. Aplicável a contratações via convênios
e termos de fomento com OSCs.

Cache 1h.
- `compras_sancao_cnep`: Consulta CNEP — Cadastro Nacional de Empresas Punidas (Lei Anticorrupção).

Endpoint `/api-de-dados/cnep`. Empresas punidas pela Lei 12.846/2013
(Lei Anticorrupção). Indicador de risco de integridade.

Cache 1h.
- `compras_uasg_buscar`: Busca UASGs por trecho do nome (match parcial, ignora acento e caixa).

**✅ Restaurada em 2026-08-05, com busca local.** Duas correções:

1. A rota exige `statusUasg`; sem ele devolvia 404 (mesma causa de
   `compras_uasg_listar`).
2. O parâmetro `nome` **não existe** no contrato da rota e era
   ignorado pelo upstream — enviá-lo devolvia o universo inteiro
   (~22 mil UASGs) como se fossem resultados de busca. Corrigir só o
   item 1 teria trocado um erro visível (404) por um erro silencioso,
   que é pior: o analista receberia "TCU - SECRETARIA DE INFORMATICA"
   como 1º resultado de qualquer termo.

Como não há filtro textual upstream, a busca é feita **localmente**:
a tool varre as páginas da rota (500 registros cada, ~8s no universo
completo), filtra por `termo` e pagina o resultado filtrado. O varrido
fica em cache por 24h, então só a primeira busca do dia paga o custo.

O payload informa `_busca_local`, `_paginas_varridas` e
`_universo_varrido` — se a varredura for truncada, isso fica explícito
em vez de virar silêncio.

Cache 24h.
- `compras_uasg_consultar`: Consulta uma UASG específica pelo código.

Devolve nome, sigla, CNPJ vinculado, órgão superior e endereço.
Útil para resolver `codigo_uasg` antes de consultas filtradas.

**✅ Restaurada em 2026-08-05** — ver `compras_uasg_listar` para o
diagnóstico do 404 que afetava toda a família `/modulo-uasg/*`.

Busca primeiro entre as ativas; se não achar, repete entre as inativas
(o upstream exige `statusUasg` e não aceita "ambas"), devolvendo
`ativa: false` para UASGs extintas.

Cache 24h.
- `compras_uasg_listar`: Lista UASGs (Unidades Administrativas de Serviços Gerais) do governo.

**✅ Restaurada em 2026-08-05.** Da v0.2.x até a v0.3.12 esta tool
devolvia "endpoint indisponível" e a documentação atribuía o 404 a um
bug de roteamento da SEGES. O diagnóstico estava errado: faltava o
parâmetro obrigatório `statusUasg`, e esta API responde **404** (não
400) quando um obrigatório não vem. Enviando o parâmetro, a rota
devolve 200 com ~22 mil UASGs ativas.

O filtro `ativo` alimenta `statusUasg`; quando não informado, a tool
assume `True` (ativas), que é o caso de uso dominante.

**Paginação**: o upstream ignora `tamanho_pagina` nesta rota e devolve
páginas fixas de 500 registros — `_total_paginas` reflete a paginação
real do servidor, não o tamanho pedido.

**`codigo_orgao` corrigido em 2026-09-07.** O filtro era enviado como
`codigoOrgao`, chave que esta rota não declara: a resposta vinha com as
22 mil UASGs do país, sem aviso, como se o órgão não tivesse recorte
nenhum. Agora a tool resolve o código para o CNPJ do órgão e filtra por
`cnpjCpfOrgao` — órgão 26246 (UFSC) devolve 3 UASGs. Custa uma chamada
extra a `/modulo-uasg/2_consultarOrgao`.

Duas ressalvas, ambas tratadas aqui: **CNPJ não identifica órgão** (599
dos 11.957 órgãos ativos compartilham CNPJ com outro — as 7 unidades do
CNPJ da Polícia Federal devolviam 110 UASGs, das quais só 8 do órgão
pedido), então o resultado é reduzido client-side pelo `codigoOrgao` de
cada UASG; e **39 órgãos não têm CNPJ próprio** (o upstream grava `"0"`),
caso em que a tool devolve lista vazia com `_aviso_filtro` em vez de um
recorte falso.

Cache 24h.
- `compras_versao`: Healthcheck/diagnóstico do MCP. Retorna versão, fontes upstream e
estado de configurações sensíveis (sem expor valores).

Útil para confirmar que o servidor está respondendo, qual a versão
instalada, quais APIs estão acessíveis e se a chave da Transparência
foi configurada (necessária para tools de sanções).
