bcb-br-mcp 1.4.1 → 1.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -41,8 +41,15 @@ The answers come live from the Brazilian Central Bank's SGS API — exact figure
41
41
  - **Popular series catalog** - 150+ economic indicators organized in 12 categories
42
42
  - **Smart search** - Find series by keyword (accent-insensitive)
43
43
  - **Current indicators** - Latest values for key economic indicators
44
+ - **Long periods, handled** - The BCB API caps daily series at a 10-year window
45
+ (HTTP 406) and refuses open windows; requests are sliced, fetched and merged
46
+ automatically, so a 15-year daily query just works
47
+ - **Frequency harmonisation** - Resample a series to monthly, quarterly or annual
48
+ with an explicit convention, including geometric compounding for series that
49
+ already are percentage changes (monthly IPCA into annual IPCA)
44
50
  - **Variation calculation** - Percentage change between periods with statistics
45
- - **Series comparison** - Compare multiple series over the same period
51
+ - **Series comparison** - Compare multiple series over the same period, with a
52
+ warning when their periodicities differ
46
53
  - **Focus survey** - Market expectations (mean, median, std. deviation, min, max, respondents) for IPCA, GDP, FX and more, by monthly/quarterly/annual horizon or rolling 12/24-month inflation, plus Selic by Copom meeting
47
54
  - **PTAX exchange rates** - Official closing quotes for any currency the BCB publishes, single day or date range
48
55
 
@@ -50,9 +57,9 @@ The answers come live from the Brazilian Central Bank's SGS API — exact figure
50
57
 
51
58
  | Tool | Description |
52
59
  |------|-------------|
53
- | `bcb_serie_valores` | Query series values by code and date range |
54
- | `bcb_serie_ultimos` | Get the last N values of a series |
55
- | `bcb_serie_metadados` | Get series metadata (name, frequency, source) |
60
+ | `bcb_serie_valores` | Query series values by code and date range; slices long windows automatically and can harmonise the series to a coarser frequency |
61
+ | `bcb_serie_ultimos` | Get the last N values of a series (any N — the upstream cap of 20 is worked around) |
62
+ | `bcb_serie_metadados` | Get series metadata (name, frequency, category, last value) |
56
63
  | `bcb_series_populares` | List popular series grouped by category |
57
64
  | `bcb_buscar_serie` | Search series by name or description (accent-insensitive) |
58
65
  | `bcb_indicadores_atuais` | Latest values: Selic, IPCA, USD/BRL, IBC-Br |
@@ -334,9 +341,35 @@ The SGS database contains over 18,000 time series. To find codes for other serie
334
341
  ### Robustness
335
342
 
336
343
  - **Timeout**: 30 seconds per request (prevents hanging)
337
- - **Auto-retry**: 3 attempts with exponential backoff (1s, 2s, 4s)
344
+ - **Auto-retry**: 3 attempts with exponential backoff (1s, 2s, 4s) for transient
345
+ failures; client errors (4xx) are not retried, since they are deterministic
338
346
  - **Error handling**: Clear error messages
339
347
 
348
+ ### Working around the SGS limits
349
+
350
+ Measured against the live API, not inferred from documentation:
351
+
352
+ - A **date window over 10 years on a daily series** is refused with HTTP **406**,
353
+ and so is an open window (no `dataInicial`, or no dates at all). The limit
354
+ applies to the *implicit* window: with no `dataFinal` the API assumes today.
355
+ Requests are sliced into windows of up to **3 years**, fetched with bounded
356
+ concurrency and merged in date order without duplicating the seams; the response
357
+ reports it in `chunking`. The slice is 3 years rather than the allowed 10 because
358
+ a 10-year daily window costs 10–20 s upstream and may be cut off around 30 s.
359
+ - **`dados/ultimos/N` is capped at 20** by the API, in every periodicity. Above 20,
360
+ the server infers the series' periodicity and fetches by date window instead.
361
+ - **There is no per-series metadata endpoint** (`/metadados` answers 404). Frequency
362
+ is inferred from the spacing of the observations and flagged with
363
+ `periodicidadeInferida`; unit of measure is not available from any source.
364
+
365
+ ### Derived values
366
+
367
+ Anything this server computes — variation, descriptive statistics, harmonised
368
+ series — is marked `derived: true` and carries a note with the conventions used.
369
+ Statistics come from [`@sbissoli/mcp-stats`](https://www.npmjs.com/package/@sbissoli/mcp-stats).
370
+ A value published by the BCB is always returned verbatim; only computed values are
371
+ rounded (to 4 decimals).
372
+
340
373
  ### Smart Search
341
374
 
342
375
  `bcb_buscar_serie` searches two layers: the curated catalog of 150+ series (which ranks first, with reviewed
package/README.pt-BR.md CHANGED
@@ -38,16 +38,23 @@ As respostas vêm ao vivo da API SGS do Banco Central — valores exatos com pro
38
38
  - **Catálogo de séries populares** - Lista de 150+ indicadores econômicos organizados em 12 categorias
39
39
  - **Busca inteligente** - Encontra séries por termo de busca (com ou sem acentos)
40
40
  - **Indicadores atuais** - Valores mais recentes dos principais indicadores econômicos
41
+ - **Períodos longos resolvidos** - A API do BCB limita séries diárias a uma janela
42
+ de 10 anos (HTTP 406) e recusa janela aberta; a consulta é fatiada, buscada e
43
+ fundida automaticamente, então pedir 15 anos de série diária simplesmente funciona
44
+ - **Harmonização de frequências** - Reamostra a série para mensal, trimestral ou
45
+ anual com convenção explícita, inclusive composição geométrica para séries que já
46
+ são variação percentual (IPCA mensal virando IPCA anual)
41
47
  - **Cálculo de variação** - Variação percentual entre períodos com estatísticas
42
- - **Comparação de séries** - Compara múltiplas séries no mesmo período
48
+ - **Comparação de séries** - Compara múltiplas séries no mesmo período, com aviso
49
+ quando as periodicidades diferem
43
50
 
44
51
  ## Ferramentas Disponíveis
45
52
 
46
53
  | Ferramenta | Descrição |
47
54
  |------------|-----------|
48
- | `bcb_serie_valores` | Consulta valores de uma série por código e período |
49
- | `bcb_serie_ultimos` | Obtém os últimos N valores de uma série |
50
- | `bcb_serie_metadados` | Retorna informações/metadados de uma série |
55
+ | `bcb_serie_valores` | Consulta valores de uma série por código e período; fatia janelas longas automaticamente e pode harmonizar a série para uma frequência mais grossa |
56
+ | `bcb_serie_ultimos` | Obtém os últimos N valores de uma série (qualquer N — o teto de 20 da origem é contornado) |
57
+ | `bcb_serie_metadados` | Retorna nome, periodicidade, categoria e último valor de uma série |
51
58
  | `bcb_series_populares` | Lista séries populares agrupadas por categoria |
52
59
  | `bcb_buscar_serie` | Busca séries por nome ou descrição (aceita termos sem acento) |
53
60
  | `bcb_indicadores_atuais` | Valores mais recentes: Selic, IPCA, Dólar, IBC-Br |
@@ -319,9 +326,35 @@ O SGS possui mais de 18.000 séries temporais. Para encontrar o código de outra
319
326
  ### Robustez
320
327
 
321
328
  - **Timeout**: 30 segundos por requisição (evita travamentos)
322
- - **Retry automático**: 3 tentativas com backoff exponencial (1s, 2s, 4s)
329
+ - **Retry automático**: 3 tentativas com backoff exponencial (1s, 2s, 4s) em falha
330
+ transitória; erro de cliente (4xx) não é repetido, porque é determinístico
323
331
  - **Tratamento de erros**: Mensagens claras em português
324
332
 
333
+ ### Contornando os limites do SGS
334
+
335
+ Tudo abaixo foi **medido** contra a API ao vivo, não inferido da documentação:
336
+
337
+ - Uma **janela maior que 10 anos em série diária** é recusada com HTTP **406**, e
338
+ janela aberta (sem `dataInicial`, ou sem data nenhuma) também. O limite vale sobre
339
+ a janela *implícita*: sem `dataFinal`, a API assume hoje. A consulta é fatiada em
340
+ janelas de até **3 anos**, buscada com concorrência limitada e fundida em ordem de
341
+ data sem duplicar as emendas; a resposta informa isso em `chunking`. A fatia é de
342
+ 3 anos, e não dos 10 permitidos, porque uma janela diária decenal custa 10–20 s na
343
+ origem e pode ser cortada por volta de 30 s.
344
+ - **`dados/ultimos/N` tem teto de 20** na API, em qualquer periodicidade. Acima de
345
+ 20, o servidor infere a periodicidade da série e busca por janela de datas.
346
+ - **Não existe endpoint de metadados por série** (`/metadados` responde 404). A
347
+ periodicidade é inferida do espaçamento das observações e marcada com
348
+ `periodicidadeInferida`; unidade de medida não está disponível em fonte nenhuma.
349
+
350
+ ### Valores derivados
351
+
352
+ Todo número que este servidor calcula — variação, estatísticas descritivas, série
353
+ harmonizada — vem marcado com `derived: true` e uma nota com as convenções usadas.
354
+ A estatística é do [`@sbissoli/mcp-stats`](https://www.npmjs.com/package/@sbissoli/mcp-stats).
355
+ Valor publicado pelo BCB sai sempre verbatim; só o que é calculado é arredondado
356
+ (em 4 casas).
357
+
325
358
  ### Busca Inteligente
326
359
 
327
360
  A ferramenta `bcb_buscar_serie` normaliza os termos de busca, permitindo encontrar séries mesmo sem acentos:
@@ -0,0 +1,174 @@
1
+ /**
2
+ * Engenharia de série do SGS: periodicidade, janelas, chunking e harmonização.
3
+ *
4
+ * Este é o módulo do **D1**. Tudo aqui existe por um limite MEDIDO da origem em
5
+ * 11/08/2026 (`bcb/docs/04-limites-sgs-medidos.md`) — não por precaução:
6
+ *
7
+ * - **Janela de 10 anos, só em série diária, erro 406.** A fronteira é exata ao
8
+ * dia e o limite é inclusivo: 10 anos justos passam, 10 anos e 1 dia não. E
9
+ * vale sobre a janela IMPLÍCITA — sem `dataFinal` a origem assume hoje; sem
10
+ * `dataInicial`, o início da série (que quase sempre estoura os 10 anos).
11
+ * - **O 406 identifica a periodicidade** ("séries de periodicidade diária") e se
12
+ * mostrou estável nas oito medições em que apareceu. Por isso o chunking é
13
+ * REATIVO: quem diz que a série é diária é a origem, não um palpite nosso.
14
+ * - **Janela legal também precisa ser fatiada.** Dez anos de série diária
15
+ * custam 10–20 s (~4–8 ms por observação) e há corte por volta de 30 s que
16
+ * devolve HTML com 200. O worker tem timeout de 10 s: uma janela decenal que a
17
+ * origem ACEITA não completa no canal hospedado. A fatia é de 3 anos (~2,6 s),
18
+ * não de 10.
19
+ * - **Não há endpoint de metadados** (404 `endpoint not found!`), então a
20
+ * periodicidade de um código arbitrário se descobre pelo espaçamento das
21
+ * datas. `ultimos/20` custa 75–340 ms e serve de sonda.
22
+ *
23
+ * A harmonização de frequências vive aqui pelo mesmo motivo: reamostrar exige
24
+ * saber a periodicidade de origem, e é este módulo que a conhece.
25
+ */
26
+ import { type SerieValor } from "./shared.js";
27
+ export declare const BCB_SGS_BASE = "https://api.bcb.gov.br/dados/serie/bcdata.sgs";
28
+ /** Teto da origem para `dados/ultimos/N`, em TODA periodicidade (medido). */
29
+ export declare const TETO_ULTIMOS = 20;
30
+ /** Janela máxima que a origem aceita em série diária. */
31
+ export declare const JANELA_MAX_ANOS = 10;
32
+ /**
33
+ * Fatia do chunking. Não é o limite da origem (10) de propósito: a 3 anos a
34
+ * requisição custa ~2,6 s e cabe nos 10 s de timeout do worker; a 10 anos custa
35
+ * 10–20 s e não cabe.
36
+ */
37
+ export declare const FATIA_ANOS = 3;
38
+ /** Requisições simultâneas por série. O portal pede parcimônia (~≤5 req/s). */
39
+ export declare const CONCORRENCIA = 3;
40
+ export type Periodicidade = "diaria" | "semanal" | "mensal" | "trimestral" | "anual" | "irregular";
41
+ /** Rótulo em pt-BR para a resposta das tools (a superfície é pt-BR). */
42
+ export declare const ROTULO_PERIODICIDADE: Record<Periodicidade, string>;
43
+ /** `dd/MM/yyyy` (formato do SGS) para epoch UTC; `null` se não casar. */
44
+ export declare function parseDataSgs(data: string): number | null;
45
+ export declare function formatarDataSgs(epoch: number): string;
46
+ /**
47
+ * Periodicidade pelo espaçamento MEDIANO entre observações consecutivas.
48
+ *
49
+ * A mediana, e não a média: série diária tem buracos de feriado e fim de semana
50
+ * (espaçamentos de 1 a 4 dias, e às vezes mais), e um buraco grande arrastaria a
51
+ * média para a faixa da semanal. Com menos de 3 observações não há espaçamento
52
+ * suficiente para afirmar nada — devolve `null`, que quem chama traduz como
53
+ * "desconhecida" em vez de inventar.
54
+ */
55
+ export declare function inferirPeriodicidade(observacoes: Array<{
56
+ data: string;
57
+ }>): Periodicidade | null;
58
+ /**
59
+ * Sonda de periodicidade: `ultimos/20` e inferência pelo espaçamento.
60
+ *
61
+ * É o substituto do endpoint de metadados que não existe. Devolve `null` (em vez
62
+ * de propagar) quando a sonda falha: ela é uma otimização, e falhar nela não
63
+ * pode derrubar a consulta que o usuário pediu de verdade.
64
+ */
65
+ export declare function sondarPeriodicidade(codigo: number, timeoutMs?: number, maxRetries?: number): Promise<Periodicidade | null>;
66
+ export interface Janela {
67
+ /** `dd/MM/yyyy` */
68
+ inicio: string;
69
+ /** `dd/MM/yyyy` */
70
+ fim: string;
71
+ }
72
+ /**
73
+ * Fatia [inicio, fim] em janelas de no máximo `anos`, sem sobreposição.
74
+ *
75
+ * A origem trata a janela como fechada nas duas pontas, então a fatia seguinte
76
+ * começa no dia SEGUINTE ao fim da anterior — sem isso, cada emenda duplicaria
77
+ * uma observação. (A fusão remove duplicata de qualquer forma; isto evita pagar
78
+ * por ela.)
79
+ */
80
+ export declare function fatiarJanela(inicio: string, fim: string, anos?: number): Janela[];
81
+ export interface PedidoSerie {
82
+ codigo: number;
83
+ /** `dd/MM/yyyy` — já normalizado por quem chama. */
84
+ dataInicial?: string;
85
+ /** `dd/MM/yyyy` — já normalizado por quem chama. */
86
+ dataFinal?: string;
87
+ }
88
+ export interface JanelaAplicada {
89
+ dataInicial: string;
90
+ dataFinal: string;
91
+ motivo: string;
92
+ }
93
+ export interface ResultadoSerie {
94
+ observacoes: SerieValor[];
95
+ /** `null` quando não deu para inferir (menos de 3 observações). */
96
+ periodicidade: Periodicidade | null;
97
+ /** Presente só quando a consulta foi fatiada. */
98
+ chunking?: {
99
+ janelas: number;
100
+ fatiaAnos: number;
101
+ };
102
+ /** Presente só quando a janela pedida estava aberta e foi fechada por nós. */
103
+ janelaAplicada?: JanelaAplicada;
104
+ /** Requisições gastas à origem, contando a sonda. */
105
+ requisicoes: number;
106
+ }
107
+ /** `dd/MM/yyyy` de hoje — a origem usa este formato e o fuso do BCB é -03:00. */
108
+ export declare function hojeSgs(): string;
109
+ /**
110
+ * Busca uma série do SGS respeitando os limites da origem.
111
+ *
112
+ * Caminho normal (janela estreita ou série não-diária): UMA requisição, igual ao
113
+ * que o servidor sempre fez. O trabalho extra só acontece quando é preciso:
114
+ *
115
+ * 1. Janela mais larga que a fatia ⇒ sonda a periodicidade (80–340 ms). Se for
116
+ * diária, já sai fatiando: evita a requisição de 10–20 s que morreria no
117
+ * timeout do worker.
118
+ * 2. Consulta direta que volta **406** ⇒ a origem acabou de dizer que a série é
119
+ * diária e a janela é grande demais. Fatia e repete.
120
+ * 3. Janela aberta em série diária (sem `dataInicial`, ou sem data nenhuma) ⇒
121
+ * não há como fatiar o que não tem começo, e a origem recusa a janela
122
+ * implícita. Aplicamos a janela máxima que ela própria aceita — 10 anos até
123
+ * `dataFinal` (ou até hoje) — e devolvemos isso explícito em
124
+ * `janelaAplicada`, para a resposta poder dizer o que fez e por quê. Truncar
125
+ * em silêncio seria o pior dos mundos.
126
+ */
127
+ export declare function buscarSerieSgs(pedido: PedidoSerie, timeoutMs?: number, maxRetries?: number, concorrencia?: number): Promise<ResultadoSerie>;
128
+ /**
129
+ * Busca os N últimos valores, contornando o teto de 20 da origem.
130
+ *
131
+ * O `inputSchema` anuncia até 1000 desde sempre e a origem devolve **400** para
132
+ * qualquer N acima de 20, em qualquer periodicidade — ou seja, a promessa nunca
133
+ * foi cumprida. Em vez de reduzir o que o schema promete, cumprimos: a sonda dá
134
+ * a periodicidade, a periodicidade dimensiona a janela de datas, e a janela vem
135
+ * pelo caminho de `dados?dataInicial=...` (que não tem teto de linhas), fatiada
136
+ * se for preciso. Devolve as N últimas observações.
137
+ *
138
+ * A margem de 1,6× na janela existe porque feriado, recesso e mês sem publicação
139
+ * rarefazem a série: pedir exatamente o período nominal costuma voltar com menos
140
+ * pontos do que o usuário pediu.
141
+ */
142
+ export declare function buscarUltimosSgs(codigo: number, quantidade: number, timeoutMs?: number, maxRetries?: number): Promise<ResultadoSerie>;
143
+ export type FrequenciaAlvo = "mensal" | "trimestral" | "anual";
144
+ export type Agregacao = "ultimo" | "primeiro" | "media" | "soma" | "acumulada";
145
+ export declare const ROTULO_AGREGACAO: Record<Agregacao, string>;
146
+ export interface ObservacaoHarmonizada {
147
+ data: string;
148
+ valor: number;
149
+ /** Observações de origem que entraram neste ponto. */
150
+ observacoes: number;
151
+ }
152
+ export interface ResultadoHarmonizacao {
153
+ dados: ObservacaoHarmonizada[];
154
+ frequencia: FrequenciaAlvo;
155
+ agregacao: Agregacao;
156
+ nota: string;
157
+ }
158
+ /**
159
+ * Reamostra a série para uma frequência mais grossa.
160
+ *
161
+ * Só agrega para baixo: pedir diária a partir de mensal exigiria inventar
162
+ * observação, e este servidor não faz isso — devolve erro explícito.
163
+ *
164
+ * A escolha da agregação é do usuário porque **não existe padrão universal
165
+ * correto**: nível de preço e taxa pedem `ultimo`, fluxo pede `soma`, e série
166
+ * que JÁ É variação percentual (IPCA mensal, por exemplo) pede `acumulada` —
167
+ * somar 12 variações mensais não dá a inflação do ano, e a média dá menos ainda.
168
+ * Toda resposta harmonizada carrega a convenção usada e a marca de derivação.
169
+ */
170
+ export declare function harmonizar(observacoes: Array<{
171
+ data: string;
172
+ valor: number;
173
+ }>, alvo: FrequenciaAlvo, agregacao: Agregacao, origem: Periodicidade | null): ResultadoHarmonizacao;
174
+ //# sourceMappingURL=series.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"series.d.ts","sourceRoot":"","sources":["../src/series.ts"],"names":[],"mappings":"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"}