ibge_sidra_metadados
Retrieve metadata for IBGE SIDRA tables, including general info, territorial levels, variables, classifications, and periods. Use this tool to explore table structure before querying data.
Instructions
Returns metadata for a specific SIDRA table.
Features:
General info (name, survey, subject, periodicity)
Available territorial levels
Variable list with units
Classifications and categories
Available periods
Use this tool to understand table structure BEFORE querying data with ibge_sidra.
Examples:
Population table metadata: tabela="6579"
Census 2022 metadata: tabela="9514"
PNAD unemployment: tabela="4714"
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| tabela | Yes | Código da tabela/agregado SIDRA (ex: '6579', '9514', '4714') | |
| incluir_periodos | No | Incluir lista de períodos disponíveis (padrão: true) | |
| incluir_localidades | No | Incluir níveis territoriais disponíveis (padrão: false) |
Implementation Reference
- src/tools/sidra-metadados.ts:74-113 (handler)Main handler function that fetches and returns metadata for a SIDRA table. Calls the IBGE API for table metadata and periods, then formats the response. Wrapped with metrics instrumentation.
export async function ibgeSidraMetadados(input: SidraMetadadosInput): Promise<string> { return withMetrics("ibge_sidra_metadados", "agregados", async () => { try { // Fetch main metadata with cache (24 hours TTL - static data) const metadadosUrl = `${IBGE_API.AGREGADOS}/${input.tabela}/metadados`; const metadadosKey = cacheKey(metadadosUrl); let metadados: Metadados; try { metadados = await cachedFetch<Metadados>(metadadosUrl, metadadosKey, CACHE_TTL.STATIC); } catch (error) { if (error instanceof Error && error.message.includes("404")) { return `Tabela ${input.tabela} não encontrada. Use ibge_sidra_tabelas para listar tabelas disponíveis.`; } throw error; } // Fetch periods if requested with cache let periodos: Periodo[] = []; if (input.incluir_periodos) { try { const periodosUrl = `${IBGE_API.AGREGADOS}/${input.tabela}/periodos`; const periodosKey = cacheKey(periodosUrl); periodos = await cachedFetch<Periodo[]>(periodosUrl, periodosKey, CACHE_TTL.STATIC); } catch { // Ignore period fetch errors } } return formatMetadadosResponse(metadados, periodos, input); } catch (error) { if (error instanceof Error) { return parseHttpError(error, "ibge_sidra_metadados", { tabela: input.tabela }, [ "ibge_sidra_tabelas", ]); } return ValidationErrors.emptyResult("ibge_sidra_metadados"); } }); } - src/tools/sidra-metadados.ts:9-21 (schema)Zod schema for the tool input: tabela (required string), incluir_periodos (optional boolean, default true), incluir_localidades (optional boolean, default false).
export const sidraMetadadosSchema = z.object({ tabela: z.string().describe("Código da tabela/agregado SIDRA (ex: '6579', '9514', '4714')"), incluir_periodos: z .boolean() .optional() .default(true) .describe("Incluir lista de períodos disponíveis (padrão: true)"), incluir_localidades: z .boolean() .optional() .default(false) .describe("Incluir níveis territoriais disponíveis (padrão: false)"), }); - src/index.ts:285-308 (registration)Registration of the tool in the main MCP server using server.tool() with name 'ibge_sidra_metadados', description, schema, and handler.
// Register ibge_sidra_metadados tool server.tool( "ibge_sidra_metadados", `Returns metadata for a specific SIDRA table. Features: - General info (name, survey, subject, periodicity) - Available territorial levels - Variable list with units - Classifications and categories - Available periods Use this tool to understand table structure BEFORE querying data with ibge_sidra. Examples: - Population table metadata: tabela="6579" - Census 2022 metadata: tabela="9514" - PNAD unemployment: tabela="4714"`, sidraMetadadosSchema.shape, async (args) => { const result = await ibgeSidraMetadados(args); return { content: [{ type: "text", text: result }] }; } ); - src/tools/sidra-metadados.ts:263-285 (registration)Tool definition object (sidraMetadadosTool) containing the name, description, inputSchema, and handler reference for the tool.
// Tool definition for MCP export const sidraMetadadosTool = { name: "ibge_sidra_metadados", description: `Retorna os metadados de uma tabela SIDRA específica. Funcionalidades: - Informações gerais (nome, pesquisa, assunto, periodicidade) - Níveis territoriais disponíveis (Brasil, UF, município, etc.) - Lista de variáveis com unidades - Classificações e categorias de cada variável - Períodos disponíveis Use esta ferramenta para entender a estrutura de uma tabela ANTES de consultar os dados com ibge_sidra. Exemplos de uso: - Metadados da tabela de população: tabela="6579" - Metadados do Censo 2022: tabela="9514" - Metadados da PNAD (desocupação): tabela="4714" - Sem períodos: tabela="6579", incluir_periodos=false`, inputSchema: sidraMetadadosSchema, handler: ibgeSidraMetadados, }; - src/tools/sidra-metadados.ts:115-261 (helper)Helper function that formats the raw metadata and periods into a Markdown string for display. Handles general info, territorial levels, variables, classifications, and periods.
function formatMetadadosResponse( meta: Metadados, periodos: Periodo[], _input: SidraMetadadosInput ): string { let output = `## Metadados da Tabela ${meta.id}\n\n`; // Basic info output += `### Informações Gerais\n\n`; output += createKeyValueTable({ "**Código**": meta.id, "**Nome**": truncate(meta.nome, 80), "**Pesquisa**": meta.pesquisa, "**Assunto**": meta.assunto, "**Periodicidade**": meta.periodicidade.frequencia, "**Período**": `${meta.periodicidade.inicio} a ${meta.periodicidade.fim}`, "**URL**": meta.URL, }); output += "\n"; // Territorial levels output += `### Níveis Territoriais Disponíveis\n\n`; const niveis: { [key: string]: string } = { N1: "Brasil", N2: "Grande Região", N3: "Unidade da Federação", N6: "Município", N7: "Região Metropolitana", N8: "Mesorregião", N9: "Microrregião", N10: "Distrito", N11: "Subdistrito", N13: "Região Metropolitana e RIDE", N14: "Região Integrada de Desenvolvimento", N15: "Aglomeração Urbana", N17: "Região Geográfica Imediata", N18: "Região Geográfica Intermediária", N101: "País do Mercosul, Bolívia e Chile", N102: "Município do Mercosul, Bolívia e Chile", N103: "UF do Mercosul, Bolívia e Chile", N104: "Aglomerado Subnormal", N105: "Macrorregião de Saúde", N106: "Região de Saúde", N107: "Bacia Hidrográfica", N108: "Sub-bacia Hidrográfica", }; const allNiveis = [ ...(meta.nivelTerritorial.Administrativo || []), ...(meta.nivelTerritorial.Especial || []), ...(meta.nivelTerritorial.IBGE || []), ]; if (allNiveis.length > 0) { const rows = allNiveis.map((nivel) => [nivel, niveis[nivel] || nivel]); output += createMarkdownTable(["Código", "Nível"], rows, { alignment: ["left", "left"], }); output += "\n"; } else { output += "_Informação não disponível_\n\n"; } // Variables output += `### Variáveis\n\n`; if (meta.variaveis && meta.variaveis.length > 0) { const variaveisRows = meta.variaveis.map((v) => [ String(v.id), truncate(v.nome, 60), v.unidade || "-", ]); output += createMarkdownTable(["ID", "Nome", "Unidade"], variaveisRows, { alignment: ["right", "left", "left"], }); output += "\n"; // Classifications for each variable for (const v of meta.variaveis) { if (v.classificacoes && v.classificacoes.length > 0) { output += `#### Classificações da Variável ${v.id} (${truncate(v.nome, 40)})\n\n`; for (const c of v.classificacoes) { output += `**${c.id} - ${c.nome}:**\n`; if (c.categorias.length <= 20) { const catRows = c.categorias.map((cat) => [String(cat.id), truncate(cat.nome, 60)]); output += createMarkdownTable(["ID", "Categoria"], catRows, { alignment: ["right", "left"], }); } else { output += `_${c.categorias.length} categorias disponíveis. Primeiras 10:_\n`; const catRows = c.categorias .slice(0, 10) .map((cat) => [String(cat.id), truncate(cat.nome, 60)]); catRows.push(["...", `_e mais ${c.categorias.length - 10} categorias_`]); output += createMarkdownTable(["ID", "Categoria"], catRows, { alignment: ["right", "left"], }); } output += "\n"; } } } } else { output += "_Nenhuma variável encontrada_\n\n"; } // Periods if (periodos.length > 0) { output += `### Períodos Disponíveis\n\n`; // Show a summary if too many periods if (periodos.length > 20) { const first5 = periodos.slice(0, 5); const last5 = periodos.slice(-5); output += `_${periodos.length} períodos disponíveis:_\n\n`; output += "**Primeiros períodos:**\n"; for (const p of first5) { output += `- ${p.id}: ${p.literals.join(", ")}\n`; } output += "\n**Últimos períodos:**\n"; for (const p of last5) { output += `- ${p.id}: ${p.literals.join(", ")}\n`; } } else { for (const p of periodos) { output += `- ${p.id}: ${p.literals.join(", ")}\n`; } } output += "\n"; } // Usage hint output += `---\n\n`; output += `### Como usar esta tabela\n\n`; output += "```\n"; output += `ibge_sidra(\n`; output += ` tabela="${meta.id}",\n`; output += ` variaveis="allxp", // todas as variáveis\n`; output += ` nivel_territorial="1", // 1=Brasil, 3=UF, 6=Município\n`; output += ` localidades="all", // todas do nível\n`; output += ` periodos="last" // último período\n`; output += `)\n`; output += "```\n"; return output; }