e-arveldaja-mcp 0.1.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/book-invoice.md +108 -0
- package/.claude/commands/month-end.md +88 -0
- package/.claude/commands/new-supplier.md +61 -0
- package/.claude/commands/reconcile-bank.md +74 -0
- package/CLAUDE.md +169 -0
- package/LICENSE +24 -0
- package/README.md +155 -0
- package/dist/api/base-resource.d.ts +22 -0
- package/dist/api/base-resource.d.ts.map +1 -0
- package/dist/api/base-resource.js +64 -0
- package/dist/api/base-resource.js.map +1 -0
- package/dist/api/clients.api.d.ts +13 -0
- package/dist/api/clients.api.d.ts.map +1 -0
- package/dist/api/clients.api.js +34 -0
- package/dist/api/clients.api.js.map +1 -0
- package/dist/api/journals.api.d.ts +16 -0
- package/dist/api/journals.api.d.ts.map +1 -0
- package/dist/api/journals.api.js +55 -0
- package/dist/api/journals.api.js.map +1 -0
- package/dist/api/products.api.d.ts +12 -0
- package/dist/api/products.api.d.ts.map +1 -0
- package/dist/api/products.api.js +28 -0
- package/dist/api/products.api.js.map +1 -0
- package/dist/api/purchase-invoices.api.d.ts +27 -0
- package/dist/api/purchase-invoices.api.d.ts.map +1 -0
- package/dist/api/purchase-invoices.api.js +117 -0
- package/dist/api/purchase-invoices.api.js.map +1 -0
- package/dist/api/readonly.api.d.ts +29 -0
- package/dist/api/readonly.api.d.ts.map +1 -0
- package/dist/api/readonly.api.js +137 -0
- package/dist/api/readonly.api.js.map +1 -0
- package/dist/api/sale-invoices.api.d.ts +13 -0
- package/dist/api/sale-invoices.api.d.ts.map +1 -0
- package/dist/api/sale-invoices.api.js +33 -0
- package/dist/api/sale-invoices.api.js.map +1 -0
- package/dist/api/transactions.api.d.ts +16 -0
- package/dist/api/transactions.api.d.ts.map +1 -0
- package/dist/api/transactions.api.js +53 -0
- package/dist/api/transactions.api.js.map +1 -0
- package/dist/auth.d.ts +2 -0
- package/dist/auth.d.ts.map +1 -0
- package/dist/auth.js +17 -0
- package/dist/auth.js.map +1 -0
- package/dist/cache.d.ts +9 -0
- package/dist/cache.d.ts.map +1 -0
- package/dist/cache.js +43 -0
- package/dist/cache.js.map +1 -0
- package/dist/config.d.ts +19 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +138 -0
- package/dist/config.js.map +1 -0
- package/dist/file-validation.d.ts +5 -0
- package/dist/file-validation.js +86 -0
- package/dist/http-client.d.ts +22 -0
- package/dist/http-client.d.ts.map +1 -0
- package/dist/http-client.js +127 -0
- package/dist/http-client.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +217 -0
- package/dist/index.js.map +1 -0
- package/dist/paginator.d.ts +8 -0
- package/dist/paginator.d.ts.map +1 -0
- package/dist/paginator.js +13 -0
- package/dist/paginator.js.map +1 -0
- package/dist/resources/static-resources.d.ts +3 -0
- package/dist/resources/static-resources.d.ts.map +1 -0
- package/dist/resources/static-resources.js +62 -0
- package/dist/resources/static-resources.js.map +1 -0
- package/dist/tools/account-balance.d.ts +3 -0
- package/dist/tools/account-balance.d.ts.map +1 -0
- package/dist/tools/account-balance.js +129 -0
- package/dist/tools/account-balance.js.map +1 -0
- package/dist/tools/aging-analysis.d.ts +3 -0
- package/dist/tools/aging-analysis.d.ts.map +1 -0
- package/dist/tools/aging-analysis.js +155 -0
- package/dist/tools/aging-analysis.js.map +1 -0
- package/dist/tools/bank-reconciliation.d.ts +3 -0
- package/dist/tools/bank-reconciliation.d.ts.map +1 -0
- package/dist/tools/bank-reconciliation.js +234 -0
- package/dist/tools/bank-reconciliation.js.map +1 -0
- package/dist/tools/crud-tools.d.ts +22 -0
- package/dist/tools/crud-tools.d.ts.map +1 -0
- package/dist/tools/crud-tools.js +472 -0
- package/dist/tools/crud-tools.js.map +1 -0
- package/dist/tools/document-audit.d.ts +3 -0
- package/dist/tools/document-audit.d.ts.map +1 -0
- package/dist/tools/document-audit.js +168 -0
- package/dist/tools/document-audit.js.map +1 -0
- package/dist/tools/estonian-tax.d.ts +3 -0
- package/dist/tools/estonian-tax.d.ts.map +1 -0
- package/dist/tools/estonian-tax.js +253 -0
- package/dist/tools/estonian-tax.js.map +1 -0
- package/dist/tools/financial-statements.d.ts +15 -0
- package/dist/tools/financial-statements.d.ts.map +1 -0
- package/dist/tools/financial-statements.js +300 -0
- package/dist/tools/financial-statements.js.map +1 -0
- package/dist/tools/lightyear-investments.d.ts +3 -0
- package/dist/tools/lightyear-investments.d.ts.map +1 -0
- package/dist/tools/lightyear-investments.js +883 -0
- package/dist/tools/lightyear-investments.js.map +1 -0
- package/dist/tools/pdf-workflow.d.ts +3 -0
- package/dist/tools/pdf-workflow.d.ts.map +1 -0
- package/dist/tools/pdf-workflow.js +434 -0
- package/dist/tools/pdf-workflow.js.map +1 -0
- package/dist/tools/purchase-vat-defaults.d.ts +11 -0
- package/dist/tools/purchase-vat-defaults.js +109 -0
- package/dist/tools/recurring-invoices.d.ts +3 -0
- package/dist/tools/recurring-invoices.d.ts.map +1 -0
- package/dist/tools/recurring-invoices.js +115 -0
- package/dist/tools/recurring-invoices.js.map +1 -0
- package/dist/tools/vat-reports.d.ts +3 -0
- package/dist/tools/vat-reports.d.ts.map +1 -0
- package/dist/tools/vat-reports.js +264 -0
- package/dist/tools/vat-reports.js.map +1 -0
- package/dist/types/api.d.ts +473 -0
- package/dist/types/api.d.ts.map +1 -0
- package/dist/types/api.js +2 -0
- package/dist/types/api.js.map +1 -0
- package/package.json +52 -0
- package/workflows/book-invoice.md +116 -0
- package/workflows/month-end.md +84 -0
- package/workflows/new-supplier.md +60 -0
- package/workflows/reconcile-bank.md +76 -0
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
# Book Purchase Invoice from PDF
|
|
2
|
+
|
|
3
|
+
Read a PDF invoice, extract data, find or create the supplier, create the purchase invoice, upload the PDF, and confirm.
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
$ARGUMENTS should be the absolute file path to the PDF invoice. If not provided, look for PDF files in the current directory and ask the user which one to book.
|
|
8
|
+
|
|
9
|
+
## Workflow
|
|
10
|
+
|
|
11
|
+
### Step 1: Read the PDF
|
|
12
|
+
|
|
13
|
+
Use the Read tool to visually read the PDF file. Extract these fields:
|
|
14
|
+
- Supplier name and registry code (registrikood, 8 digits)
|
|
15
|
+
- Supplier VAT number (KMKR, starts with EE)
|
|
16
|
+
- Invoice number
|
|
17
|
+
- Invoice date (convert to YYYY-MM-DD)
|
|
18
|
+
- Due date or payment term in days
|
|
19
|
+
- Reference number (viitenumber) if present
|
|
20
|
+
- Supplier IBAN
|
|
21
|
+
- Line items: description, quantity, unit price, net total, VAT rate
|
|
22
|
+
- Invoice totals: net (without VAT), VAT amount, gross (with VAT)
|
|
23
|
+
|
|
24
|
+
Also call `extract_pdf_invoice` with the file_path to get machine-readable hints (IBAN, registry code, VAT number, reference number). Cross-check against what you read visually.
|
|
25
|
+
|
|
26
|
+
### Step 2: Validate the numbers
|
|
27
|
+
|
|
28
|
+
Call `validate_invoice_data`:
|
|
29
|
+
- total_net: invoice net total
|
|
30
|
+
- total_vat: invoice VAT total
|
|
31
|
+
- total_gross: invoice gross total
|
|
32
|
+
- items: JSON array of items, each with `total_net_price` and `vat_rate_dropdown` (e.g. "24", "22", "9", "0", or "-")
|
|
33
|
+
- invoice_date: YYYY-MM-DD
|
|
34
|
+
- due_date: YYYY-MM-DD (if available)
|
|
35
|
+
|
|
36
|
+
Do NOT proceed until validation passes (valid: true). If errors, re-check the extracted values.
|
|
37
|
+
|
|
38
|
+
### Step 3: Check for duplicates
|
|
39
|
+
|
|
40
|
+
Call `detect_duplicate_purchase_invoice` (no params needed) to scan all existing invoices.
|
|
41
|
+
|
|
42
|
+
If a duplicate is found with the same supplier and invoice number, STOP and tell the user.
|
|
43
|
+
|
|
44
|
+
### Step 4: Resolve the supplier
|
|
45
|
+
|
|
46
|
+
Call `resolve_supplier`:
|
|
47
|
+
- name: supplier name
|
|
48
|
+
- reg_code: registry code (if found)
|
|
49
|
+
- vat_no: VAT number (if found)
|
|
50
|
+
- iban: IBAN (if found)
|
|
51
|
+
- auto_create: true
|
|
52
|
+
|
|
53
|
+
Note the returned client ID.
|
|
54
|
+
|
|
55
|
+
If the supplier was found (not created) and the invoice has an IBAN or VAT number missing from the existing client, call `update_client` to add it.
|
|
56
|
+
|
|
57
|
+
### Step 5: Look up booking suggestions
|
|
58
|
+
|
|
59
|
+
Call `suggest_booking`:
|
|
60
|
+
- clients_id: the supplier client ID
|
|
61
|
+
- description: first line item description (helps find similar past invoices)
|
|
62
|
+
|
|
63
|
+
Use the returned past invoice data to determine:
|
|
64
|
+
- Which `cl_purchase_articles_id` to use
|
|
65
|
+
- Which `purchase_accounts_id` (expense account) to use
|
|
66
|
+
|
|
67
|
+
If no past invoices exist, call `list_purchase_articles` and choose the most appropriate article. Common expense articles:
|
|
68
|
+
- 35 (Leases/Üür, acct 5020) - office rent, coworking
|
|
69
|
+
- 37 (Office expenses/Bürookulud, acct 5040)
|
|
70
|
+
- 45 (Internet, acct 5230)
|
|
71
|
+
- 49 (Consultation/Konsultatsioon, acct 5340)
|
|
72
|
+
- 62 (Other operating/Muud tegevuskulud, acct 5990)
|
|
73
|
+
|
|
74
|
+
### Step 6: Create the purchase invoice
|
|
75
|
+
|
|
76
|
+
Call `create_purchase_invoice_from_pdf`:
|
|
77
|
+
- supplier_client_id: from step 4
|
|
78
|
+
- invoice_number: from the PDF
|
|
79
|
+
- invoice_date: YYYY-MM-DD
|
|
80
|
+
- journal_date: same as invoice_date
|
|
81
|
+
- term_days: from due date calculation, or 0 if already paid
|
|
82
|
+
- items: JSON array where each item has:
|
|
83
|
+
- custom_title: description from PDF
|
|
84
|
+
- cl_purchase_articles_id: from step 5
|
|
85
|
+
- purchase_accounts_id: from step 5
|
|
86
|
+
- total_net_price: net amount
|
|
87
|
+
- vat_rate_dropdown: VAT rate as string (e.g. "24")
|
|
88
|
+
- amount: quantity
|
|
89
|
+
- vat_price: EXACT total VAT from the original invoice
|
|
90
|
+
- gross_price: EXACT total gross from the original invoice
|
|
91
|
+
- ref_number: reference number (if found)
|
|
92
|
+
- bank_account_no: supplier IBAN (spaces removed)
|
|
93
|
+
- notes: PDF filename
|
|
94
|
+
|
|
95
|
+
### Step 7: Upload the PDF
|
|
96
|
+
|
|
97
|
+
Call `upload_invoice_document`:
|
|
98
|
+
- invoice_id: the ID from step 6
|
|
99
|
+
- file_path: the original PDF path
|
|
100
|
+
|
|
101
|
+
### Step 8: Confirm the invoice
|
|
102
|
+
|
|
103
|
+
Call `confirm_purchase_invoice`:
|
|
104
|
+
- id: the invoice ID
|
|
105
|
+
|
|
106
|
+
### Step 9: Summary
|
|
107
|
+
|
|
108
|
+
Report: invoice number, supplier, net/VAT/gross, expense account used, invoice ID, whether supplier was new or existing, confirmation status.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# Month-End Close Checklist
|
|
2
|
+
|
|
3
|
+
Run the month-end close checklist, compute financial statements, and flag issues.
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
$ARGUMENTS should be the month in YYYY-MM format (e.g. 2026-02). If not provided, use the previous calendar month.
|
|
8
|
+
|
|
9
|
+
## Workflow
|
|
10
|
+
|
|
11
|
+
### Step 1: Run the checklist
|
|
12
|
+
|
|
13
|
+
Call `month_end_close_checklist`:
|
|
14
|
+
- month: the YYYY-MM value
|
|
15
|
+
|
|
16
|
+
### Step 2: Flag blocking issues
|
|
17
|
+
|
|
18
|
+
Present in priority order:
|
|
19
|
+
|
|
20
|
+
**BLOCKERS (must fix before closing):**
|
|
21
|
+
1. Unconfirmed purchase invoices - not registered in ledger
|
|
22
|
+
2. Unconfirmed sale invoices - revenue not recorded
|
|
23
|
+
3. Unconfirmed journal entries - adjustments not posted
|
|
24
|
+
4. Unconfirmed bank transactions - cash not reconciled
|
|
25
|
+
|
|
26
|
+
For each, show ID, date, amount/title, and suggest the fix:
|
|
27
|
+
- Purchase invoices: `confirm_purchase_invoice` or delete if duplicate
|
|
28
|
+
- Sale invoices: `confirm_sale_invoice`
|
|
29
|
+
- Journals: `confirm_journal`
|
|
30
|
+
- Transactions: suggest running `/reconcile-bank`
|
|
31
|
+
|
|
32
|
+
**WARNINGS:**
|
|
33
|
+
- Overdue receivables - may need follow-up
|
|
34
|
+
- Overdue payables - check if payment was made
|
|
35
|
+
|
|
36
|
+
### Step 3: Check for missing documents
|
|
37
|
+
|
|
38
|
+
Call `find_missing_documents`:
|
|
39
|
+
- date_from: YYYY-MM-01
|
|
40
|
+
- date_to: last day of the month
|
|
41
|
+
|
|
42
|
+
Report confirmed purchase invoices without attached PDFs.
|
|
43
|
+
|
|
44
|
+
### Step 4: Check for duplicates
|
|
45
|
+
|
|
46
|
+
Call `detect_duplicate_purchase_invoice`:
|
|
47
|
+
- date_from: YYYY-MM-01
|
|
48
|
+
- date_to: last day of the month
|
|
49
|
+
|
|
50
|
+
Report any exact duplicates or suspicious matches.
|
|
51
|
+
|
|
52
|
+
### Step 5: Compute financial statements
|
|
53
|
+
|
|
54
|
+
Call `compute_trial_balance`:
|
|
55
|
+
- date_from: YYYY-MM-01
|
|
56
|
+
- date_to: last day of the month
|
|
57
|
+
|
|
58
|
+
Verify total debits = total credits.
|
|
59
|
+
|
|
60
|
+
Call `compute_profit_and_loss`:
|
|
61
|
+
- date_from: YYYY-01-01 (fiscal year start)
|
|
62
|
+
- date_to: last day of the month
|
|
63
|
+
|
|
64
|
+
Show YTD P&L: total revenue, expenses, net profit.
|
|
65
|
+
|
|
66
|
+
Call `compute_balance_sheet`:
|
|
67
|
+
- date_to: last day of the month
|
|
68
|
+
|
|
69
|
+
Verify balanced (assets = liabilities + equity).
|
|
70
|
+
|
|
71
|
+
### Step 6: Summary report
|
|
72
|
+
|
|
73
|
+
```
|
|
74
|
+
Month-End Close: YYYY-MM
|
|
75
|
+
================================
|
|
76
|
+
Blockers: X issues
|
|
77
|
+
Warnings: X items
|
|
78
|
+
Missing docs: X invoices
|
|
79
|
+
Duplicates: X found
|
|
80
|
+
|
|
81
|
+
Trial Balance: BALANCED / IMBALANCED by X EUR
|
|
82
|
+
Balance Sheet: BALANCED / IMBALANCED
|
|
83
|
+
YTD Net Profit: X.XX EUR
|
|
84
|
+
|
|
85
|
+
Status: READY TO CLOSE / HAS BLOCKERS
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
If blockers exist, list specific actions. Offer to help fix them.
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
# Create New Supplier
|
|
2
|
+
|
|
3
|
+
Create a new supplier (client) in e-arveldaja with proper fields.
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
$ARGUMENTS should be the supplier name or Estonian registry code (8 digits). If not provided, ask the user.
|
|
8
|
+
|
|
9
|
+
## Workflow
|
|
10
|
+
|
|
11
|
+
### Step 1: Determine input type
|
|
12
|
+
|
|
13
|
+
- 8-digit number: treat as registry code
|
|
14
|
+
- Text: treat as supplier name
|
|
15
|
+
|
|
16
|
+
### Step 2: Check if supplier already exists
|
|
17
|
+
|
|
18
|
+
If registry code: call `find_client_by_code` with code: the registry code.
|
|
19
|
+
If name: call `search_client` with name: the supplier name.
|
|
20
|
+
|
|
21
|
+
If found, show the existing client and ask if the user wants to use it or create a new one. If using existing, stop and report details.
|
|
22
|
+
|
|
23
|
+
### Step 3: Resolve supplier details
|
|
24
|
+
|
|
25
|
+
Call `resolve_supplier`:
|
|
26
|
+
- name: supplier name (if provided)
|
|
27
|
+
- reg_code: registry code (if provided)
|
|
28
|
+
- auto_create: false (check registry data first)
|
|
29
|
+
- country: "EST" (default)
|
|
30
|
+
|
|
31
|
+
If an Estonian code was provided, the tool queries the business registry for the official company name and address. Show this to the user.
|
|
32
|
+
|
|
33
|
+
### Step 4: Gather additional information
|
|
34
|
+
|
|
35
|
+
Ask the user for any details they want to add:
|
|
36
|
+
- Bank account (IBAN)
|
|
37
|
+
- VAT number (KMKR, e.g. EE123456789)
|
|
38
|
+
- Email address
|
|
39
|
+
- Phone number
|
|
40
|
+
- Address (if not found from registry)
|
|
41
|
+
|
|
42
|
+
### Step 5: Create the supplier
|
|
43
|
+
|
|
44
|
+
Call `create_client`:
|
|
45
|
+
- name: official name from registry, or user-provided name
|
|
46
|
+
- code: registry code (if known)
|
|
47
|
+
- is_client: false
|
|
48
|
+
- is_supplier: true
|
|
49
|
+
- cl_code_country: "EST" (or as specified)
|
|
50
|
+
- is_juridical_entity: true (default, false for natural persons)
|
|
51
|
+
- bank_account_no: IBAN (if provided)
|
|
52
|
+
- invoice_vat_no: VAT number (if provided)
|
|
53
|
+
- email: (if provided)
|
|
54
|
+
- telephone: (if provided)
|
|
55
|
+
- address_text: from registry or user
|
|
56
|
+
|
|
57
|
+
### Step 6: Report
|
|
58
|
+
|
|
59
|
+
Show created supplier: client ID, name, registry code, country, any additional fields.
|
|
60
|
+
|
|
61
|
+
Remind user this supplier is now available for `/book-invoice`.
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Reconcile Bank Transactions
|
|
2
|
+
|
|
3
|
+
Match unconfirmed bank transactions to open invoices and confirm the matches.
|
|
4
|
+
|
|
5
|
+
## Arguments
|
|
6
|
+
|
|
7
|
+
$ARGUMENTS can be:
|
|
8
|
+
- empty or "auto" - dry run first, then confirm high-confidence matches with user approval
|
|
9
|
+
- "review" - show all matches for manual review without confirming
|
|
10
|
+
- a transaction ID number - show match details for that specific transaction
|
|
11
|
+
|
|
12
|
+
## Workflow
|
|
13
|
+
|
|
14
|
+
### Step 1: Get matches
|
|
15
|
+
|
|
16
|
+
Call `reconcile_transactions`:
|
|
17
|
+
- min_confidence: 30 (to see all potential matches)
|
|
18
|
+
|
|
19
|
+
Review the output:
|
|
20
|
+
- total_unconfirmed: bank transactions needing attention
|
|
21
|
+
- matched: transactions with at least one candidate
|
|
22
|
+
- unmatched: no match found
|
|
23
|
+
|
|
24
|
+
If total_unconfirmed is 0, tell the user everything is reconciled and stop.
|
|
25
|
+
|
|
26
|
+
### Step 2: Present matches
|
|
27
|
+
|
|
28
|
+
Show a summary table grouped by confidence:
|
|
29
|
+
|
|
30
|
+
**HIGH (>=80):** safe to auto-confirm
|
|
31
|
+
- Transaction date, amount, type (D=incoming, C=outgoing), description
|
|
32
|
+
- Matched invoice: number, client, gross amount, confidence, reasons
|
|
33
|
+
|
|
34
|
+
**MEDIUM (50-79):** needs review
|
|
35
|
+
**LOW (<50):** unlikely matches, shown for reference
|
|
36
|
+
|
|
37
|
+
### Step 3: Handle based on mode
|
|
38
|
+
|
|
39
|
+
**If "auto" or empty:**
|
|
40
|
+
|
|
41
|
+
Call `auto_confirm_exact_matches`:
|
|
42
|
+
- execute: false (dry run first)
|
|
43
|
+
- min_confidence: 90
|
|
44
|
+
|
|
45
|
+
Show what would be confirmed. Ask user for approval.
|
|
46
|
+
|
|
47
|
+
If approved, call `auto_confirm_exact_matches`:
|
|
48
|
+
- execute: true
|
|
49
|
+
- min_confidence: 90
|
|
50
|
+
|
|
51
|
+
Report results.
|
|
52
|
+
|
|
53
|
+
**If "review":**
|
|
54
|
+
|
|
55
|
+
Show all matches. For each, ask user to confirm or skip.
|
|
56
|
+
|
|
57
|
+
For approved matches, call `confirm_transaction`:
|
|
58
|
+
- id: transaction ID
|
|
59
|
+
- distributions: JSON string `[{"related_table": "sale_invoices" or "purchase_invoices", "related_id": invoice_id, "amount": transaction_amount}]`
|
|
60
|
+
|
|
61
|
+
**If transaction ID:**
|
|
62
|
+
|
|
63
|
+
Call `get_transaction` with that ID. Show details and matches. Offer to confirm if a match exists.
|
|
64
|
+
|
|
65
|
+
### Step 4: Unmatched transactions
|
|
66
|
+
|
|
67
|
+
List transactions with no matches and suggest:
|
|
68
|
+
- Small amounts (<1 EUR): likely bank fees/interest, need manual journal entry
|
|
69
|
+
- Description contains "teenustasu", "intress", "service fee": bank charges
|
|
70
|
+
- Larger amounts: check if corresponding invoice exists
|
|
71
|
+
|
|
72
|
+
### Step 5: Summary
|
|
73
|
+
|
|
74
|
+
Report: confirmed count, remaining unconfirmed, unmatched needing manual attention.
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
# e-arveldaja MCP Server
|
|
2
|
+
|
|
3
|
+
TypeScript MCP server for the Estonian e-arveldaja (RIK e-Financials) REST API.
|
|
4
|
+
84 tools across 11 modules + 6 resources. Supports multiple companies/accounts.
|
|
5
|
+
|
|
6
|
+
## Quick Start
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
npm run build # tsc -> dist/
|
|
10
|
+
npm run start # node dist/index.js (stdio transport)
|
|
11
|
+
npm run dev # tsx src/index.ts (development)
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Credentials
|
|
15
|
+
|
|
16
|
+
All `apikey*.txt` files are scanned from the project root and its parent directory. Multiple files = multiple connections (companies).
|
|
17
|
+
|
|
18
|
+
Credentials are loaded in this priority order (see `src/config.ts`):
|
|
19
|
+
|
|
20
|
+
1. **Environment variables**: `EARVELDAJA_API_KEY_ID`, `EARVELDAJA_API_PUBLIC_VALUE`, `EARVELDAJA_API_PASSWORD`
|
|
21
|
+
2. **`EARVELDAJA_API_KEY_FILE`** env var pointing to a specific file
|
|
22
|
+
3. **`apikey*.txt` files** — scanned from the project root. Set `EARVELDAJA_SCAN_PARENT=true` to also scan the parent directory.
|
|
23
|
+
|
|
24
|
+
The `apikey.txt` format:
|
|
25
|
+
```
|
|
26
|
+
ApiKey ID: <key_id>
|
|
27
|
+
ApiKey public value: <public_value>
|
|
28
|
+
Password: <password>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Set `EARVELDAJA_SERVER=demo` for the demo API (default: `live`).
|
|
32
|
+
|
|
33
|
+
### Multi-account (multiple companies)
|
|
34
|
+
|
|
35
|
+
Place multiple `apikey*.txt` files (e.g. `apikey.txt`, `apikey (1).txt`) next to the project.
|
|
36
|
+
Use `list_connections` to see all available accounts and `switch_connection` to switch between them.
|
|
37
|
+
Switching clears all cached data to prevent cross-company data leaks.
|
|
38
|
+
|
|
39
|
+
**NEVER commit `.env` or `apikey.txt` to git.** The `.gitignore` is configured to exclude them.
|
|
40
|
+
|
|
41
|
+
## Authentication
|
|
42
|
+
|
|
43
|
+
HMAC-SHA-384 signing (`src/auth.ts`):
|
|
44
|
+
- Message: `{keyId}:{utcTime}:{urlPath}`
|
|
45
|
+
- Signature: `BASE64(HMAC-SHA-384(message, password))`
|
|
46
|
+
- Headers: `X-AUTH-KEY: {publicValue}:{signature}`, `X-AUTH-QUERYTIME: {utcTime}`
|
|
47
|
+
- Signing uses the URL path only (no query params)
|
|
48
|
+
|
|
49
|
+
## API Endpoints (RIK e-Financials v1)
|
|
50
|
+
|
|
51
|
+
OpenAPI spec: `GET /openapi.yaml` on the API server. HTML docs: `/api.html`.
|
|
52
|
+
|
|
53
|
+
### Action endpoints
|
|
54
|
+
- **Confirm/Register**: `PATCH /{entity}/{id}/register` (not `/confirm`)
|
|
55
|
+
- **Invalidate**: `PATCH /{entity}/{id}/invalidate`
|
|
56
|
+
- **Reactivate**: `PATCH /clients|products/{id}/reactivate`
|
|
57
|
+
- **Deactivate**: `PATCH /clients|products/{id}/deactivate`
|
|
58
|
+
- **Deliver sale invoice**: `PATCH /sale_invoices/{id}/deliver` (not `/send_einvoice`)
|
|
59
|
+
|
|
60
|
+
### Document endpoints
|
|
61
|
+
- **User-uploaded docs**: `GET/PUT/DELETE /{entity}/{id}/document_user` (PUT to upload, not POST)
|
|
62
|
+
- **System-generated sale invoice PDF**: `GET /sale_invoices/{id}/pdf_system`
|
|
63
|
+
|
|
64
|
+
### Transaction registration
|
|
65
|
+
- Body is a **top-level JSON array** of `TransactionsDistribution` objects (not wrapped in `{items: [...]}`)
|
|
66
|
+
- Each distribution: `{related_table, amount, related_id?, related_sub_id?}`
|
|
67
|
+
- Example: `PATCH /transactions/{id}/register` with body `[{"related_table":"purchase_invoices","related_id":123,"amount":59.94}]`
|
|
68
|
+
- **Card payments often have `clients_id: null`** — confirmation fails with "buyer or supplier is missing". `TransactionsApi.confirm()` auto-fixes this by looking up the client from the linked invoice.
|
|
69
|
+
|
|
70
|
+
### Purchase invoice creation (non-VAT company)
|
|
71
|
+
- Do **not** pass `gross_price` at creation — the API computes it
|
|
72
|
+
- For VAT tracking on items: set `vat_rate_dropdown`, `vat_accounts_id`, `cl_vat_articles_id`, `project_no_vat_gross_price`
|
|
73
|
+
- The API will compute `vat_amount` on the item but invoice-level `vat_price` stays 0 for non-VAT companies
|
|
74
|
+
|
|
75
|
+
## Architecture
|
|
76
|
+
|
|
77
|
+
```
|
|
78
|
+
src/
|
|
79
|
+
config.ts # Env/file credential loading, server URL selection
|
|
80
|
+
auth.ts # HMAC-SHA-384 request signing
|
|
81
|
+
http-client.ts # Authenticated HTTP client (rate-limited, 60s timeout)
|
|
82
|
+
cache.ts # In-memory TTL cache (300s default, 500 entry max)
|
|
83
|
+
index.ts # Server entry point, wires everything together
|
|
84
|
+
api/
|
|
85
|
+
base-resource.ts # Generic CRUD with caching (listAll max 200 pages)
|
|
86
|
+
clients.api.ts # Clients (buyers/suppliers)
|
|
87
|
+
products.api.ts # Products/services
|
|
88
|
+
journals.api.ts # Journal entries with postings
|
|
89
|
+
transactions.api.ts # Bank transactions
|
|
90
|
+
sale-invoices.api.ts # Sales invoices
|
|
91
|
+
purchase-invoices.api.ts # Purchase invoices
|
|
92
|
+
readonly.api.ts # Reference data (accounts, articles, templates, etc.)
|
|
93
|
+
tools/
|
|
94
|
+
crud-tools.ts # ~50 CRUD tools for all entities + reference data
|
|
95
|
+
purchase-vat-defaults.ts # Purchase VAT article/account resolution from reference data
|
|
96
|
+
account-balance.ts # D/C balance computation, client debt
|
|
97
|
+
pdf-workflow.ts # PDF text extraction, invoice validation, supplier resolution, booking suggestions
|
|
98
|
+
bank-reconciliation.ts # Transaction matching and auto-confirmation
|
|
99
|
+
financial-statements.ts # Trial balance, balance sheet, P&L, month-end close
|
|
100
|
+
aging-analysis.ts # Receivables/payables aging buckets
|
|
101
|
+
recurring-invoices.ts # Clone sale invoices for recurring billing
|
|
102
|
+
estonian-tax.ts # Dividend package, owner expense reimbursement
|
|
103
|
+
document-audit.ts # Duplicate detection, missing documents
|
|
104
|
+
lightyear-investments.ts # Lightyear CSV import (buy/sell/distribution booking)
|
|
105
|
+
types/
|
|
106
|
+
api.ts # All TypeScript interfaces (~530 lines)
|
|
107
|
+
resources/
|
|
108
|
+
static-resources.ts # MCP resources (accounts, articles, templates, etc.)
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
## Key Accounting Concepts
|
|
112
|
+
|
|
113
|
+
### D/C Balance Logic
|
|
114
|
+
- **D-type accounts** (assets, expenses): balance = debits - credits
|
|
115
|
+
- **C-type accounts** (liabilities, equity, revenue): balance = credits - debits
|
|
116
|
+
- Journal postings use `base_amount` (EUR) when available for multi-currency entries
|
|
117
|
+
- Balance sheet handles **contra-accounts** (e.g., accumulated depreciation is C-type within Varad)
|
|
118
|
+
|
|
119
|
+
### Account Types (Estonian)
|
|
120
|
+
- **Varad** = Assets (normal balance: D, but contra-assets like kulum are C)
|
|
121
|
+
- **Kohustused** = Liabilities (normal: C)
|
|
122
|
+
- **Omakapital** = Equity (normal: C)
|
|
123
|
+
- **Tulud** = Revenue (normal: C)
|
|
124
|
+
- **Kulud** = Expenses (normal: D)
|
|
125
|
+
|
|
126
|
+
### Cache Invalidation
|
|
127
|
+
All mutating API methods (`create`, `update`, `delete`, `confirm`, `merge`, `deactivate`, `uploadDocument`, `deleteDocument`) call `cache.invalidate(this.basePath)` before the API call.
|
|
128
|
+
|
|
129
|
+
### Lightyear Investment CSV
|
|
130
|
+
- **BRICEKSP** (IE000GWTNRJ7): money market cash fund, always excluded from trades
|
|
131
|
+
- **FX pairing**: Foreign currency trades (e.g., USD) are paired with CN-xxx Conversion entries by date + amount match. Consumed conversions are tracked to prevent double-matching.
|
|
132
|
+
- **Sells require capital gains file**: Cost basis comes from the FIFO capital gains CSV. Sells without cost basis data are skipped with a warning.
|
|
133
|
+
- **Duplicate detection**: Journal `document_number` field stores `LY:{reference}` (e.g., `LY:OR-EVN9C76R7A`)
|
|
134
|
+
- **Dry run default**: Both `book_lightyear_trades` and `book_lightyear_distributions` default to `dry_run=true`
|
|
135
|
+
|
|
136
|
+
## Security Notes
|
|
137
|
+
|
|
138
|
+
- File read operations (PDF, CSV) resolve symlinks via `realpath()` and re-check extensions
|
|
139
|
+
- `safeJsonParse` enforces 1MB input size limit
|
|
140
|
+
- `listAll()` is bounded to 200 pages max
|
|
141
|
+
- HTTP client rate-limits to ~10 req/sec
|
|
142
|
+
- Error messages are sanitized (no raw API response bodies)
|
|
143
|
+
- Cache is bounded to 500 entries with LRU eviction
|
|
144
|
+
|
|
145
|
+
## Estonian Tax Rules
|
|
146
|
+
|
|
147
|
+
- **KMD INF**: Partner detail annex, threshold 1000 EUR net per partner
|
|
148
|
+
- **Standard VAT rate**: 24% (from 1.07.2025)
|
|
149
|
+
- **VD**: Intra-community supply declaration (EU only)
|
|
150
|
+
- **CIT on dividends**: 22/78 corporate income tax rate
|
|
151
|
+
- **Capital gains**: Securities taxed at 22% income tax
|
|
152
|
+
|
|
153
|
+
## Development
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
npx tsc --noEmit # Type-check without emitting
|
|
157
|
+
npx tsc # Full build to dist/
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
No test framework is configured. Test via MCP client connection:
|
|
161
|
+
```typescript
|
|
162
|
+
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
|
|
163
|
+
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
|
|
164
|
+
|
|
165
|
+
const transport = new StdioClientTransport({ command: "node", args: ["dist/index.js"] });
|
|
166
|
+
const client = new Client({ name: "test", version: "1.0.0" });
|
|
167
|
+
await client.connect(transport);
|
|
168
|
+
const { tools } = await client.listTools(); // 82 tools
|
|
169
|
+
```
|
package/LICENSE
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
This is free and unencumbered software released into the public domain.
|
|
2
|
+
|
|
3
|
+
Anyone is free to copy, modify, publish, use, compile, sell, or
|
|
4
|
+
distribute this software, either in source code form or as a compiled
|
|
5
|
+
binary, for any purpose, commercial or non-commercial, and by any
|
|
6
|
+
means.
|
|
7
|
+
|
|
8
|
+
In jurisdictions that recognize copyright laws, the author or authors
|
|
9
|
+
of this software dedicate any and all copyright interest in the
|
|
10
|
+
software to the public domain. We make this dedication for the benefit
|
|
11
|
+
of the public at large and to the detriment of our heirs and
|
|
12
|
+
successors. We intend this dedication to be an overt act of
|
|
13
|
+
relinquishment in perpetuity of all present and future rights to this
|
|
14
|
+
software under copyright law.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
|
19
|
+
IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
|
20
|
+
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
|
21
|
+
ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
22
|
+
OTHER DEALINGS IN THE SOFTWARE.
|
|
23
|
+
|
|
24
|
+
For more information, please refer to <https://unlicense.org/>
|
package/README.md
ADDED
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
# e-arveldaja MCP Server
|
|
2
|
+
|
|
3
|
+
MCP (Model Context Protocol) server for the Estonian e-arveldaja (RIK e-Financials) REST API. Works with any MCP-compatible AI assistant — Claude Code, Cursor, Windsurf, Cline, and others.
|
|
4
|
+
|
|
5
|
+
## Disclaimer
|
|
6
|
+
|
|
7
|
+
**This is an experimental, unofficial project.** It is not affiliated with, endorsed by, or in any way officially connected to RIK (Registrite ja Infosüsteemide Keskus) or the e-arveldaja / e-Financials service.
|
|
8
|
+
|
|
9
|
+
**Use entirely at your own risk.** This software interacts with live financial data and can create, modify, confirm, and delete accounting records (invoices, journal entries, transactions, etc.). The authors accept no responsibility for any data loss, incorrect bookings, or other damages resulting from the use of this software.
|
|
10
|
+
|
|
11
|
+
By using this software you acknowledge that:
|
|
12
|
+
- You are solely responsible for verifying all data and operations
|
|
13
|
+
- You should test thoroughly on the demo server before using with live data
|
|
14
|
+
- This is experimental software with no warranty of any kind
|
|
15
|
+
|
|
16
|
+
## Getting an API Key
|
|
17
|
+
|
|
18
|
+
1. Log in to [e-arveldaja](https://www.earveldaja.ee/)
|
|
19
|
+
2. Go to **Seadistused** → **Üldised seadistused** → **Lisa uus juurdepääsuluba** (Settings → General settings → Add new access token)
|
|
20
|
+
3. Enter any name for the token
|
|
21
|
+
4. Find your public IP address (e.g. at [whatismyipaddress.com](https://whatismyipaddress.com/)) and enter it in the allowed IP field. Multiple IPs can be separated by `;`
|
|
22
|
+
5. Save — download the `apikey.txt` file and place it next to the project directory (i.e. in the parent folder)
|
|
23
|
+
|
|
24
|
+
If you don't have a static IP address, you will need to update the allowed IP in e-arveldaja settings whenever your IP changes.
|
|
25
|
+
|
|
26
|
+
**Never commit the `apikey.txt` file to git.**
|
|
27
|
+
|
|
28
|
+
For the demo server, set the environment variable `EARVELDAJA_SERVER=demo`.
|
|
29
|
+
|
|
30
|
+
## Setup
|
|
31
|
+
|
|
32
|
+
### Option A: npx (no install needed)
|
|
33
|
+
|
|
34
|
+
Just reference `npx e-arveldaja-mcp` in your MCP config — no cloning or building required. See configuration examples below.
|
|
35
|
+
|
|
36
|
+
### Option B: From source
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
git clone https://github.com/iseppo/e-arveldaja-mcp.git
|
|
40
|
+
cd e-arveldaja-mcp
|
|
41
|
+
npm install
|
|
42
|
+
npm run build # tsc -> dist/
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Connecting to your AI assistant
|
|
46
|
+
|
|
47
|
+
This is a standard MCP server using stdio transport. Most AI assistants can set this up themselves — just ask:
|
|
48
|
+
|
|
49
|
+
> "Add the e-arveldaja MCP server from /path/to/e-arveldaja-mcp to my MCP configuration"
|
|
50
|
+
|
|
51
|
+
The assistant will read the config format it needs and add the server entry. You can also ask it to install the workflows:
|
|
52
|
+
|
|
53
|
+
> "Copy the workflow files from /path/to/e-arveldaja-mcp/workflows/ into your commands so I can use them"
|
|
54
|
+
|
|
55
|
+
If you prefer to configure manually:
|
|
56
|
+
|
|
57
|
+
**JSON-based config** (Claude Code, Cursor, Windsurf, Cline, Gemini CLI, Antigravity):
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"mcpServers": {
|
|
62
|
+
"e-arveldaja": {
|
|
63
|
+
"command": "npx",
|
|
64
|
+
"args": ["-y", "e-arveldaja-mcp"]
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
**TOML-based config** (Codex CLI):
|
|
71
|
+
|
|
72
|
+
```toml
|
|
73
|
+
[mcp_servers.e-arveldaja]
|
|
74
|
+
command = "npx"
|
|
75
|
+
args = ["-y", "e-arveldaja-mcp"]
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
If running from source, replace `"npx", "-y", "e-arveldaja-mcp"` with `"node", "/path/to/e-arveldaja-mcp/dist/index.js"`.
|
|
79
|
+
|
|
80
|
+
Where this config file lives depends on your tool:
|
|
81
|
+
|
|
82
|
+
| Tool | Config file |
|
|
83
|
+
|---|---|
|
|
84
|
+
| **Claude Code** | `~/.claude/settings.json` or project `.claude/settings.json` |
|
|
85
|
+
| **Codex CLI** | `~/.codex/config.toml` or project `.codex/config.toml` |
|
|
86
|
+
| **Gemini CLI** | `~/.gemini/settings.json` or project `.gemini/settings.json` |
|
|
87
|
+
| **Google Antigravity** | MCP Store UI → Manage MCP Servers → View raw config (`mcp_config.json`) |
|
|
88
|
+
| **Cursor** | `.cursor/mcp.json` in your project |
|
|
89
|
+
| **Windsurf** | `~/.codeium/windsurf/mcp_config.json` |
|
|
90
|
+
| **Cline** | VS Code settings under `cline.mcpServers` |
|
|
91
|
+
|
|
92
|
+
See [CLAUDE.md](CLAUDE.md) for architecture details and full API documentation.
|
|
93
|
+
|
|
94
|
+
## Workflows
|
|
95
|
+
|
|
96
|
+
The project includes step-by-step workflow guides in [`workflows/`](workflows/) that orchestrate multiple MCP tools into complete accounting tasks. These work with any MCP client — just paste the workflow into your AI assistant's prompt or follow the steps manually.
|
|
97
|
+
|
|
98
|
+
| Workflow | Description |
|
|
99
|
+
|---|---|
|
|
100
|
+
| [book-invoice](workflows/book-invoice.md) | Book a purchase invoice from PDF: extract data, validate, find/create supplier, suggest accounts, create invoice, upload PDF, confirm |
|
|
101
|
+
| [reconcile-bank](workflows/reconcile-bank.md) | Match unconfirmed bank transactions to open invoices and confirm matches |
|
|
102
|
+
| [month-end](workflows/month-end.md) | Run month-end close checklist: blockers, missing docs, duplicates, trial balance, P&L, balance sheet |
|
|
103
|
+
| [new-supplier](workflows/new-supplier.md) | Create a supplier with Estonian business registry lookup and dedup check |
|
|
104
|
+
|
|
105
|
+
### Claude Code slash commands
|
|
106
|
+
|
|
107
|
+
If you use Claude Code, the same workflows are also available as slash commands in `.claude/commands/`. To install:
|
|
108
|
+
|
|
109
|
+
**Option A:** Run Claude Code from the `e-arveldaja-mcp` directory — skills are auto-detected.
|
|
110
|
+
|
|
111
|
+
**Option B:** Symlink or copy to your global commands:
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Symlink (stays up to date)
|
|
115
|
+
ln -s /path/to/e-arveldaja-mcp/.claude/commands/*.md ~/.claude/commands/
|
|
116
|
+
|
|
117
|
+
# Or copy
|
|
118
|
+
cp /path/to/e-arveldaja-mcp/.claude/commands/*.md ~/.claude/commands/
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
Then use `/book-invoice`, `/reconcile-bank`, `/month-end`, `/new-supplier` in any conversation.
|
|
122
|
+
|
|
123
|
+
## Usage Examples
|
|
124
|
+
|
|
125
|
+
Once the MCP server is connected, just talk to your AI assistant in natural language:
|
|
126
|
+
|
|
127
|
+
### Enter purchase invoices from PDF files
|
|
128
|
+
|
|
129
|
+
> "Book this invoice PDF into e-arveldaja and match it to the bank payment"
|
|
130
|
+
|
|
131
|
+
The assistant will extract invoice data from the PDF, create a purchase invoice with the correct accounts and VAT rates, and match it to existing bank transactions.
|
|
132
|
+
|
|
133
|
+
### Book Lightyear investment trades
|
|
134
|
+
|
|
135
|
+
Download your Lightyear account statement CSV and capital gains report, then:
|
|
136
|
+
|
|
137
|
+
> "Create e-arveldaja journal entries from these Lightyear CSVs"
|
|
138
|
+
|
|
139
|
+
The assistant will parse the trades, pair foreign currency conversions, calculate capital gains from the FIFO report, and create journal entries with the correct securities accounts.
|
|
140
|
+
|
|
141
|
+
### Generate financial reports
|
|
142
|
+
|
|
143
|
+
> "Generate a P&L and balance sheet as of 28.02.2026"
|
|
144
|
+
|
|
145
|
+
### Reconcile bank transactions
|
|
146
|
+
|
|
147
|
+
> "Match unconfirmed bank transactions to invoices"
|
|
148
|
+
|
|
149
|
+
### Month-end close
|
|
150
|
+
|
|
151
|
+
> "Run the month-end close checklist for February 2026"
|
|
152
|
+
|
|
153
|
+
## License
|
|
154
|
+
|
|
155
|
+
[The Unlicense](LICENSE) — public domain. Do whatever you want with it.
|