From a7885b64162a0760330eacebb88045fca0957f72 Mon Sep 17 00:00:00 2001 From: Roberto Date: Wed, 12 Aug 2026 16:33:41 -0300 Subject: [PATCH 1/4] docs: document Mais Retorno MCP Free quota limits Make the optional resolver cascade step explicit about operator-owned API keys and the public Free tier (500 credits/month), so deploy wiring does not treat it as unlimited. Co-authored-by: Cursor --- CHANGELOG.md | 5 +++++ docs/RESOLVER.md | 32 ++++++++++++++++++++++++++++---- docs/SOURCES_WITH_AUTH.md | 15 +++++++++++++++ src/findata/resolver/engine.py | 4 +++- 4 files changed, 51 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2b195ee..7c2aaa8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,11 @@ adheres to [Semantic Versioning](https://semver.org/). ### Changed +- **Resolver docs: Mais Retorno MCP Free limits.** `docs/RESOLVER.md` now + states that the optional cascade step uses the operator's own API key and + documents the public Free tier (500 credits/month, 1-year history, MCP on + Free, 15 req/s, HTTP 429 when exhausted), with a dated link to + [maisretorno.com/mcp](https://maisretorno.com/mcp). - **Distribution slug renamed `findata-br` → `openfindata`.** The PyPI distribution name is now `openfindata` (`pip install openfindata`, `pip install 'openfindata[b3]'`), aligning the package slug with the diff --git a/docs/RESOLVER.md b/docs/RESOLVER.md index 2df546b..92b7d4c 100644 --- a/docs/RESOLVER.md +++ b/docs/RESOLVER.md @@ -92,7 +92,8 @@ Quando `confidence < ~0.9` ou status `candidate`, é gancho de revisão humana. 1. **openfindata** (primário, offline): seed curado + regras estruturais. Resolve o test set sem rede. -2. **Mais Retorno MCP** (dados BR de fundo/CNPJ/classe CVM). +2. **Mais Retorno MCP** (dados BR de fundo/CNPJ/classe CVM) — provider externo + opcional; ver limites Free abaixo. 3. **outro provider** (CVM dados abertos / B3). 4. **web_search restrito** a `maisretorno.com`, `b3.com.br`, `yahoofinance.com.br`, `debentures.com.br`. @@ -100,8 +101,30 @@ Quando `confidence < ~0.9` ou status `candidate`, é gancho de revisão humana. Cada degrau preenche o que o anterior não trouxe e **baixa a confidence**; `source` reflete a origem final; `cascade` loga o caminho. Os degraus 2 a 4 são um ponto de extensão injetável (`AssetProvider`), consultado só quando o -resultado do núcleo está fraco. No estado atual deste PR, **só o degrau 1 está -ligado** (os externos são stubs a conectar no deploy). +resultado do núcleo está fraco. Hoje **só o degrau 1 está ligado** (os externos +são stubs a conectar no deploy). + +### Mais Retorno MCP: plano Free e cotas + +O openfindata **não embute** chave nem cota da Mais Retorno. Quem ligar o +degrau 2 no deploy traz a própria API key +([developers.maisretorno.com](https://developers.maisretorno.com)). Referência +pública do produto: [maisretorno.com/mcp](https://maisretorno.com/mcp) +(conferido em 2026-08-12). + +Limites relevantes do plano **Free** (permanente, sem cartão): + +| Item | Free | +|---|---| +| Créditos | 500/mês (1 chamada na API de dados ≈ 1 crédito) | +| Histórico | até 1 ano (planos pagos: histórico completo) | +| MCP | disponível no Free (mesmos endpoints/classes dos planos pagos) | +| Rate limit | 15 req/s em todos os planos | +| Cota esgotada | HTTP 429 até renovar o ciclo (aviso por email ~80%) | + +Fora do escopo desse MCP (não usar como fallback para esses ativos): CRI, CRA, +FIDC, debêntures e ativos offshore. Volume e profundidade de histórico sobem +nos planos pagos; o rate limit por segundo não. ## Test set (passa 100%, offline) @@ -126,7 +149,8 @@ ligado** (os externos são stubs a conectar no deploy). ## Pendências antes de produção -- Conectar os providers externos reais (Mais Retorno MCP, web search restrito). +- Conectar os providers externos reais (Mais Retorno MCP com API key/cota do + operador — Free = 500 créditos/mês —, e web search restrito). - Confirmação ISIN-level da incentivada (12.431) via ANBIMA/debentures.com.br no degrau de cascata — hoje fica `candidate`. - Ampliar o seed curado de ETFs conforme novos ETFs forem listados na B3. diff --git a/docs/SOURCES_WITH_AUTH.md b/docs/SOURCES_WITH_AUTH.md index 0bc0109..bf1d03c 100644 --- a/docs/SOURCES_WITH_AUTH.md +++ b/docs/SOURCES_WITH_AUTH.md @@ -64,6 +64,21 @@ Quirks da API ANBIMA (já validamos em testes ao vivo): +## Mais Retorno MCP (cascata do resolver): Free com cota + +Não é fonte core do openfindata — é um degrau opcional da cascata de +`resolve_asset` (`docs/RESOLVER.md`). O operador traz a própria API key; o +projeto não embute credenciais. + +Plano **Free** permanente (sem cartão), conforme +[maisretorno.com/mcp](https://maisretorno.com/mcp) (conferido em 2026-08-12): +500 créditos/mês, histórico de até 1 ano, MCP incluso, rate limit 15 req/s. +Cota esgotada → HTTP 429. Volume e histórico completo ficam nos planos pagos. + +Trate como `free_logged_in` com cota mensal: self-serve, mas não anônimo e +não ilimitado. Detalhes e escopo (o que o MCP não cobre) estão em +`docs/RESOLVER.md`. + ## Base dos Dados: grátis, mas com login/projeto do usuário Base dos Dados não entra na mesma categoria da API autenticada da ANBIMA. O diff --git a/src/findata/resolver/engine.py b/src/findata/resolver/engine.py index 5e3dcb1..2983388 100644 --- a/src/findata/resolver/engine.py +++ b/src/findata/resolver/engine.py @@ -10,7 +10,9 @@ 3. **External providers** (optional, injected) — Mais Retorno MCP, CVM/B3, restricted web search. Not bundled here (they are client-side / networked); the resolver takes a chain of async callbacks so a deployment can wire them. - Each step that fires lowers ``confidence`` and is appended to ``cascade``. + Mais Retorno is the operator's own key/quota (public Free tier: 500 + credits/month; see ``docs/RESOLVER.md``). Each step that fires lowers + ``confidence`` and is appended to ``cascade``. The seed + rules layers are pure and offline, so the spec's test set resolves deterministically with no network. ``source`` is ``"openfindata"`` for every From 4c4de9fa0225896c01c01bac7cd8ebc93978968e Mon Sep 17 00:00:00 2001 From: Roberto Date: Wed, 12 Aug 2026 16:35:28 -0300 Subject: [PATCH 2/4] docs: clarify Mais Retorno Free credits and auth channels Correct variable per-call credit costs and separate REST API-key wiring from MCP OAuth so the cascade docs do not imply one credit per resolution or the wrong auth path. Co-authored-by: Cursor --- CHANGELOG.md | 12 +++++----- docs/RESOLVER.md | 40 ++++++++++++++++++++++------------ docs/SOURCES_WITH_AUTH.md | 13 ++++++----- src/findata/resolver/engine.py | 8 +++---- 4 files changed, 45 insertions(+), 28 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7c2aaa8..43b1fac 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,11 +8,13 @@ adheres to [Semantic Versioning](https://semver.org/). ### Changed -- **Resolver docs: Mais Retorno MCP Free limits.** `docs/RESOLVER.md` now - states that the optional cascade step uses the operator's own API key and - documents the public Free tier (500 credits/month, 1-year history, MCP on - Free, 15 req/s, HTTP 429 when exhausted), with a dated link to - [maisretorno.com/mcp](https://maisretorno.com/mcp). +- **Resolver docs: Mais Retorno Free limits.** `docs/RESOLVER.md` now + states that the optional cascade step uses the operator's own account and + documents the public Free tier (500 credits/month shared by REST+MCP, + variable per-call cost, 1-year history, 15 req/s, HTTP 429 when exhausted), + distinguishing REST API key vs MCP OAuth, with dated links to + [maisretorno.com/mcp](https://maisretorno.com/mcp) and + [developers.maisretorno.com](https://developers.maisretorno.com). - **Distribution slug renamed `findata-br` → `openfindata`.** The PyPI distribution name is now `openfindata` (`pip install openfindata`, `pip install 'openfindata[b3]'`), aligning the package slug with the diff --git a/docs/RESOLVER.md b/docs/RESOLVER.md index 92b7d4c..9a646bc 100644 --- a/docs/RESOLVER.md +++ b/docs/RESOLVER.md @@ -92,8 +92,8 @@ Quando `confidence < ~0.9` ou status `candidate`, é gancho de revisão humana. 1. **openfindata** (primário, offline): seed curado + regras estruturais. Resolve o test set sem rede. -2. **Mais Retorno MCP** (dados BR de fundo/CNPJ/classe CVM) — provider externo - opcional; ver limites Free abaixo. +2. **Mais Retorno** (dados BR de fundo/CNPJ/classe CVM) — provider externo + opcional via API de dados / MCP; ver limites Free abaixo. 3. **outro provider** (CVM dados abertos / B3). 4. **web_search restrito** a `maisretorno.com`, `b3.com.br`, `yahoofinance.com.br`, `debentures.com.br`. @@ -104,27 +104,38 @@ um ponto de extensão injetável (`AssetProvider`), consultado só quando o resultado do núcleo está fraco. Hoje **só o degrau 1 está ligado** (os externos são stubs a conectar no deploy). -### Mais Retorno MCP: plano Free e cotas +### Mais Retorno: plano Free e cotas O openfindata **não embute** chave nem cota da Mais Retorno. Quem ligar o -degrau 2 no deploy traz a própria API key -([developers.maisretorno.com](https://developers.maisretorno.com)). Referência -pública do produto: [maisretorno.com/mcp](https://maisretorno.com/mcp) -(conferido em 2026-08-12). +degrau 2 no deploy usa a conta do operador. A API de dados tem dois canais +sobre o **mesmo saldo de créditos** +([developers.maisretorno.com](https://developers.maisretorno.com), conferido em +2026-08-12): + +- **REST** (típico para um `AssetProvider` server-side): API key + (`X-Api-Key` / `Authorization: Bearer`) gerada em + [maisretorno.com/app/meu-perfil/api](https://maisretorno.com/app/meu-perfil/api). +- **MCP** (agente de IA): URL + `https://data.maisretorno.com/mr-data/v4/mcp`, autenticação **OAuth** (sem + api-key). Página de produto: + [maisretorno.com/mcp](https://maisretorno.com/mcp). Limites relevantes do plano **Free** (permanente, sem cartão): | Item | Free | |---|---| -| Créditos | 500/mês (1 chamada na API de dados ≈ 1 crédito) | +| Créditos | 500/mês no mesmo saldo REST+MCP | +| Custo por chamada | variável (ex.: search grátis; `asset-info`/quotes/`fund-class-subclass` = 1; stats/drawdown = 5; `wallet-detail` = 10; compare/backtest = 25) | | Histórico | até 1 ano (planos pagos: histórico completo) | -| MCP | disponível no Free (mesmos endpoints/classes dos planos pagos) | +| MCP | disponível no Free (mesmas classes/endpoints dos planos pagos) | | Rate limit | 15 req/s em todos os planos | | Cota esgotada | HTTP 429 até renovar o ciclo (aviso por email ~80%) | -Fora do escopo desse MCP (não usar como fallback para esses ativos): CRI, CRA, -FIDC, debêntures e ativos offshore. Volume e profundidade de histórico sobem -nos planos pagos; o rate limit por segundo não. +Não trate 500 créditos como “500 resoluções”: um provider que chame stats ou +carteira consome bem mais por ativo. Fora do escopo dessa API/MCP (não usar +como fallback para esses ativos): CRI, CRA, FIDC, debêntures e ativos offshore. +Volume e profundidade de histórico sobem nos planos pagos; o rate limit por +segundo não. ## Test set (passa 100%, offline) @@ -149,8 +160,9 @@ nos planos pagos; o rate limit por segundo não. ## Pendências antes de produção -- Conectar os providers externos reais (Mais Retorno MCP com API key/cota do - operador — Free = 500 créditos/mês —, e web search restrito). +- Conectar os providers externos reais (Mais Retorno via REST/API key do + operador — Free = 500 créditos/mês no saldo compartilhado com o MCP —, e + web search restrito). - Confirmação ISIN-level da incentivada (12.431) via ANBIMA/debentures.com.br no degrau de cascata — hoje fica `candidate`. - Ampliar o seed curado de ETFs conforme novos ETFs forem listados na B3. diff --git a/docs/SOURCES_WITH_AUTH.md b/docs/SOURCES_WITH_AUTH.md index bf1d03c..90103ef 100644 --- a/docs/SOURCES_WITH_AUTH.md +++ b/docs/SOURCES_WITH_AUTH.md @@ -64,19 +64,22 @@ Quirks da API ANBIMA (já validamos em testes ao vivo): -## Mais Retorno MCP (cascata do resolver): Free com cota +## Mais Retorno (cascata do resolver): Free com cota Não é fonte core do openfindata — é um degrau opcional da cascata de -`resolve_asset` (`docs/RESOLVER.md`). O operador traz a própria API key; o +`resolve_asset` (`docs/RESOLVER.md`). O operador traz a própria conta; o projeto não embute credenciais. Plano **Free** permanente (sem cartão), conforme -[maisretorno.com/mcp](https://maisretorno.com/mcp) (conferido em 2026-08-12): -500 créditos/mês, histórico de até 1 ano, MCP incluso, rate limit 15 req/s. +[maisretorno.com/mcp](https://maisretorno.com/mcp) e +[developers.maisretorno.com](https://developers.maisretorno.com) (conferido em +2026-08-12): 500 créditos/mês no mesmo saldo para REST e MCP, histórico de até +1 ano, rate limit 15 req/s. Custo por operação é variável (não 1 crédito por +qualquer chamada). REST autentica com API key; MCP autentica com OAuth. Cota esgotada → HTTP 429. Volume e histórico completo ficam nos planos pagos. Trate como `free_logged_in` com cota mensal: self-serve, mas não anônimo e -não ilimitado. Detalhes e escopo (o que o MCP não cobre) estão em +não ilimitado. Detalhes e escopo (o que a API/MCP não cobre) estão em `docs/RESOLVER.md`. ## Base dos Dados: grátis, mas com login/projeto do usuário diff --git a/src/findata/resolver/engine.py b/src/findata/resolver/engine.py index 2983388..56782be 100644 --- a/src/findata/resolver/engine.py +++ b/src/findata/resolver/engine.py @@ -7,12 +7,12 @@ 2. **Structural rules** (this module) — name/ticker patterns that *are* derivable: COE, debenture, CRA/CRI, bank paper, Tesouro, IE/global, FII, FIA/Ações, Multimercado, FIDC/FIP, plain tickers. -3. **External providers** (optional, injected) — Mais Retorno MCP, CVM/B3, +3. **External providers** (optional, injected) — Mais Retorno, CVM/B3, restricted web search. Not bundled here (they are client-side / networked); the resolver takes a chain of async callbacks so a deployment can wire them. - Mais Retorno is the operator's own key/quota (public Free tier: 500 - credits/month; see ``docs/RESOLVER.md``). Each step that fires lowers - ``confidence`` and is appended to ``cascade``. + Mais Retorno uses the operator's own account/quota (see + ``docs/RESOLVER.md``). Each step that fires lowers ``confidence`` and is + appended to ``cascade``. The seed + rules layers are pure and offline, so the spec's test set resolves deterministically with no network. ``source`` is ``"openfindata"`` for every From a9a15e78a2cb3f8adfdc62b1e082118642644f28 Mon Sep 17 00:00:00 2001 From: Roberto Date: Thu, 13 Aug 2026 10:44:16 -0300 Subject: [PATCH 3/4] docs: align resolver cascade wording with provider replace semantics Address CodeRabbit feedback: providers replace the classification and own confidence/source; document HTTP 429 clears on cycle renewal or plan upgrade. Co-authored-by: Cursor --- docs/RESOLVER.md | 13 +++++++------ docs/SOURCES_WITH_AUTH.md | 3 ++- src/findata/resolver/engine.py | 19 +++++++++++-------- 3 files changed, 20 insertions(+), 15 deletions(-) diff --git a/docs/RESOLVER.md b/docs/RESOLVER.md index 9a646bc..df3d97f 100644 --- a/docs/RESOLVER.md +++ b/docs/RESOLVER.md @@ -98,11 +98,12 @@ Quando `confidence < ~0.9` ou status `candidate`, é gancho de revisão humana. 4. **web_search restrito** a `maisretorno.com`, `b3.com.br`, `yahoofinance.com.br`, `debentures.com.br`. -Cada degrau preenche o que o anterior não trouxe e **baixa a confidence**; -`source` reflete a origem final; `cascade` loga o caminho. Os degraus 2 a 4 são -um ponto de extensão injetável (`AssetProvider`), consultado só quando o -resultado do núcleo está fraco. Hoje **só o degrau 1 está ligado** (os externos -são stubs a conectar no deploy). +Cada degrau que retorna resultado **substitui** a classificação atual (o +provider controla campos, `source` e `confidence`); o resolver só antepõe o +`cascade` anterior ao `cascade` devolvido. Os degraus 2 a 4 são um ponto de +extensão injetável (`AssetProvider`), consultado só quando o resultado do +núcleo está fraco. Hoje **só o degrau 1 está ligado** (os externos são stubs a +conectar no deploy). ### Mais Retorno: plano Free e cotas @@ -129,7 +130,7 @@ Limites relevantes do plano **Free** (permanente, sem cartão): | Histórico | até 1 ano (planos pagos: histórico completo) | | MCP | disponível no Free (mesmas classes/endpoints dos planos pagos) | | Rate limit | 15 req/s em todos os planos | -| Cota esgotada | HTTP 429 até renovar o ciclo (aviso por email ~80%) | +| Cota esgotada | HTTP 429 até renovar o ciclo ou fazer upgrade (aviso por email ~80%) | Não trate 500 créditos como “500 resoluções”: um provider que chame stats ou carteira consome bem mais por ativo. Fora do escopo dessa API/MCP (não usar diff --git a/docs/SOURCES_WITH_AUTH.md b/docs/SOURCES_WITH_AUTH.md index 90103ef..0fcf024 100644 --- a/docs/SOURCES_WITH_AUTH.md +++ b/docs/SOURCES_WITH_AUTH.md @@ -76,7 +76,8 @@ Plano **Free** permanente (sem cartão), conforme 2026-08-12): 500 créditos/mês no mesmo saldo para REST e MCP, histórico de até 1 ano, rate limit 15 req/s. Custo por operação é variável (não 1 crédito por qualquer chamada). REST autentica com API key; MCP autentica com OAuth. -Cota esgotada → HTTP 429. Volume e histórico completo ficam nos planos pagos. +Cota esgotada → HTTP 429 até renovar o ciclo ou fazer upgrade. Volume e +histórico completo ficam nos planos pagos. Trate como `free_logged_in` com cota mensal: self-serve, mas não anônimo e não ilimitado. Detalhes e escopo (o que a API/MCP não cobre) estão em diff --git a/src/findata/resolver/engine.py b/src/findata/resolver/engine.py index 56782be..3ace3ff 100644 --- a/src/findata/resolver/engine.py +++ b/src/findata/resolver/engine.py @@ -11,8 +11,9 @@ restricted web search. Not bundled here (they are client-side / networked); the resolver takes a chain of async callbacks so a deployment can wire them. Mais Retorno uses the operator's own account/quota (see - ``docs/RESOLVER.md``). Each step that fires lowers ``confidence`` and is - appended to ``cascade``. + ``docs/RESOLVER.md``). A non-``None`` provider result replaces the current + classification (provider owns fields/``source``/``confidence``); the + resolver only prepends the prior ``cascade``. The seed + rules layers are pure and offline, so the spec's test set resolves deterministically with no network. ``source`` is ``"openfindata"`` for every @@ -103,10 +104,11 @@ class AssetProvider(Protocol): """An external cascade step (Mais Retorno, CVM/B3, web search). - Receives the normalized input and the best classification so far; returns an - enriched classification (new ``source``, possibly higher-detail fields) or - ``None`` to pass. Implementations live outside the library because they are - networked / client-side; the resolver only orchestrates them. + Receives the normalized input and the best classification so far; returns a + full classification that **replaces** the current result (provider owns + fields, ``source``, and ``confidence``), or ``None`` to pass. The resolver + only prepends the prior ``cascade``. Implementations live outside the + library because they are networked / client-side. """ async def __call__( @@ -709,8 +711,9 @@ async def resolve_asset( Runs the deterministic core (curated seed → structural rules), then walks the optional external provider chain (Mais Retorno → CVM/B3 → restricted web search) only while the result is still weak (``Indefinido`` or low - confidence). Each provider that fires is appended to ``cascade`` and may lower - confidence; the deepest one to set a field owns ``source``. + confidence). A provider result replaces the current classification; the + resolver prepends the prior ``cascade``. The provider owns ``source`` and + ``confidence``. No PII: callers pass only an asset identifier, never client data. """ From 16ead70a40c923e3d5fa70fd9aec70c75d216cab Mon Sep 17 00:00:00 2001 From: Roberto Date: Thu, 13 Aug 2026 10:44:22 -0300 Subject: [PATCH 4/4] docs: note Free-tier upgrade path and changelog cascade semantics Include plan-upgrade escape for Mais Retorno HTTP 429 and record the provider-replace wording alignment in the changelog. Co-authored-by: Cursor --- CHANGELOG.md | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43b1fac..0491294 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,10 +11,13 @@ adheres to [Semantic Versioning](https://semver.org/). - **Resolver docs: Mais Retorno Free limits.** `docs/RESOLVER.md` now states that the optional cascade step uses the operator's own account and documents the public Free tier (500 credits/month shared by REST+MCP, - variable per-call cost, 1-year history, 15 req/s, HTTP 429 when exhausted), - distinguishing REST API key vs MCP OAuth, with dated links to + variable per-call cost, 1-year history, 15 req/s, HTTP 429 until renewal or + upgrade), distinguishing REST API key vs MCP OAuth, with dated links to [maisretorno.com/mcp](https://maisretorno.com/mcp) and - [developers.maisretorno.com](https://developers.maisretorno.com). + [developers.maisretorno.com](https://developers.maisretorno.com). Also + aligns the cascade wording with runtime behavior: a provider result replaces + the current classification (provider owns ``confidence``/``source``); the + resolver only prepends ``cascade``. - **Distribution slug renamed `findata-br` → `openfindata`.** The PyPI distribution name is now `openfindata` (`pip install openfindata`, `pip install 'openfindata[b3]'`), aligning the package slug with the