A API do PNCP ignora filtros em silêncio: o que aprendi montando um servidor MCP de licitações
Estou montando um servidor MCP sobre o PNCP (Portal Nacional de Contratações Públicas): licitações abertas, compras que um órgão publicou e contratos que ele assinou. O que mais me custou tempo não foi chamar a API. Foi descobrir o que ela faz quando você pede algo que ela não sabe fazer.
O problema
A API do PNCP aceita palavraChave e niFornecedor e ignora os dois, sem avisar. Você manda "notebook" e recebe as licitações de qualquer coisa. Manda o CNPJ de um fornecedor e recebe contratos de todo mundo.
Para uma pessoa, isso aparece na primeira tela. Para um agente de IA, não: ele lê "20 resultados" como "20 resultados do que eu pedi" e segue em frente. É o mesmo tipo de erro de devolver [] quando a fonte caiu: a resposta parece boa e está errada.
Medi isso em 04/10/2026. A API não documenta esse comportamento, então pode mudar.
Outras pegadinhas (medidas na mesma data)
- 204 sem corpo significa "nenhum registro", não erro. Quem trata só 200 e 4xx/5xx acaba chamando de falha o que é resposta vazia legítima.
- Rate limit sem aviso: depois de umas 15 chamadas em rajada, vem 429 em HTML (não JSON), sem informar o limite. Meu padrão ficou em 12 chamadas por minuto por instância.
- A modalidade é obrigatória em
/contratacoes/propostae em/contratacoes/publicacao. Para varrer várias, é uma chamada por modalidade. As modalidades vão de 1 a 13 (1 leilão eletrônico, 6 pregão eletrônico, etc.). tamanhoPaginatem teto diferente por endpoint: de 10 a 50 nas contratações e até 500 nos contratos. Uso 20.- Contratos exigem o CNPJ do órgão. Não há como perguntar "quais contratos este fornecedor tem?", porque o filtro por fornecedor é justamente o que a API ignora.
O que fiz
- O servidor diz o que não faz. A descrição de cada ferramenta lista o que ela NÃO cobre (busca por palavra no objeto, propostas encerradas, quem venceu). O agente lê isso antes de chamar.
- Status por fonte em toda resposta, com a regra de que lista vazia só existe quando o status é
ok. Se o PNCP deu 429, voltanullelimite_excedido, nunca[]. Detalhei essa parte no post anterior. - Fato, não opinião. Nada de score, nada de IA dentro do servidor. Cada resposta traz fonte e data da consulta.
LGPD
O endpoint de contratos traz CPF e nome de fornecedor pessoa física. O servidor descarta esses contratos e só os conta (omitidos_pessoa_fisica). CPF dentro do texto livre do objeto vira [CPF omitido]. Quando o fornecedor parece sociedade, a razão social sai; quando pode ser MEI ou empresário individual, o nome é omitido e o campo fornecedor_nome_omitido_lgpd avisa.
Onde está
- Servidor (plano gratuito de 100 chamadas/mês): https://mcpize.com/mcp/mcp-licitacoes-br
- Docs e exemplos: https://github.com/DouglasGouvea/mcp-licitacoes-br-docs
- Também no Smithery e no registro oficial de MCP.
Quem trabalha com compras públicas ou vende para o governo: o que falta para isso entrar na sua rotina? A limitação que mais me incomoda é não ter busca por palavra no objeto, e isso é limite do PNCP, não meu.