@kirjapro/mcp-server 0.19.0 → 0.20.1

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,133 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.20.1] - 2026-10-20
4
+
5
+ The MCP audit review of 20.10.2026 (N2 item 8, before the OAuth write switch). No tool,
6
+ description or fingerprint changes.
7
+
8
+ - The core-surface instructions no longer suggest composing a VAT settlement (ALV-tilitys)
9
+ by hand with `kirjapro_create_transaction`: such a voucher does not mark the VAT period
10
+ settled, so the period could be settled twice. They redirect it to the Kirjapro app
11
+ (ALV-yhteenveto → Kirjaa ALV-tilitys), which settles through the same function as
12
+ `kirjapro_book_vat_settlement` and marks a period settled earlier with a voucher. Purchases
13
+ and sales may still be composed by hand.
14
+ - `kirjapro_book_vat_settlement` refuses a VAT period that has not ended yet in
15
+ Europe/Helsinki (`Kausi … ei ole vielä päättynyt, joten sitä ei voi vielä tilittää.`), its
16
+ dry run included, so VAT booked later in that period is not left unsettled. Migration
17
+ `20261020180000` refuses it in the database too, for every package version.
18
+
19
+ ## [0.20.0] - 2026-10-20
20
+
21
+ PR D of the MCP audit of 18.10.2026 (batches 7 to 12 and 14). Against 0.19.0, 3 of the 56
22
+ tool fingerprints change: `kirjapro_book_vat_settlement`, `kirjapro_send_invoice` and
23
+ `kirjapro_send_offer`. The package now bundles its runtime dependencies (no `dependencies`
24
+ in `package.json`).
25
+
26
+ **PR D release order** (one checklist for every section below; the rollout runbook row 7d0b
27
+ in `docs/guides/ai-workspace-rollout.md` is its source): (1) merge by hand, which deploys the
28
+ web app (until step 2 its Settings page can neither create nor revoke an API key); (2) `npm
29
+ run db:deploy` from clean `main` at low traffic, all six migrations `20261019140000`,
30
+ `20261019150000`, `20261019150100`, `20261019164710`, `20261019170000` and `20261019180000`;
31
+ (3) `npm run functions:deploy` of `dispatch-invoice`, `send-offer-email`, `prh-lookup`,
32
+ `generate-recurring-invoices` and `send-payment-reminders`; (4) `mcp-auth`; (5) `mcp` last;
33
+ (6) this package. For about 11 minutes after step 2 an OAuth connection of a user with MFA
34
+ that was approved just before it may answer 401 once and authorize again.
35
+
36
+ API key lifecycle and DB-boundary hygiene (MCP audit of 18.10.2026, PR D batch 9). Server
37
+ side only: no tool, description or fingerprint changes, and every published package gets
38
+ the behaviour once migrations `20261019150000` and `20261019150100` and the `mcp-auth`
39
+ deploy are live (steps 2 and 4). `src/database.types.ts` gains `api_keys.membership_id`
40
+ and the RPCs `create_api_key`, `revoke_api_key` and `mcp_api_key_access`.
41
+
42
+ - A revoked or expired key's live token, or that of a key whose creator left the company,
43
+ now gets `CREDENTIAL_INVALID` from its next read instead of empty lists ("0 invoices",
44
+ "not found"): the Data API gate answers such a key token with 401 and a message that
45
+ starts with the code.
46
+ - `mcp-auth` answers the key of a creator who was removed from the company (even if
47
+ invited again) with 401, which the server reads as a permanent `CREDENTIAL_INVALID`,
48
+ instead of the `API_ENTITLEMENT_REQUIRED` 403; a failed check is a transient 503.
49
+ - A credential holds at most 1 000 unresolved idempotency claims. Beyond them a write is
50
+ refused before it runs (`IDEMPOTENCY_BACKEND_UNAVAILABLE`, the write was not executed).
51
+ - Keys are created and revoked only in the Kirjapro app (Asetukset → MCP-palvelin), which
52
+ now generates the key in the database and, before revoking, lists the key's writes and
53
+ offers to pause the recurring invoices with automatic sending that it touched; the revoke
54
+ button waits for that list. A key stays bound to its creator's membership for good: no
55
+ later write, not even an operator's, moves or restores the binding.
56
+
57
+ Untrusted text and send friction (MCP audit of 18.10.2026, PR D batch 7: T2-7, T2-8, T3-40,
58
+ T3-42 to T3-45, T4-13, T4-18; T3-41 was fixed by PR A). Released by the PR D order above
59
+ (the migration `20261019164710` and the Edge functions before this package). Three
60
+ fingerprints change:
61
+ `kirjapro_send_invoice`, `kirjapro_send_offer` and `kirjapro_book_vat_settlement`.
62
+
63
+ - `kirjapro_send_invoice` and `kirjapro_send_offer` take `dryRun`: nothing is claimed or
64
+ sent, and the preview names the recipient (wrapped), the channel and the invoice or offer
65
+ number, with `recipient_confirmation_required`. The results name the recipient(s),
66
+ wrapped. The preview asks the Edge function with `previewInvoiceId` or `previewOfferId`,
67
+ never with `invoiceId` or `offerId`, so a function deployed before previews refuses it
68
+ (`PREVIEW_UNAVAILABLE: … Nothing was sent`) and a dry run can never deliver. The text says
69
+ `Nothing was sent` only for a refusal or a lost answer.
70
+ - Recipient confirmation (founder decision 19.10.2026): when the customer's e-mail or
71
+ e-invoice address was created or changed through an MCP credential (an API key or an
72
+ OAuth connection) in the last 24 hours, the send is refused with a cached
73
+ `RECIPIENT_CONFIRMATION_REQUIRED` naming the address, unless the call passes
74
+ `confirmRecipient` equal to it (an e-mail address in any case). A person who saves the
75
+ customer in the Kirjapro app confirms it too. The rule runs in the Edge functions, so the
76
+ remote endpoint enforces it as well; signers configured for a contract in the app need no
77
+ confirmation. The tool descriptions and the server instructions ask the agent to show the
78
+ address to the user first. An e-invoice refusal also names the operator. The automatic
79
+ sends have nobody to confirm, so they hold any recipient an MCP credential set that no
80
+ person has saved since, however old: the daily recurring run leaves the invoice a draft
81
+ and the template's generation log says why, and the payment reminders skip the customer.
82
+ An offer without any recipient answers the missing e-mail address, not
83
+ `RECIPIENT_CONFIRMATION_REQUIRED`.
84
+ - Invoice, reference, offer and customer numbers are no longer trusted as "generated": they
85
+ stay bare only in the shape Kirjapro allocates (`2026-0001`, digits, `TAR00001`/`SOP00001`,
86
+ `C00001`) and are wrapped otherwise, in the read tools (also the ALV reconciliation, the
87
+ offer events and the recurring invoice log) and in the write tools' results and messages
88
+ (a partial reversal of U-65). The company's own IBAN is bare only with a numeric account
89
+ part. The server instructions and `kirjapro://security/data-handling` say so.
90
+ - Refusal texts of the bank reconciliation tools and of `kirjapro_book_vat_settlement` that
91
+ quote stored text (an e-invoice number, a voucher number, the line's currency) are wrapped.
92
+ - An argument that contains `⟦redacted⟧`, which a read result shows in place of text that
93
+ looked like an instruction, is refused with `INVALID_ARGUMENTS` instead of being stored.
94
+ - `kirjapro_get_received_invoice` wraps `pdf_storage_path` (the sender's file name).
95
+ - `kirjapro_get_recurring_invoice` keeps a `template_data` code bare only when it is a VAT
96
+ treatment code, VAT category, price-entry mode or account id the server writes.
97
+ - `kirjapro_get_general_ledger` echoes an unknown account wrapped unless it is a number;
98
+ `kirjapro_book_vat_settlement` takes a 4- or 5-digit `paymentAccount` only.
99
+ - `kirjapro_get_offer` keeps the status codes `from_status` and `to_status` of an offer event
100
+ bare.
101
+
102
+ PR D of the MCP audit of 18.10.2026 (batches 8, 11 and 14). No tool definition changes and
103
+ no fingerprint changes. Released by the PR D order above (`20261019170000`, the server-side
104
+ `batch_size` clamp, is in its `db:deploy`; the package does not need it). Before the first
105
+ tag, run the publish workflow once by hand on `main`: its `publish` job now runs in the
106
+ `npm-publish` environment.
107
+
108
+ - **No runtime dependencies** (T3-58): `@modelcontextprotocol/sdk`, `zod` and
109
+ `@supabase/supabase-js` are bundled into `dist/index.js` (about 2.7 MB) and are
110
+ devDependencies; the optional `@supabase/supabase-js` peer dependency is gone. `npx -y
111
+ @kirjapro/mcp-server` installs this one package, so no unpinned third-party package or
112
+ install script runs with `KIRJAPRO_API_KEY` in its environment. Up to 0.19.0 about 105
113
+ packages were resolved at install time.
114
+ - **Stable code for a schema refusal** (T4-16): arguments that fail a tool's input schema
115
+ answer `INVALID_ARGUMENTS: Input validation error: Invalid arguments for tool …` instead
116
+ of `MCP error -32602: Input validation error: …`, so every failed call starts with a code.
117
+ Telemetry already recorded these as `INVALID_ARGUMENTS`.
118
+ - **Telemetry `batch_size`** (T3-60): only a transactions count within 1–250 is sent. A
119
+ batch call with `transactions: []` or more than 250 items (which the SDK then refuses)
120
+ made the database refuse the whole telemetry flush, its neighbours' events included.
121
+ - **Release pipeline** (T2-12, T3-78; no package change): `publish-mcp.yml` builds and packs
122
+ in a job without secrets or publish rights, checks the live types in a job that holds
123
+ only the read token and installs nothing but the checksum-pinned Supabase CLI 2.111.0
124
+ release, and publishes the packed tarball from a job
125
+ in the `npm-publish` environment that installs nothing. `check:release-version` keeps
126
+ `package.json`, `server.json`, `mcpb/manifest.json` and this file's version heading in
127
+ step on every pull request; `mcpb:validate` and `mcpb:pack` pin `@anthropic-ai/mcpb@2.1.2`.
128
+ `check:types-drift` (also in `prepublishOnly`) runs `supabase` from `PATH` and fails unless
129
+ `supabase --version` is exactly 2.111.0; it no longer runs `npx -y supabase@latest`.
130
+
3
131
  ## [0.19.0] - 2026-10-19
4
132
 
5
133
  PR C of the MCP audit of 18.10.2026 (batches 3 and 4: posting guards and e-invoice send-state