get_licitacao
Retrieve complete details of a Brazilian procurement bid (licitação) from PNCP using the control number or agency CNPJ, year, and sequential number.
Instructions
Get the full details of a single licitação (procurement bid) on PNCP. Provide either numeroControlePNCP (the full PNCP control number string) or all three of orgaoCnpj, ano, sequencial.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| numeroControlePNCP | No | PNCP control number, format like 00000000000000-1-000001/2024 | |
| orgaoCnpj | No | Procuring agency CNPJ (14 digits) | |
| ano | No | Year of the bid (e.g. 2024) | |
| sequencial | No | Sequential number of the bid |
Implementation Reference
- src/tools/get_licitacao.ts:27-41 (handler)The main handler function for the get_licitacao tool. Parses arguments using PncpIdInputSchema, resolves the PNCP ID (via numeroControlePNCP or orgaoCnpj/ano/sequencial), calls getContratacao to fetch the data from the PNCP API, and returns the result as JSON.
async handler(rawArgs) { const parse = ArgsSchema.safeParse(rawArgs ?? {}); if (!parse.success) { return errorResult(`Invalid arguments: ${parse.error.message}`); } try { const { orgaoCnpj, ano, sequencial } = resolvePncpId(parse.data); const data = await getContratacao(orgaoCnpj, ano, sequencial); return jsonResult(data); } catch (err) { const msg = err instanceof PncpError ? err.message : String(err); return errorResult(`Failed to get licitação: ${msg}`); } }, }; - src/utils/pncp_id.ts:36-50 (schema)PncpIdInputSchema: Zod schema defining the input for get_licitacao. Accepts either numeroControlePNCP (string) or all three of orgaoCnpj (string), ano (integer), and sequencial (integer). Validates that one group or the other is provided.
export const PncpIdInputSchema = z .object({ numeroControlePNCP: z.string().optional(), orgaoCnpj: z.string().optional(), ano: z.number().int().optional(), sequencial: z.number().int().optional(), }) .refine( (v) => Boolean(v.numeroControlePNCP) || (Boolean(v.orgaoCnpj) && Boolean(v.ano) && Boolean(v.sequencial)), { message: 'Provide either numeroControlePNCP, or all three of orgaoCnpj/ano/sequencial.', }, ); - src/schemas/pncp.ts:31-62 (schema)ContratacaoSchema: Zod schema defining the response shape for a licitação (procurement bid). Includes fields like numeroControlePNCP, anoCompra, sequencialCompra, orgaoEntidade, modalidadeNome, objetoCompra, valorTotalEstimado, valorTotalHomologado, dates, etc.
export const ContratacaoSchema = z .object({ numeroControlePNCP: z.string(), anoCompra: z.number(), sequencialCompra: z.number(), numeroCompra: z.string().nullable().optional(), processo: z.string().nullable().optional(), orgaoEntidade: orgaoEntidadeSchema.nullable().optional(), unidadeOrgao: unidadeOrgaoSchema.nullable().optional(), modalidadeId: z.number().nullable().optional(), modalidadeNome: z.string().nullable().optional(), modoDisputaId: z.number().nullable().optional(), modoDisputaNome: z.string().nullable().optional(), srp: z.boolean().nullable().optional(), objetoCompra: z.string().nullable().optional(), informacaoComplementar: z.string().nullable().optional(), valorTotalEstimado: z.number().nullable().optional(), valorTotalHomologado: z.number().nullable().optional(), situacaoCompraId: z.number().nullable().optional(), situacaoCompraNome: z.string().nullable().optional(), dataPublicacaoPncp: z.string().nullable().optional(), dataAberturaProposta: z.string().nullable().optional(), dataEncerramentoProposta: z.string().nullable().optional(), dataInclusao: z.string().nullable().optional(), dataAtualizacao: z.string().nullable().optional(), linkSistemaOrigem: z.string().nullable().optional(), linkProcessoEletronico: z.string().nullable().optional(), amparoLegal: amparoLegalSchema.nullable().optional(), tipoInstrumentoConvocatorioCodigo: z.number().nullable().optional(), tipoInstrumentoConvocatorioNome: z.string().nullable().optional(), }) .passthrough(); - src/tools/index.ts:3-49 (registration)Registration of getLicitacao in the allTools array (line 24) and construction of the toolMap (line 49) which maps tool name 'get_licitacao' to its ToolDef.
import { getLicitacao } from './get_licitacao.js'; import { listLicitacaoItens } from './list_licitacao_itens.js'; import { listLicitacaoResultados } from './list_licitacao_resultados.js'; import { listLicitacaoArquivos } from './list_licitacao_arquivos.js'; import { searchContratos } from './search_contratos.js'; import { getContratoTool } from './get_contrato.js'; import { listContratoTermosTool } from './list_contrato_termos.js'; import { listContratoInstrumentosTool } from './list_contrato_instrumentos.js'; import { searchAtasRp } from './search_atas_rp.js'; import { getAtaRp } from './get_ata_rp.js'; import { getOrgaoTool } from './get_orgao.js'; import { getFornecedorContratos } from './get_fornecedor_contratos.js'; import { searchPca } from './search_pca.js'; import { listPcaItensTool } from './list_pca_itens.js'; import { getCnpjDataTool } from './get_cnpj_data.js'; import { aggregateLicitacoes } from './aggregate_licitacoes.js'; import { comparePeriodos } from './compare_periodos.js'; export const allTools: ToolDef[] = [ // Compras / Licitações searchLicitacoes, getLicitacao, listLicitacaoItens, listLicitacaoResultados, listLicitacaoArquivos, // Contratos searchContratos, getContratoTool, listContratoTermosTool, listContratoInstrumentosTool, // Atas RP searchAtasRp, getAtaRp, // Órgãos / Fornecedores getOrgaoTool, getFornecedorContratos, // PCA searchPca, listPcaItensTool, // CNPJ enrichment getCnpjDataTool, // Análise agregada (v0.2.0) aggregateLicitacoes, comparePeriodos, ]; export const toolMap = new Map<string, ToolDef>(allTools.map((t) => [t.definition.name, t])); - src/adapters/pncp.ts:174-197 (helper)getContratacao: The downstream API call that fetches a single licitação from the PNCP consulta API endpoint. Includes caching (TTL_30_MIN) and error handling via PncpError.
export async function getContratacao( orgaoCnpj: string, ano: number, sequencial: number, ): Promise<Contratacao> { const cacheKey = `get:contratacao:${orgaoCnpj}:${ano}:${sequencial}`; const cached = cache.get<Contratacao>(cacheKey); if (cached) return cached; try { // PNCP moved this detail endpoint from /api/pncp/v1 to /api/consulta/v1 const { data } = await withRetry(() => consultaClient.get(`/orgaos/${orgaoCnpj}/compras/${ano}/${sequencial}`), ); const parsed = ContratacaoSchema.parse(data); cache.set(cacheKey, parsed, TTL_30_MIN); return parsed; } catch (err) { if (err instanceof AxiosError) { throw new PncpError(describeAxiosError(err), err); } throw err; } }