@kirjapro/mcp-server 0.6.3 → 0.8.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.
Files changed (67) hide show
  1. package/CHANGELOG.md +115 -0
  2. package/README.md +73 -9
  3. package/dist/index.js +1472 -657
  4. package/package.json +10 -4
  5. package/server.json +6 -2
  6. package/tool-fingerprints.json +55 -51
  7. package/dist/accounts.d.ts +0 -40
  8. package/dist/accounts.js +0 -45
  9. package/dist/auth.d.ts +0 -17
  10. package/dist/auth.js +0 -245
  11. package/dist/compliance/rates.d.ts +0 -53
  12. package/dist/compliance/rates.js +0 -57
  13. package/dist/database.types.d.ts +0 -6525
  14. package/dist/database.types.js +0 -20
  15. package/dist/index.d.ts +0 -2
  16. package/dist/lib/incomeStatementSynthesis.d.ts +0 -47
  17. package/dist/lib/incomeStatementSynthesis.js +0 -140
  18. package/dist/resources/company.d.ts +0 -2
  19. package/dist/resources/company.js +0 -75
  20. package/dist/resources/compliance.d.ts +0 -2
  21. package/dist/resources/compliance.js +0 -338
  22. package/dist/resources/index.d.ts +0 -2
  23. package/dist/resources/index.js +0 -10
  24. package/dist/resources/schema.d.ts +0 -2
  25. package/dist/resources/schema.js +0 -63
  26. package/dist/resources/security.d.ts +0 -2
  27. package/dist/resources/security.js +0 -33
  28. package/dist/schemas.d.ts +0 -12
  29. package/dist/schemas.js +0 -12
  30. package/dist/tools/accounts.d.ts +0 -2
  31. package/dist/tools/accounts.js +0 -48
  32. package/dist/tools/banking.d.ts +0 -2
  33. package/dist/tools/banking.js +0 -196
  34. package/dist/tools/bookings.d.ts +0 -2
  35. package/dist/tools/bookings.js +0 -294
  36. package/dist/tools/customers.d.ts +0 -2
  37. package/dist/tools/customers.js +0 -320
  38. package/dist/tools/financialNotes.d.ts +0 -2
  39. package/dist/tools/financialNotes.js +0 -255
  40. package/dist/tools/fingerprints.d.ts +0 -6
  41. package/dist/tools/fingerprints.js +0 -28
  42. package/dist/tools/fiscal-years.d.ts +0 -2
  43. package/dist/tools/fiscal-years.js +0 -35
  44. package/dist/tools/index.d.ts +0 -9
  45. package/dist/tools/index.js +0 -105
  46. package/dist/tools/invoices.d.ts +0 -2
  47. package/dist/tools/invoices.js +0 -489
  48. package/dist/tools/offers.d.ts +0 -2
  49. package/dist/tools/offers.js +0 -443
  50. package/dist/tools/received-invoices.d.ts +0 -2
  51. package/dist/tools/received-invoices.js +0 -134
  52. package/dist/tools/recurring-invoices.d.ts +0 -2
  53. package/dist/tools/recurring-invoices.js +0 -348
  54. package/dist/tools/reports.d.ts +0 -2
  55. package/dist/tools/reports.js +0 -869
  56. package/dist/tools/templates.d.ts +0 -89
  57. package/dist/tools/templates.js +0 -636
  58. package/dist/tools/transactions.d.ts +0 -2
  59. package/dist/tools/transactions.js +0 -597
  60. package/dist/tools/validation.d.ts +0 -26
  61. package/dist/tools/validation.js +0 -127
  62. package/dist/types.d.ts +0 -388
  63. package/dist/types.js +0 -34
  64. package/dist/utils.d.ts +0 -276
  65. package/dist/utils.js +0 -637
  66. package/dist/version.d.ts +0 -1
  67. package/dist/version.js +0 -3
package/CHANGELOG.md CHANGED
@@ -1,5 +1,120 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.8.0] - 2026-08-30
4
+
5
+ Safety and observability release for agent-driven accounting. This release has
6
+ breaking input changes for write and batch tools and requires the paired
7
+ database migrations plus an `mcp-auth` redeploy before the package is published.
8
+
9
+ ### Breaking changes
10
+
11
+ - Every one of the 23 write tools now requires `idempotencyKey` as a UUID v4.
12
+ A write executes only after the database atomically confirms its claim. A
13
+ missing/unavailable claim fails closed; a crashed or uncertain operation is
14
+ permanently blocked from automatic re-execution instead of being recycled
15
+ after a timeout.
16
+ - `kirjapro_create_transactions_batch` and
17
+ `kirjapro_create_from_template_batch` no longer expose `mode` or partial
18
+ success. They default to `dryRun: true`; committing with `dryRun: false` is
19
+ always atomic and any invalid member aborts the whole batch.
20
+ - Invoice, offer, and recurring-invoice payloads are capped at 100 lines;
21
+ transactions are capped at 100 journal entries each and 500 entries across a
22
+ batch. Write annotations no longer claim unbounded MCP idempotence: the
23
+ completed-response replay contract remains 24 hours.
24
+ - `kirjapro_get_general_ledger` is now seek-cursor paginated (`limit` 1–100).
25
+ The full-period summary remains exact while each entry page is bounded and
26
+ pinned to the first page's creation-time cutoff.
27
+ - `kirjapro_get_ar_aging` now returns aggregate buckets only. Invoice/customer
28
+ rows are intentionally omitted; null due dates have an explicit bucket and
29
+ the weighted-age metric is no longer presented as revenue-based DSO.
30
+
31
+ ### Added
32
+
33
+ - Metadata-only operational telemetry, enabled by default and explicitly
34
+ disableable with `KIRJAPRO_TELEMETRY=false`. It records tool/version/surface,
35
+ client, timing, outcome class, byte counts, batch/preview flags, idempotency
36
+ state, and company/API-key attribution. It never sends arguments, results,
37
+ prompts, accounting-record identifiers, names, or monetary values. Raw events
38
+ expire after 90 days.
39
+ - Platform-admin MCP metrics panel with 7/30/90-day trends, tool adoption,
40
+ client/surface breakdowns, error classes, response-budget events, and
41
+ idempotency safety signals. Only aggregate data is exposed to the UI.
42
+ - Soft 50 KiB response telemetry and a hard 200 KiB context-safety budget with
43
+ an actionable `RESPONSE_BUDGET_EXCEEDED` error. Write responses are shaped
44
+ before replay completion, so a committed operation cannot cache an envelope
45
+ different from the one returned to the client.
46
+ - Full `tools/call` lifecycle instrumentation, including SDK input validation,
47
+ unknown tools, output-schema failures, and malformed protocol requests.
48
+ - Stable, explicit registration order for all 52 tools and regression coverage
49
+ for the 27-tool `core` prefix.
50
+
51
+ ### Security
52
+
53
+ - Idempotency state is server-owned: direct authenticated table access is
54
+ revoked, claim/complete require an AAL2 company-scoped JWT carrying a live
55
+ matching MCP API-key and write-protocol claims, request bodies are SHA-256
56
+ bound, and replay payloads have bounded JSONB storage headroom. Ordinary
57
+ browser sessions cannot reserve or
58
+ complete MCP replay keys. A registry-level boundary covers the complete
59
+ write handler, so state-dependent preflight reads cannot bypass replay.
60
+ - Telemetry ingestion accepts only `mcp-auth` JWTs carrying a revalidated
61
+ `mcp_api_key_id` and protocol-2 claim; unknown event fields and tool names
62
+ outside the pinned 52-tool catalog plus the privacy-preserving unknown-tool
63
+ sentinel are rejected, and raw rows are not readable by authenticated users.
64
+ - Tool fingerprints now cover public output schemas in addition to description,
65
+ annotations, and input schemas, using stable JSON Schema rather than mutable
66
+ Zod internals.
67
+
68
+ ### Server-side coupling
69
+
70
+ 1. After merge, redeploy `mcp-auth` through
71
+ `npm run functions:deploy -- mcp-auth` (the wrapper preserves
72
+ `--no-verify-jwt`). It rejects clients without write protocol 2 and records
73
+ successful v0.8 exchanges in the audit log.
74
+ 2. Deploy migrations `20260830120000_mcp_v08_idempotency_telemetry.sql` and
75
+ `20260830121000_mcp_v08_bounded_reports.sql` through `npm run db:deploy`.
76
+ The foundation migration denies every still-live pre-protocol company JWT
77
+ on the protected table/RPC paths used by MCP writes before it revokes the
78
+ legacy replay-table path. Deliberately unprotected bootstrap reads remain.
79
+ 3. Publish `@kirjapro/mcp-server@0.8.0` only after the backend checks pass.
80
+ No active-client restart inventory is part of the safety proof.
81
+
82
+ ## [0.7.1] - 2026-08-23
83
+
84
+ Adds structured sales VAT treatment across invoice and offer creation.
85
+
86
+ ### Added
87
+
88
+ - Invoice and offer tools accept VAT-inclusive unit prices, explicit 0 % treatment codes,
89
+ construction reverse-charge confirmation, and intra-EU goods transport confirmation.
90
+ - Customer country/VAT identifier and seller registration are validated before special VAT
91
+ treatments are persisted; document delivery remains guarded by the server readiness RPC.
92
+
93
+ ### Fixed
94
+
95
+ - VAT summary output now distinguishes official OmaVero purchase fields 318/320 from the
96
+ construction/scrap sales field 319 and exposes treatment-derived EU/zero-rate sales bases.
97
+ - Tool fingerprint baseline regenerated for the intentional schema and description changes.
98
+
99
+ ## [0.7.0] - 2026-07-16
100
+
101
+ Adds invoice delivery as a first-class MCP workflow.
102
+
103
+ ### Added
104
+
105
+ - **`kirjapro_send_invoice`** sends a draft invoice through an explicit `email` or `einvoice` channel. The tool calls the authenticated `dispatch-invoice` Edge Function, keeps provider credentials server-side, and returns the delivery identifier.
106
+ - Invoice create → send guidance now uses the delivery tool instead of redirecting users to the web UI.
107
+
108
+ ### Changed
109
+
110
+ - The default `core` surface now contains 27 tools; the complete catalog remains 52 tools.
111
+ - Package, server manifest, and MCPB versions are aligned at 0.7.0.
112
+ - Client setup now documents native local `stdio` use with Mistral Vibe and ChatGPT access through OpenAI Secure MCP Tunnel. Mistral Le Chat is explicitly marked as requiring a separately hosted remote endpoint.
113
+
114
+ ### Fixed
115
+
116
+ - Server instructions no longer list e-invoice sending as web-only now that `kirjapro_send_invoice` supports the explicit `einvoice` channel.
117
+
3
118
  ## [0.6.1] - 2026-05-29
4
119
 
5
120
  Hardening release from a full server audit (12 dimensions, adversarially verified). No new tools; tightens input validation, closes two security gaps, and corrects compliance guidance + tool descriptions. `tool-fingerprints.json` regenerated for the description/input-schema changes.
package/README.md CHANGED
@@ -1,13 +1,13 @@
1
1
  # @kirjapro/mcp-server
2
2
 
3
- MCP server for Finnish accounting. Exposes Kirjapro bookkeeping, invoicing, and reporting tools to Claude Code, Claude Desktop, and any MCP client.
3
+ MCP server for Finnish accounting. Exposes Kirjapro bookkeeping, invoicing, and reporting tools to Claude Code, Claude Desktop, Mistral Vibe, ChatGPT through Secure MCP Tunnel, and other MCP clients.
4
4
 
5
5
  **Full documentation:** [kirjapro.fi/docs/mcp](https://kirjapro.fi/docs/mcp/)
6
6
 
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
@@ -72,9 +72,30 @@ Add to `claude_desktop_config.json`:
72
72
 
73
73
  Restart Claude Desktop after saving.
74
74
 
75
+ #### Mistral Vibe
76
+
77
+ Add to `~/.vibe/config.toml`:
78
+
79
+ ```toml
80
+ [[mcp_servers]]
81
+ name = "kirjapro"
82
+ transport = "stdio"
83
+ command = "npx"
84
+ args = ["-y", "@kirjapro/mcp-server"]
85
+ env = { KIRJAPRO_API_KEY = "kp_your_key_here" }
86
+ ```
87
+
88
+ Restart Vibe and verify the connection from `/mcp`.
89
+
90
+ #### ChatGPT
91
+
92
+ ChatGPT requires a remote MCP connection and cannot launch this local `stdio` package directly. Use [OpenAI Secure MCP Tunnel](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels) to bridge ChatGPT to `npx -y @kirjapro/mcp-server`. Full write/modify support currently requires ChatGPT Business or Enterprise/Edu; see the [full setup guide](https://kirjapro.fi/docs/mcp/) for the tunnel commands and plan limitations.
93
+
94
+ Mistral Le Chat likewise requires a remote MCP server URL. The local npm package works directly with Mistral Vibe; Le Chat support requires a separately hosted remote endpoint.
95
+
75
96
  #### Other clients
76
97
 
77
- See [full setup guide](https://kirjapro.fi/docs/mcp/) for Cursor, VS Code / Copilot, Windsurf, and generic stdio.
98
+ See [full setup guide](https://kirjapro.fi/docs/mcp/) for ChatGPT, Mistral Vibe, Cursor, VS Code / Copilot, Windsurf, and generic stdio.
78
99
 
79
100
  ### 3. Verify
80
101
 
@@ -86,6 +107,7 @@ A few prompts to feel out the daily workflows the agent handles cleanly:
86
107
 
87
108
  - *"Show my dashboard"* — financial snapshot of the current fiscal year
88
109
  - *"Create an invoice for Acme Oy, 5000 € for consulting in March"* — full lifecycle from customer lookup to draft invoice
110
+ - *"Send invoice #42 by email"* — server-rendered PDF delivery with an explicit channel
89
111
  - *"Draft a contract for Acme Oy and email it to john@acme.fi, 3-month retainer at 5000 € / month"* — `tarjous`/`sopimus` create + customer-visible email link
90
112
  - *"Record that invoice #42 was paid yesterday"* — payment recording + auto status transition
91
113
  - *"What's my VAT for this quarter?"* — `kirjapro_get_alv_summary` with OmaVero field codes
@@ -94,7 +116,7 @@ A few prompts to feel out the daily workflows the agent handles cleanly:
94
116
 
95
117
  ## What's included
96
118
 
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:
119
+ **27 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
120
 
99
121
  ```jsonc
100
122
  {
@@ -104,14 +126,19 @@ A few prompts to feel out the daily workflows the agent handles cleanly:
104
126
  "args": ["-y", "@kirjapro/mcp-server"],
105
127
  "env": {
106
128
  "KIRJAPRO_API_KEY": "kp_your_key_here",
107
- "KIRJAPRO_MCP_SURFACE": "full" // 52 tools instead of 26
129
+ "KIRJAPRO_MCP_SURFACE": "full" // 52 tools instead of 27
108
130
  }
109
131
  }
110
132
  }
111
133
  }
112
134
  ```
113
135
 
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.
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.
115
142
 
116
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`.
117
144
 
@@ -119,7 +146,7 @@ A few prompts to feel out the daily workflows the agent handles cleanly:
119
146
  |---|---|
120
147
  | Read your books | `list_fiscal_years`, `list_accounts`, `get_dashboard`, `get_income_statement`, `get_balance_sheet`, `get_alv_summary`, `get_ar_aging` |
121
148
  | Customers | `list_customers`, `get_customer`, `create_customer`, `lookup_business` (PRH) |
122
- | Invoice lifecycle | `list_invoices`, `get_invoice`, `create_invoice`, `record_payment`, `update_invoice_status` |
149
+ | Invoice lifecycle | `list_invoices`, `get_invoice`, `create_invoice`, `send_invoice`, `record_payment`, `update_invoice_status` |
123
150
  | Transactions + banking | `list_transactions`, `create_transaction`, `list_bank_transactions`, `match_bank_transaction` |
124
151
  | Contracts | `create_offer` (`tarjous` / `sopimus`), `send_offer` (email link), `convert_offer_to_invoice` |
125
152
  | Validators (free) | `validate_business_id`, `validate_iban`, `generate_reference` |
@@ -130,15 +157,52 @@ A few prompts to feel out the daily workflows the agent handles cleanly:
130
157
 
131
158
  See the [full tool reference](https://kirjapro.fi/docs/mcp/) for parameters, usage examples, and error handling.
132
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
+
133
192
  ## Security
134
193
 
135
194
  - API keys are hashed with SHA-256; the full key is never stored
136
- - 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
137
197
  - All queries use Row Level Security (RLS) — users can only access their own company's data
138
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)
139
199
  - Automatic token refresh keeps long-running sessions alive
140
200
  - Rate limiting: 10 auth requests per minute per key
141
- - **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.
142
206
 
143
207
  ## License
144
208