@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.
- package/CHANGELOG.md +115 -0
- package/README.md +73 -9
- package/dist/index.js +1472 -657
- package/package.json +10 -4
- package/server.json +6 -2
- package/tool-fingerprints.json +55 -51
- package/dist/accounts.d.ts +0 -40
- package/dist/accounts.js +0 -45
- package/dist/auth.d.ts +0 -17
- package/dist/auth.js +0 -245
- package/dist/compliance/rates.d.ts +0 -53
- package/dist/compliance/rates.js +0 -57
- package/dist/database.types.d.ts +0 -6525
- package/dist/database.types.js +0 -20
- package/dist/index.d.ts +0 -2
- package/dist/lib/incomeStatementSynthesis.d.ts +0 -47
- package/dist/lib/incomeStatementSynthesis.js +0 -140
- package/dist/resources/company.d.ts +0 -2
- package/dist/resources/company.js +0 -75
- package/dist/resources/compliance.d.ts +0 -2
- package/dist/resources/compliance.js +0 -338
- package/dist/resources/index.d.ts +0 -2
- package/dist/resources/index.js +0 -10
- package/dist/resources/schema.d.ts +0 -2
- package/dist/resources/schema.js +0 -63
- package/dist/resources/security.d.ts +0 -2
- package/dist/resources/security.js +0 -33
- package/dist/schemas.d.ts +0 -12
- package/dist/schemas.js +0 -12
- package/dist/tools/accounts.d.ts +0 -2
- package/dist/tools/accounts.js +0 -48
- package/dist/tools/banking.d.ts +0 -2
- package/dist/tools/banking.js +0 -196
- package/dist/tools/bookings.d.ts +0 -2
- package/dist/tools/bookings.js +0 -294
- package/dist/tools/customers.d.ts +0 -2
- package/dist/tools/customers.js +0 -320
- package/dist/tools/financialNotes.d.ts +0 -2
- package/dist/tools/financialNotes.js +0 -255
- package/dist/tools/fingerprints.d.ts +0 -6
- package/dist/tools/fingerprints.js +0 -28
- package/dist/tools/fiscal-years.d.ts +0 -2
- package/dist/tools/fiscal-years.js +0 -35
- package/dist/tools/index.d.ts +0 -9
- package/dist/tools/index.js +0 -105
- package/dist/tools/invoices.d.ts +0 -2
- package/dist/tools/invoices.js +0 -489
- package/dist/tools/offers.d.ts +0 -2
- package/dist/tools/offers.js +0 -443
- package/dist/tools/received-invoices.d.ts +0 -2
- package/dist/tools/received-invoices.js +0 -134
- package/dist/tools/recurring-invoices.d.ts +0 -2
- package/dist/tools/recurring-invoices.js +0 -348
- package/dist/tools/reports.d.ts +0 -2
- package/dist/tools/reports.js +0 -869
- package/dist/tools/templates.d.ts +0 -89
- package/dist/tools/templates.js +0 -636
- package/dist/tools/transactions.d.ts +0 -2
- package/dist/tools/transactions.js +0 -597
- package/dist/tools/validation.d.ts +0 -26
- package/dist/tools/validation.js +0 -127
- package/dist/types.d.ts +0 -388
- package/dist/types.js +0 -34
- package/dist/utils.d.ts +0 -276
- package/dist/utils.js +0 -637
- package/dist/version.d.ts +0 -1
- 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
|
|
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
|
|
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
|
-
**
|
|
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
|
|
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
|
|
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
|
-
-
|
|
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
|
|