list_contrato_termos
Retrieve additive terms of a contract including extensions, value adjustments, and term changes to understand its evolution.
Instructions
List the additive terms (termos aditivos) of a contract — extensions, value increases/reductions, term changes. Useful to understand contract evolution.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| numeroControlePNCP | No | ||
| orgaoCnpj | No | ||
| ano | No | ||
| sequencial | No |
Implementation Reference
- src/tools/list_contrato_termos.ts:6-37 (handler)ToolDef for list_contrato_termos: defines the MCP tool with input schema (numeroControlePNCP, orgaoCnpj, ano, sequencial) and handler that resolves the PNCP ID, calls the adapter, and returns the list of additive terms.
export const listContratoTermosTool: ToolDef = { definition: { name: 'list_contrato_termos', description: 'List the additive terms (termos aditivos) of a contract — extensions, value increases/reductions, term changes. Useful to understand contract evolution.', inputSchema: { type: 'object', properties: { numeroControlePNCP: { type: 'string' }, orgaoCnpj: { type: 'string' }, ano: { type: 'integer' }, sequencial: { type: 'integer' }, }, }, }, async handler(rawArgs) { const parse = PncpIdInputSchema.safeParse(rawArgs ?? {}); if (!parse.success) return errorResult(`Invalid arguments: ${parse.error.message}`); try { const { orgaoCnpj, ano, sequencial } = resolvePncpId(parse.data); const termos = await listContratoTermos(orgaoCnpj, ano, sequencial); return jsonResult({ meta: { orgaoCnpj, ano, sequencial, total: termos.length }, termos, }); } catch (err) { const msg = err instanceof PncpError ? err.message : String(err); return errorResult(`Failed to list termos: ${msg}`); } }, }; - src/adapters/pncp.ts:341-365 (handler)Core adapter function listContratoTermos: fetches additive terms from PNCP API endpoint /orgaos/{cnpj}/contratos/{ano}/{sequencial}/termos, validates with Zod schema, caches for 30 min TTL, returns empty array on 404.
export async function listContratoTermos( orgaoCnpj: string, ano: number, sequencial: number, ): Promise<TermoContrato[]> { const cacheKey = `list:termos:${orgaoCnpj}:${ano}:${sequencial}`; const cached = cache.get<TermoContrato[]>(cacheKey); if (cached) return cached; try { const { data } = await withRetry(() => pncpClient.get(`/orgaos/${orgaoCnpj}/contratos/${ano}/${sequencial}/termos`), ); const arr = asArray(data); const parsed = TermoContratoSchema.array().parse(arr); cache.set(cacheKey, parsed, TTL_30_MIN); return parsed; } catch (err) { if (err instanceof AxiosError) { if (err.response?.status === 404) return []; throw new PncpError(describeAxiosError(err), err); } throw err; } } - src/schemas/pncp.ts:206-225 (schema)Zod schema TermoContratoSchema defining the shape of each term (sequencialTermo, tipoTermoContratoNome, valorAcrescimo, valorReducao, prazoAcrescimoDias, novaDataVigenciaFim, etc.) and the inferred TermoContrato type.
export const TermoContratoSchema = z .object({ numeroControlePNCPContrato: z.string().nullable().optional(), sequencialTermo: z.number().nullable().optional(), tipoTermoContratoId: z.number().nullable().optional(), tipoTermoContratoNome: z.string().nullable().optional(), numeroTermoContrato: z.string().nullable().optional(), dataAssinatura: z.string().nullable().optional(), dataPublicacaoPncp: z.string().nullable().optional(), fundamentoLegal: z.string().nullable().optional(), informacaoComplementar: z.string().nullable().optional(), valorAcrescimo: z.number().nullable().optional(), valorReducao: z.number().nullable().optional(), prazoAcrescimoDias: z.number().nullable().optional(), prazoReducaoDias: z.number().nullable().optional(), novaDataVigenciaFim: z.string().nullable().optional(), }) .passthrough(); export type TermoContrato = z.infer<typeof TermoContratoSchema>; - src/tools/index.ts:9-49 (registration)Import and registration of listContratoTermosTool in the allTools array (line 31) and toolMap (line 49), making it available to the MCP server.
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]));