e-arveldaja-mcp 0.17.0 → 0.18.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.
- package/.claude/commands/accounting-inbox.md +1 -1
- package/.claude/commands/book-invoice.md +6 -5
- package/.claude/commands/classify-unmatched.md +8 -4
- package/.claude/commands/company-overview.md +2 -1
- package/.claude/commands/import-camt.md +9 -7
- package/.claude/commands/import-wise.md +1 -1
- package/.claude/commands/lightyear-booking.md +6 -6
- package/.claude/commands/month-end.md +1 -1
- package/.claude/commands/prepare-accounting-review-action.md +2 -2
- package/.claude/commands/receipt-batch.md +3 -3
- package/.claude/commands/reconcile-bank.md +10 -11
- package/.claude/commands/resolve-accounting-review.md +2 -2
- package/.claude/commands/setup-credentials.md +3 -1
- package/CHANGELOG.md +30 -0
- package/CLAUDE.md +84 -12
- package/README.md +12 -5
- package/dist/accounting-defaults.d.ts +25 -0
- package/dist/accounting-defaults.d.ts.map +1 -1
- package/dist/accounting-defaults.js +25 -0
- package/dist/accounting-defaults.js.map +1 -1
- package/dist/api/purchase-invoices.api.d.ts.map +1 -1
- package/dist/api/purchase-invoices.api.js +5 -1
- package/dist/api/purchase-invoices.api.js.map +1 -1
- package/dist/config.d.ts +81 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +7 -0
- package/dist/config.js.map +1 -1
- package/dist/estonian-tax-rules.d.ts +27 -3
- package/dist/estonian-tax-rules.d.ts.map +1 -1
- package/dist/estonian-tax-rules.js +35 -7
- package/dist/estonian-tax-rules.js.map +1 -1
- package/dist/http-client.js +1 -1
- package/dist/http-client.js.map +1 -1
- package/dist/index.js +130 -117
- package/dist/index.js.map +1 -1
- package/dist/invoice-extraction-fallback.d.ts +1 -1
- package/dist/invoice-extraction-fallback.d.ts.map +1 -1
- package/dist/invoice-extraction-fallback.js +7 -2
- package/dist/invoice-extraction-fallback.js.map +1 -1
- package/dist/prompts.d.ts +2 -1
- package/dist/prompts.d.ts.map +1 -1
- package/dist/prompts.js +26 -20
- package/dist/prompts.js.map +1 -1
- package/dist/tools/account-balance.d.ts.map +1 -1
- package/dist/tools/account-balance.js +7 -5
- package/dist/tools/account-balance.js.map +1 -1
- package/dist/tools/accounting-inbox.d.ts +2 -1
- package/dist/tools/accounting-inbox.d.ts.map +1 -1
- package/dist/tools/accounting-inbox.js +103 -54
- package/dist/tools/accounting-inbox.js.map +1 -1
- package/dist/tools/aging-analysis.d.ts +2 -1
- package/dist/tools/aging-analysis.d.ts.map +1 -1
- package/dist/tools/aging-analysis.js +80 -76
- package/dist/tools/aging-analysis.js.map +1 -1
- package/dist/tools/annual-report.d.ts.map +1 -1
- package/dist/tools/annual-report.js +68 -6
- package/dist/tools/annual-report.js.map +1 -1
- package/dist/tools/bank-reconciliation.d.ts +2 -1
- package/dist/tools/bank-reconciliation.d.ts.map +1 -1
- package/dist/tools/bank-reconciliation.js +13 -3
- package/dist/tools/bank-reconciliation.js.map +1 -1
- package/dist/tools/camt-import.d.ts +2 -1
- package/dist/tools/camt-import.d.ts.map +1 -1
- package/dist/tools/camt-import.js +11 -45
- package/dist/tools/camt-import.js.map +1 -1
- package/dist/tools/crud/clients.js +1 -1
- package/dist/tools/crud/clients.js.map +1 -1
- package/dist/tools/crud/journals.js +2 -2
- package/dist/tools/crud/journals.js.map +1 -1
- package/dist/tools/crud/transactions.d.ts.map +1 -1
- package/dist/tools/crud/transactions.js +6 -8
- package/dist/tools/crud/transactions.js.map +1 -1
- package/dist/tools/crud-tools.d.ts +2 -1
- package/dist/tools/crud-tools.d.ts.map +1 -1
- package/dist/tools/crud-tools.js +7 -4
- package/dist/tools/crud-tools.js.map +1 -1
- package/dist/tools/currency-rounding.d.ts.map +1 -1
- package/dist/tools/currency-rounding.js +13 -1
- package/dist/tools/currency-rounding.js.map +1 -1
- package/dist/tools/estonian-tax.d.ts +16 -1
- package/dist/tools/estonian-tax.d.ts.map +1 -1
- package/dist/tools/estonian-tax.js +194 -30
- package/dist/tools/estonian-tax.js.map +1 -1
- package/dist/tools/lightyear-investments.d.ts.map +1 -1
- package/dist/tools/lightyear-investments.js +23 -13
- package/dist/tools/lightyear-investments.js.map +1 -1
- package/dist/tools/pdf-workflow.d.ts.map +1 -1
- package/dist/tools/pdf-workflow.js +17 -12
- package/dist/tools/pdf-workflow.js.map +1 -1
- package/dist/tools/purchase-vat-defaults.js +1 -1
- package/dist/tools/purchase-vat-defaults.js.map +1 -1
- package/dist/tools/receipt-inbox.d.ts +2 -1
- package/dist/tools/receipt-inbox.d.ts.map +1 -1
- package/dist/tools/receipt-inbox.js +36 -18
- package/dist/tools/receipt-inbox.js.map +1 -1
- package/dist/tools/reference-data-tools.d.ts +2 -1
- package/dist/tools/reference-data-tools.d.ts.map +1 -1
- package/dist/tools/reference-data-tools.js +186 -171
- package/dist/tools/reference-data-tools.js.map +1 -1
- package/dist/tools/workflow-recommendations.d.ts +2 -1
- package/dist/tools/workflow-recommendations.d.ts.map +1 -1
- package/dist/tools/workflow-recommendations.js +50 -5
- package/dist/tools/workflow-recommendations.js.map +1 -1
- package/dist/workflow-response.d.ts +24 -0
- package/dist/workflow-response.d.ts.map +1 -1
- package/dist/workflow-response.js +100 -0
- package/dist/workflow-response.js.map +1 -1
- package/package.json +4 -4
- package/server.json +2 -2
- package/workflows/accounting-inbox.md +1 -1
- package/workflows/book-invoice.md +6 -5
- package/workflows/classify-unmatched.md +8 -4
- package/workflows/company-overview.md +2 -1
- package/workflows/import-camt.md +9 -7
- package/workflows/import-wise.md +1 -1
- package/workflows/lightyear-booking.md +6 -6
- package/workflows/month-end.md +1 -1
- package/workflows/prepare-accounting-review-action.md +2 -2
- package/workflows/receipt-batch.md +3 -3
- package/workflows/reconcile-bank.md +10 -11
- package/workflows/resolve-accounting-review.md +2 -2
- package/workflows/setup-credentials.md +3 -1
|
@@ -56,7 +56,7 @@ If there are no unresolved questions, continue immediately.
|
|
|
56
56
|
If `autopilot.next_recommended_action` is present, treat it as the default next safe step.
|
|
57
57
|
If `autopilot.next_question` is present, use it as the first follow-up question when no safer dry-run step should happen first.
|
|
58
58
|
|
|
59
|
-
### Step 4:
|
|
59
|
+
### Step 4: Continue with the recommended dry-run steps
|
|
60
60
|
|
|
61
61
|
The autopilot already ran the safe default dry-run steps.
|
|
62
62
|
- do not repeat them unless the user asks
|
|
@@ -78,15 +78,16 @@ Call `detect_duplicate_purchase_invoice` with:
|
|
|
78
78
|
- `gross_price`: extracted gross total
|
|
79
79
|
- `clients_id`: resolved client ID if step 4 returned `found=true`
|
|
80
80
|
|
|
81
|
-
Inspect
|
|
82
|
-
-
|
|
81
|
+
Inspect the result:
|
|
82
|
+
- Check `candidate_invoice_number_matches` and `candidate_same_amount_date_matches` first.
|
|
83
|
+
- Review `exact_duplicates` and `suspicious_same_amount_date` as warning context.
|
|
83
84
|
- If a candidate looks like the same invoice, stop and report it before creating anything.
|
|
84
85
|
|
|
85
86
|
## Step 6: Prepare the supplier client decision
|
|
86
87
|
|
|
87
88
|
- If step 4 returned `found=true`, use `client.id` as `supplier_client_id`.
|
|
88
89
|
- If no existing supplier was found, do NOT create the supplier yet. Treat the new supplier as part of the approval card and keep the extracted name, registry code, VAT number, IBAN, country, and registry data ready for the post-approval call.
|
|
89
|
-
- For a new supplier, say clearly in the approval card that the new supplier record will be created after approval before the invoice is created.
|
|
90
|
+
- For a new supplier, say clearly in the approval card that the new supplier record will be created after approval, before the invoice is created.
|
|
90
91
|
|
|
91
92
|
## Step 7: Reuse the best booking setup
|
|
92
93
|
|
|
@@ -132,7 +133,7 @@ If there is no suitable history, call `list_purchase_articles` or ask the user i
|
|
|
132
133
|
|
|
133
134
|
Before creating anything, present one approval card:
|
|
134
135
|
- Supplier name and supplier client ID when an existing supplier was found
|
|
135
|
-
- For a new supplier: supplier name, registry code, VAT number, IBAN, country, and registry/address data, plus the explicit note that a new supplier record will be created after approval before the invoice is created
|
|
136
|
+
- For a new supplier: supplier name, registry code, VAT number, IBAN, country, and registry/address data, plus the explicit note that a new supplier record will be created after approval, before the invoice is created
|
|
136
137
|
- Invoice number, invoice date, due date, journal date, and term days
|
|
137
138
|
- Net / VAT / gross amounts
|
|
138
139
|
- Currency, `currency_rate`, and any `base_gross_price` / other `base_*` EUR totals for non-EUR invoices
|
|
@@ -168,7 +169,7 @@ Call `create_purchase_invoice_from_pdf`:
|
|
|
168
169
|
- `notes`: leave empty by default; use it only for genuinely useful context such as assumptions made or manual adjustments. Do NOT put the source document filename here — the document is auto-uploaded and attached via `file_path` below.
|
|
169
170
|
- `file_path`: the original file path (auto-uploads the source document)
|
|
170
171
|
|
|
171
|
-
Use the exact `vat_price` and `gross_price` from the invoice
|
|
172
|
+
Use the exact `vat_price` and `gross_price` from the invoice; do not recalculate them. Omit them only when they are genuinely unknown.
|
|
172
173
|
If source document upload fails after invoice creation, the draft invoice is invalidated.
|
|
173
174
|
|
|
174
175
|
## Step 12: Confirm and report
|
|
@@ -29,7 +29,7 @@ Call `classify_bank_transactions`:
|
|
|
29
29
|
- `accounts_dimensions_id`: the confirmed or provided dimension ID
|
|
30
30
|
- include `date_from` / `date_to` when provided
|
|
31
31
|
|
|
32
|
-
Fallback compatibility primitive: `classify_unmatched_transactions`
|
|
32
|
+
Fallback compatibility primitive: `classify_unmatched_transactions` is registered only when `EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`; by default use `classify_bank_transactions` with `mode="classify"`. Do not mention fallback tool names to the user.
|
|
33
33
|
|
|
34
34
|
Show:
|
|
35
35
|
- `result.total_unconfirmed`
|
|
@@ -59,15 +59,19 @@ Call `classify_bank_transactions`:
|
|
|
59
59
|
- mode: "dry_run_apply"
|
|
60
60
|
- `classifications_json`: `JSON.stringify(the result payload from step 1)`
|
|
61
61
|
|
|
62
|
-
Fallback compatibility primitive: `apply_transaction_classifications`
|
|
62
|
+
Fallback compatibility primitive: `apply_transaction_classifications` is registered only when `EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`; by default use `classify_bank_transactions` with `mode="dry_run_apply"` / `mode="execute_apply"`.
|
|
63
63
|
|
|
64
|
-
|
|
64
|
+
Read the result:
|
|
65
65
|
- Treat `result.execution` as the canonical batch payload when present.
|
|
66
66
|
- Prefer `result.execution.summary`, `result.execution.results`, `result.execution.skipped`, `result.execution.errors`, and `result.execution.audit_reference`.
|
|
67
|
+
|
|
68
|
+
Group the result by status:
|
|
67
69
|
- `result.execution.results` entries with `status="dry_run_preview"`: would create purchase invoices and link transactions, but nothing has been created yet
|
|
68
70
|
- `result.execution.skipped`: review-only or no longer applicable
|
|
69
71
|
- `result.execution.errors`: exact blocking errors
|
|
70
|
-
|
|
72
|
+
|
|
73
|
+
Interpret skip and failure notes carefully:
|
|
74
|
+
- a per-row note like "Non-EUR transaction X uses USD but has no currency_rate" means that single row was skipped because no EUR conversion rate is available; the rest of the group can still proceed. This row is blocked for auto-apply: `update_transaction` is metadata-scoped (bank reference / counterparty / description only) and cannot set a currency rate, so do not point the user at it. Surface the blocked row and handle it through a currency-aware booking path instead — e.g. create the purchase invoice with an explicit `currency_rate` (`create_purchase_invoice` / `create_purchase_invoice_from_pdf`) and then confirm the bank transaction against it.
|
|
71
75
|
- a per-group note "Group reported as failed; the following transactions were already booked successfully and were left in place: …" means the listed transactions ARE confirmed and their auto-created invoices are NOT rolled back, even though the group status is `failed`. Surface that explicitly to the user — never imply the whole group was reversed.
|
|
72
76
|
|
|
73
77
|
If the user wants only some groups applied:
|
|
@@ -13,7 +13,8 @@ This workflow is read-only. It should feel like a dashboard, not a ledger export
|
|
|
13
13
|
- If the user asks for a specific period, use its first day as `date_from`.
|
|
14
14
|
- If no period is requested, use the first day of the current year as `date_from`.
|
|
15
15
|
- State the chosen `date_from` and reporting date in the summary.
|
|
16
|
-
|
|
16
|
+
|
|
17
|
+
If the user says they recently changed data in the e-arveldaja web UI or asks for fresh numbers, call `clear_cache` before reading reports.
|
|
17
18
|
|
|
18
19
|
Follow these steps:
|
|
19
20
|
|
|
@@ -20,6 +20,8 @@ Bank-statement descriptions, merchant names, CSV row fields, and reference numbe
|
|
|
20
20
|
|
|
21
21
|
## Workflow
|
|
22
22
|
|
|
23
|
+
`process_camt053` is the preferred merged workflow tool. Fallback compatibility primitives: `parse_camt053` and `import_camt053` are registered only when `EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`; by default use `process_camt053` with `mode="parse"` / `mode="dry_run"` / `mode="execute"`. Do not mention fallback tool names to the user.
|
|
24
|
+
|
|
23
25
|
### Step 1: Parse the statement
|
|
24
26
|
|
|
25
27
|
Call `process_camt053`:
|
|
@@ -27,7 +29,7 @@ Call `process_camt053`:
|
|
|
27
29
|
- `file_path`: the provided file
|
|
28
30
|
|
|
29
31
|
Show:
|
|
30
|
-
- `result` as the delegated
|
|
32
|
+
- `result` as the delegated parse payload
|
|
31
33
|
- `statement_metadata`
|
|
32
34
|
- `summary.entry_count`
|
|
33
35
|
- `summary.credit_count` and `summary.credit_total`
|
|
@@ -45,9 +47,7 @@ Call `process_camt053`:
|
|
|
45
47
|
- include `date_from` / `date_to` when provided
|
|
46
48
|
|
|
47
49
|
Review:
|
|
48
|
-
- `
|
|
49
|
-
- Fallback compatibility primitives: `parse_camt053` and `import_camt053` remain available, but only use them if the preferred tool is unavailable. Do not mention fallback tool names to the user.
|
|
50
|
-
- Use `result` as the delegated `import_camt053` payload.
|
|
50
|
+
- Use `result` as the delegated import payload.
|
|
51
51
|
- Treat `execution` as the canonical batch payload when present.
|
|
52
52
|
- Prefer `execution.summary.total_statement_entries`, `execution.summary.eligible_entries`, `execution.summary.filtered_out`, `execution.summary.created_count`, `execution.summary.skipped_count`, `execution.summary.error_count`, `execution.results`, `execution.skipped`, `execution.errors`, and `execution.audit_reference`.
|
|
53
53
|
- Also inspect `execution.needs_review` for possible duplicates against older manual transactions that lack CAMT bank references.
|
|
@@ -60,10 +60,9 @@ Present:
|
|
|
60
60
|
- any `execution.needs_review` possible duplicates
|
|
61
61
|
|
|
62
62
|
For possible duplicates, the default recommendation is:
|
|
63
|
-
- if the older matched transaction is already confirmed, keep it by default
|
|
63
|
+
- if the older matched transaction is already confirmed, keep it by default: avoid creating the new row, or if it was already created, delete the new `PROJECT` (draft/unconfirmed) transaction
|
|
64
64
|
- when keep/delete IDs are known, prefer `cleanup_camt_possible_duplicate` to enrich the kept transaction and delete the newly imported duplicate
|
|
65
65
|
- fall back to `update_transaction` plus `delete_transaction` only when the cleanup tool cannot be called
|
|
66
|
-
- then avoid creating, or if already created, delete the new `PROJECT` (draft/unconfirmed) transaction
|
|
67
66
|
- if the older match is PROJECT (unconfirmed), present its current state and offer to confirm it inline using `confirm_transaction` (or `reconcile_inter_account_transfers` for inter-account transfers). Do NOT defer it to manual UI work in e-arveldaja — the agent has the IDs and amounts loaded, so the natural next step is to ask the user yes/no for inline confirmation.
|
|
68
67
|
|
|
69
68
|
Do not suggest overwriting curated manual fields like description or reference when they are already filled.
|
|
@@ -93,7 +92,10 @@ Report:
|
|
|
93
92
|
- `execution.summary.created_count`
|
|
94
93
|
- `execution.summary.skipped_count`
|
|
95
94
|
- `execution.summary.error_count`
|
|
96
|
-
- any `execution.needs_review` possible duplicates — group similar duplicate decisions, show the first 10 plus counts, then propose one batch-friendly inline action set with clear exceptions
|
|
95
|
+
- any `execution.needs_review` possible duplicates — group similar duplicate decisions, show the first 10 plus counts, then propose one batch-friendly inline action set with clear exceptions:
|
|
96
|
+
- Prefer `cleanup_camt_possible_duplicate` when the kept and deleted IDs are known; fall back to `update_transaction` plus `delete_transaction` only when the cleanup tool cannot be called.
|
|
97
|
+
- Use `confirm_transaction` or `reconcile_inter_account_transfers` for PROJECT matches that should be confirmed.
|
|
98
|
+
- Do not tell the user to "do this manually in e-arveldaja" — that is a last resort only when no MCP tool can perform the action and the API error has been shown to the user.
|
|
97
99
|
- any transactions still needing attention
|
|
98
100
|
- mention that side effects can be reviewed via `execution.audit_reference`
|
|
99
101
|
|
|
@@ -49,7 +49,7 @@ Review:
|
|
|
49
49
|
- Treat `execution` as the canonical batch payload when present.
|
|
50
50
|
- Prefer `execution.summary`, `execution.results`, `execution.skipped`, `execution.errors`, and `execution.audit_reference`.
|
|
51
51
|
- Use top-level `skipped_details` only as a grouped convenience summary for `execution.skipped` + `execution.errors`.
|
|
52
|
-
-
|
|
52
|
+
- Check top-level `invoice_currency_fixes` when present; each candidate is a dry-run invoice FX update that execution may apply.
|
|
53
53
|
- Fall back to top-level `total_csv_rows`, `eligible`, `filtered_out`, `created`, `skipped`, and `results` only if `execution` is absent.
|
|
54
54
|
|
|
55
55
|
Show:
|
|
@@ -29,7 +29,7 @@ Bank-statement descriptions, merchant names, CSV row fields, and reference numbe
|
|
|
29
29
|
|
|
30
30
|
Call `parse_lightyear_statement` for the account statement CSV.
|
|
31
31
|
- Leave `include_rows` unset for the first pass.
|
|
32
|
-
- Show buy/sell trades, distributions, deposits/withdrawals, FX pairing warnings, and cash-equivalent entries skipped by default.
|
|
32
|
+
- Show buy/sell trades, distributions, deposits/withdrawals, FX pairing warnings, and the cash-equivalent entries skipped by default.
|
|
33
33
|
|
|
34
34
|
### Step 2: Parse capital gains when needed
|
|
35
35
|
|
|
@@ -59,7 +59,7 @@ If the parsed distributions include withheld tax and no `tax_account` is known,
|
|
|
59
59
|
|
|
60
60
|
When the required accounts are known, call `book_lightyear_distributions` with `dry_run: true`.
|
|
61
61
|
- Include `broker_account`, `income_account`, optional `tax_account`, optional `fee_account`, and optional `broker_dimension_id`.
|
|
62
|
-
- The tool defaults `reward_account` to
|
|
62
|
+
- The tool defaults `reward_account` to 3800 ("Muud äritulud", other operating income) for platform rewards — rewards are non-investment income, not a financial cost. Only pass `reward_account` explicitly when the user wants to override the default.
|
|
63
63
|
- Present dividends, interest, platform rewards, withheld tax, skipped entries, duplicate-detection basis, and warnings.
|
|
64
64
|
- Ask for explicit approval before re-running with `dry_run: false`.
|
|
65
65
|
- The distribution approval card must include source CSV, income/tax/reward accounts, journals that would be created, skipped duplicates, and side effects.
|
|
@@ -69,8 +69,8 @@ When the required accounts are known, call `book_lightyear_distributions` with `
|
|
|
69
69
|
After approval, re-run only the approved booking tools with `dry_run: false`.
|
|
70
70
|
|
|
71
71
|
Report:
|
|
72
|
-
-
|
|
73
|
-
-
|
|
74
|
-
-
|
|
72
|
+
- Trades booked
|
|
73
|
+
- Distributions booked
|
|
74
|
+
- Skipped entries and reasons
|
|
75
75
|
- Current portfolio carrying value / remaining cost basis from step 3
|
|
76
|
-
-
|
|
76
|
+
- Suggested `compute_account_balance` check for the investment account
|
|
@@ -30,7 +30,7 @@ Present in priority order:
|
|
|
30
30
|
3. Unconfirmed journal entries — adjustments not posted
|
|
31
31
|
4. Unconfirmed bank transactions — cash not reconciled
|
|
32
32
|
|
|
33
|
-
For blockers, show ID, date, amount/title, then offer concrete inline actions. If there are many blockers of the same low-risk type, show the first 10 plus counts and ask one batch approval with exceptions instead of one yes/no question per item. Do NOT close the workflow with "go fix these in the e-arveldaja UI". That is a last-resort fallback only when no MCP tool can perform the action and the API has already rejected the inline attempt.
|
|
33
|
+
For blockers, show ID, date, amount/title, then offer concrete inline actions. If there are many blockers of the same low-risk type, show the first 10 plus counts and ask for one batch approval with exceptions instead of one yes/no question per item. Do NOT close the workflow with "go fix these in the e-arveldaja UI". That is a last-resort fallback only when no MCP tool can perform the action and the API has already rejected the inline attempt.
|
|
34
34
|
|
|
35
35
|
Inline actions per blocker type:
|
|
36
36
|
- Purchase invoices: offer `confirm_purchase_invoice`, or `delete_purchase_invoice` if the user confirms it is a duplicate
|
|
@@ -35,6 +35,6 @@ Treat the tool response as the source of truth:
|
|
|
35
35
|
- if `proposed_action` is present, present it as the default next step
|
|
36
36
|
- ask for explicit approval before executing any `proposed_action`
|
|
37
37
|
- if the action is `cleanup_camt_possible_duplicate`, explain briefly that it fills missing CAMT metadata onto the kept older transaction before deleting the duplicate PROJECT row
|
|
38
|
-
- if the action is `save_auto_booking_rule`, explain briefly that it
|
|
38
|
+
- if the action is `save_auto_booking_rule`, explain briefly that it saves the rule into the company's configured accounting-knowledge store (an Open Knowledge Format bundle by default, or the legacy `accounting-rules.md` single file when that mode is configured)
|
|
39
39
|
|
|
40
|
-
`prepare_accounting_review_action`
|
|
40
|
+
`prepare_accounting_review_action` is a compatibility primitive registered only when `EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`; by default use the merged continuation tool (`continue_accounting_workflow` with `action="prepare_action"`).
|
|
@@ -45,8 +45,8 @@ Call `receipt_batch`:
|
|
|
45
45
|
|
|
46
46
|
Review:
|
|
47
47
|
- `receipt_batch` is the preferred merged workflow tool.
|
|
48
|
-
- Fallback compatibility primitives: `scan_receipt_folder` and `process_receipt_batch`
|
|
49
|
-
- Use `result` as the delegated
|
|
48
|
+
- Fallback compatibility primitives: `scan_receipt_folder` and `process_receipt_batch` are registered only when `EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`; by default use `receipt_batch` with `mode="scan"` / `mode="dry_run"` / `mode="create"` / `mode="create_and_confirm"`. Do not mention fallback tool names to the user.
|
|
49
|
+
- Use `result` as the delegated batch payload.
|
|
50
50
|
- Treat `execution` as the canonical batch payload when present.
|
|
51
51
|
- Prefer `execution.summary`, `execution.results`, `execution.skipped`, `execution.needs_review`, `execution.errors`, and `execution.audit_reference`.
|
|
52
52
|
- Fall back to legacy top-level `summary`, `skipped`, and `results` only if `execution` is absent.
|
|
@@ -58,7 +58,7 @@ Group the preview by status:
|
|
|
58
58
|
- `execution.errors`: show the file and exact error
|
|
59
59
|
|
|
60
60
|
Recurring `needs_review` reasons to recognize and explain plainly:
|
|
61
|
-
- "Non-EUR receipt currency X requires an explicit currency_rate before automatic invoice creation": the receipt is in a foreign currency and OCR cannot derive a reliable EUR conversion rate.
|
|
61
|
+
- "Non-EUR receipt currency X requires an explicit currency_rate before automatic invoice creation": the receipt is in a foreign currency and OCR cannot derive a reliable EUR conversion rate, so the batch cannot auto-book it. This is NOT a dead end and does not require the e-arveldaja UI: ask the user for the correct rate (EUR per 1 foreign unit), then create the invoice inline via `create_purchase_invoice_from_pdf` with `currency` + `currency_rate` (or `create_purchase_invoice` for a non-PDF source). Only fall back to manual UI work if the user cannot supply a rate.
|
|
62
62
|
- "N bank transactions tied at confidence X; no candidate auto-selected": the booking flow found multiple equally-good bank transaction matches and refused to auto-pick. The invoice will still be created (in `mode: "create"` / `mode: "create_and_confirm"`) but without a bank link. Show the tied transactions to the user and ask which one to confirm via `confirm_transaction`.
|
|
63
63
|
|
|
64
64
|
### Step 3: Approval gate
|
|
@@ -19,7 +19,7 @@ Preferred: call `reconcile_bank_transactions`:
|
|
|
19
19
|
- mode: "suggest"
|
|
20
20
|
- min_confidence: 30 (to see all potential matches including low-confidence ones)
|
|
21
21
|
|
|
22
|
-
Fallback compatibility primitive: `reconcile_transactions`
|
|
22
|
+
Fallback compatibility primitive: `reconcile_transactions` is registered only when `EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`; by default use `reconcile_bank_transactions` with `mode="suggest"`. Do not mention fallback tool names to the user.
|
|
23
23
|
|
|
24
24
|
Review the output:
|
|
25
25
|
- `result.total_unconfirmed`: bank transactions needing attention
|
|
@@ -32,18 +32,17 @@ If `result.total_unconfirmed` is 0, everything is reconciled — stop here.
|
|
|
32
32
|
|
|
33
33
|
Show a summary grouped by confidence level from `result.matches`:
|
|
34
34
|
|
|
35
|
-
**HIGH (>=80):**
|
|
35
|
+
**HIGH (>=80):** Strong matches. In auto mode only confidence >= 90 is eligible for confirmation (Step 3, "Auto mode"), and even then only with user approval — never auto-confirm an 80-89 match without asking.
|
|
36
36
|
- Transaction: date, amount, description, and raw `type` if helpful
|
|
37
|
-
- Keep the tool-provided `type` when importing or creating a transaction, but never infer accounting treatment from an existing transaction's `type`; bank transactions are commonly stored as `C` regardless of direction in e-arveldaja.
|
|
38
37
|
- Matched invoice: number, client, gross amount, confidence, match reasons
|
|
39
|
-
-
|
|
40
|
-
- do NOT derive `distribution.amount` from `tx.amount` when base and source currencies differ; use the invoice open balance and the tool-provided distribution.
|
|
38
|
+
- Keep the tool-provided `type` when importing or creating a transaction, but never infer accounting treatment from an existing transaction's `type`; bank transactions are commonly stored as `C` regardless of direction in e-arveldaja.
|
|
39
|
+
- For cross-currency matches, prefer `match_reasons` such as `exact_base_amount`, and do NOT derive `distribution.amount` from `tx.amount` when base and source currencies differ; use the invoice open balance and the tool-provided distribution.
|
|
41
40
|
|
|
42
41
|
**MEDIUM (50-79):** Review recommended.
|
|
43
42
|
|
|
44
43
|
**LOW (<50):** Unlikely matches, shown for reference only.
|
|
45
44
|
|
|
46
|
-
If no `distribution` key is present or a partially paid warning
|
|
45
|
+
If no `distribution` key is present or there is a partially paid warning, say clearly that no ready-to-use distribution is provided and the remaining open balance must be checked manually first.
|
|
47
46
|
|
|
48
47
|
## Step 3: Handle based on mode
|
|
49
48
|
|
|
@@ -55,7 +54,7 @@ Call `reconcile_bank_transactions`:
|
|
|
55
54
|
- mode: "dry_run_auto_confirm"
|
|
56
55
|
- min_confidence: 90
|
|
57
56
|
|
|
58
|
-
Fallback compatibility primitive: `auto_confirm_exact_matches`
|
|
57
|
+
Fallback compatibility primitive: `auto_confirm_exact_matches` is registered only when `EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`; by default use `reconcile_bank_transactions` with `mode="dry_run_auto_confirm"` / `mode="execute_auto_confirm"`.
|
|
59
58
|
|
|
60
59
|
Treat `result.execution` as the canonical batch payload when present. Prefer `result.execution.summary`, `result.execution.results`, `result.execution.errors`, and `result.execution.audit_reference`.
|
|
61
60
|
|
|
@@ -102,7 +101,7 @@ Call `reconcile_bank_transactions`:
|
|
|
102
101
|
Fallback compatibility primitive: `reconcile_inter_account_transfers` remains available, but prefer the mode-based dry run through `reconcile_bank_transactions` before execution.
|
|
103
102
|
|
|
104
103
|
Review the results:
|
|
105
|
-
- Treat `result.execution.summary` as the canonical source for counts, and use `result.pairs`, `result.one_sided`, `result.already_handled`, and `result.ambiguous_pairs` for detailed breakdown.
|
|
104
|
+
- Treat `result.execution.summary` as the canonical source for counts, and use `result.pairs`, `result.one_sided`, `result.already_handled`, and `result.ambiguous_pairs` for the detailed breakdown.
|
|
106
105
|
- `already_handled`: transfers already journalized from the other side — safe to delete
|
|
107
106
|
- `one_sided`: would confirm against the other bank account
|
|
108
107
|
- `pairs`: would confirm the outgoing side and delete the duplicate incoming `PROJECT` (draft/unconfirmed) row (`incoming_action: "would_delete_duplicate"`)
|
|
@@ -119,10 +118,10 @@ Ask for approval. If approved, call `reconcile_inter_account_transfers` with `ex
|
|
|
119
118
|
|
|
120
119
|
List transactions with no matches and offer inline actions in compact groups — do NOT close the workflow with "create the journal entry yourself in e-arveldaja". Show the first 10 plus counts, group obvious fees/interest together, and ask for one batch approval with exceptions when the proposed contra account is the same. Manual e-arveldaja UI work is a last-resort fallback only when no MCP tool can perform the action and the API has already rejected the inline attempt.
|
|
121
120
|
|
|
122
|
-
Inline actions:
|
|
123
|
-
- Small amounts (<1 EUR): likely bank fees or interest. Offer
|
|
121
|
+
Inline actions — these are existing PROJECT bank transactions, so book them by CONFIRMING the transaction against a GL account with `confirm_transaction` (an `accounts` distribution: `distributions: [{ related_table: "accounts", related_id: <account id>, amount: <tx amount>, related_sub_id: <dimension id if the account has dimensions> }]`). Do NOT use a standalone `create_journal` for these rows: confirming ties the journal to the bank transaction and reconciles the bank balance in one step, whereas a separate `create_journal` leaves the bank row unreconciled and risks double-counting the bank movement. Reserve `create_journal` for adjustments that are NOT tied to any existing bank transaction.
|
|
122
|
+
- Small amounts (<1 EUR): likely bank fees or interest. Offer `confirm_transaction` with a distribution to the appropriate contra-account (e.g. 8610 "Muud finantskulud" for bank/transfer fees — consistent with how Wise fees are booked — and 8400 "Intressitulu" for interest credits — financial income, 8xxx range, not a 6xxx staff-cost account) and ask the user to approve the proposed contra before executing.
|
|
124
123
|
- Description contains "teenustasu", "intress", "service fee": same as above; pre-fill the contra account based on the keyword and ask for approval.
|
|
125
|
-
- Larger amounts: check if the corresponding invoice exists in the system; if it does, offer `confirm_transaction` against that invoice; if it does not,
|
|
124
|
+
- Larger amounts: check if the corresponding invoice exists in the system; if it does, offer `confirm_transaction` against that invoice; if it does not, offer `confirm_transaction` against a suggested expense/income account (accounts distribution) after the user approves the proposed account.
|
|
126
125
|
|
|
127
126
|
## Step 6: Summary
|
|
128
127
|
|
|
@@ -32,7 +32,7 @@ Always present:
|
|
|
32
32
|
- only the unresolved questions, if any
|
|
33
33
|
- the next concrete workflow or tool step
|
|
34
34
|
|
|
35
|
-
For owner-paid expense receipts,
|
|
35
|
+
For owner-paid expense receipts: for VAT-registered companies, ordinary business input VAT normally defaults to deductible (a non-VAT-registered company books the gross amount with no input-VAT deduction), while likely restricted categories (representation, passenger-car, etc.) need confirmation unless local rules define the policy.
|
|
36
36
|
|
|
37
37
|
### Step 3: Keep the interaction minimal
|
|
38
38
|
|
|
@@ -43,4 +43,4 @@ For owner-paid expense receipts, Ordinary business VAT defaults to deductible, w
|
|
|
43
43
|
|
|
44
44
|
If the next step is clear, continue with `continue_accounting_workflow` and `action: "prepare_action"` instead of inventing your own action plan.
|
|
45
45
|
|
|
46
|
-
`resolve_accounting_review_item`
|
|
46
|
+
`resolve_accounting_review_item` is a compatibility primitive registered only when `EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`; by default use the merged continuation tool (`continue_accounting_workflow` with `action="resolve_review"`).
|
|
@@ -26,6 +26,8 @@ Treat its response as the source of truth for:
|
|
|
26
26
|
- If `mode="setup"`, say clearly that API-backed workflows are blocked until credentials are configured.
|
|
27
27
|
- If `mode="configured"`, say clearly that credentials already exist and this workflow can be used to inspect, append, replace, or remove stored `.env` credentials.
|
|
28
28
|
|
|
29
|
+
The credential-management tools (`import_apikey_credentials`, `list_stored_credentials`, `remove_stored_credentials`) are always registered in `setup` mode. In `configured` mode they are hidden by default and only appear when the server is started with `EARVELDAJA_EXPOSE_SETUP_TOOLS=1`. If a step below needs one of these tools and it is not in `tools/list`, do not guess: explain the setup paths from `get_setup_instructions`, tell the user to restart the server with `EARVELDAJA_EXPOSE_SETUP_TOOLS=1` (or from the setup folder) to expose them, and stop.
|
|
30
|
+
|
|
29
31
|
Explain the two storage scopes:
|
|
30
32
|
- `local`: works only when the MCP server is started from this folder
|
|
31
33
|
- `global`: works when the MCP server is started from any folder on this computer
|
|
@@ -61,7 +63,7 @@ If the user wants to remove stored credentials instead of importing:
|
|
|
61
63
|
- if the user confirms a specific stored target should be removed, call `remove_stored_credentials` with:
|
|
62
64
|
- `storage_scope`
|
|
63
65
|
- `target`
|
|
64
|
-
- state clearly that removal is destructive and requires restart
|
|
66
|
+
- state clearly that removal is destructive and requires a restart
|
|
65
67
|
|
|
66
68
|
## Step 5: Handle clients without interactive prompting
|
|
67
69
|
|
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [0.18.0] - 2026-07-04
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
- **Dependency upgrades + security fixes.** Upgraded every outdated dependency (the rest — `@modelcontextprotocol/sdk`, `zod`, `dotenv`, `@toon-format/toon`, `fastest-levenshtein`, `typescript` — were already current). Runtime deps moved within their existing ranges (`@llamaindex/liteparse` 2.0.4→2.4.0, `fast-xml-parser` 5.8.0→5.9.3); the dev toolchain moved to current majors (`vitest` 3→4, `vite` 6→8, `@types/node` 25→26, `tsx` 4.22→4.23). This clears all 4 `npm audit` advisories — 1 **critical** (`vitest` UI-server arbitrary file read/execute), 2 **high** (`vite` Windows path handling), 1 low — every one of them in the dev toolchain; the shipped runtime had no advisories. `vitest` 4 required no config or test migration (the full suite passes unchanged). Note: `vitest` 4 / `vite` 8 require **Node 20.19+ for development and CI**; the published server's runtime still targets Node 18 (`engines.node` unchanged at `>=18.0.0`), so `npx e-arveldaja-mcp` end users are unaffected.
|
|
9
|
+
- **Smaller default tool surface (per-session token cost).** The 10 granular constituent tools whose functionality is fully covered by the merged mode-based entry points — `reconcile_transactions`, `auto_confirm_exact_matches` (→ `reconcile_bank_transactions`), `parse_camt053`, `import_camt053` (→ `process_camt053`), `scan_receipt_folder`, `process_receipt_batch` (→ `receipt_batch`), `classify_unmatched_transactions`, `apply_transaction_classifications` (→ `classify_bank_transactions`), `resolve_accounting_review_item`, `prepare_accounting_review_action` (→ `continue_accounting_workflow`) — are no longer registered in `tools/list` by default. The merged tools keep routing to the same handlers internally, so no functionality is lost; set the new **`EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`** to register them again. `reconcile_inter_account_transfers` stays exposed (the merged tool has no inter-account execute mode). Default surface: 133 → **123** tools (118 with Lightyear disabled; 133 with granular tools exposed). Workflow prompts, error-recovery hints, and review-item suggestions now point at the merged mode-based calls.
|
|
10
|
+
- **`lightyear-booking` prompt follows the Lightyear tool group.** When `EARVELDAJA_DISABLE_LIGHTYEAR=1` drops the Lightyear tools, the matching workflow prompt is no longer registered either, so `prompts/list` never advertises a workflow whose tools are missing.
|
|
11
|
+
- **Tighter tool and prompt descriptions.** Compressed verbose filler in the heaviest tool descriptions and in-schema parameter docs (`create_purchase_invoice_from_pdf`, `prepare_dividend_package`, `confirm_transaction`, `create_transaction`, `list_transactions`, `get_session_log`, `check_tax_free_limits`, `create_journal`, `create_client`, and the `import-wise` / `prepare-accounting-review-action` prompt dispatch lines) without dropping any contract or safety wording (EXACT-totals/never-recalculate VAT rules, dry-run defaults, approval requirements, untrusted-OCR and dimension-required warnings are all preserved verbatim).
|
|
12
|
+
- **Setup/credential tools hidden once connections are configured.** The three credential-management tools — `import_apikey_credentials`, `list_stored_credentials`, `remove_stored_credentials` — are no longer registered in `tools/list` once the server has configured connections; they are only needed to add or rotate credentials and stay registered in setup mode (no connections). `get_setup_instructions` is never gated, so the agent can always explain how to add a connection (its payload documents these tools). Set the new **`EARVELDAJA_EXPOSE_SETUP_TOOLS=1`** to keep them registered in configured mode too (e.g. to add a second company without a restart). Default surface: 123 → **120** tools (115 with Lightyear disabled).
|
|
13
|
+
- **Opt-out feature-group flags for lean deployments.** Five new env flags drop whole tool groups a given deployment may not use, mirroring the existing `EARVELDAJA_DISABLE_LIGHTYEAR` semantics (default enabled — set `=1` to drop). They change **nothing** by default; the default surface stays 120 tools. **`EARVELDAJA_DISABLE_TAX_TOOLS=1`** drops the Estonian tax helpers `prepare_dividend_package`, `create_owner_expense_reimbursement`, `check_tax_free_limits` (−3; the statutory tax-rules advisory layer behind `suggest_booking` is untouched — only these user-facing tools are unregistered). **`EARVELDAJA_DISABLE_REFERENCE_ADMIN=1`** drops the reference-data administration tools `create/update/delete_bank_account`, `create/update/delete_invoice_series`, `update_invoice_info`, and the single-record `get_bank_account`/`get_invoice_series` reads (−9), keeping the `list_*`/`get_invoice_info`/`get_vat_info` reads so the configuration is still inspectable. **`EARVELDAJA_DISABLE_ANNUAL_REPORT=1`** drops the year-end tools `prepare_year_end_close`, `generate_annual_report_data`, `execute_year_end_close` (−3). **`EARVELDAJA_DISABLE_SALES=1`** drops the sales-invoicing side — the 11 sale-invoice tools, `create_recurring_sale_invoices`, and receivables aging `compute_receivables_aging` (−13) — for purchase-side-only bookkeeping; the payables-aging report `compute_payables_aging` and every purchase-invoice tool stay. **`EARVELDAJA_DISABLE_PRODUCTS=1`** drops the product-catalog tools `list/get/create/update/deactivate/reactivate/delete_product` (−7); products are chiefly the sale-invoice line-item catalog (purchase items key on `cl_purchase_articles_id` but can also carry an optional `products_id`), so a `DISABLE_SALES` deployment usually sets this too; the flag only removes catalog management (creating either invoice type is unaffected), so the flags are independent. A lean purchase-side-only deployment with every disable flag set (incl. Lightyear) lands near **80** tools; each flag can be toggled independently (e.g. re-enable `DISABLE_ANNUAL_REPORT` only at closing time). `recommend_workflow` now filters its suggestions to the registered surface — it never names a tool an opt-out flag dropped, and it hides a workflow whose tools are all gated (e.g. `lightyear-booking` when Lightyear is off). The static workflow prompts (`company-overview`, `month-end`) are shared across purchase/sales deployments and still mention their full tool set; the agent skips any tool absent from `tools/list`.
|
|
14
|
+
- **`extract_pdf_invoice` no longer emits a duplicate `extracted.raw_text`.** The full document/OCR text was returned twice per call — once as `hints.raw_text` and again as `extracted.raw_text` (both are the same parsed text). Only `hints.raw_text` is kept (the booking workflow's documented source of truth; still capped to `MAX_UNTRUSTED_TEXT_CHARS` and wrapped in the per-call untrusted-OCR nonce sandbox). The `extracted` object keeps its structured fields (supplier, totals, and the still-wrapped `description` / `supplier_name`) but no longer carries `raw_text` or its `raw_text_truncated` / `raw_text_length` markers. Saves up to ~5k tokens per extraction on long documents with no loss of information — read the document text from `hints.raw_text`. The tool's own `llm_fallback.guidance` now points field-recovery at `hints.raw_text` to match (the receipt-batch flow, which still carries `extracted.raw_text`, keeps its existing guidance).
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
- **`prepare_dividend_package` — dividend income tax is now booked as an expense, not a retained-earnings debit.** Previously the tool debited the **full gross** (net dividend + CIT) to retained earnings (Jaotamata kasum, 3020) across two D-lines, which overstated the drain on equity and never recorded the tax on the profit-and-loss statement. Per Estonian GAAP / RTJ, the corporate income tax on a distribution (TuMS § 50, 22/78) is charged against **current-year profit as an income-tax expense** — the P&L "Tulumaks" line — while only the **net dividend** reduces retained earnings. The journal now debits the net dividend to retained earnings and the CIT to an income-tax-expense account (auto-detected as the lowest Kulud account in 8900–8999, matching the annual report's "Tulumaks" mapping; override with the new `income_tax_expense_account` parameter, default 8900). Credits (dividend payable 2370, CIT liability 2540) and the gross-based ÄS § 157 / retained-earnings legality checks are unchanged — net assets still fall by the full gross. The response now includes a `booking` summary showing which accounts were debited.
|
|
18
|
+
- **Annual report — FX gain/loss and financial fees no longer drop out of net profit.** `generate_annual_report_data` mapped the "Finantstulud ja -kulud" (financial income/expense) line only to accounts 7200–7699, where nothing is booked. The MCP actually books FX gain (8500), FX loss (8600) and other financial expense (8610) into the 8xxx block, so those amounts fell into `unmapped_accounts` and were excluded from profit-before-tax, net profit, and equity. The mapping now also covers **8000–8899** (Tulumaks stays isolated at 8900–8999) and nets correctly — financial income adds, financial expense subtracts — so a booked FX loss reduces profit instead of being ignored or mis-signed.
|
|
19
|
+
- **`prepare_dividend_package` — ÄS § 157(2) restricted-reserve floor.** The net-assets legality check now floors at share capital **+ non-distributable reserves** (reservkapital) rather than share capital alone. Reservkapital is auto-detected on account 3010 (override or extend with the new `restricted_reserve_accounts` parameter); when detected it raises the minimum-net-assets floor and emits a non-blocking notice. The `net_assets_check` echo now reports `restricted_reserves`, `restricted_reserve_accounts`, and `minimum_net_assets`. Distributions that clear bare share capital but not the reserve-inclusive floor are now correctly blocked (overridable with `force=true`). The tool now also warns (non-blocking) when share capital or retained earnings reads as **zero** — the symptom of opening balances entered as "Algbilansi kanded" that the `/journals` API may omit, meaning the § 157 check ran on incomplete data; that caveat is now surfaced on the blocked path too, not just on previews. An explicit `restricted_reserve_accounts` override is validated (and deduped) up front, so a mistyped or absent reserve account errors instead of silently lowering the floor.
|
|
20
|
+
- **`book_lightyear_distributions` — platform rewards booked to income, not the FX-loss account.** `reward_account` defaulted to **8600**, which is the FX-loss *expense* account — crediting a platform reward there put non-investment income on the wrong statement line with the wrong sign. It now defaults to **3800** ("Muud äritulud", other operating income). Real investment income (fund distributions, interest) still uses the caller-supplied `income_account`; the reward path is separate. The reward account is only validated when a statement actually contains a reward (or the caller pins `reward_account`), so a dividend/interest-only import no longer fails just because the chart lacks the reward income account.
|
|
21
|
+
- **`prepare_dividend_package` — sub-cent and non-positive `net_dividend` hardening.** The net dividend is rounded to cents once up front, so a sub-cent input can never leak an unrounded amount into the booked journal or make the reported gross disagree with the sum posted; a value that rounds to 0.00 EUR (or is ≤ 0) is rejected instead of booking an empty journal. The executed-path `net_assets_check.sufficient` now uses the same tolerance as the block decision (it previously used a stricter bare comparison than the dry-run path).
|
|
22
|
+
- **Currency-rounding and purchase-invoice base VAT reconcile to the cent.** `reconcile_currency_rounding` and the foreign-currency purchase-invoice writer now derive `base_vat` as the residual `base_gross − base_net`, so the trio always reconciles exactly instead of drifting a cent when net, vat, and gross are each rounded independently against the FX rate (which could fail the API's sum validation). `compute_account_balance` also rounds its returned balance so an exact-boundary consumer (the § 157 check) can't be flipped by sub-cent float noise.
|
|
23
|
+
- **Consistency and documentation fixes.** `reconcile-bank` now books bank/transfer fees to 8610 (consistent with Wise fees) and no longer labels an ≥80 confidence match "safe to auto-confirm" (auto mode gates at ≥90 and still requires approval). `compute_client_debt` and the purchase-VAT fallback now interpolate their default account numbers into descriptions/warnings instead of hard-coding them, and `compute_account_balance`'s `account_id` help text is corrected. Lightyear fee accounts reference the shared `DEFAULT_OTHER_FINANCIAL_EXPENSE_ACCOUNT` constant instead of a repeated literal.
|
|
24
|
+
- **`reconcile-bank` books interest credits to the correct financial-income account.** The unmatched-transaction guidance suggested account **6080 "Interest income"** for interest credits, but 6080 sits in the annual report's staff-costs range (6000–6999 "Tööjõukulud"), not the "Finantstulud ja -kulud" mapping (7200–7699 + 8000–8899). Interest income booked there never reaches the financial-income line: depending on how 6080 is typed in the chart, `generate_annual_report_data` either misclassifies the credit as a negative staff cost (a `Kulud` account in 6000–6999) or drops it into `unmapped_accounts` (an income-typed account, since 6xxx has no `Tulud` mapping) — either way it is excluded from the financial result. It now books to **8400 "Intressitulu"** (financial income, 8xxx range — the interest example carried by the Lightyear `income_account` parameter), so bank interest lands on the annual report's financial-income line.
|
|
25
|
+
- **Merged workflow tools no longer point their next action at a granular tool that is hidden by default.** When `EARVELDAJA_EXPOSE_GRANULAR_TOOLS` is unset (the default), the 10 granular constituent tools are not in `tools/list`, but the merged entry points still named their granular delegate in the `workflow_action_v1` envelope they return — so `recommended_next_action` / `available_actions` / `approval_previews` pointed at a tool the caller cannot invoke. `reconcile_bank_transactions` (`mode="dry_run_auto_confirm"` → `auto_confirm_exact_matches`), `accounting_inbox` and `continue_accounting_workflow` (→ `parse_camt053` / `import_camt053` / `process_receipt_batch` / `classify_unmatched_transactions`), `classify_bank_transactions` (→ `apply_transaction_classifications`), and `receipt_batch` (→ `process_receipt_batch`) were all affected; only `process_camt053` had a fix (its own bespoke remap). A shared `remapHiddenGranularWorkflowEnvelope` now rewrites every granular tool named in an emitted envelope back to its merged entry point plus the equivalent `mode` (e.g. `auto_confirm_exact_matches {execute:true}` → `reconcile_bank_transactions {mode:"execute_auto_confirm"}`), so the contract only ever names a registered tool. The informational `delegated_tool` field still reports the real internal delegate. (The `process_camt053`-specific remap was replaced by the shared one.)
|
|
26
|
+
- **Annual report balance sheet — short-term payables to owners and 11xx financial assets are now classified, not dropped.** `generate_annual_report_data` classified balance-sheet lines by account-number prefix but had two range gaps. (1) On the **liabilities** side, short-term payables in **2100–2199** — which includes the MCP's own default owner-payable account **2110** booked by `create_owner_expense_reimbursement` — matched no current-liability range (only 2300–2399 and 2500–2599 were covered), so they fell into the "Klassifitseerimata kohustused" (unclassified) review line instead of "Lühiajalised kohustused". The current-liability ranges now include 2100–2199, while an explicit long-term name marker still diverts a genuinely non-current 21xx account first. (2) On the **assets** side, the current-asset (Käibevara) prefixes covered 10, 12–16 but **not 11** (short-term financial investments / broker cash, e.g. a Lightyear/Wise settlement account), so an 11xx asset counted toward `total_assets` yet appeared in neither the current nor non-current asset line — silently unbalancing the two asset lines against the total. Prefix **11** is now a current asset. As a safety net mirroring the liabilities' unclassified line, any asset account that still falls outside the current (10–16) / non-current (17–19) ranges now raises a non-blocking warning naming the account instead of vanishing from the asset lines.
|
|
27
|
+
- **`accounting_inbox` `recommended_steps` / `next_recommended_action` no longer name a granular tool that is hidden by default.** The #48 remap fixed the `workflow_action_v1` envelope, but the parallel caller-facing `recommended_steps[]` array and `next_recommended_action` object — which sit *outside* that envelope — still named the hidden granular constituents (`parse_camt053`, `import_camt053`, `process_receipt_batch`, `classify_unmatched_transactions`). Under the default exposure those tools are absent from `tools/list`, so the prescriptive "run this next" fields pointed at un-invokable tools. They are now rewritten to the merged entry point plus `mode` (e.g. `parse_camt053 {file_path}` → `process_camt053 {mode:"parse", file_path}`), consistent with the envelope. The rewrite is skipped when `EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1` (the granular names are valid and preferred in that power-user mode), and the past-tense `autopilot.executed_steps` telemetry keeps the real internal delegate (like the envelope's informational `delegated_tool`).
|
|
28
|
+
- **`continue_accounting_workflow` owner-expense resolution no longer suggests `create_owner_expense_reimbursement` when the tax tools are disabled.** For an owner-paid-expense receipt review, `resolve_review` / `prepare_action` suggested `create_owner_expense_reimbursement` and named it in `next_step_summary`. That tool belongs to the tax-tool group and is unregistered under `EARVELDAJA_DISABLE_TAX_TOOLS=1`, so on a lean deployment the contract named a tool the caller cannot invoke. The resolver now takes the exposure config into account: when the tax helpers are disabled it drops that tool from `suggested_tools`, points at the always-registered `create_journal` instead, and rewrites the summary to spell out the manual owner-reimbursement booking (debit the business expense, credit the owner-payable account, default 2110) without naming the unavailable tool.
|
|
29
|
+
- **`check_tax_free_limits` — representation limit is date-gated (32 € before 2025, 50 € from 2025).** The TuMS § 49 lg 4 representation/entertainment tax-free allowance is **50 €/calendar month only from 2025-01-01**; it was **32 €/month through 2024**. `computeRepresentationCostLimit` hard-coded 50 €, so a check run for a 2024 period over-stated the limit and under-stated the taxable excess (and the 20/78 income tax on it). The monthly figure is now a date-gated timeline (`REPRESENTATION_MONTHLY_LIMIT_TIMELINE` + `representationMonthlyLimitOn`, mirroring the standard-VAT-rate timeline), and `check_tax_free_limits` selects it from `as_of_date` — a cumulative year-to-date figure sits within one calendar year, so its whole accrual uses that year's rate. The `earveldaja://tax_rules` reference now notes the pre-2025 32 €/month figure.
|
|
30
|
+
- **`create_owner_expense_reimbursement` — rejects a non-positive `net_amount` or negative VAT.** `net_amount`/`vat_rate`/`vat_amount`/`deductible_vat_amount` only carried a `finite()` schema check plus the existing "looks like a percentage" guard, so a `net_amount` of 0 or a negative value (or a negative VAT input) would post an empty or sign-reversed journal (crediting the expense, debiting the owner-payable). The tool now rejects `net_amount ≤ 0` and any negative `vat_rate` / `vat_amount` / `deductible_vat_amount` up front with a clear error instead of booking nonsense.
|
|
31
|
+
- **`prepare_dividend_package` — the ÄS § 157(2) floor cannot be lowered by a negative reserve or share-capital balance.** The net-assets floor (`share capital + restricted reserves`) previously summed the raw balances, so an anomalous **debit** balance on the reservkapital or share-capital account (which should never occur on a clean ledger) would *reduce* the floor and could let an otherwise-unlawful distribution through. Both the share capital and **each restricted reserve individually** are now clamped to ≥ 0 before they enter the floor (clamping only the reserve *total* would still let a negative reserve offset a positive one), so a data anomaly can only make the § 157 block **more** conservative, never less; the `net_assets_check` echo still reports the raw signed `restricted_reserves` so the anomaly stays visible, and the opening-balance caveat warning now also fires on a non-positive (not just zero) share capital.
|
|
32
|
+
- **Hotel/hostel/motel suppliers now trigger the KMS § 30 accommodation note.** The entertainment/hospitality detector matched `majutus` / `accommodation` but not a bare hotel name, so a `Hotel …` / `Hostel …` / `Motell …` supplier with no "majutus" in the description slipped past the input-VAT-restriction note. Added the `hotel` / `hostel` / `motel` stems (they also cover the Estonian `hotell` / `motell` inflections) to the shared classifier; the note stays advisory and still states the business-trip accommodation exception.
|
|
33
|
+
- **Workflow-prompt corrections — booking guidance now matches the tool surface (prompt/doc text only).** A full review of the `workflows/*.md` runbooks (and their generated `.claude/commands/` mirror) fixed six inconsistencies with the current tools. (1) `reconcile-bank` told the agent to book unmatched bank rows (fees/interest) with a standalone **`create_journal`** — but those are existing PROJECT bank transactions, so a separate journal leaves the bank row unreconciled and risks double-counting the bank movement; it now confirms the transaction against the contra GL account via `confirm_transaction` (an `accounts` distribution), reserving `create_journal` for adjustments not tied to a bank row. (2) `classify-unmatched` suggested fixing a missing `currency_rate` "via `update_transaction`", which is impossible — `update_transaction` is metadata-scoped (bank reference / counterparty / description) and cannot set a rate; the row is now surfaced as blocked with a currency-aware booking path instead. (3) `receipt-batch` sent non-EUR receipts to manual UI work; it now routes them inline through `create_purchase_invoice_from_pdf` / `create_purchase_invoice` with a user-supplied `currency_rate` (matching the inline-confirmation policy), UI as last resort only. (4) `prepare-accounting-review-action` described `save_auto_booking_rule` as updating "the local `accounting-rules.md` file" — corrected to the configured accounting-knowledge store (OKF bundle by default, legacy single file when configured). (5) `setup-credentials` now notes that the credential-management tools are hidden in `configured` mode unless `EARVELDAJA_EXPOSE_SETUP_TOOLS=1`, with an absent-tool fallback. (6) `resolve-accounting-review`'s "ordinary business VAT defaults to deductible" now carries the VAT-registration qualifier (a non-VAT-registered company books gross with no input-VAT deduction).
|
|
34
|
+
|
|
5
35
|
## [0.17.0] - 2026-06-17
|
|
6
36
|
|
|
7
37
|
### Added
|
package/CLAUDE.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# e-arveldaja MCP Server
|
|
2
2
|
|
|
3
3
|
TypeScript MCP server for the Estonian e-arveldaja (RIK e-Financials) REST API.
|
|
4
|
-
|
|
4
|
+
120 tools by default (115 with Lightyear disabled; up to 133 with the optional granular and setup tools exposed — see Tool exposure below), 15 workflow prompts, 15 resources across 12 modules. Supports multiple companies/accounts.
|
|
5
5
|
|
|
6
6
|
## Quick Start
|
|
7
7
|
|
|
@@ -70,20 +70,88 @@ serialized with an `O_EXCL` lock file at `<dir>.lock` (`withBundleLock()`).
|
|
|
70
70
|
### Tool exposure (per-session token cost)
|
|
71
71
|
|
|
72
72
|
`tools/list` is loaded into the client context on every session, so the tool
|
|
73
|
-
surface is a fixed per-session token cost.
|
|
74
|
-
|
|
75
|
-
`getToolExposureConfig()` in `src/config.ts`):
|
|
73
|
+
surface is a fixed per-session token cost. Eight env flags control optional
|
|
74
|
+
parts of the surface (see `getToolExposureConfig()` in `src/config.ts`):
|
|
76
75
|
|
|
77
76
|
- **`EARVELDAJA_DISABLE_LIGHTYEAR=1`** — do not register the Lightyear
|
|
78
77
|
investment tools (`book_lightyear_*`, `parse_lightyear_*`,
|
|
79
|
-
`lightyear_portfolio_summary`)
|
|
80
|
-
investments. Default: Lightyear is enabled.
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
78
|
+
`lightyear_portfolio_summary`) or the `lightyear-booking` prompt. Use when
|
|
79
|
+
the company does not track investments. Default: Lightyear is enabled.
|
|
80
|
+
- **`EARVELDAJA_EXPOSE_GRANULAR_TOOLS=1`** — also register the 10 granular
|
|
81
|
+
constituent tools whose functionality is fully covered by merged mode-based
|
|
82
|
+
entry points: `reconcile_transactions`, `auto_confirm_exact_matches`
|
|
83
|
+
(→ `reconcile_bank_transactions`), `parse_camt053`, `import_camt053`
|
|
84
|
+
(→ `process_camt053`), `scan_receipt_folder`, `process_receipt_batch`
|
|
85
|
+
(→ `receipt_batch`), `classify_unmatched_transactions`,
|
|
86
|
+
`apply_transaction_classifications` (→ `classify_bank_transactions`),
|
|
87
|
+
`resolve_accounting_review_item`, `prepare_accounting_review_action`
|
|
88
|
+
(→ `continue_accounting_workflow`). Default: hidden — the merged tools keep
|
|
89
|
+
routing to the same handlers internally, so no functionality is lost.
|
|
90
|
+
`reconcile_inter_account_transfers` is never gated (no merged execute mode).
|
|
91
|
+
- **`EARVELDAJA_EXPOSE_SETUP_TOOLS=1`** — also register the credential-management
|
|
92
|
+
tools (`import_apikey_credentials`, `list_stored_credentials`,
|
|
93
|
+
`remove_stored_credentials`) when the server already has configured
|
|
94
|
+
connections. They are always registered in setup mode (no connections) and
|
|
95
|
+
hidden by default once credentials exist, since they are only needed to add or
|
|
96
|
+
rotate credentials. `get_setup_instructions` is never gated, so the agent can
|
|
97
|
+
always explain how to add a connection (set this flag to add a second company
|
|
98
|
+
without a restart).
|
|
99
|
+
|
|
100
|
+
The next five are opt-out feature-group flags (default enabled; the group is
|
|
101
|
+
registered unless the flag is set). They cut the surface for a lean deployment
|
|
102
|
+
without changing the default:
|
|
103
|
+
|
|
104
|
+
- **`EARVELDAJA_DISABLE_TAX_TOOLS=1`** — do not register the Estonian tax
|
|
105
|
+
helpers (`prepare_dividend_package`, `create_owner_expense_reimbursement`,
|
|
106
|
+
`check_tax_free_limits`). The statutory tax-rules advisory layer used by
|
|
107
|
+
`suggest_booking` is unaffected — only these three tools are unregistered.
|
|
108
|
+
Use when the deployment never runs dividend/reimbursement/tax-free-limit
|
|
109
|
+
workflows. Saves ≈1.5k tokens.
|
|
110
|
+
- **`EARVELDAJA_DISABLE_REFERENCE_ADMIN=1`** — do not register the reference-data
|
|
111
|
+
administration tools that create, update, or delete configuration:
|
|
112
|
+
`create/update/delete_bank_account`, `create/update/delete_invoice_series`,
|
|
113
|
+
`update_invoice_info`, and the single-record `get_bank_account` /
|
|
114
|
+
`get_invoice_series` reads. The `list_*` / `get_invoice_info` / `get_vat_info`
|
|
115
|
+
reads stay registered so the agent can still inspect the configuration. Use
|
|
116
|
+
when the chart of accounts, bank accounts, and invoice series are already set
|
|
117
|
+
up and managed in the e-arveldaja UI. Saves ≈1.7k tokens.
|
|
118
|
+
- **`EARVELDAJA_DISABLE_ANNUAL_REPORT=1`** — do not register the annual-report /
|
|
119
|
+
year-end tools (`prepare_year_end_close`, `generate_annual_report_data`,
|
|
120
|
+
`execute_year_end_close`). Use for the bulk of the year; re-enable at closing
|
|
121
|
+
time. Saves ≈0.4k tokens.
|
|
122
|
+
- **`EARVELDAJA_DISABLE_SALES=1`** — do not register the sales-invoicing side:
|
|
123
|
+
the 11 sale-invoice tools (`list/get/create/update/delete/confirm/invalidate_sale_invoice`,
|
|
124
|
+
`get_sale_invoice_delivery_options`, `send_sale_invoice`,
|
|
125
|
+
`get_sale_invoice_document`, `get_sale_invoice_xml`),
|
|
126
|
+
`create_recurring_sale_invoices`, and the accounts-receivable report
|
|
127
|
+
`compute_receivables_aging`. The accounts-payable report
|
|
128
|
+
`compute_payables_aging` and all purchase-invoice tools stay. Use on a
|
|
129
|
+
purchase-side-only bookkeeping deployment. Saves ≈2.7k tokens (13 tools).
|
|
130
|
+
- **`EARVELDAJA_DISABLE_PRODUCTS=1`** — do not register the product-catalog tools
|
|
131
|
+
(`list/get/create/update/deactivate/reactivate/delete_product`). Products are
|
|
132
|
+
the sale-invoice line-item catalog (not used by purchase invoices), so a
|
|
133
|
+
`DISABLE_SALES` deployment usually sets this too — but the flags are
|
|
134
|
+
independent. Saves ≈1.3k tokens (7 tools).
|
|
135
|
+
|
|
136
|
+
The default surface is 120 tools; `DISABLE_LIGHTYEAR` drops it to 115.
|
|
137
|
+
`EXPOSE_GRANULAR_TOOLS` adds the 10 granular tools, `EXPOSE_SETUP_TOOLS` the 3
|
|
138
|
+
credential tools; enabling both raises it to the full 133. The five opt-out
|
|
139
|
+
group flags trim the default further — `DISABLE_TAX_TOOLS` (−3),
|
|
140
|
+
`DISABLE_REFERENCE_ADMIN` (−9), `DISABLE_ANNUAL_REPORT` (−3), `DISABLE_SALES`
|
|
141
|
+
(−13), `DISABLE_PRODUCTS` (−7) — so a lean purchase-side-only deployment with
|
|
142
|
+
every disable flag set (incl. Lightyear) lands near 80 tools. (The former
|
|
143
|
+
`prepare_accounting_inbox` / `run_accounting_inbox_dry_runs` tools were
|
|
84
144
|
exact aliases of `accounting_inbox` `mode="scan"` / `mode="dry_run"` and have
|
|
85
145
|
been removed — use `accounting_inbox` with the matching `mode`.)
|
|
86
146
|
|
|
147
|
+
`recommend_workflow` filters its suggestions to the registered surface, so it
|
|
148
|
+
never names a tool an opt-out flag has dropped (and it hides a whole workflow
|
|
149
|
+
whose tools are all gated, e.g. `lightyear-booking` when Lightyear is off). The
|
|
150
|
+
static workflow prompts (`company-overview`, `month-end`, …) are shared across
|
|
151
|
+
purchase- and sales-side deployments and are not gated per flag, so they may
|
|
152
|
+
still mention a dropped tool (e.g. `compute_receivables_aging` under
|
|
153
|
+
`DISABLE_SALES`); the agent simply skips a tool that is not in `tools/list`.
|
|
154
|
+
|
|
87
155
|
## Authentication
|
|
88
156
|
|
|
89
157
|
HMAC-SHA-384 signing (`src/auth.ts`):
|
|
@@ -245,7 +313,10 @@ fields with a per-call random nonce sandbox via `wrapUntrustedOcr` in
|
|
|
245
313
|
**Wrapped at MCP output:**
|
|
246
314
|
- Direct processing tools: `extract_pdf_invoice`, `parse_camt053`,
|
|
247
315
|
`import_camt053`, `process_receipt_batch`, `parse_lightyear_capital_gains`,
|
|
248
|
-
`parse_lightyear_statement`, `import_wise_transactions`, etc.
|
|
316
|
+
`parse_lightyear_statement`, `import_wise_transactions`, etc. (Granular-gated
|
|
317
|
+
tools listed here stay wrapped when exposed; the merged entry points that
|
|
318
|
+
delegate to them — `process_camt053`, `receipt_batch`, … — inherit the same
|
|
319
|
+
wrapped output.)
|
|
249
320
|
- `get_document`: the stored/uploaded-document filename (`name`) — it is
|
|
250
321
|
user-supplied content, so it is wrapped in both the metadata-only and
|
|
251
322
|
full-payload branches.
|
|
@@ -298,7 +369,8 @@ API data remains raw.
|
|
|
298
369
|
- **Standard VAT rate**: 24% (from 1.07.2025)
|
|
299
370
|
- **VD**: Intra-community supply declaration (EU only)
|
|
300
371
|
- **CIT on dividends**: 22/78 from 2025-01-01; 20/80 before (date-gated via `getCitRateForDate` in `src/tools/estonian-tax.ts`)
|
|
301
|
-
-
|
|
372
|
+
- **Dividend booking (net vs. gross)**: `prepare_dividend_package` debits **only the net dividend** to retained earnings (Jaotamata kasum, 3020). The CIT is a current-period **income-tax expense** (the P&L "Tulumaks" line), booked to an 8900-series Kulud account (auto-detected via `resolveIncomeTaxExpenseAccount`, override with `income_tax_expense_account`, default 8900), NOT a second debit to retained earnings. Per Estonian GAAP / RTJ the dividend income tax (TuMS § 50) is charged against current-year profit, not equity directly. Net assets still fall by the full gross (dividend payable + tax liability), so the § 157 checks stay gross-based.
|
|
373
|
+
- **ÄS § 157 net-assets block**: `prepare_dividend_package` hard-blocks distributions that lack retained earnings OR would push net assets below the § 157(2) floor of share capital **+ non-distributable reserves** (reservkapital, auto-detected on account 3010; override with `restricted_reserve_accounts`). `force=true` overrides both checks (use only alongside a legitimate action such as a capital reduction).
|
|
302
374
|
- **Capital gains**: Securities taxed at 22% income tax
|
|
303
375
|
- **Input-VAT deduction restrictions** (`src/estonian-tax-rules.ts`): single date-gated source for the standard VAT-rate timeline (20→22%→24%), current reduced rates, and the deduction detectors. `suggest_booking` returns these as `tax_notes` — `KMS § 30` (külaliste vastuvõtt / esinduskulu: input VAT non-deductible; also `TuMS § 49 lg 4` representation limit 50 €/month + 2% of payroll) and `KMS § 30 lg 4` (M1 passenger car: 50% cap). Notes are advisory; `workflows/book-invoice.md` requires surfacing each on the approval card. `validate_invoice_data` also uses the rate timeline to warn when a line's standard rate (20/22/24%) does not match the invoice date. The full dataset is browsable read-only at `earveldaja://tax_rules` (also lists the `TuMS § 49` representation 50 €+2% and donation 3%/10% limits). `check_tax_free_limits` computes the cumulative `TuMS § 49` representation/donation limits and the 22/78 tax on any excess from caller-supplied year-to-date figures (it does not read the ledger). Update the figures in this module when the law changes.
|
|
304
376
|
|
|
@@ -329,5 +401,5 @@ import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js"
|
|
|
329
401
|
const transport = new StdioClientTransport({ command: "node", args: ["dist/index.js"] });
|
|
330
402
|
const client = new Client({ name: "test", version: "1.0.0" });
|
|
331
403
|
await client.connect(transport);
|
|
332
|
-
const { tools } = await client.listTools(); //
|
|
404
|
+
const { tools } = await client.listTools(); // 120 tools (default exposure)
|
|
333
405
|
```
|