fin-app-mcp 2.1.0 → 2.2.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 (3) hide show
  1. package/docs/guia.md +54 -0
  2. package/index.mjs +96 -1
  3. package/package.json +1 -1
package/docs/guia.md CHANGED
@@ -269,3 +269,57 @@ As ocorrências são geradas **lazily**: ao consultar um mês (`fin_bills_do_mes
269
269
 
270
270
  - `fixed`: valor fixo todo mês (ex: condomínio R$1.383). O `amount` da ocorrência já vem preenchido.
271
271
  - `variable`: valor muda (ex: Light). O `amount` da ocorrência vem `null` até ser definido no momento do pagamento.
272
+
273
+ ## 10. Câmbio USD/BRL e ajuste de saldo
274
+
275
+ O FIN tem suporte para contas cash em USD (carteira física, Wise, conta no exterior). No v0, contas em USD trabalham com **saldo manual** — você não lança despesas/receitas categorizadas em dólar. Em vez disso, usa duas operações:
276
+
277
+ ### `fin_cambio` — comprar ou vender dólar
278
+
279
+ O FIN não usa cotação automática para câmbio — **você informa a taxa praticada** na operação, porque a taxa real varia por banco/spread/operação. A tool cria atomicamente 2 transações vinculadas (`exchange_pair_id` compartilhado):
280
+
281
+ - **Vender dólar:** `from = conta USD`, `to = conta BRL`
282
+ - **Comprar dólar:** `from = conta BRL`, `to = conta USD`
283
+
284
+ Cada transação fica na sua conta respectiva, com a moeda da conta. A categoria "Câmbio" é criada automaticamente no primeiro uso.
285
+
286
+ **Exemplo — vendi $100 e recebi R$540 no Itaú:**
287
+ ```json
288
+ fin_cambio({
289
+ "from_account_name": "Wise USD",
290
+ "to_account_name": "Itaú",
291
+ "amount_from_cents": 10000,
292
+ "amount_to_cents": 54000,
293
+ "description": "Venda de dólar"
294
+ })
295
+ ```
296
+
297
+ Resultado: despesa de $100 na Wise USD + receita de R$540 no Itaú. Ambas com `exchange_pair_id` igual.
298
+
299
+ ### `fin_ajustar_saldo_conta` — atualizar saldo manualmente
300
+
301
+ Para casos onde o saldo USD muda **sem motivo categórico** (ex: você achou mais $50 na carteira, ou simplesmente quer atualizar pra refletir o saldo real), use `fin_ajustar_saldo_conta`. Ele atualiza o `initial_balance` da conta diretamente, **sem criar transação**.
302
+
303
+ **Importante:** o valor é o **saldo absoluto**, não um delta. Se a conta tinha $400 e você quer somar $50, passe `45000` (não `5000`).
304
+
305
+ ```json
306
+ fin_ajustar_saldo_conta({
307
+ "account_name": "Wise USD",
308
+ "amount_cents": 45000
309
+ })
310
+ ```
311
+
312
+ Funciona para qualquer conta cash (BRL ou USD). Não funciona para cartão de crédito.
313
+
314
+ ### Restrições no v0
315
+
316
+ - ❌ Lançar despesa/receita categorizada em USD via `fin_criar_despesa`/`fin_criar_receita` (continua bloqueado — mensagem: "use fin_cambio ou fin_ajustar_saldo_conta")
317
+ - ❌ Cotação automática (você sempre informa a taxa)
318
+ - ❌ Cartão de crédito em USD
319
+ - ❌ Filtros nos relatórios mensais por moeda (transações de câmbio aparecem no relatório como categoria "Câmbio" — visualmente identificadas)
320
+
321
+ ### Para "comprei algo no exterior por $20"
322
+
323
+ No v0, a recomendação é **registrar como ajuste de saldo**: subtrair $20 do saldo atual da conta USD via `fin_ajustar_saldo_conta`. A categorização (que tipo de gasto foi) pode ser feita depois manualmente pela UI, ou simplesmente ignorada se não for crítica para o seu controle.
324
+
325
+ Lançar despesas categorizadas em USD pode entrar em uma versão futura se virar uma dor real.
package/index.mjs CHANGED
@@ -621,6 +621,92 @@ EXEMPLO — anular estorno que não abate (GitHub R$38,63):
621
621
  required: ["card_name", "cycle_end", "amount_cents"],
622
622
  },
623
623
  },
624
+ // ── Câmbio USD/BRL e ajuste manual de saldo ─────────────────────
625
+ {
626
+ name: "fin_cambio",
627
+ description: `Registra uma operação de câmbio (compra ou venda de dólar) entre uma conta BRL e uma conta USD. Cria 2 transações vinculadas com a categoria "Câmbio".
628
+
629
+ QUANDO USAR:
630
+ - Vender dólar: from = conta USD, to = conta BRL. Ex: "vendi $100 por R$540".
631
+ - Comprar dólar: from = conta BRL, to = conta USD. Ex: "comprei $50 por R$280".
632
+
633
+ NÃO USAR QUANDO:
634
+ - Quiser apenas atualizar o saldo de uma conta sem registrar a operação (use fin_ajustar_saldo_conta).
635
+ - Quiser lançar despesa em USD (não suportado no v0 — só câmbio).
636
+ - Quiser transferir entre contas da mesma moeda (use fin_criar_transferencia).
637
+
638
+ CAMPOS:
639
+ - from_account_name: string — conta de origem (a que fica negativa). Match parcial.
640
+ - to_account_name: string — conta de destino (a que fica positiva). Match parcial.
641
+ - amount_from_cents: number — valor que SAI da from_account, em centavos da moeda da conta. Ex: $100 = 10000 (centavos USD).
642
+ - amount_to_cents: number — valor que ENTRA na to_account, em centavos da moeda da conta. Ex: R$540 = 54000 (centavos BRL).
643
+ - tx_date: string YYYY-MM-DD — data (default: hoje).
644
+ - description: string — descrição livre (opcional).
645
+
646
+ REGRAS DE NEGÓCIO:
647
+ - As contas DEVEM ter moedas diferentes (uma BRL, outra USD).
648
+ - Cria 2 transações: uma despesa na from_account, uma receita na to_account.
649
+ - Ambas transações ficam linkadas via exchange_pair_id.
650
+ - A categoria "Câmbio" é criada automaticamente no primeiro uso.
651
+ - A taxa de câmbio é INFORMADA por você — não usa cotação automática.
652
+ - Operação atômica: se uma transação falhar, a outra é desfeita.
653
+
654
+ EXEMPLO — vender $100 por R$540:
655
+ { "from_account_name": "Wise USD", "to_account_name": "Itaú", "amount_from_cents": 10000, "amount_to_cents": 54000, "description": "Venda de dólar" }
656
+
657
+ EXEMPLO — comprar $50 por R$280:
658
+ { "from_account_name": "Itaú", "to_account_name": "Wise USD", "amount_from_cents": 28000, "amount_to_cents": 5000 }`,
659
+ inputSchema: {
660
+ type: "object",
661
+ properties: {
662
+ from_account_name: { type: "string", description: "Nome da conta de origem" },
663
+ to_account_name: { type: "string", description: "Nome da conta de destino" },
664
+ amount_from_cents: { type: "number", description: "Valor que SAI da origem, em centavos da moeda da conta" },
665
+ amount_to_cents: { type: "number", description: "Valor que ENTRA no destino, em centavos da moeda da conta" },
666
+ tx_date: { type: "string", description: "YYYY-MM-DD (default: hoje)" },
667
+ description: { type: "string", description: "Descrição livre (opcional)" },
668
+ },
669
+ required: ["from_account_name", "to_account_name", "amount_from_cents", "amount_to_cents"],
670
+ },
671
+ },
672
+ {
673
+ name: "fin_ajustar_saldo_conta",
674
+ description: `Atualiza o saldo de uma conta cash (BRL ou USD) diretamente, sem criar transação. Útil para correções e contas em USD que mudam sem motivo categórico.
675
+
676
+ QUANDO USAR:
677
+ - Conta USD: registrar quanto dólar você tem agora (ex: "achei mais $50 na carteira", "agora tenho $537").
678
+ - Conta BRL: corrigir saldo inicial após verificar extrato bancário.
679
+ - Onboarding: definir saldo inicial de uma conta recém-criada.
680
+
681
+ NÃO USAR QUANDO:
682
+ - Quiser registrar uma despesa ou receita categorizada (use fin_criar_despesa / fin_criar_receita).
683
+ - Quiser registrar câmbio entre contas (use fin_cambio).
684
+ - For uma conta de cartão de crédito (não suportado — cartão tem fatura).
685
+
686
+ CAMPOS:
687
+ - account_name: string — nome da conta (match parcial).
688
+ - amount_cents: number — novo saldo ABSOLUTO, em centavos da moeda da conta. Ex: $487 = 48700 (centavos USD); R$1.234,00 = 123400 (centavos BRL).
689
+
690
+ REGRAS DE NEGÓCIO:
691
+ - O valor é o SALDO ABSOLUTO, não um delta. Se a conta tinha $400 e você quer somar $50, passe 45000 (não 5000).
692
+ - Funciona para qualquer conta cash (BRL ou USD).
693
+ - Não cria transação — atualiza diretamente o initial_balance da conta.
694
+ - Não suportado para cartão de crédito.
695
+
696
+ EXEMPLO — atualizar saldo USD pra $537:
697
+ { "account_name": "Wise USD", "amount_cents": 53700 }
698
+
699
+ EXEMPLO — corrigir saldo BRL pra R$1.234,56:
700
+ { "account_name": "Itaú", "amount_cents": 123456 }`,
701
+ inputSchema: {
702
+ type: "object",
703
+ properties: {
704
+ account_name: { type: "string", description: "Nome da conta (match parcial)" },
705
+ amount_cents: { type: "number", description: "Novo saldo absoluto em centavos da moeda da conta" },
706
+ },
707
+ required: ["account_name", "amount_cents"],
708
+ },
709
+ },
624
710
  // ── Bills (Contas a Pagar) ──────────────────────────────────────
625
711
  {
626
712
  name: "fin_listar_bills",
@@ -1041,6 +1127,15 @@ async function handleTool(name, args) {
1041
1127
  case "fin_ajuste_fatura": {
1042
1128
  return ok(await api("POST", `/api/genius/card-invoice-adjustments`, args));
1043
1129
  }
1130
+ case "fin_cambio": {
1131
+ return ok(await api("POST", `/api/genius/exchange`, args));
1132
+ }
1133
+ case "fin_ajustar_saldo_conta": {
1134
+ const { account_name, amount_cents } = args;
1135
+ return ok(
1136
+ await api("POST", `/api/genius/accounts/${encodeURIComponent(account_name)}/balance`, { amount_cents })
1137
+ );
1138
+ }
1044
1139
  case "fin_listar_bills": {
1045
1140
  return ok(await api("GET", `/api/genius/bills`));
1046
1141
  }
@@ -1094,7 +1189,7 @@ async function handleTool(name, args) {
1094
1189
  // ── Server ──────────────────────────────────────────────────────────
1095
1190
 
1096
1191
  const server = new Server(
1097
- { name: "fin-app", version: "2.0.0" },
1192
+ { name: "fin-app", version: "2.2.0" },
1098
1193
  { capabilities: { tools: {}, resources: {} } }
1099
1194
  );
1100
1195
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "fin-app-mcp",
3
- "version": "2.1.0",
3
+ "version": "2.2.0",
4
4
  "description": "MCP server para o FIN App — finanças pessoais. Expõe tools para agents LLM operarem contas, despesas, faturas de cartão, bills recorrentes e mais.",
5
5
  "type": "module",
6
6
  "main": "index.mjs",