bcb-br-mcp 1.3.5 → 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.
Files changed (47) hide show
  1. package/README.md +98 -9
  2. package/README.pt-BR.md +38 -5
  3. package/dist/cambio.d.ts +72 -0
  4. package/dist/cambio.d.ts.map +1 -0
  5. package/dist/cambio.js +284 -0
  6. package/dist/cambio.js.map +1 -0
  7. package/dist/catalog.d.ts +107 -0
  8. package/dist/catalog.d.ts.map +1 -0
  9. package/dist/catalog.js +206 -0
  10. package/dist/catalog.js.map +1 -0
  11. package/dist/focus.d.ts +134 -0
  12. package/dist/focus.d.ts.map +1 -0
  13. package/dist/focus.js +683 -0
  14. package/dist/focus.js.map +1 -0
  15. package/dist/index.d.ts +6 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +12 -346
  18. package/dist/index.js.map +1 -1
  19. package/dist/olinda.d.ts +59 -0
  20. package/dist/olinda.d.ts.map +1 -0
  21. package/dist/olinda.js +98 -0
  22. package/dist/olinda.js.map +1 -0
  23. package/dist/register.d.ts +61 -0
  24. package/dist/register.d.ts.map +1 -0
  25. package/dist/register.js +116 -0
  26. package/dist/register.js.map +1 -0
  27. package/dist/series.d.ts +174 -0
  28. package/dist/series.d.ts.map +1 -0
  29. package/dist/series.js +413 -0
  30. package/dist/series.js.map +1 -0
  31. package/dist/shared.d.ts +102 -0
  32. package/dist/shared.d.ts.map +1 -0
  33. package/dist/shared.js +183 -0
  34. package/dist/shared.js.map +1 -0
  35. package/dist/stats.d.ts +63 -0
  36. package/dist/stats.d.ts.map +1 -0
  37. package/dist/stats.js +66 -0
  38. package/dist/stats.js.map +1 -0
  39. package/dist/tools.d.ts +10436 -334
  40. package/dist/tools.d.ts.map +1 -1
  41. package/dist/tools.js +574 -286
  42. package/dist/tools.js.map +1 -1
  43. package/package.json +13 -11
  44. package/dist/worker.d.ts +0 -20
  45. package/dist/worker.d.ts.map +0 -1
  46. package/dist/worker.js +0 -240
  47. package/dist/worker.js.map +0 -1
package/README.md CHANGED
@@ -18,7 +18,7 @@ Query economic and financial indicators such as **Selic** (interest rate), **IPC
18
18
 
19
19
  > If you find this project useful, please consider giving it a [star on GitHub](https://github.com/SidneyBissoli/bcb-br-mcp). It helps others discover the project!
20
20
 
21
- **Capabilities:** 8 tools (skills) · 3 resources · 3 prompts — everything an MCP client needs to query the Brazilian Central Bank (SGS/BCB) time-series API.
21
+ **Capabilities:** 13 tools (skills) · 3 resources · 3 prompts — everything an MCP client needs to query the Brazilian Central Bank: SGS/BCB time series, the **Focus** market-expectations survey and **PTAX** exchange rates.
22
22
 
23
23
  ## See it in action
24
24
 
@@ -27,6 +27,9 @@ Ask your assistant, in plain Portuguese:
27
27
  - *"Qual a taxa Selic atual?"* → `bcb_indicadores_atuais`
28
28
  - *"Mostre o IPCA mês a mês em 2024."* → `bcb_serie_valores`
29
29
  - *"Qual foi a variação do dólar nos últimos 12 meses?"* → `bcb_variacao`
30
+ - *"O que o mercado espera do IPCA em 2027?"* → `bcb_focus_expectativas`
31
+ - *"Qual a Selic esperada na próxima reunião do Copom?"* → `bcb_focus_selic`
32
+ - *"Qual foi a PTAX de fechamento do euro na sexta?"* → `bcb_cambio_cotacao`
30
33
 
31
34
  The answers come live from the Brazilian Central Bank's SGS API — exact figures with provenance, not numbers guessed from training data.
32
35
 
@@ -38,21 +41,35 @@ The answers come live from the Brazilian Central Bank's SGS API — exact figure
38
41
  - **Popular series catalog** - 150+ economic indicators organized in 12 categories
39
42
  - **Smart search** - Find series by keyword (accent-insensitive)
40
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)
41
50
  - **Variation calculation** - Percentage change between periods with statistics
42
- - **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
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
54
+ - **PTAX exchange rates** - Official closing quotes for any currency the BCB publishes, single day or date range
43
55
 
44
56
  ## Available Tools
45
57
 
46
58
  | Tool | Description |
47
59
  |------|-------------|
48
- | `bcb_serie_valores` | Query series values by code and date range |
49
- | `bcb_serie_ultimos` | Get the last N values of a series |
50
- | `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) |
51
63
  | `bcb_series_populares` | List popular series grouped by category |
52
64
  | `bcb_buscar_serie` | Search series by name or description (accent-insensitive) |
53
65
  | `bcb_indicadores_atuais` | Latest values: Selic, IPCA, USD/BRL, IBC-Br |
54
66
  | `bcb_variacao` | Calculate percentage variation between dates or last N periods |
55
67
  | `bcb_comparar` | Compare 2 to 5 series over the same period with ranking |
68
+ | `bcb_focus_expectativas` | Focus survey expectations for one indicator, horizon as a parameter (monthly, quarterly, annual, rolling 12m/24m inflation); `top5` flag |
69
+ | `bcb_focus_selic` | Focus expectations for the Selic rate, by Copom meeting (R1/2026 form) |
70
+ | `bcb_focus_referencias` | Which indicators and reference dates the Focus survey actually publishes, **broken down per scope** (the five horizons plus `selic`, whose axis is the Copom meeting) — the indicator set differs by scope (9 monthly vs 26 annual) |
71
+ | `bcb_cambio_cotacao` | PTAX quote for a currency (USD by default), single day or date range |
72
+ | `bcb_cambio_moedas` | Currencies with quotes published by the BCB |
56
73
 
57
74
  ## Resources
58
75
 
@@ -85,9 +102,14 @@ Visit [bcb-br-mcp on Smithery](https://smithery.ai/servers/sidneybissoli/bcb-br-
85
102
  Use the HTTP endpoint directly, no installation required:
86
103
 
87
104
  ```
88
- https://bcb.sidneybissoli.workers.dev
105
+ https://bcb.sidneybissoli.com/mcp
89
106
  ```
90
107
 
108
+ The legacy hostname `https://bcb.sidneybissoli.workers.dev` keeps working, and so
109
+ does the older `POST /` route — clients configured before the endpoint moved to
110
+ `/mcp` are rewritten transparently, so nothing that used to work stopped working.
111
+ New setups should use the URL above.
112
+
91
113
  ### Via npx (Claude Desktop)
92
114
 
93
115
  Add to your Claude Desktop configuration file:
@@ -319,16 +341,57 @@ The SGS database contains over 18,000 time series. To find codes for other serie
319
341
  ### Robustness
320
342
 
321
343
  - **Timeout**: 30 seconds per request (prevents hanging)
322
- - **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
323
346
  - **Error handling**: Clear error messages
324
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
+
325
373
  ### Smart Search
326
374
 
327
- The `bcb_buscar_serie` tool normalizes search terms, allowing you to find series even without Portuguese accents:
375
+ `bcb_buscar_serie` searches two layers: the curated catalog of 150+ series (which ranks first, with reviewed
376
+ names) and the index of the BCB Open Data Portal, with thousands of series identified by code. Terms are
377
+ accent- and case-insensitive, and several terms are combined with AND:
328
378
 
329
379
  - `"inflacao"` → finds "Inflação"
330
380
  - `"cambio"` → finds "Câmbio"
331
- - `"credito"` → finds "Crédito"
381
+ - `"ipca servicos"` → both terms must match
382
+
383
+ The portal index is served from a 24-hour cache, renewed by the first search after it expires (one request to
384
+ the portal, only metadata — series codes and names, never observations). Every answer carries
385
+ `catalogo.cobertura`: the index is **not** the whole SGS, so not finding a series here is not proof it does not
386
+ exist.
387
+
388
+ ### Data source and licence
389
+
390
+ Data obtained from the Banco Central do Brasil (SGS / Olinda-Expectativas / PTAX), published under the
391
+ **Open Data Commons Open Database License (ODbL) v1.0** — https://opendatacommons.org/licenses/odbl/.
392
+ Exchange-rate answers pass through the BCB's own liability disclaimer verbatim; cross-currency parities are
393
+ **not** compiled by the BCB — they come from an information agency (Refinitiv) and are redistributed by the
394
+ BCB, and the tools say so.
332
395
 
333
396
  ## Development
334
397
 
@@ -379,6 +442,32 @@ This server uses the Brazilian Central Bank's public API:
379
442
 
380
443
  ## Changelog
381
444
 
445
+ ### v1.4.1
446
+
447
+ - `bcb_focus_referencias`: the parameter is now `escopo`, not `horizonte`, and the
448
+ response array is `escopos`. The scopes are the five horizons of
449
+ `bcb_focus_expectativas` **plus `selic`** — and `selic` is not a horizon: its
450
+ axis is the Copom meeting. Each block names the `tool` that consumes it. The
451
+ previous name implied `selic` was a queryable horizon of
452
+ `bcb_focus_expectativas`, which it is not. Never published to npm under the old
453
+ name.
454
+
455
+ ### v1.4.0
456
+
457
+ - **Three APIs under one contract, 8 tools → 13.** Focus market-expectations
458
+ survey (`bcb_focus_expectativas`, `bcb_focus_selic`, `bcb_focus_referencias`)
459
+ and PTAX exchange rates (`bcb_cambio_cotacao`, `bcb_cambio_moedas`), consolidated
460
+ by parameter rather than mirroring the source's ~18 OData resources.
461
+ - **Real search.** `bcb_buscar_serie` now queries the Open Data Portal index
462
+ (3,500+ series, 24-hour cache, metadata only) on top of the curated catalog, and
463
+ states the index's coverage instead of claiming a series does not exist.
464
+ - Every Focus and PTAX field name verified against the live API, including the
465
+ Top 5 Selic resource, which publishes its fields in a different case from the
466
+ other twelve.
467
+ - ODbL obligations shipped with the exchange-rate tools: the BCB disclaimer is
468
+ passed through verbatim, and non-USD parities are qualified as third-party
469
+ (Refinitiv) data redistributed by the BCB.
470
+
382
471
  ### v1.2.0
383
472
 
384
473
  - HTTP endpoint via Cloudflare Workers (`https://bcb.sidneybissoli.workers.dev`)
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,72 @@
1
+ /**
2
+ * PTAX — cotações de câmbio e lista de moedas.
3
+ *
4
+ * Desenho aprovado (fronteira concreta da sessão de D3): os quatro recursos de
5
+ * cotação da fonte (dólar-dia, dólar-período, moeda-dia, moeda-período) viram
6
+ * UMA tool, `bcb_cambio_cotacao`, com `moeda` (padrão USD) e data única ou
7
+ * intervalo. Mais `bcb_cambio_moedas` para a lista de moedas, porque descobrir o
8
+ * símbolo é pergunta própria.
9
+ *
10
+ * Duas obrigações legais do `bcb/docs/01` nascem implementadas aqui, não no D4:
11
+ *
12
+ * 1. **O disclaimer do BCB é repassado literalmente** em toda resposta de
13
+ * cotação — é o único texto tipo-ToS que a fonte publica.
14
+ * 2. **Paridades de moedas não-dólar são QUALIFICADAS**: elas não são dado do
15
+ * BCB, vêm de agência de informação (Refinitiv) e são redistribuídas pelo BCB.
16
+ * Anunciá-las como dado do BCB sem qualificar seria incorreto.
17
+ *
18
+ * Pegadinha da API que mora em `olinda.ts`: os parâmetros de data da PTAX são
19
+ * **MM-DD-YYYY**, não ISO nem dd/MM/yyyy.
20
+ */
21
+ import { type ToolDefinition, type ToolResult } from "./shared.js";
22
+ /** Repassado literalmente, como o `docs/01` exige. */
23
+ export declare const DISCLAIMER_PTAX: string;
24
+ export declare const QUALIFICACAO_PARIDADE: string;
25
+ export interface CotacaoNormalizada {
26
+ /** Data e hora da cotação como a fonte publica. */
27
+ dataHora: string | null;
28
+ cotacaoCompra: number | null;
29
+ cotacaoVenda: number | null;
30
+ /** Só para moedas não-dólar: paridade contra o USD (origem: agência de informação). */
31
+ paridadeCompra?: number | null;
32
+ paridadeVenda?: number | null;
33
+ /** Nulo em USD: verificado contra a origem, os recursos de dólar não publicam este campo. */
34
+ tipoBoletim: string | null;
35
+ }
36
+ export declare function normalizarCotacao(linha: Record<string, unknown>, dolar: boolean): CotacaoNormalizada;
37
+ interface UrlCotacao {
38
+ url: string;
39
+ dolar: boolean;
40
+ dataInicial: string;
41
+ dataFinal: string;
42
+ janelaPadrao: boolean;
43
+ }
44
+ /**
45
+ * Monta a URL da cotação escolhendo entre os quatro recursos da fonte. É o único
46
+ * lugar que sabe que existem quatro: para fora há uma tool só.
47
+ */
48
+ export declare function montarUrlCotacao(args: {
49
+ moeda?: string;
50
+ data?: string;
51
+ dataInicial?: string;
52
+ dataFinal?: string;
53
+ }): UrlCotacao | {
54
+ erro: string;
55
+ };
56
+ export interface ArgsCotacao {
57
+ moeda?: string;
58
+ data?: string;
59
+ dataInicial?: string;
60
+ dataFinal?: string;
61
+ limite?: number;
62
+ }
63
+ export declare function handleCambioCotacao(args: ArgsCotacao, timeoutMs?: number, maxRetries?: number): Promise<ToolResult>;
64
+ export interface ArgsMoedas {
65
+ termo?: string;
66
+ }
67
+ export declare function handleCambioMoedas(args: ArgsMoedas, timeoutMs?: number, maxRetries?: number): Promise<ToolResult>;
68
+ export declare const CAMBIO_TOOL_DEFINITIONS: ToolDefinition[];
69
+ /** Retorna null quando a tool não é deste módulo (o dispatcher central segue). */
70
+ export declare function dispatchCambioTool(toolName: string, args: Record<string, unknown>, timeoutMs?: number, maxRetries?: number): Promise<ToolResult> | null;
71
+ export {};
72
+ //# sourceMappingURL=cambio.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cambio.d.ts","sourceRoot":"","sources":["../src/cambio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAaH,OAAO,EAA+D,KAAK,cAAc,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAKhI,sDAAsD;AACtD,eAAO,MAAM,eAAe,QAIO,CAAC;AAEpC,eAAO,MAAM,qBAAqB,QAGT,CAAC;AAE1B,MAAM,WAAW,kBAAkB;IACjC,mDAAmD;IACnD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,aAAa,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,uFAAuF;IACvF,cAAc,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9B,6FAA6F;IAC7F,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;CAC5B;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,EAAE,OAAO,GAAG,kBAAkB,CAcpG;AAED,UAAU,UAAU;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,OAAO,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,GAAG,UAAU,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CA4ChC;AAED,MAAM,WAAW,WAAW;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,WAAW,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC,CA0CrB;AAED,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,UAAU,EAChB,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC,CA8BrB;AASD,eAAO,MAAM,uBAAuB,EAAE,cAAc,EA6GnD,CAAC;AAEF,kFAAkF;AAClF,wBAAgB,kBAAkB,CAChC,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,SAAS,CAAC,EAAE,MAAM,EAClB,UAAU,CAAC,EAAE,MAAM,GAClB,OAAO,CAAC,UAAU,CAAC,GAAG,IAAI,CAS5B"}
package/dist/cambio.js ADDED
@@ -0,0 +1,284 @@
1
+ /**
2
+ * PTAX — cotações de câmbio e lista de moedas.
3
+ *
4
+ * Desenho aprovado (fronteira concreta da sessão de D3): os quatro recursos de
5
+ * cotação da fonte (dólar-dia, dólar-período, moeda-dia, moeda-período) viram
6
+ * UMA tool, `bcb_cambio_cotacao`, com `moeda` (padrão USD) e data única ou
7
+ * intervalo. Mais `bcb_cambio_moedas` para a lista de moedas, porque descobrir o
8
+ * símbolo é pergunta própria.
9
+ *
10
+ * Duas obrigações legais do `bcb/docs/01` nascem implementadas aqui, não no D4:
11
+ *
12
+ * 1. **O disclaimer do BCB é repassado literalmente** em toda resposta de
13
+ * cotação — é o único texto tipo-ToS que a fonte publica.
14
+ * 2. **Paridades de moedas não-dólar são QUALIFICADAS**: elas não são dado do
15
+ * BCB, vêm de agência de informação (Refinitiv) e são redistribuídas pelo BCB.
16
+ * Anunciá-las como dado do BCB sem qualificar seria incorreto.
17
+ *
18
+ * Pegadinha da API que mora em `olinda.ts`: os parâmetros de data da PTAX são
19
+ * **MM-DD-YYYY**, não ISO nem dd/MM/yyyy.
20
+ */
21
+ import { PTAX_ODATA, consultarOData, hojeIso, montarUrlOData, numeroOuNulo, paraDataPtax, paraIso, somarDiasIso, textoOuNulo } from "./olinda.js";
22
+ import { erroResult, leituraRemota, mensagemDeErro, structuredResult } from "./shared.js";
23
+ /** Janela padrão quando não se informa data nenhuma: cobre feriados e fins de semana. */
24
+ const JANELA_PADRAO_DIAS = 7;
25
+ /** Repassado literalmente, como o `docs/01` exige. */
26
+ export const DISCLAIMER_PTAX = "O Banco Central não assume qualquer responsabilidade pela não simultaneidade ou falta das informações " +
27
+ "prestadas, assim como por eventuais erros de paridades das moedas. Não assume, também, responsabilidade " +
28
+ "por qualquer perda ou dano oriundo de tais interrupções, atrasos, falhas ou imperfeições, bem como pelo " +
29
+ "uso inadequado das informações.";
30
+ export const QUALIFICACAO_PARIDADE = "As paridades das moedas contra o dólar americano NÃO são apuradas pelo Banco Central: são obtidas junto a " +
31
+ "agências de informação (Refinitiv) e redistribuídas pelo BCB. Trate-as como dado de terceiro qualificado, " +
32
+ "não como dado do BCB.";
33
+ export function normalizarCotacao(linha, dolar) {
34
+ const normalizada = {
35
+ dataHora: textoOuNulo(linha.dataHoraCotacao),
36
+ cotacaoCompra: numeroOuNulo(linha.cotacaoCompra),
37
+ cotacaoVenda: numeroOuNulo(linha.cotacaoVenda),
38
+ tipoBoletim: textoOuNulo(linha.tipoBoletim)
39
+ };
40
+ if (!dolar) {
41
+ normalizada.paridadeCompra = numeroOuNulo(linha.paridadeCompra);
42
+ normalizada.paridadeVenda = numeroOuNulo(linha.paridadeVenda);
43
+ }
44
+ return normalizada;
45
+ }
46
+ /**
47
+ * Monta a URL da cotação escolhendo entre os quatro recursos da fonte. É o único
48
+ * lugar que sabe que existem quatro: para fora há uma tool só.
49
+ */
50
+ export function montarUrlCotacao(args) {
51
+ const moeda = (args.moeda ?? "USD").toUpperCase();
52
+ const dolar = moeda === "USD";
53
+ let inicio;
54
+ let fim;
55
+ let janelaPadrao = false;
56
+ if (args.data !== undefined) {
57
+ if (args.dataInicial !== undefined || args.dataFinal !== undefined) {
58
+ return { erro: "Use `data` para um dia específico OU `dataInicial`/`dataFinal` para um intervalo, não os dois." };
59
+ }
60
+ inicio = paraIso(args.data);
61
+ if (!inicio)
62
+ return { erro: `data inválida: "${args.data}". Use yyyy-MM-dd ou dd/MM/yyyy.` };
63
+ fim = inicio;
64
+ }
65
+ else {
66
+ fim = args.dataFinal ? paraIso(args.dataFinal) : hojeIso();
67
+ if (!fim)
68
+ return { erro: `dataFinal inválida: "${args.dataFinal}". Use yyyy-MM-dd ou dd/MM/yyyy.` };
69
+ inicio = args.dataInicial ? paraIso(args.dataInicial) : somarDiasIso(fim, -JANELA_PADRAO_DIAS);
70
+ if (!inicio)
71
+ return { erro: `dataInicial inválida: "${args.dataInicial}". Use yyyy-MM-dd ou dd/MM/yyyy.` };
72
+ janelaPadrao = args.dataInicial === undefined && args.dataFinal === undefined;
73
+ }
74
+ if (inicio > fim) {
75
+ return { erro: `A janela está invertida: dataInicial (${inicio}) é posterior a dataFinal (${fim}).` };
76
+ }
77
+ const diaUnico = inicio === fim && args.data !== undefined;
78
+ const pInicio = paraDataPtax(inicio);
79
+ const pFim = paraDataPtax(fim);
80
+ // Recursos parametrizados do OData: os argumentos vão como @parâmetros.
81
+ const recurso = diaUnico
82
+ ? dolar
83
+ ? `CotacaoDolarDia(dataCotacao=@dataCotacao)?@dataCotacao='${pInicio}'`
84
+ : `CotacaoMoedaDia(moeda=@moeda,dataCotacao=@dataCotacao)?@moeda='${moeda}'&@dataCotacao='${pInicio}'`
85
+ : dolar
86
+ ? `CotacaoDolarPeriodo(dataInicial=@dataInicial,dataFinalCotacao=@dataFinalCotacao)?@dataInicial='${pInicio}'&@dataFinalCotacao='${pFim}'`
87
+ : `CotacaoMoedaPeriodo(moeda=@moeda,dataInicial=@dataInicial,dataFinalCotacao=@dataFinalCotacao)?@moeda='${moeda}'&@dataInicial='${pInicio}'&@dataFinalCotacao='${pFim}'`;
88
+ // O recurso já carrega query string, então o formato entra com `&`.
89
+ const url = `${PTAX_ODATA}/${recurso}&$format=json`;
90
+ return { url, dolar, dataInicial: inicio, dataFinal: fim, janelaPadrao };
91
+ }
92
+ export async function handleCambioCotacao(args, timeoutMs, maxRetries) {
93
+ const montada = montarUrlCotacao(args);
94
+ if ("erro" in montada)
95
+ return erroResult(montada.erro);
96
+ try {
97
+ const linhas = await consultarOData(montada.url, timeoutMs, maxRetries);
98
+ const limite = args.limite ?? 100;
99
+ const todas = linhas
100
+ .map(l => normalizarCotacao(l, montada.dolar))
101
+ .sort((a, b) => (b.dataHora ?? "").localeCompare(a.dataHora ?? ""));
102
+ const cotacoes = todas.slice(0, limite);
103
+ const payload = {
104
+ moeda: (args.moeda ?? "USD").toUpperCase(),
105
+ periodo: {
106
+ dataInicial: montada.dataInicial,
107
+ dataFinal: montada.dataFinal,
108
+ janelaPadrao: montada.janelaPadrao
109
+ },
110
+ totalRegistros: todas.length,
111
+ cotacoes,
112
+ disclaimer: DISCLAIMER_PTAX,
113
+ urlConsulta: montada.url,
114
+ consultadoEm: new Date().toISOString()
115
+ };
116
+ if (!montada.dolar)
117
+ payload.qualificacaoParidade = QUALIFICACAO_PARIDADE;
118
+ if (cotacoes.length < todas.length) {
119
+ payload.observacao = `Exibindo ${cotacoes.length} de ${todas.length} boletins; aumente 'limite' ou estreite o período.`;
120
+ }
121
+ if (todas.length === 0) {
122
+ payload.observacao =
123
+ "Nenhuma cotação no período. A PTAX só existe em dia útil com fechamento de câmbio — fim de semana, " +
124
+ "feriado e o próprio dia antes do fechamento voltam vazios. Confirme também o símbolo da moeda com " +
125
+ "bcb_cambio_moedas.";
126
+ }
127
+ return structuredResult(payload);
128
+ }
129
+ catch (error) {
130
+ return erroResult(`Erro ao consultar cotação de câmbio: ${mensagemDeErro(error)}`);
131
+ }
132
+ }
133
+ export async function handleCambioMoedas(args, timeoutMs, maxRetries) {
134
+ const url = montarUrlOData(PTAX_ODATA, { recurso: "Moedas" });
135
+ try {
136
+ const linhas = await consultarOData(url, timeoutMs, maxRetries);
137
+ let moedas = linhas.map(l => ({
138
+ simbolo: textoOuNulo(l.simbolo),
139
+ nome: textoOuNulo(l.nomeFormatado),
140
+ tipo: textoOuNulo(l.tipoMoeda)
141
+ }));
142
+ if (args.termo !== undefined) {
143
+ const termo = args.termo.toUpperCase();
144
+ moedas = moedas.filter(m => (m.simbolo ?? "").includes(termo) || (m.nome ?? "").toUpperCase().includes(termo));
145
+ }
146
+ return structuredResult({
147
+ termo: args.termo ?? null,
148
+ totalMoedas: moedas.length,
149
+ moedas,
150
+ disclaimer: DISCLAIMER_PTAX,
151
+ qualificacaoParidade: QUALIFICACAO_PARIDADE,
152
+ urlConsulta: url,
153
+ consultadoEm: new Date().toISOString(),
154
+ observacao: "Use o `simbolo` em bcb_cambio_cotacao. O dólar americano (USD) é o padrão da tool de cotação."
155
+ });
156
+ }
157
+ catch (error) {
158
+ return erroResult(`Erro ao listar moedas: ${mensagemDeErro(error)}`);
159
+ }
160
+ }
161
+ // ==================== SCHEMAS ====================
162
+ const NOTA_PTAX = "Fonte: PTAX / Cotações e boletins de câmbio do Banco Central do Brasil, via Olinda OData. A resposta repassa " +
163
+ "literalmente o disclaimer de responsabilidade do BCB, em `disclaimer`. Cotações existem só em dia útil com " +
164
+ "fechamento de câmbio.";
165
+ export const CAMBIO_TOOL_DEFINITIONS = [
166
+ {
167
+ name: "bcb_cambio_cotacao",
168
+ description: "Consulta a cotação PTAX de uma moeda contra o real, em um dia específico ou num intervalo de datas. " +
169
+ "Padrão: dólar americano (USD). Devolve compra, venda, data/hora e tipo de boletim; para moedas " +
170
+ "não-dólar devolve também a paridade contra o USD, com a origem qualificada. " +
171
+ "Quando usar: para a cotação oficial de fechamento de um dia ou a série de um período curto. " +
172
+ "Quando NÃO usar: para a série histórica longa do dólar como série temporal do SGS use bcb_serie_valores " +
173
+ "(códigos 1 = livre venda, 3698 = PTAX venda, 3697 = PTAX compra, 3695 = PTAX média) — esta tool é a " +
174
+ "fonte primária do boletim, com compra e venda no mesmo registro; para descobrir o símbolo da moeda use " +
175
+ "bcb_cambio_moedas. " +
176
+ "Retorna: `moeda`, `periodo` (dataInicial, dataFinal, janelaPadrao), `totalRegistros`, `cotacoes`, " +
177
+ "`disclaimer`, `qualificacaoParidade` (só para moedas não-dólar), `urlConsulta`, `consultadoEm` e, quando " +
178
+ "aplicável, `observacao`. Sem datas, cobre os últimos 7 dias (para atravessar fim de semana e feriado). " +
179
+ NOTA_PTAX +
180
+ " As paridades de moedas não-dólar vêm de agência de informação (Refinitiv), redistribuídas pelo BCB — não " +
181
+ "são apuradas pelo Banco Central.",
182
+ annotations: leituraRemota("Cotação de câmbio (PTAX)"),
183
+ inputSchema: {
184
+ type: "object",
185
+ properties: {
186
+ moeda: { type: "string", description: "Símbolo da moeda (ex.: USD, EUR, GBP, JPY). Padrão: USD.", default: "USD" },
187
+ data: { type: "string", description: "Dia específico (yyyy-MM-dd ou dd/MM/yyyy). Não combine com dataInicial/dataFinal." },
188
+ dataInicial: { type: "string", description: "Início do intervalo (yyyy-MM-dd ou dd/MM/yyyy). Padrão: 7 dias antes do fim." },
189
+ dataFinal: { type: "string", description: "Fim do intervalo (yyyy-MM-dd ou dd/MM/yyyy). Padrão: hoje." },
190
+ limite: { type: "number", description: "Máximo de boletins a devolver (1-1000, padrão 100)", default: 100, minimum: 1, maximum: 1000 }
191
+ }
192
+ },
193
+ outputSchema: {
194
+ type: "object",
195
+ properties: {
196
+ moeda: { type: "string" },
197
+ periodo: {
198
+ type: "object",
199
+ properties: {
200
+ dataInicial: { type: "string" },
201
+ dataFinal: { type: "string" },
202
+ janelaPadrao: { type: "boolean", description: "true quando a janela de 7 dias foi assumida" }
203
+ },
204
+ required: ["dataInicial", "dataFinal", "janelaPadrao"]
205
+ },
206
+ totalRegistros: { type: "number" },
207
+ cotacoes: {
208
+ type: "array",
209
+ items: {
210
+ type: "object",
211
+ properties: {
212
+ dataHora: { type: ["string", "null"], description: "Data e hora da cotação" },
213
+ cotacaoCompra: { type: ["number", "null"] },
214
+ cotacaoVenda: { type: ["number", "null"] },
215
+ paridadeCompra: { type: ["number", "null"], description: "Paridade de compra contra o USD (moedas não-dólar; origem: agência de informação)" },
216
+ paridadeVenda: { type: ["number", "null"], description: "Paridade de venda contra o USD (moedas não-dólar; origem: agência de informação)" },
217
+ tipoBoletim: { type: ["string", "null"], description: "Tipo de boletim (ex.: Fechamento, Abertura, Intermediário). Nulo em USD: a fonte não publica este campo nos recursos de dólar, só nos de moeda." }
218
+ },
219
+ required: ["dataHora"]
220
+ }
221
+ },
222
+ disclaimer: { type: "string", description: "Disclaimer de responsabilidade do BCB, repassado literalmente" },
223
+ qualificacaoParidade: { type: "string", description: "Qualificação da origem das paridades não-dólar" },
224
+ urlConsulta: { type: "string" },
225
+ consultadoEm: { type: "string" },
226
+ observacao: { type: "string" }
227
+ },
228
+ required: ["moeda", "periodo", "totalRegistros", "cotacoes", "disclaimer", "urlConsulta", "consultadoEm"]
229
+ }
230
+ },
231
+ {
232
+ name: "bcb_cambio_moedas",
233
+ description: "Lista as moedas com cotação publicada pelo Banco Central, com símbolo, nome e tipo, e aceita um termo " +
234
+ "para filtrar. " +
235
+ "Quando usar: para descobrir o símbolo correto antes de chamar bcb_cambio_cotacao (é a causa mais comum " +
236
+ "de cotação vazia). Quando NÃO usar: para valores de cotação. " +
237
+ "Retorna: `termo`, `totalMoedas`, `moedas` (simbolo, nome, tipo), `disclaimer`, `qualificacaoParidade`, " +
238
+ "`urlConsulta` e `consultadoEm`. " + NOTA_PTAX,
239
+ annotations: leituraRemota("Moedas com cotação no BCB"),
240
+ inputSchema: {
241
+ type: "object",
242
+ properties: {
243
+ termo: { type: "string", description: "Filtro por símbolo ou nome (ex.: 'EUR', 'libra'). Opcional." }
244
+ }
245
+ },
246
+ outputSchema: {
247
+ type: "object",
248
+ properties: {
249
+ termo: { type: ["string", "null"], description: "Termo aplicado no filtro; nulo quando não foi informado" },
250
+ totalMoedas: { type: "number" },
251
+ moedas: {
252
+ type: "array",
253
+ items: {
254
+ type: "object",
255
+ properties: {
256
+ simbolo: { type: ["string", "null"], description: "Símbolo a usar em bcb_cambio_cotacao" },
257
+ nome: { type: ["string", "null"] },
258
+ tipo: { type: ["string", "null"], description: "Tipo da moeda conforme a fonte (A ou B)" }
259
+ },
260
+ required: ["simbolo"]
261
+ }
262
+ },
263
+ disclaimer: { type: "string" },
264
+ qualificacaoParidade: { type: "string" },
265
+ urlConsulta: { type: "string" },
266
+ consultadoEm: { type: "string" },
267
+ observacao: { type: "string" }
268
+ },
269
+ required: ["totalMoedas", "moedas", "disclaimer", "urlConsulta", "consultadoEm"]
270
+ }
271
+ }
272
+ ];
273
+ /** Retorna null quando a tool não é deste módulo (o dispatcher central segue). */
274
+ export function dispatchCambioTool(toolName, args, timeoutMs, maxRetries) {
275
+ switch (toolName) {
276
+ case "bcb_cambio_cotacao":
277
+ return handleCambioCotacao(args, timeoutMs, maxRetries);
278
+ case "bcb_cambio_moedas":
279
+ return handleCambioMoedas(args, timeoutMs, maxRetries);
280
+ default:
281
+ return null;
282
+ }
283
+ }
284
+ //# sourceMappingURL=cambio.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cambio.js","sourceRoot":"","sources":["../src/cambio.ts"],"names":[],"mappings":"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"}