@kirjapro/mcp-server 0.7.0 → 0.8.2

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 CHANGED
@@ -1,5 +1,132 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.2] - Unreleased
4
+
5
+ - Subtract finalized same-company credit notes from invoice-detail balances and
6
+ manual/bank payment preflight. Preserve signed detail/manual-payment results,
7
+ floor only payable preflight and the bank-response fallback at zero, and keep
8
+ the existing one-cent MCP allowance and cash-derived invoice status.
9
+ - Expose document type and original-invoice identity in invoice lists/details,
10
+ plus credited totals in details. Credit-note details preserve positive stored
11
+ gross/VAT amounts and show no payable balance; payment tools reject credit-note
12
+ targets. Credit reads use exact-count pages and fail closed on incomplete data.
13
+ - Preserve manual-payment journal IDs and skipped-posting warnings, matching
14
+ the existing bank-confirmation warning contract.
15
+ - Reuse the canonical customer aggregate for credit-aware outstanding balances
16
+ and counts without invoice-list truncation. Keep the existing output fields;
17
+ clarify that `total_revenue` is the VAT-inclusive value of paid invoices after
18
+ finalized credits, rather than accounting turnover or all cash received.
19
+ Preserve the company-scoped customer check and return errors for unavailable
20
+ or invalid aggregate metrics instead of a zero summary.
21
+ - Review affected tool fingerprints for the additive output fields and corrected
22
+ balance/payment descriptions. This work is local, accompanies the pending
23
+ credit-aware payment migrations, and has not been deployed or published.
24
+
25
+ ## [0.8.1] - 2026-09-05
26
+
27
+ - Update the MCP SDK, Supabase client, Zod, and build/test dependencies.
28
+ - Review and refresh 12 tool fingerprints for Zod 4.5.4: nullable primitive
29
+ schemas now use a type array, and ledger cursor timestamps require seconds.
30
+ Database-generated cursors already include seconds; UTC, numeric offsets,
31
+ and fractional seconds remain supported. Tool descriptions, annotations,
32
+ write inputs, and authorization behavior are unchanged.
33
+
34
+ ## [0.8.0] - 2026-08-30
35
+
36
+ Safety and observability release for agent-driven accounting. This release has
37
+ breaking input changes for write and batch tools and requires the paired
38
+ database migrations plus an `mcp-auth` redeploy before the package is published.
39
+
40
+ ### Breaking changes
41
+
42
+ - Every one of the 23 write tools now requires `idempotencyKey` as a UUID v4.
43
+ A write executes only after the database atomically confirms its claim. A
44
+ missing/unavailable claim fails closed; a crashed or uncertain operation is
45
+ permanently blocked from automatic re-execution instead of being recycled
46
+ after a timeout.
47
+ - `kirjapro_create_transactions_batch` and
48
+ `kirjapro_create_from_template_batch` no longer expose `mode` or partial
49
+ success. They default to `dryRun: true`; committing with `dryRun: false` is
50
+ always atomic and any invalid member aborts the whole batch.
51
+ - Invoice, offer, and recurring-invoice payloads are capped at 100 lines;
52
+ transactions are capped at 100 journal entries each and 500 entries across a
53
+ batch. Write annotations no longer claim unbounded MCP idempotence: the
54
+ completed-response replay contract remains 24 hours.
55
+ - `kirjapro_get_general_ledger` is now seek-cursor paginated (`limit` 1–100).
56
+ The full-period summary remains exact while each entry page is bounded and
57
+ pinned to the first page's creation-time cutoff.
58
+ - `kirjapro_get_ar_aging` now returns aggregate buckets only. Invoice/customer
59
+ rows are intentionally omitted; null due dates have an explicit bucket and
60
+ the weighted-age metric is no longer presented as revenue-based DSO.
61
+
62
+ ### Added
63
+
64
+ - Metadata-only operational telemetry, enabled by default and explicitly
65
+ disableable with `KIRJAPRO_TELEMETRY=false`. It records tool/version/surface,
66
+ client, timing, outcome class, byte counts, batch/preview flags, idempotency
67
+ state, and company/API-key attribution. It never sends arguments, results,
68
+ prompts, accounting-record identifiers, names, or monetary values. Raw events
69
+ expire after 90 days.
70
+ - Platform-admin MCP metrics panel with 7/30/90-day trends, tool adoption,
71
+ client/surface breakdowns, error classes, response-budget events, and
72
+ idempotency safety signals. Only aggregate data is exposed to the UI.
73
+ - Soft 50 KiB response telemetry and a hard 200 KiB context-safety budget with
74
+ an actionable `RESPONSE_BUDGET_EXCEEDED` error. Write responses are shaped
75
+ before replay completion, so a committed operation cannot cache an envelope
76
+ different from the one returned to the client.
77
+ - Full `tools/call` lifecycle instrumentation, including SDK input validation,
78
+ unknown tools, output-schema failures, and malformed protocol requests.
79
+ - Stable, explicit registration order for all 52 tools and regression coverage
80
+ for the 27-tool `core` prefix.
81
+
82
+ ### Security
83
+
84
+ - Idempotency state is server-owned: direct authenticated table access is
85
+ revoked, claim/complete require an AAL2 company-scoped JWT carrying a live
86
+ matching MCP API-key and write-protocol claims, request bodies are SHA-256
87
+ bound, and replay payloads have bounded JSONB storage headroom. Ordinary
88
+ browser sessions cannot reserve or
89
+ complete MCP replay keys. A registry-level boundary covers the complete
90
+ write handler, so state-dependent preflight reads cannot bypass replay.
91
+ - Telemetry ingestion accepts only `mcp-auth` JWTs carrying a revalidated
92
+ `mcp_api_key_id` and protocol-2 claim; unknown event fields and tool names
93
+ outside the pinned 52-tool catalog plus the privacy-preserving unknown-tool
94
+ sentinel are rejected, and raw rows are not readable by authenticated users.
95
+ - Tool fingerprints now cover public output schemas in addition to description,
96
+ annotations, and input schemas, using stable JSON Schema rather than mutable
97
+ Zod internals.
98
+
99
+ ### Server-side coupling
100
+
101
+ 1. After merge, redeploy `mcp-auth` through
102
+ `npm run functions:deploy -- mcp-auth` (the wrapper preserves
103
+ `--no-verify-jwt`). It rejects clients without write protocol 2 and records
104
+ successful v0.8 exchanges in the audit log.
105
+ 2. Deploy migrations `20260830120000_mcp_v08_idempotency_telemetry.sql` and
106
+ `20260830121000_mcp_v08_bounded_reports.sql` through `npm run db:deploy`.
107
+ The foundation migration denies every still-live pre-protocol company JWT
108
+ on the protected table/RPC paths used by MCP writes before it revokes the
109
+ legacy replay-table path. Deliberately unprotected bootstrap reads remain.
110
+ 3. Publish `@kirjapro/mcp-server@0.8.0` only after the backend checks pass.
111
+ No active-client restart inventory is part of the safety proof.
112
+
113
+ ## [0.7.1] - 2026-08-23
114
+
115
+ Adds structured sales VAT treatment across invoice and offer creation.
116
+
117
+ ### Added
118
+
119
+ - Invoice and offer tools accept VAT-inclusive unit prices, explicit 0 % treatment codes,
120
+ construction reverse-charge confirmation, and intra-EU goods transport confirmation.
121
+ - Customer country/VAT identifier and seller registration are validated before special VAT
122
+ treatments are persisted; document delivery remains guarded by the server readiness RPC.
123
+
124
+ ### Fixed
125
+
126
+ - VAT summary output now distinguishes official OmaVero purchase fields 318/320 from the
127
+ construction/scrap sales field 319 and exposes treatment-derived EU/zero-rate sales bases.
128
+ - Tool fingerprint baseline regenerated for the intentional schema and description changes.
129
+
3
130
  ## [0.7.0] - 2026-07-16
4
131
 
5
132
  Adds invoice delivery as a first-class MCP workflow.
package/README.md CHANGED
@@ -7,7 +7,7 @@ MCP server for Finnish accounting. Exposes Kirjapro bookkeeping, invoicing, and
7
7
  ## Requirements
8
8
 
9
9
  - Node.js 20+
10
- - Kirjapro account on a paid tier with API access — **Yrittäjä** or **Kasvu**
10
+ - Kirjapro account on a paid tier with API access — **Yrittäjä**, **Kasvu**, **Tilitoimisto**, or **Räätälöity**
11
11
  - API key (generate at Settings > API-avaimet)
12
12
 
13
13
  ## Quick Start
@@ -133,7 +133,12 @@ A few prompts to feel out the daily workflows the agent handles cleanly:
133
133
  }
134
134
  ```
135
135
 
136
- **Why default to 27 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.
136
+ **Why default to 27 instead of 52:** large catalogs with overlapping tools cost
137
+ more context and can make selection harder, but there is no universal tool-count
138
+ cliff that applies to every model and task. Twenty-seven is a conservative
139
+ launch default for Kirjapro's daily workflows. Its own usage and error data,
140
+ not an industry magic number, will determine which deferred tools move into
141
+ core.
137
142
 
138
143
  **Payroll is intentionally not exposed.** Kirjapro does not calculate or book salaries. Direct users to a dedicated payroll service (such as [Palkkaus.fi](https://www.palkkaus.fi) or [Palkka.fi](https://www.palkka.fi)) for the calculation — these services hold the regulated responsibility for Tulorekisteri-ilmoitus, TyEL/TVR raportointi, and ennakonpidätys-tilitys. Once the payslip is calculated externally, book it manually via `kirjapro_create_transaction`.
139
144
 
@@ -152,15 +157,52 @@ A few prompts to feel out the daily workflows the agent handles cleanly:
152
157
 
153
158
  See the [full tool reference](https://kirjapro.fi/docs/mcp/) for parameters, usage examples, and error handling.
154
159
 
160
+ ## Write safety contract
161
+
162
+ - Every write requires a fresh UUID-v4 `idempotencyKey`. Reuse that key only
163
+ for an exact retry of the same tool and arguments.
164
+ - Writes fail closed if the atomic database claim cannot be confirmed. An
165
+ `IDEMPOTENCY_OUTCOME_UNKNOWN` response means the earlier operation may have
166
+ completed: reconcile with a read tool or the Kirjapro UI and do not invent a
167
+ new key.
168
+ - Dry runs have no side effects and are not cached. The two batch tools default
169
+ to `dryRun: true`; `dryRun: false` commits the complete batch atomically.
170
+ - Tool responses have a 200 KiB hard context budget. Narrow a range, lower a
171
+ limit, or follow the returned cursor if `RESPONSE_BUDGET_EXCEEDED` appears.
172
+ For writes, the bounded envelope is cached before completion, so the response
173
+ returned now is also the response replayed by the same key.
174
+ - Invoice/offer/recurring-document writes accept at most 100 lines. A direct
175
+ transaction accepts at most 100 journal entries; a transaction batch accepts
176
+ at most 500 entries across its 50 transactions.
177
+
178
+ ## Operational telemetry
179
+
180
+ Kirjapro records bounded first-party operational metadata by default: company
181
+ and API-key identifiers, tool/server/client names and versions, timing, outcome
182
+ class, request/response byte counts, surface, batch/preview flags, idempotency
183
+ state, and response-budget state. Tool arguments, results, and prompts are
184
+ never sent, nor are accounting-record identifiers, names, or monetary values.
185
+ Raw events are deleted after 90 days and application users cannot read them.
186
+
187
+ Set `KIRJAPRO_TELEMETRY=false` in the MCP environment to opt out. See the
188
+ [privacy notice](https://kirjapro.fi/tietosuoja) for the complete contract.
189
+ Opting out disables metadata delivery only; the 200 KiB local context-safety
190
+ limit remains active.
191
+
155
192
  ## Security
156
193
 
157
194
  - API keys are hashed with SHA-256; the full key is never stored
158
- - Keys exchange for short-lived JWTs (1 hour) via the `mcp-auth` edge function
195
+ - Keys exchange for short-lived JWTs (1 hour) via the `mcp-auth` edge function;
196
+ the exchange and guarded write RPCs require write protocol 2
159
197
  - All queries use Row Level Security (RLS) — users can only access their own company's data
160
198
  - Each API key is scoped to a single company — the issued JWT carries a company claim enforced by RESTRICTIVE row-level security, so a key for one company cannot read another's data even via raw database access (not just application-layer filtering)
161
199
  - Automatic token refresh keeps long-running sessions alive
162
200
  - Rate limiting: 10 auth requests per minute per key
163
- - **Tool description fingerprint guard** — every tool's `description + annotations + inputSchema` is hashed and shipped as `tool-fingerprints.json`. Downstream operators who want supply-chain pinning can verify the running MCP matches the known-good fingerprint set, defending against silent description tampering between releases.
201
+ - Every write is guarded by a server-owned atomic idempotency claim; direct authenticated access to the replay table is denied
202
+ - Write tools advertise `idempotentHint: false` because completed replay lasts
203
+ 24 hours rather than forever; exact retries remain protected inside that
204
+ documented window
205
+ - **Tool contract fingerprint guard** — every tool's `description + annotations + inputSchema + outputSchema` is hashed and shipped as `tool-fingerprints.json`. Downstream operators who want supply-chain pinning can verify the running MCP matches the known-good fingerprint set, defending against silent contract tampering between releases.
164
206
 
165
207
  ## License
166
208