@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 +127 -0
- package/README.md +46 -4
- package/dist/index.js +8120 -2625
- package/package.json +1 -1
- package/server.json +5 -1
- package/tool-fingerprints.json +52 -52
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
|
|
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:**
|
|
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
|
-
-
|
|
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
|
|