@gabrielerandelli/minus-tracker 0.7.0 → 0.8.1
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 +168 -32
- package/dist/cli/index.js +224 -82
- package/dist/cli/index.js.map +1 -1
- package/dist/index.cjs +179 -69
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +11 -1
- package/dist/index.d.ts +11 -1
- package/dist/index.js +179 -69
- package/dist/index.js.map +1 -1
- package/dist/mcp/index.js +1885 -0
- package/dist/mcp/index.js.map +1 -0
- package/package.json +18 -5
package/README.md
CHANGED
|
@@ -2,6 +2,21 @@
|
|
|
2
2
|
|
|
3
3
|
[](./LICENSE)
|
|
4
4
|
[](https://www.npmjs.com/package/@gabrielerandelli/minus-tracker)
|
|
5
|
+
[](https://www.npmjs.com/package/@gabrielerandelli/minus-tracker)
|
|
6
|
+
[](https://nodejs.org)
|
|
7
|
+
[](https://modelcontextprotocol.io)
|
|
8
|
+
|
|
9
|
+
⚠️ **Ausilio al calcolo, non consulenza fiscale** — vedi l'[Avvertenza](#avvertenza).
|
|
10
|
+
⚠️ **Calculation aid only, not tax advice** — see the [Disclaimer](#disclaimer).
|
|
11
|
+
|
|
12
|
+
🤖 **Novità: server MCP** — qualsiasi agente AI può calcolare plusvalenze/minusvalenze italiane direttamente, senza passare dalla CLI.
|
|
13
|
+
🤖 **New: MCP server** — any AI agent can compute Italian capital gains/losses directly, no CLI required.
|
|
14
|
+
|
|
15
|
+
✅ Validato su tutti i 12 scenari FAQ dell'Agenzia delle Entrate · 120 test automatici · zero dipendenze runtime nella libreria core.
|
|
16
|
+
✅ Validated against all 12 Agenzia delle Entrate FAQ scenarios · 120 automated tests · zero runtime dependencies in the core library.
|
|
17
|
+
|
|
18
|
+
_L'unico tool open-source che trasforma un export DEGIRO grezzo direttamente in plusvalenze/minusvalenze corrette secondo l'Agenzia delle Entrate — come CLI, libreria, o strumento MCP richiamabile dal tuo agente AI._
|
|
19
|
+
_The only open-source tool that turns a raw DEGIRO export directly into Agenzia-Entrate-correct capital gains/losses — as a CLI, a library, or an MCP tool your AI agent can call._
|
|
5
20
|
|
|
6
21
|
---
|
|
7
22
|
|
|
@@ -16,10 +31,23 @@ Il tool elabora i dati partendo direttamente dal formato CSV esportato da DEGIRO
|
|
|
16
31
|
- Calcolo di plusvalenze e minusvalenze con gestione dei lotti via **LIFO o FIFO** (configurabile)
|
|
17
32
|
- **Parser integrato** per i file CSV di DEGIRO
|
|
18
33
|
- Gestione **multivaluta** con tassi storici BCE (EUR, USD, GBP, CHF)
|
|
34
|
+
- **Classificazione fiscale degli strumenti finanziari in due categorie** (Bucket A/B) — azioni,
|
|
35
|
+
ETF, titoli di stato, derivati — con classificazione automatica tramite OpenFIGI e sidecar JSON
|
|
36
|
+
persistente
|
|
37
|
+
- **Modello Redditi PF**: genera Quadro RT (redditi diversi) e Quadro RM (redditi di capitale) a
|
|
38
|
+
partire dai lotti calcolati, con riporto delle minusvalenze pregresse (regola dei 4 anni)
|
|
19
39
|
- Suite di test allineata alle **FAQ dell'Agenzia delle Entrate**
|
|
20
40
|
- Output disponibile in **italiano** (default) o **inglese** (`--lang en`)
|
|
21
41
|
- Disponibile come pacchetto NPM con supporto CLI
|
|
22
42
|
|
|
43
|
+
**Novità in v0.8.0:**
|
|
44
|
+
|
|
45
|
+
- **Modalità stateless per `Classifier`**: `classify()` può ora funzionare senza alcun accesso al
|
|
46
|
+
filesystem (nessun sidecar), utile per l'integrazione con agenti e automazioni
|
|
47
|
+
- **Server MCP** (`minus-tracker-mcp`): espone `parse_transactions`, `classify_instruments` e
|
|
48
|
+
`calculate_gains` come tool MCP su stdio, per l'uso diretto da parte di agenti AI — vedi la
|
|
49
|
+
sezione [Server MCP](#server-mcp) più sotto
|
|
50
|
+
|
|
23
51
|
### Avvio rapido
|
|
24
52
|
|
|
25
53
|
Se non hai ancora un export di DEGIRO a disposizione, puoi testare il tool con il file di esempio incluso nel pacchetto.
|
|
@@ -85,15 +113,16 @@ npx @gabrielerandelli/minus-tracker calc trades.csv
|
|
|
85
113
|
|
|
86
114
|
### Utilizzo CLI
|
|
87
115
|
|
|
88
|
-
| Comando | Flag principali
|
|
89
|
-
| ---------------------- |
|
|
90
|
-
| `calc <file.csv>` | `--method LIFO\|FIFO` (default: LIFO), `--lang it\|en`, `--json` |
|
|
91
|
-
| `
|
|
92
|
-
| `
|
|
93
|
-
| `rates --
|
|
94
|
-
| `
|
|
95
|
-
| `config --
|
|
96
|
-
| `
|
|
116
|
+
| Comando | Flag principali | Note |
|
|
117
|
+
| ---------------------- | -------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
|
|
118
|
+
| `calc <file.csv>` | `--method LIFO\|FIFO` (default: LIFO), `--lang it\|en`, `--json`, `--export-dichiarazione [path]`, `--carry-forward` | Non aggiorna mai i tassi BCE da solo — esegui `rates --update` periodicamente; usa il sidecar di `classify` se presente |
|
|
119
|
+
| `classify <file.csv>` | `--offline` | Classifica gli strumenti (Bucket A/B) e crea/aggiorna il sidecar `*.classify.json` |
|
|
120
|
+
| `validate <file.csv>` | `--lang it\|en` | Exit 0 con avvisi; exit 1 in caso di errori bloccanti |
|
|
121
|
+
| `rates --check` | — | Mostra la copertura della snapshot BCE in locale |
|
|
122
|
+
| `rates --update` | — | Scarica i tassi aggiornati dall'API BCE |
|
|
123
|
+
| `config --lang it\|en` | — | Salva la lingua preferita |
|
|
124
|
+
| `config --show` | — | Mostra la lingua correntemente impostata |
|
|
125
|
+
| `stress-test` | `--range N-M`, `--keep`, `--json`, `--output-dir` | Documentato in fondo |
|
|
97
126
|
|
|
98
127
|
Precedenza lingua: `--lang` > lingua salvata > italiano (default).
|
|
99
128
|
|
|
@@ -128,6 +157,7 @@ npm install @gabrielerandelli/minus-tracker
|
|
|
128
157
|
import {
|
|
129
158
|
DEGIROParser,
|
|
130
159
|
Calculator,
|
|
160
|
+
Classifier,
|
|
131
161
|
ParseError,
|
|
132
162
|
CalculationError,
|
|
133
163
|
} from "@gabrielerandelli/minus-tracker";
|
|
@@ -140,19 +170,25 @@ if (parser.warnings.length > 0) {
|
|
|
140
170
|
console.warn("Righe saltate:", parser.warnings);
|
|
141
171
|
}
|
|
142
172
|
|
|
143
|
-
// 2.
|
|
144
|
-
const
|
|
145
|
-
const report: GainsReport = new Calculator(
|
|
173
|
+
// 2. Classificazione (Bucket A/B) — facoltativa, abilita Quadro RT/RM nel report
|
|
174
|
+
const classification = await new Classifier().classify(
|
|
146
175
|
transactions,
|
|
147
|
-
|
|
148
|
-
)
|
|
176
|
+
"trades.classify.json", // sidecar persistente; assente in modalità stateless
|
|
177
|
+
);
|
|
178
|
+
|
|
179
|
+
// 3. Calcolo
|
|
180
|
+
const method: LotMethod = "LIFO"; // oppure "FIFO"
|
|
181
|
+
const report: GainsReport = new Calculator(transactions, parser.warnings, {
|
|
182
|
+
classification,
|
|
183
|
+
}).calculateGains(method);
|
|
149
184
|
|
|
150
185
|
console.log(report.plusvalenze); // numero in EUR
|
|
151
186
|
console.log(report.minusvalenze); // numero in EUR (valore assoluto)
|
|
152
187
|
console.log(report.netResult); // plusvalenze - minusvalenze
|
|
153
188
|
console.log(report.lots); // MatchedLot[] — dettaglio per lotto
|
|
189
|
+
console.log(report.dichiarazione); // Quadro RT/RM, se classification è stata passata
|
|
154
190
|
|
|
155
|
-
//
|
|
191
|
+
// 4. Gestione errori
|
|
156
192
|
try {
|
|
157
193
|
const txs = parser.parse(csvString);
|
|
158
194
|
const r = new Calculator(txs, parser.warnings).calculateGains("LIFO");
|
|
@@ -177,6 +213,46 @@ try {
|
|
|
177
213
|
|
|
178
214
|
**Prerequisiti:** Node.js ≥ 24 ([nodejs.org](https://nodejs.org))
|
|
179
215
|
|
|
216
|
+
### Server MCP
|
|
217
|
+
|
|
218
|
+
A partire dalla v0.8.0, minus-tracker include un binario `minus-tracker-mcp` che espone un
|
|
219
|
+
[server MCP](https://modelcontextprotocol.io) su stdio, pensato per l'uso diretto da parte di
|
|
220
|
+
agenti AI (senza passare dalla CLI):
|
|
221
|
+
|
|
222
|
+
```bash
|
|
223
|
+
npx -p @gabrielerandelli/minus-tracker minus-tracker-mcp
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
Configurazione tipica per un client MCP (es. Claude Desktop, `claude_desktop_config.json`):
|
|
227
|
+
|
|
228
|
+
```json
|
|
229
|
+
{
|
|
230
|
+
"mcpServers": {
|
|
231
|
+
"minus-tracker": {
|
|
232
|
+
"command": "npx",
|
|
233
|
+
"args": [
|
|
234
|
+
"-y",
|
|
235
|
+
"-p",
|
|
236
|
+
"@gabrielerandelli/minus-tracker",
|
|
237
|
+
"minus-tracker-mcp"
|
|
238
|
+
]
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
```
|
|
243
|
+
|
|
244
|
+
Il server espone 3 tool:
|
|
245
|
+
|
|
246
|
+
| Tool | Descrizione |
|
|
247
|
+
| ---------------------- | -------------------------------------------------------------------------------------- |
|
|
248
|
+
| `parse_transactions` | Esegue il parsing di un CSV DEGIRO, restituendo `transactions`/`warnings`/`incomeRows` |
|
|
249
|
+
| `classify_instruments` | Classifica gli ISIN in Bucket A/B (modalità stateless — nessun sidecar) |
|
|
250
|
+
| `calculate_gains` | Calcola plusvalenze/minusvalenze (LIFO/FIFO) e, se disponibile, Quadro RT/RM |
|
|
251
|
+
|
|
252
|
+
`classify_instruments` supporta `existingClassification`, `overrides` e `offline: true` per
|
|
253
|
+
funzionare senza rete e senza accesso al filesystem — pensato per essere invocato ripetutamente
|
|
254
|
+
da un agente in chiamate successive, mantenendo lo stato lato client.
|
|
255
|
+
|
|
180
256
|
### Domande frequenti
|
|
181
257
|
|
|
182
258
|
**Il CSV viene rifiutato con "colonna mancante" o "CSV non valido"**
|
|
@@ -189,7 +265,7 @@ Le righe vengono saltate (senza bloccare il calcolo) quando: l'ISIN è vuoto, la
|
|
|
189
265
|
Il CSV contiene una vendita per un titolo senza un acquisto precedente nel file. L'acquisto potrebbe essere in un export di un anno precedente non incluso. Usa `validate` per esaminare le transazioni parsate.
|
|
190
266
|
|
|
191
267
|
**I tassi BCE sono scaduti**
|
|
192
|
-
Esegui `minus-tracker rates --update`. Il comando `calc`
|
|
268
|
+
Esegui `minus-tracker rates --update`. Il comando `calc` non aggiorna mai i tassi da solo: l'aggiornamento è sempre un'azione esplicita.
|
|
193
269
|
|
|
194
270
|
**LIFO o FIFO?**
|
|
195
271
|
Il Regime Dichiarativo utilizza il LIFO come metodo predefinito ai sensi della normativa fiscale italiana. Il FIFO è disponibile per confronto. Consulta il tuo commercialista per conferma.
|
|
@@ -251,10 +327,22 @@ It loads data following the CSV format used by DEGIRO.
|
|
|
251
327
|
- Capital-gains/loss calculation with configurable **LIFO and FIFO** lot matching
|
|
252
328
|
- **DEGIRO CSV parser**
|
|
253
329
|
- **Multi-currency** handling with historical ECB rates (EUR, USD, GBP, CHF)
|
|
330
|
+
- **Two-bucket classification** (Bucket A/B) of financial instruments — stocks, ETFs, government
|
|
331
|
+
bonds, derivatives — with automatic OpenFIGI-backed classification and a persistent JSON sidecar
|
|
332
|
+
- **Modello Redditi PF** generation: Quadro RT (capital gains) and Quadro RM (capital income) built
|
|
333
|
+
from the calculated lots, with prior-year loss carryforward (4-year rule)
|
|
254
334
|
- Test suite based on **Agenzia Entrate FAQ**
|
|
255
335
|
- Output in **Italian** (default) or **English** (`--lang en`)
|
|
256
336
|
- minus-tracker is an NPM package with CLI support
|
|
257
337
|
|
|
338
|
+
**New in v0.8.0:**
|
|
339
|
+
|
|
340
|
+
- **Stateless mode for `Classifier`**: `classify()` can now run with zero filesystem access (no
|
|
341
|
+
sidecar file), useful for embedding in agents/automations
|
|
342
|
+
- **MCP server** (`minus-tracker-mcp`): exposes `parse_transactions`, `classify_instruments`, and
|
|
343
|
+
`calculate_gains` as MCP tools over stdio, for direct use by AI agents — see the
|
|
344
|
+
[MCP Server](#mcp-server) section below
|
|
345
|
+
|
|
258
346
|
### Quick Start
|
|
259
347
|
|
|
260
348
|
Don't have a DEGIRO export yet? Use the sample file bundled with the package.
|
|
@@ -321,15 +409,16 @@ npx @gabrielerandelli/minus-tracker calc trades.csv
|
|
|
321
409
|
|
|
322
410
|
### CLI Usage
|
|
323
411
|
|
|
324
|
-
| Command | Key flags
|
|
325
|
-
| ---------------------- |
|
|
326
|
-
| `calc <file.csv>` | `--method LIFO\|FIFO` (default: LIFO), `--lang it\|en`, `--json` |
|
|
327
|
-
| `
|
|
328
|
-
| `
|
|
329
|
-
| `rates --
|
|
330
|
-
| `
|
|
331
|
-
| `config --
|
|
332
|
-
| `
|
|
412
|
+
| Command | Key flags | Notes |
|
|
413
|
+
| ---------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
|
|
414
|
+
| `calc <file.csv>` | `--method LIFO\|FIFO` (default: LIFO), `--lang it\|en`, `--json`, `--export-dichiarazione [path]`, `--carry-forward` | Never fetches ECB rates on its own — run `rates --update` periodically; uses `classify`'s sidecar when present |
|
|
415
|
+
| `classify <file.csv>` | `--offline` | Classifies instruments (Bucket A/B) and creates/updates the `*.classify.json` sidecar |
|
|
416
|
+
| `validate <file.csv>` | `--lang it\|en` | Exit 0 with warnings; exit 1 on hard errors |
|
|
417
|
+
| `rates --check` | — | Shows bundled ECB snapshot coverage |
|
|
418
|
+
| `rates --update` | — | Fetches fresh rates from the ECB API |
|
|
419
|
+
| `config --lang it\|en` | — | Saves language preference |
|
|
420
|
+
| `config --show` | — | Shows current language setting |
|
|
421
|
+
| `stress-test` | `--range N-M`, `--keep`, `--json`, `--output-dir` | Documented below |
|
|
333
422
|
|
|
334
423
|
Language precedence: `--lang` flag > saved config > Italian (default).
|
|
335
424
|
|
|
@@ -364,6 +453,7 @@ npm install @gabrielerandelli/minus-tracker
|
|
|
364
453
|
import {
|
|
365
454
|
DEGIROParser,
|
|
366
455
|
Calculator,
|
|
456
|
+
Classifier,
|
|
367
457
|
ParseError,
|
|
368
458
|
CalculationError,
|
|
369
459
|
} from "@gabrielerandelli/minus-tracker";
|
|
@@ -376,19 +466,25 @@ if (parser.warnings.length > 0) {
|
|
|
376
466
|
console.warn("Skipped rows:", parser.warnings);
|
|
377
467
|
}
|
|
378
468
|
|
|
379
|
-
// 2.
|
|
380
|
-
const
|
|
381
|
-
const report: GainsReport = new Calculator(
|
|
469
|
+
// 2. Classify (Bucket A/B) — optional, enables Quadro RT/RM in the report
|
|
470
|
+
const classification = await new Classifier().classify(
|
|
382
471
|
transactions,
|
|
383
|
-
|
|
384
|
-
)
|
|
472
|
+
"trades.classify.json", // persistent sidecar; omit for stateless mode
|
|
473
|
+
);
|
|
474
|
+
|
|
475
|
+
// 3. Calculate
|
|
476
|
+
const method: LotMethod = "LIFO"; // or "FIFO"
|
|
477
|
+
const report: GainsReport = new Calculator(transactions, parser.warnings, {
|
|
478
|
+
classification,
|
|
479
|
+
}).calculateGains(method);
|
|
385
480
|
|
|
386
481
|
console.log(report.plusvalenze); // EUR capital gains (number)
|
|
387
482
|
console.log(report.minusvalenze); // EUR capital losses (number, absolute value)
|
|
388
483
|
console.log(report.netResult); // plusvalenze - minusvalenze
|
|
389
484
|
console.log(report.lots); // MatchedLot[] — per-lot breakdown
|
|
485
|
+
console.log(report.dichiarazione); // Quadro RT/RM, when classification was passed
|
|
390
486
|
|
|
391
|
-
//
|
|
487
|
+
// 4. Error handling
|
|
392
488
|
try {
|
|
393
489
|
const txs = parser.parse(csvString);
|
|
394
490
|
const r = new Calculator(txs, parser.warnings).calculateGains("LIFO");
|
|
@@ -411,6 +507,46 @@ minus-tracker is **pure tax math** — no UI, auth, database, or PDF.
|
|
|
411
507
|
|
|
412
508
|
**Prerequisites:** Node.js ≥ 24 ([nodejs.org](https://nodejs.org))
|
|
413
509
|
|
|
510
|
+
### MCP Server
|
|
511
|
+
|
|
512
|
+
As of v0.8.0, minus-tracker ships a `minus-tracker-mcp` binary exposing an
|
|
513
|
+
[MCP server](https://modelcontextprotocol.io) over stdio, for direct use by AI agents (no need to
|
|
514
|
+
go through the CLI):
|
|
515
|
+
|
|
516
|
+
```bash
|
|
517
|
+
npx -p @gabrielerandelli/minus-tracker minus-tracker-mcp
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
Typical MCP client configuration (e.g. Claude Desktop, `claude_desktop_config.json`):
|
|
521
|
+
|
|
522
|
+
```json
|
|
523
|
+
{
|
|
524
|
+
"mcpServers": {
|
|
525
|
+
"minus-tracker": {
|
|
526
|
+
"command": "npx",
|
|
527
|
+
"args": [
|
|
528
|
+
"-y",
|
|
529
|
+
"-p",
|
|
530
|
+
"@gabrielerandelli/minus-tracker",
|
|
531
|
+
"minus-tracker-mcp"
|
|
532
|
+
]
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
}
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
The server exposes 3 tools:
|
|
539
|
+
|
|
540
|
+
| Tool | Description |
|
|
541
|
+
| ---------------------- | --------------------------------------------------------------------- |
|
|
542
|
+
| `parse_transactions` | Parses a DEGIRO CSV into `transactions`/`warnings`/`incomeRows` |
|
|
543
|
+
| `classify_instruments` | Classifies ISINs into Bucket A/B (stateless mode — no sidecar file) |
|
|
544
|
+
| `calculate_gains` | Calculates gains/losses (LIFO/FIFO) and, when available, Quadro RT/RM |
|
|
545
|
+
|
|
546
|
+
`classify_instruments` supports `existingClassification`, `overrides`, and `offline: true` to run
|
|
547
|
+
without network access or filesystem access — designed to be called repeatedly by an agent across
|
|
548
|
+
multiple calls, with state kept client-side.
|
|
549
|
+
|
|
414
550
|
### FAQ / Troubleshooting
|
|
415
551
|
|
|
416
552
|
**My CSV is rejected with "missing column" or "invalid CSV"**
|
|
@@ -423,7 +559,7 @@ Rows are skipped (without aborting the calculation) when: the ISIN is empty, the
|
|
|
423
559
|
The CSV contains a SELL for a position that has no prior BUY in the same file. The BUY may be in a prior year's export that was not included. Use `validate` to inspect the parsed transactions.
|
|
424
560
|
|
|
425
561
|
**ECB rates are outdated**
|
|
426
|
-
Run `minus-tracker rates --update`. The `calc` command
|
|
562
|
+
Run `minus-tracker rates --update`. The `calc` command never fetches rates on its own — refreshing is always an explicit, user-invoked action.
|
|
427
563
|
|
|
428
564
|
**LIFO or FIFO?**
|
|
429
565
|
LIFO is the standard lot-matching method under Italian tax law for the Regime Dichiarativo. FIFO is available for comparison or other jurisdictions. Consult your tax advisor for confirmation.
|