@kirjapro/mcp-server 0.5.8 → 0.5.10
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/CHANGELOG.md +31 -0
- package/README.md +5 -3
- package/dist/index.js +51 -213
- package/package.json +1 -1
- package/server.json +1 -1
- package/tool-fingerprints.json +2 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,36 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.5.10] - 2026-05-18
|
|
4
|
+
|
|
5
|
+
Documentation-only release. Surfaces the v0.5.9 payroll removal (DT-065) in the npm-visible `README.md` and adds the full CHANGELOG entry for v0.5.9. No code or behavior changes — `dist/index.js` is byte-identical to v0.5.9 modulo the version string written by the prebuild hook.
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- **`README.md`** — added the "Payroll is intentionally not exposed" paragraph explaining that Kirjapro does not calculate or book salaries, with links to Palkkaus.fi / Palkka.fi as the recommended flow (matches sister-tier competitors: Procountor Solo, NoCFO, Holvi, Talenom Solo). Tool count corrected from 53 → 52 across the three places it appeared.
|
|
10
|
+
- **`CHANGELOG.md`** — the v0.5.9 entry detailing the rollback was added to the package's changelog so users browsing the npm page can see the rationale.
|
|
11
|
+
|
|
12
|
+
## [0.5.9] - 2026-05-18
|
|
13
|
+
|
|
14
|
+
Removed autonomously-shipped payroll feature (DT-065). The 2026-05-18 audit discovered that `kirjapro_book_salary`, the `salary_payment` template, and supporting parameters had been added across March–May 2026 without explicit user approval — DT-047 (April 2026) had marked palkanlaskenta as `gated_on: klt-advisor-partnership`, but the gate never propagated. The 2026-05-18 Finnish-market scan confirmed every Kirjapro-tier vendor (Procountor Solo, NoCFO, Holvi, Talenom Solo) uses the **Palkkaus.fi/Salaxy partnership pattern** rather than building native payroll — that is the design target when this feature does eventually unblock.
|
|
15
|
+
|
|
16
|
+
### Removed
|
|
17
|
+
|
|
18
|
+
- **`kirjapro_book_salary` tool** — removed from registration in `bookings.ts`. Tool count drops 53 → 52. Existing v0.5.8 callers will hit the new DB-side stub which raises SQLSTATE `P0001` with the Finnish redirect message `'Palkanlaskenta on poistettu Kirjaprosta. Käytä Palkkaus.fi- tai Palkka.fi-palvelua palkanlaskentaan ja kirjaa sieltä saamasi palkkalaskelma kirjanpitoon manuaalisesti.'`
|
|
19
|
+
- **`salary_payment` template** — removed from `expandTemplate()` template catalog. `kirjapro_create_from_template` and `_batch` tools no longer accept `withholdingRate` / `tyelRate` parameters.
|
|
20
|
+
- **`FINNISH_RATES_2026` import** — became unused after the template removal.
|
|
21
|
+
|
|
22
|
+
### Changed
|
|
23
|
+
|
|
24
|
+
- **`KIRJAPRO_MCP_SURFACE` documentation** — `full` mode now exposes 52 tools instead of 53. Error message for unknown surface values updated.
|
|
25
|
+
- **Instructions text** — `full` and `core` mode INSTRUCTIONS both clarify "Payroll (palkanlaskenta) is intentionally NOT exposed" and direct AI assistants to Palkkaus.fi/Palkka.fi for the calculation, then book the resulting payslip via `kirjapro_create_transaction` with explicit debit/credit lines.
|
|
26
|
+
- **`tool-fingerprints.json`** — regenerated. 3 changed (`kirjapro_create_from_template`, `kirjapro_create_from_template_batch` lost params; `salary_payment` template removed). 1 removed (`kirjapro_book_salary`).
|
|
27
|
+
- **`server.json`** — caught up to package.json version (was stuck at 0.5.7).
|
|
28
|
+
|
|
29
|
+
### Server-side coupling
|
|
30
|
+
|
|
31
|
+
- DB migration `20260518120000_remove_palkka_payroll_feature.sql` stubs `book_salary_atomic`, drops the Tmi-payroll guard trigger + function, and drops `'palkka'` from `transaction_templates.category` CHECK constraint (verified 0 rows used the value before apply).
|
|
32
|
+
- See `memory/decision-traces.md` DT-065 and `memory/feedback_ai-no-autonomous-compliance-features.md` for the full decision context and the process gate that now guards against autonomous compliance-feature shipping.
|
|
33
|
+
|
|
3
34
|
## [0.5.8] - 2026-05-18
|
|
4
35
|
|
|
5
36
|
Three coordinated dep-migration waves (W1, W3, W4b) of the pre-launch
|
package/README.md
CHANGED
|
@@ -94,7 +94,7 @@ A few prompts to feel out the daily workflows the agent handles cleanly:
|
|
|
94
94
|
|
|
95
95
|
## What's included
|
|
96
96
|
|
|
97
|
-
**26 tools** in the default `core` surface, focused on the daily-use workflows: read your books, invoice flow, transactions + banking, contract create / send / convert, Finnish validators. The full
|
|
97
|
+
**26 tools** in the default `core` surface, focused on the daily-use workflows: read your books, invoice flow, transactions + banking, contract create / send / convert, Finnish validators. The full 52-tool catalog (booking shortcuts, recurring invoices, templates, batch tools, etc.) is available via opt-in:
|
|
98
98
|
|
|
99
99
|
```jsonc
|
|
100
100
|
{
|
|
@@ -104,14 +104,16 @@ A few prompts to feel out the daily workflows the agent handles cleanly:
|
|
|
104
104
|
"args": ["-y", "@kirjapro/mcp-server"],
|
|
105
105
|
"env": {
|
|
106
106
|
"KIRJAPRO_API_KEY": "kp_your_key_here",
|
|
107
|
-
"KIRJAPRO_MCP_SURFACE": "full" //
|
|
107
|
+
"KIRJAPRO_MCP_SURFACE": "full" // 52 tools instead of 26
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
}
|
|
111
111
|
}
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
**Why default to 26 instead of
|
|
114
|
+
**Why default to 26 instead of 52:** 2025-2026 SOTA research on tool catalog scaling (Anthropic, OpenAI, MCP authors) shows tool-selection accuracy degrades between 25-50 tools per catalog. A focused surface produces better first-call selections for the daily workflows. As real usage data informs which deferred tools matter most, they'll be promoted into core.
|
|
115
|
+
|
|
116
|
+
**Payroll is intentionally not exposed.** Kirjapro does not calculate or book salaries. Direct users to [Palkkaus.fi](https://www.palkkaus.fi) or [Palkka.fi](https://www.palkka.fi) for the calculation (these hold legal responsibility for Tulorekisteri-ilmoitus, TyEL/TVR raportointi, ennakonpidätys-tilitys), then book the resulting payslip manually via `kirjapro_create_transaction`. Sister-tier competitors (Procountor Solo, NoCFO, Holvi, Talenom Solo) all follow the same partnership pattern.
|
|
115
117
|
|
|
116
118
|
| Domain (core) | Tools |
|
|
117
119
|
|---|---|
|
package/dist/index.js
CHANGED
|
@@ -34012,50 +34012,6 @@ var ACCOUNTS = {
|
|
|
34012
34012
|
VAKUUTUKSET: "7970"
|
|
34013
34013
|
};
|
|
34014
34014
|
|
|
34015
|
-
// src/compliance/rates.ts
|
|
34016
|
-
var FINNISH_RATES_2026 = {
|
|
34017
|
-
year: 2026,
|
|
34018
|
-
validFrom: "2026-01-01",
|
|
34019
|
-
validUntil: "2026-12-31",
|
|
34020
|
-
sourcesVerifiedAt: "2026-03-15",
|
|
34021
|
-
source: "AVL 1501/1993, ETK 2026, Elo 2026, vero.fi 2026",
|
|
34022
|
-
vat: {
|
|
34023
|
-
standard: 25.5,
|
|
34024
|
-
reduced: 13.5,
|
|
34025
|
-
secondReduced: 10,
|
|
34026
|
-
zero: 0
|
|
34027
|
-
},
|
|
34028
|
-
social: {
|
|
34029
|
-
tyelEmployee: 7.3,
|
|
34030
|
-
tyelEmployer: 17.55,
|
|
34031
|
-
tyelEmployerAverage: 17.1,
|
|
34032
|
-
tyelKeskimaarainen: 24.4,
|
|
34033
|
-
tyelPerusmaksu: 24.85,
|
|
34034
|
-
sotu: 1.91,
|
|
34035
|
-
ttvEmployer: 0.31,
|
|
34036
|
-
ttvEmployerLarge: 1.23,
|
|
34037
|
-
ttvEmployerLargeThreshold: 2509500,
|
|
34038
|
-
ttvEmployee: 0.89,
|
|
34039
|
-
tapaturmaAverage: 0.51,
|
|
34040
|
-
ryhmahenki: 0.06
|
|
34041
|
-
}
|
|
34042
|
-
};
|
|
34043
|
-
function freshnessMeta(rates = FINNISH_RATES_2026, today = /* @__PURE__ */ new Date()) {
|
|
34044
|
-
const validUntil = /* @__PURE__ */ new Date(`${rates.validUntil}T23:59:59Z`);
|
|
34045
|
-
const msPerDay = 864e5;
|
|
34046
|
-
const daysUntilExpiry = Math.ceil(
|
|
34047
|
-
(validUntil.getTime() - today.getTime()) / msPerDay
|
|
34048
|
-
);
|
|
34049
|
-
return {
|
|
34050
|
-
published_at: rates.sourcesVerifiedAt,
|
|
34051
|
-
valid_from: rates.validFrom,
|
|
34052
|
-
valid_through: rates.validUntil,
|
|
34053
|
-
sources_verified_at: rates.sourcesVerifiedAt,
|
|
34054
|
-
stale: daysUntilExpiry < 0,
|
|
34055
|
-
days_until_expiry: daysUntilExpiry
|
|
34056
|
-
};
|
|
34057
|
-
}
|
|
34058
|
-
|
|
34059
34015
|
// src/tools/templates.ts
|
|
34060
34016
|
function splitVat(gross, vatRate) {
|
|
34061
34017
|
if (vatRate === 0) return { net: roundCents(gross), vat: 0 };
|
|
@@ -34279,36 +34235,6 @@ var TEMPLATES = [
|
|
|
34279
34235
|
opts?.accountOverrides
|
|
34280
34236
|
)
|
|
34281
34237
|
},
|
|
34282
|
-
// Salary
|
|
34283
|
-
{
|
|
34284
|
-
id: "salary_payment",
|
|
34285
|
-
description: "Palkanmaksu (bruttopalkka, ennakonpid\xE4tys, TyEL)",
|
|
34286
|
-
vatRate: null,
|
|
34287
|
-
expand: (amount, opts) => {
|
|
34288
|
-
const gross = roundCents(amount);
|
|
34289
|
-
const withholdingRate = opts?.withholdingRate ?? 20;
|
|
34290
|
-
const tyelEmployeeRate = opts?.tyelRate ?? FINNISH_RATES_2026.social.tyelEmployee;
|
|
34291
|
-
const tyelEmployerRate = FINNISH_RATES_2026.social.tyelEmployer;
|
|
34292
|
-
const withholding = roundCents(gross * withholdingRate / 100);
|
|
34293
|
-
const tyelEmployee = roundCents(gross * tyelEmployeeRate / 100);
|
|
34294
|
-
const tyelEmployer = roundCents(gross * tyelEmployerRate / 100);
|
|
34295
|
-
const netPay = roundCents(gross - withholding - tyelEmployee);
|
|
34296
|
-
return applyOverrides(
|
|
34297
|
-
[
|
|
34298
|
-
{ accountNumber: ACCOUNTS.PALKAT, debitAmount: gross, creditAmount: 0 },
|
|
34299
|
-
{ accountNumber: ACCOUNTS.ELAKEKULUT, debitAmount: tyelEmployer, creditAmount: 0 },
|
|
34300
|
-
{ accountNumber: ACCOUNTS.PANKKITILI, debitAmount: 0, creditAmount: netPay },
|
|
34301
|
-
{ accountNumber: ACCOUNTS.ENNAKONPIDATYSVELKA, debitAmount: 0, creditAmount: withholding },
|
|
34302
|
-
{
|
|
34303
|
-
accountNumber: ACCOUNTS.TYEL_VELKA,
|
|
34304
|
-
debitAmount: 0,
|
|
34305
|
-
creditAmount: roundCents(tyelEmployee + tyelEmployer)
|
|
34306
|
-
}
|
|
34307
|
-
],
|
|
34308
|
-
opts?.accountOverrides
|
|
34309
|
-
);
|
|
34310
|
-
}
|
|
34311
|
-
},
|
|
34312
34238
|
// Bank transfer
|
|
34313
34239
|
{
|
|
34314
34240
|
id: "bank_transfer",
|
|
@@ -34477,8 +34403,6 @@ function registerTemplateTools(server2) {
|
|
|
34477
34403
|
amount: external_exports.number().finite().positive().max(1e9).describe("Gross amount in EUR"),
|
|
34478
34404
|
description: external_exports.string().min(1).max(500).describe("Transaction description"),
|
|
34479
34405
|
documentNumber: external_exports.string().optional().describe("Document/receipt number"),
|
|
34480
|
-
withholdingRate: external_exports.number().min(0).max(100).optional().describe("Withholding tax % for salary_payment (default 20)"),
|
|
34481
|
-
tyelRate: external_exports.number().min(0).max(100).optional().describe("TyEL employee % for salary_payment (default 7.30)"),
|
|
34482
34406
|
accountOverrides: external_exports.record(external_exports.string(), external_exports.string()).optional().describe('Account number swaps, e.g. {"2320": "2330"}'),
|
|
34483
34407
|
idempotencyKey: IDEMPOTENCY_KEY_SCHEMA
|
|
34484
34408
|
},
|
|
@@ -34499,8 +34423,6 @@ function registerTemplateTools(server2) {
|
|
|
34499
34423
|
if ("error" in ov) return toErrorContent(ov.error);
|
|
34500
34424
|
}
|
|
34501
34425
|
const result = expandTemplate(params.template, params.amount, {
|
|
34502
|
-
withholdingRate: params.withholdingRate,
|
|
34503
|
-
tyelRate: params.tyelRate,
|
|
34504
34426
|
accountOverrides: params.accountOverrides
|
|
34505
34427
|
});
|
|
34506
34428
|
if ("error" in result) {
|
|
@@ -34542,8 +34464,6 @@ function registerTemplateTools(server2) {
|
|
|
34542
34464
|
amount: external_exports.number().finite().positive().max(1e9).describe("Gross amount in EUR"),
|
|
34543
34465
|
description: external_exports.string().min(1).max(500),
|
|
34544
34466
|
documentNumber: external_exports.string().optional(),
|
|
34545
|
-
withholdingRate: external_exports.number().min(0).max(100).optional(),
|
|
34546
|
-
tyelRate: external_exports.number().min(0).max(100).optional(),
|
|
34547
34467
|
accountOverrides: external_exports.record(external_exports.string(), external_exports.string()).optional()
|
|
34548
34468
|
})
|
|
34549
34469
|
).min(1).max(50).describe("Array of template transactions to create (max 50)"),
|
|
@@ -34600,8 +34520,6 @@ function registerTemplateTools(server2) {
|
|
|
34600
34520
|
for (let i = 0; i < params.transactions.length; i++) {
|
|
34601
34521
|
const tx = params.transactions[i];
|
|
34602
34522
|
const result2 = expandTemplate(tx.template, tx.amount, {
|
|
34603
|
-
withholdingRate: tx.withholdingRate,
|
|
34604
|
-
tyelRate: tx.tyelRate,
|
|
34605
34523
|
accountOverrides: tx.accountOverrides
|
|
34606
34524
|
});
|
|
34607
34525
|
if ("error" in result2) {
|
|
@@ -34705,6 +34623,50 @@ function registerTemplateTools(server2) {
|
|
|
34705
34623
|
);
|
|
34706
34624
|
}
|
|
34707
34625
|
|
|
34626
|
+
// src/compliance/rates.ts
|
|
34627
|
+
var FINNISH_RATES_2026 = {
|
|
34628
|
+
year: 2026,
|
|
34629
|
+
validFrom: "2026-01-01",
|
|
34630
|
+
validUntil: "2026-12-31",
|
|
34631
|
+
sourcesVerifiedAt: "2026-03-15",
|
|
34632
|
+
source: "AVL 1501/1993, ETK 2026, Elo 2026, vero.fi 2026",
|
|
34633
|
+
vat: {
|
|
34634
|
+
standard: 25.5,
|
|
34635
|
+
reduced: 13.5,
|
|
34636
|
+
secondReduced: 10,
|
|
34637
|
+
zero: 0
|
|
34638
|
+
},
|
|
34639
|
+
social: {
|
|
34640
|
+
tyelEmployee: 7.3,
|
|
34641
|
+
tyelEmployer: 17.55,
|
|
34642
|
+
tyelEmployerAverage: 17.1,
|
|
34643
|
+
tyelKeskimaarainen: 24.4,
|
|
34644
|
+
tyelPerusmaksu: 24.85,
|
|
34645
|
+
sotu: 1.91,
|
|
34646
|
+
ttvEmployer: 0.31,
|
|
34647
|
+
ttvEmployerLarge: 1.23,
|
|
34648
|
+
ttvEmployerLargeThreshold: 2509500,
|
|
34649
|
+
ttvEmployee: 0.89,
|
|
34650
|
+
tapaturmaAverage: 0.51,
|
|
34651
|
+
ryhmahenki: 0.06
|
|
34652
|
+
}
|
|
34653
|
+
};
|
|
34654
|
+
function freshnessMeta(rates = FINNISH_RATES_2026, today = /* @__PURE__ */ new Date()) {
|
|
34655
|
+
const validUntil = /* @__PURE__ */ new Date(`${rates.validUntil}T23:59:59Z`);
|
|
34656
|
+
const msPerDay = 864e5;
|
|
34657
|
+
const daysUntilExpiry = Math.ceil(
|
|
34658
|
+
(validUntil.getTime() - today.getTime()) / msPerDay
|
|
34659
|
+
);
|
|
34660
|
+
return {
|
|
34661
|
+
published_at: rates.sourcesVerifiedAt,
|
|
34662
|
+
valid_from: rates.validFrom,
|
|
34663
|
+
valid_through: rates.validUntil,
|
|
34664
|
+
sources_verified_at: rates.sourcesVerifiedAt,
|
|
34665
|
+
stale: daysUntilExpiry < 0,
|
|
34666
|
+
days_until_expiry: daysUntilExpiry
|
|
34667
|
+
};
|
|
34668
|
+
}
|
|
34669
|
+
|
|
34708
34670
|
// src/tools/bookings.ts
|
|
34709
34671
|
var DEFAULTS = {
|
|
34710
34672
|
tyelEmployee: FINNISH_RATES_2026.social.tyelEmployee,
|
|
@@ -34802,131 +34764,6 @@ function registerBookingTools(server2) {
|
|
|
34802
34764
|
);
|
|
34803
34765
|
}
|
|
34804
34766
|
);
|
|
34805
|
-
server2.registerTool(
|
|
34806
|
-
"kirjapro_book_salary",
|
|
34807
|
-
{
|
|
34808
|
-
description: "Book salary payment (palkanmaksu). Creates salary + employer cost transactions with withholding, TyEL, TTV, sotu. Default rates are 2026 Finnish social insurance rates.",
|
|
34809
|
-
inputSchema: {
|
|
34810
|
-
grossSalary: external_exports.number().finite().positive().max(1e8).describe("Gross salary EUR"),
|
|
34811
|
-
employeeName: external_exports.string().min(1).describe("Employee name (for description)"),
|
|
34812
|
-
date: ISO_DATE_SCHEMA.describe("Payment date (YYYY-MM-DD)"),
|
|
34813
|
-
withholdingRate: external_exports.number().min(0).max(100).describe("Withholding tax % (ennakonpid\xE4tys)"),
|
|
34814
|
-
tyelEmployeeRate: external_exports.number().min(0).max(100).default(DEFAULTS.tyelEmployee).describe("TyEL employee % (default 7.30)"),
|
|
34815
|
-
tyelEmployerRate: external_exports.number().min(0).max(100).default(DEFAULTS.tyelEmployer).describe("TyEL employer % (default 17.55)"),
|
|
34816
|
-
sotuRate: external_exports.number().min(0).max(100).default(DEFAULTS.sotu).describe("Sairausvakuutusmaksu employer % (default 1.91)"),
|
|
34817
|
-
ttvEmployerRate: external_exports.number().min(0).max(100).default(DEFAULTS.ttvEmployer).describe("Ty\xF6tt\xF6myysvakuutus employer % (default 0.31)"),
|
|
34818
|
-
ttvEmployeeRate: external_exports.number().min(0).max(100).default(DEFAULTS.ttvEmployee).describe("Ty\xF6tt\xF6myysvakuutus employee % (default 0.89)"),
|
|
34819
|
-
fiscalYearId: external_exports.string().uuid().optional().describe("Fiscal year UUID (auto-resolved if omitted)"),
|
|
34820
|
-
paymentAccount: external_exports.string().default(ACCOUNTS.PANKKITILI).describe(`Bank account (default "${ACCOUNTS.PANKKITILI}" Pankkitili)`),
|
|
34821
|
-
idempotencyKey: IDEMPOTENCY_KEY_SCHEMA,
|
|
34822
|
-
dryRun: DRY_RUN_SCHEMA
|
|
34823
|
-
},
|
|
34824
|
-
annotations: WRITE_ANNOTATIONS
|
|
34825
|
-
},
|
|
34826
|
-
async (params) => {
|
|
34827
|
-
const gross = roundCents(params.grossSalary);
|
|
34828
|
-
const withholding = roundCents(gross * params.withholdingRate / 100);
|
|
34829
|
-
const tyelEmployee = roundCents(gross * params.tyelEmployeeRate / 100);
|
|
34830
|
-
const ttvEmployee = roundCents(gross * params.ttvEmployeeRate / 100);
|
|
34831
|
-
const netPay = roundCents(gross - withholding - tyelEmployee - ttvEmployee);
|
|
34832
|
-
const tyelEmployer = roundCents(gross * params.tyelEmployerRate / 100);
|
|
34833
|
-
const sotuAmount = roundCents(gross * params.sotuRate / 100);
|
|
34834
|
-
const ttvEmployer = roundCents(gross * params.ttvEmployerRate / 100);
|
|
34835
|
-
if (netPay < 0) {
|
|
34836
|
-
return toErrorContent(
|
|
34837
|
-
`Net pay is negative (${netPay.toFixed(2)}). Check withholding rate (${params.withholdingRate}%) and deduction rates.`
|
|
34838
|
-
);
|
|
34839
|
-
}
|
|
34840
|
-
const supabase2 = getSupabase();
|
|
34841
|
-
const companyId2 = getCompanyId();
|
|
34842
|
-
let fiscalYearId = params.fiscalYearId;
|
|
34843
|
-
if (!fiscalYearId) {
|
|
34844
|
-
const resolved = await resolveOpenFiscalYear(supabase2, companyId2);
|
|
34845
|
-
if ("isError" in resolved) return resolved;
|
|
34846
|
-
fiscalYearId = resolved.id;
|
|
34847
|
-
}
|
|
34848
|
-
const fy = await validateFiscalYearForDate(fiscalYearId, params.date);
|
|
34849
|
-
if ("isError" in fy) return fy;
|
|
34850
|
-
const salaryEntries = [
|
|
34851
|
-
{ accountNumber: ACCOUNTS.PALKAT, debitAmount: gross, creditAmount: 0 },
|
|
34852
|
-
{ accountNumber: params.paymentAccount, debitAmount: 0, creditAmount: netPay },
|
|
34853
|
-
{ accountNumber: ACCOUNTS.ENNAKONPIDATYSVELKA, debitAmount: 0, creditAmount: withholding },
|
|
34854
|
-
{ accountNumber: ACCOUNTS.TYEL_VELKA, debitAmount: 0, creditAmount: tyelEmployee },
|
|
34855
|
-
{ accountNumber: ACCOUNTS.TTV_VELKA, debitAmount: 0, creditAmount: ttvEmployee }
|
|
34856
|
-
];
|
|
34857
|
-
const employerSotuTtv = roundCents(sotuAmount + ttvEmployer);
|
|
34858
|
-
const employerEntries = [
|
|
34859
|
-
{ accountNumber: ACCOUNTS.ELAKEKULUT, debitAmount: tyelEmployer, creditAmount: 0 },
|
|
34860
|
-
{ accountNumber: ACCOUNTS.SOSIAALITURVAMAKSUT, debitAmount: employerSotuTtv, creditAmount: 0 },
|
|
34861
|
-
{ accountNumber: ACCOUNTS.TYEL_VELKA, debitAmount: 0, creditAmount: tyelEmployer },
|
|
34862
|
-
{ accountNumber: ACCOUNTS.SOTU_VELKA, debitAmount: 0, creditAmount: sotuAmount },
|
|
34863
|
-
{ accountNumber: ACCOUNTS.TTV_VELKA, debitAmount: 0, creditAmount: ttvEmployer }
|
|
34864
|
-
];
|
|
34865
|
-
if (params.dryRun) {
|
|
34866
|
-
return toDryRunResponse("kirjapro_book_salary", {
|
|
34867
|
-
action: "book_salary",
|
|
34868
|
-
employee: params.employeeName,
|
|
34869
|
-
date: params.date,
|
|
34870
|
-
salary_entries: salaryEntries,
|
|
34871
|
-
employer_entries: employerEntries,
|
|
34872
|
-
summary: {
|
|
34873
|
-
gross,
|
|
34874
|
-
withholding,
|
|
34875
|
-
tyelEmployee,
|
|
34876
|
-
ttvEmployee,
|
|
34877
|
-
netPay,
|
|
34878
|
-
tyelEmployer,
|
|
34879
|
-
sotu: sotuAmount,
|
|
34880
|
-
ttvEmployer,
|
|
34881
|
-
totalEmployerCost: roundCents(gross + tyelEmployer + sotuAmount + ttvEmployer)
|
|
34882
|
-
}
|
|
34883
|
-
});
|
|
34884
|
-
}
|
|
34885
|
-
const accountMap = await resolveAccountNumbers(
|
|
34886
|
-
[...salaryEntries, ...employerEntries].map((e) => e.accountNumber)
|
|
34887
|
-
);
|
|
34888
|
-
if ("isError" in accountMap) return accountMap;
|
|
34889
|
-
return withIdempotency(
|
|
34890
|
-
supabase2,
|
|
34891
|
-
companyId2,
|
|
34892
|
-
"kirjapro_book_salary",
|
|
34893
|
-
params.idempotencyKey,
|
|
34894
|
-
params,
|
|
34895
|
-
async () => {
|
|
34896
|
-
const { data, error: error51 } = await supabase2.rpc("book_salary_atomic", {
|
|
34897
|
-
p_company_id: companyId2,
|
|
34898
|
-
p_fiscal_year_id: fiscalYearId,
|
|
34899
|
-
p_transaction_date: params.date,
|
|
34900
|
-
p_employee_name: params.employeeName,
|
|
34901
|
-
p_salary_entries: toJournalEntries(salaryEntries, accountMap),
|
|
34902
|
-
p_employer_entries: toJournalEntries(employerEntries, accountMap)
|
|
34903
|
-
});
|
|
34904
|
-
if (error51 || !data) {
|
|
34905
|
-
return toErrorContent(
|
|
34906
|
-
error51 ? sanitizeDbError("Failed to book salary", error51) : "Failed to book salary: no response from RPC"
|
|
34907
|
-
);
|
|
34908
|
-
}
|
|
34909
|
-
const result = data;
|
|
34910
|
-
return toResult({
|
|
34911
|
-
message: "Salary booked (2 transactions, atomic)",
|
|
34912
|
-
salary_transaction_id: result.salary_transaction_id,
|
|
34913
|
-
employer_costs_transaction_id: result.employer_costs_transaction_id,
|
|
34914
|
-
summary: {
|
|
34915
|
-
gross,
|
|
34916
|
-
withholding,
|
|
34917
|
-
tyelEmployee,
|
|
34918
|
-
ttvEmployee,
|
|
34919
|
-
netPay,
|
|
34920
|
-
tyelEmployer,
|
|
34921
|
-
sotu: sotuAmount,
|
|
34922
|
-
ttvEmployer,
|
|
34923
|
-
totalEmployerCost: roundCents(gross + tyelEmployer + sotuAmount + ttvEmployer)
|
|
34924
|
-
}
|
|
34925
|
-
});
|
|
34926
|
-
}
|
|
34927
|
-
);
|
|
34928
|
-
}
|
|
34929
|
-
);
|
|
34930
34767
|
server2.registerTool(
|
|
34931
34768
|
"kirjapro_book_vat_settlement",
|
|
34932
34769
|
{
|
|
@@ -36251,7 +36088,7 @@ function resolveSurface(explicit) {
|
|
|
36251
36088
|
if (env === "core") return "core";
|
|
36252
36089
|
if (env && env !== "core") {
|
|
36253
36090
|
console.error(
|
|
36254
|
-
`[kirjapro-mcp] Unknown KIRJAPRO_MCP_SURFACE="${env}" \u2014 falling back to "core". Valid values: "core" (default, 26 tools), "full" (
|
|
36091
|
+
`[kirjapro-mcp] Unknown KIRJAPRO_MCP_SURFACE="${env}" \u2014 falling back to "core". Valid values: "core" (default, 26 tools), "full" (52 tools).`
|
|
36255
36092
|
);
|
|
36256
36093
|
}
|
|
36257
36094
|
return "core";
|
|
@@ -36286,7 +36123,7 @@ function registerTools(server2, options = {}) {
|
|
|
36286
36123
|
);
|
|
36287
36124
|
} else {
|
|
36288
36125
|
console.error(
|
|
36289
|
-
`[kirjapro-mcp] surface=full \u2014 registered all
|
|
36126
|
+
`[kirjapro-mcp] surface=full \u2014 registered all 52 tools (CORE_TOOL_NAMES bypass active).`
|
|
36290
36127
|
);
|
|
36291
36128
|
}
|
|
36292
36129
|
}
|
|
@@ -36800,7 +36637,7 @@ function registerResources(server2) {
|
|
|
36800
36637
|
}
|
|
36801
36638
|
|
|
36802
36639
|
// src/version.ts
|
|
36803
|
-
var VERSION = "0.5.
|
|
36640
|
+
var VERSION = "0.5.10";
|
|
36804
36641
|
|
|
36805
36642
|
// src/index.ts
|
|
36806
36643
|
var INSTRUCTIONS_COMMON = `
|
|
@@ -36907,7 +36744,8 @@ var INSTRUCTIONS_CORE_ADDENDUM = `
|
|
|
36907
36744
|
The following workflows are NOT exposed in the current (core) surface. When a user asks for them, redirect to the web UI rather than reaching for the closest available tool:
|
|
36908
36745
|
|
|
36909
36746
|
- **Recurring invoice templates** \u2014 created and managed in the web app; cron generates the issued invoices
|
|
36910
|
-
- **Booking shortcuts** (book_purchase / book_sale /
|
|
36747
|
+
- **Booking shortcuts** (book_purchase / book_sale / book_vat_settlement) \u2014 for these, you CAN compose the journal entries manually via \`kirjapro_create_transaction\` with explicit debit/credit lines if the user prefers; otherwise redirect
|
|
36748
|
+
- **Payroll (palkanlaskenta)** \u2014 Kirjapro does NOT calculate or book payroll. Direct the user to Palkkaus.fi or Palkka.fi for the calculation, then bring the resulting payslip back and book it via \`kirjapro_create_transaction\` with explicit debit/credit lines
|
|
36911
36749
|
- **Transaction templates** \u2014 manual journal entries via \`kirjapro_create_transaction\`
|
|
36912
36750
|
- **Manual offer status changes** \u2014 the customer's email-link click sets status server-side; just wait for the user to confirm acceptance
|
|
36913
36751
|
- **Listing or fetching past offers** \u2014 the user can view them in the web UI
|
|
@@ -36926,8 +36764,8 @@ var INSTRUCTIONS_FULL_ADDENDUM = `
|
|
|
36926
36764
|
### Booking Shortcuts
|
|
36927
36765
|
Faster than composing journal entries via \`kirjapro_create_transaction\`:
|
|
36928
36766
|
- \`kirjapro_book_sale\` / \`kirjapro_book_purchase\` \u2014 one-liner with auto VAT splitting
|
|
36929
|
-
- \`kirjapro_book_salary\` \u2014 creates 2 atomic transactions (salary + employer costs), 2026 rates as defaults
|
|
36930
36767
|
- \`kirjapro_book_vat_settlement\` \u2014 reads ALV-saamiset/ALV-velka, creates settlement entry. Call \`kirjapro_get_alv_summary\` first to preview.
|
|
36768
|
+
- **Payroll is intentionally NOT exposed.** Direct users to Palkkaus.fi / Palkka.fi for salary calculation; the payslip can then be booked manually via \`kirjapro_create_transaction\`.
|
|
36931
36769
|
- \`kirjapro_list_templates\` \u2192 \`kirjapro_create_from_template\` for common patterns (13 built-in templates)
|
|
36932
36770
|
|
|
36933
36771
|
### Manual Offer Status
|
|
@@ -36946,7 +36784,7 @@ Faster than composing journal entries via \`kirjapro_create_transaction\`:
|
|
|
36946
36784
|
|
|
36947
36785
|
### Destructive Operations (always dryRun first)
|
|
36948
36786
|
- \`kirjapro_delete_invoice\`, \`kirjapro_delete_offer\`, \`kirjapro_delete_recurring_invoice\` \u2014 drafts only; sent/paid must be cancelled first
|
|
36949
|
-
- \`kirjapro_book_purchase\`, \`kirjapro_book_sale
|
|
36787
|
+
- \`kirjapro_book_purchase\`, \`kirjapro_book_sale\` \u2014 call with \`dryRun: true\` to preview the journal entries before commit
|
|
36950
36788
|
`.trim();
|
|
36951
36789
|
function buildInstructions(surface) {
|
|
36952
36790
|
return surface === "full" ? `${INSTRUCTIONS_COMMON}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kirjapro/mcp-server",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.10",
|
|
4
4
|
"description": "MCP server for Finnish accounting — exposes Kirjapro bookkeeping, invoicing, and reporting tools to Claude Code, Claude Desktop, and any MCP client.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
package/server.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@kirjapro/mcp-server",
|
|
3
3
|
"displayName": "Kirjapro - Finnish Accounting",
|
|
4
4
|
"description": "Finnish double-entry bookkeeping, invoicing, and financial reporting for growing businesses. Create transactions, generate invoices with VAT calculation, produce income statements and balance sheets, and validate Finnish business identifiers.",
|
|
5
|
-
"version": "0.5.
|
|
5
|
+
"version": "0.5.10",
|
|
6
6
|
"homepage": "https://kirjapro.fi",
|
|
7
7
|
"repository": "https://github.com/Jaollo/kirja-pro",
|
|
8
8
|
"license": "MIT",
|
package/tool-fingerprints.json
CHANGED
|
@@ -4,10 +4,6 @@
|
|
|
4
4
|
"name": "kirjapro_book_purchase",
|
|
5
5
|
"hash": "ddb30ea742fd64ef"
|
|
6
6
|
},
|
|
7
|
-
{
|
|
8
|
-
"name": "kirjapro_book_salary",
|
|
9
|
-
"hash": "d60f5e3af5b9814c"
|
|
10
|
-
},
|
|
11
7
|
{
|
|
12
8
|
"name": "kirjapro_book_sale",
|
|
13
9
|
"hash": "9ce00f1687fc23e0"
|
|
@@ -26,11 +22,11 @@
|
|
|
26
22
|
},
|
|
27
23
|
{
|
|
28
24
|
"name": "kirjapro_create_from_template",
|
|
29
|
-
"hash": "
|
|
25
|
+
"hash": "d5544fb7b65148b4"
|
|
30
26
|
},
|
|
31
27
|
{
|
|
32
28
|
"name": "kirjapro_create_from_template_batch",
|
|
33
|
-
"hash": "
|
|
29
|
+
"hash": "a6290b31dc0a430e"
|
|
34
30
|
},
|
|
35
31
|
{
|
|
36
32
|
"name": "kirjapro_create_invoice",
|