next-finance-mcp 0.9.2 → 0.9.4

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/dist/client.js CHANGED
@@ -377,9 +377,11 @@ function slimConta(c) {
377
377
  const _id = o["Id"] ?? o["IdConta"] ?? o["id"] ?? o["idConta"];
378
378
  const _idTipo = o["IdTipoConta"];
379
379
  // Nível 1 — Moeda (ex: "BRL", "USD")
380
+ // REST retorna NomeMoeda; web retorna apenas IdMoeda (moeda tratada como vazia no fallback)
380
381
  const moeda = String(o["NomeMoeda"] ?? o["Moeda"] ?? o["SiglaMoeda"] ?? o["CodigoMoeda"] ?? "").trim();
381
382
  // Nível 2 — Portfolio (ex: "Tesouraria", "Renda Variável", "Previdência")
382
- const portfolio = String(o["NomePortfolio"] ?? o["Portfolio"] ?? o["NomeGrupo"] ?? o["Grupo"] ?? "").trim();
383
+ // REST e web usam NomeTipoPortfolio
384
+ const portfolio = String(o["NomeTipoPortfolio"] ?? o["NomePortfolio"] ?? o["Portfolio"] ?? o["NomeGrupo"] ?? o["Grupo"] ?? "").trim();
383
385
  // Nível 3 — Tipo de Conta (ex: "Conta Corrente", "Ações", "CDB")
384
386
  let tipoConta = String(o["NomeTipoConta"] ?? "").trim();
385
387
  if (!tipoConta && o["TipoConta"] && typeof o["TipoConta"] === "object") {
@@ -388,7 +390,7 @@ function slimConta(c) {
388
390
  // Nível 4 — Nome da Conta
389
391
  const nome = String(o["Nome"] ?? o["NomeConta"] ?? o["Descricao"] ?? "").trim();
390
392
  const slim = {};
391
- // Campos internos (nunca retornados ao usuário final, usados pelo MCP)
393
+ // Campos internos (prefixo _, nunca exibidos ao usuário final)
392
394
  if (_id !== undefined)
393
395
  slim["_id"] = _id;
394
396
  if (_idTipo !== undefined)
@@ -402,17 +404,35 @@ function slimConta(c) {
402
404
  slim["tipo_conta"] = tipoConta;
403
405
  if (nome)
404
406
  slim["nome"] = nome;
405
- // Campos financeiros extras se disponíveis
407
+ // Campos financeiros extras REST e web usam campos diferentes
406
408
  if (o["Saldo"] !== undefined && o["Saldo"] !== null)
407
409
  slim["saldo"] = o["Saldo"];
408
- if (o["Banco"] !== undefined && typeof o["Banco"] === "string")
409
- slim["banco"] = o["Banco"];
410
- if (o["Agencia"] !== undefined && typeof o["Agencia"] === "string")
411
- slim["agencia"] = o["Agencia"];
412
- if (o["Numero"] !== undefined && typeof o["Numero"] === "string")
413
- slim["numero"] = o["Numero"];
410
+ // Banco: REST = NomeBanco, web = NomeBanco também
411
+ const banco = o["NomeBanco"] ?? o["Banco"];
412
+ if (banco && typeof banco === "string" && banco.trim())
413
+ slim["banco"] = banco.trim();
414
+ // Agência: REST = NumeroAgencia, web = NumeroAgencia também
415
+ const agencia = o["NumeroAgencia"] ?? o["Agencia"];
416
+ if (agencia && typeof agencia === "string" && agencia.trim())
417
+ slim["agencia"] = agencia.trim();
418
+ // Conta bancária: REST = NumeroContaBancaria + DigitoContaBancaria, web = NumeroContaBancaria
419
+ const numConta = o["NumeroContaBancaria"] ?? o["Numero"];
420
+ const digConta = o["DigitoContaBancaria"];
421
+ if (numConta && typeof numConta === "string" && numConta.trim()) {
422
+ slim["numero"] = digConta ? `${numConta.trim()}-${String(digConta).trim()}` : numConta.trim();
423
+ }
414
424
  return slim;
415
425
  }
426
+ /** Retorna true se a conta está ativa (não encerrada). */
427
+ function isContaAtiva(c) {
428
+ // Encerrada === true → conta encerrada (campo presente em REST e web)
429
+ if (c["Encerrada"] === true)
430
+ return false;
431
+ // Ativo === false → inativa (campo legado, só em alguns endpoints)
432
+ if (c["Ativo"] === false)
433
+ return false;
434
+ return true;
435
+ }
416
436
  /** Tenta endpoints em ordem até encontrar um que responda com dados */
417
437
  async function fetchContas() {
418
438
  // Todos os endpoints REST agora apontam para api.finance.net.br via apiGet()
@@ -446,8 +466,8 @@ async function fetchContas() {
446
466
  }
447
467
  export async function listarContas(filtro = {}) {
448
468
  const { contas: raw } = await fetchContas();
449
- // Apenas contas ativas (Ativo === true no cadastro)
450
- const ativas = raw.filter(c => c["Ativo"] !== false);
469
+ // Apenas contas ativas (Encerrada !== true e Ativo !== false)
470
+ const ativas = raw.filter(c => isContaAtiva(c));
451
471
  let contas = ativas.map(slimConta);
452
472
  // Nível 4 — filtro por nome da conta
453
473
  if (filtro.busca?.trim()) {
@@ -826,13 +846,18 @@ export async function buscarLancamentos(opts) {
826
846
  if (opts.nomeConta?.trim()) {
827
847
  const { contas } = await fetchContas();
828
848
  const termo = opts.nomeConta.trim().toLowerCase();
829
- const encontrada = contas
830
- .map(c => c)
831
- .filter(c => c["Ativo"] !== false) // apenas contas ativas
832
- .find(c => String(c["Nome"] ?? c["NomeConta"] ?? "").toLowerCase().includes(termo));
833
- if (!encontrada)
834
- throw new Error(`Conta "${opts.nomeConta}" não encontrada entre as contas ativas. Use listar_contas para ver as contas disponíveis.`);
835
- // Tenta todos os nomes possíveis de campo ID na resposta da API
849
+ const ativas = contas.map(c => c).filter(isContaAtiva);
850
+ const matches = ativas.filter(c => String(c["Nome"] ?? c["NomeConta"] ?? "").toLowerCase().includes(termo));
851
+ if (matches.length === 0) {
852
+ throw new Error(`Conta "${opts.nomeConta}" não encontrada. Use listar_contas para ver as contas disponíveis.`);
853
+ }
854
+ // Preferir match exato; se ainda ambíguo, listar as opções
855
+ const exata = matches.find(c => String(c["Nome"] ?? c["NomeConta"] ?? "").toLowerCase() === termo);
856
+ const encontrada = exata ?? (matches.length === 1 ? matches[0] : null);
857
+ if (!encontrada) {
858
+ const nomes = matches.map(c => String(c["Nome"] ?? c["NomeConta"] ?? "")).join(", ");
859
+ throw new Error(`"${opts.nomeConta}" corresponde a ${matches.length} contas: ${nomes}. Informe um nome mais específico.`);
860
+ }
836
861
  idContaResolvido = String(encontrada["Id"] ?? encontrada["IdConta"] ?? encontrada["id"] ?? encontrada["idConta"] ?? "");
837
862
  }
838
863
  let lancamentos;
@@ -863,8 +888,6 @@ export async function buscarLancamentos(opts) {
863
888
  if (r.status !== 200)
864
889
  throw new Error(`Erro ${r.status} ao buscar lançamentos (endpoint legado).`);
865
890
  const raw = JSON.parse(r.text);
866
- // O endpoint legado retorna { Lancamentos: [...], SaldosPorMes: [...], ... }
867
- // Extraímos explicitamente o campo Lancamentos para não confundir com SaldosPorMes
868
891
  if (Array.isArray(raw)) {
869
892
  lancamentos = raw;
870
893
  }
package/dist/index.js CHANGED
@@ -8,7 +8,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
8
8
  import { CallToolRequestSchema, ListToolsRequestSchema } from "@modelcontextprotocol/sdk/types.js";
9
9
  import * as client from "./client.js";
10
10
  import { openLoginUI } from "./login-server.js";
11
- const server = new Server({ name: "next-finance-mcp", version: "0.9.2" }, { capabilities: { tools: {} } });
11
+ const server = new Server({ name: "next-finance-mcp", version: "0.9.4" }, { capabilities: { tools: {} } });
12
12
  // ── Ferramentas ─────────────────────────────────────────────────────────────
13
13
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
14
14
  tools: [
@@ -361,6 +361,6 @@ server.setRequestHandler(CallToolRequestSchema, async (req) => {
361
361
  async function main() {
362
362
  const transport = new StdioServerTransport();
363
363
  await server.connect(transport);
364
- console.error("NEXT Finance MCP server v0.9.0 iniciado.");
364
+ console.error("NEXT Finance MCP server v0.9.3 iniciado.");
365
365
  }
366
366
  main().catch((err) => { console.error("Erro fatal:", err); process.exit(1); });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "next-finance-mcp",
3
- "version": "0.9.2",
3
+ "version": "0.9.4",
4
4
  "mcpName": "io.github.paivapiovesan/next-finance",
5
5
  "description": "MCP Server para o NEXT Finance (finance.net.br) — login via browser, listagem de carteiras, contas e lançamentos",
6
6
  "type": "module",