@kirjapro/mcp-server 0.5.0 → 0.5.6

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,257 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.5.5] - 2026-04-11
4
+
5
+ Tool-annotation sweep: every remaining `server.tool()` call migrated to
6
+ `server.registerTool()` and tagged with MCP tool annotations. No behavioural
7
+ changes — clients get richer `list_tools` metadata and `destructiveHint`
8
+ now flags the three `delete_*` tools so UIs can warn before invoking them.
9
+
10
+ ### registerTool() migration
11
+
12
+ - **All 43 remaining tools migrated** — `customers`, `invoices`, `bookings`,
13
+ `offers`, `recurring-invoices`, `templates`, `accounts`, `received-invoices`,
14
+ `banking`, `validation`, `fiscal-years`, and `transactions` now exclusively
15
+ use `server.registerTool(name, { description, inputSchema, annotations }, cb)`.
16
+ The deprecated `server.tool()` overload is no longer called anywhere in the
17
+ codebase (verified by test guard — see below).
18
+ - **Shared annotation constants** (`src/utils.ts`) — `READ_ONLY_ANNOTATIONS`,
19
+ `READ_ONLY_EXTERNAL_ANNOTATIONS`, `WRITE_ANNOTATIONS`,
20
+ `WRITE_EXTERNAL_ANNOTATIONS`, `DESTRUCTIVE_ANNOTATIONS`. The five constants
21
+ cover the read/write × local/external × destructive matrix, so individual
22
+ tool files don't re-declare the hint bags inline.
23
+ - **`destructiveHint: true`** on `kirjapro_delete_invoice`,
24
+ `kirjapro_delete_offer`, and `kirjapro_delete_recurring_invoice`. MCP
25
+ clients that support the annotation can now show a distinct confirmation
26
+ prompt before executing irreversible operations.
27
+ - **`openWorldHint: true`** on `kirjapro_lookup_business` (PRH API) and
28
+ `kirjapro_send_offer` (sends customer-visible email via Maventa). Everything
29
+ else sets `openWorldHint: false` since the operation is confined to the
30
+ caller's own Supabase tenant.
31
+ - **Inline annotation block in `list_transactions`** replaced with the shared
32
+ `READ_ONLY_ANNOTATIONS` constant — single source of truth for hint values.
33
+ - **`reports.ts` local annotation const** removed; imports from `utils.js`.
34
+ Drops one duplicate definition that was introduced in v0.5.2.
35
+
36
+ ### Test infrastructure
37
+
38
+ - **`tools-registry.test.ts` guard tests added:**
39
+ - `declares annotations on every registered tool` — iterates the full
40
+ 52-tool list and asserts `annotations` is defined. Any regression that
41
+ forgets to pass annotations (or accidentally re-introduces
42
+ `server.tool()`) fails CI.
43
+ - `flags delete_* tools as destructive` — asserts every tool whose name
44
+ starts with `kirjapro_delete_` has `destructiveHint: true` and
45
+ `readOnlyHint: false`. Prevents a delete tool from being silently
46
+ labelled safe.
47
+ - **Full suite: 111 passing (was 109 in v0.5.4).** 7 test files, same auth
48
+ DNS warning as before (benign — `test.supabase.co` resolution in legacy
49
+ env-var test).
50
+
51
+ ### Notes
52
+
53
+ - `outputSchema` on write tools is intentionally NOT added in this pass.
54
+ Write payloads are complex (invoice line refinements, journal entries
55
+ with balanced debit/credit tuples) and declaring them risks runtime
56
+ validation surprises on real rows. Deferred to v0.5.6+ as an incremental
57
+ per-tool exercise.
58
+ - The `WRITE_EXTERNAL_ANNOTATIONS` constant is exported but currently only
59
+ used by `kirjapro_send_offer`. Kept in `utils.ts` for future e-invoice
60
+ tools that hit Maventa directly.
61
+
62
+ ## [0.5.4] - 2026-04-11
63
+
64
+ M6 tail: the three remaining read tools now declare `outputSchema`.
65
+
66
+ ### Structured output
67
+
68
+ - **`registerTool()` + `outputSchema` on `get_balance_sheet`,
69
+ `get_ar_aging`, `get_general_ledger`** — all 9 read tools in the
70
+ reports / invoices / transactions surface now expose typed response
71
+ contracts at `list_tools` time and carry the `readOnlyHint` /
72
+ `idempotentHint` / `openWorldHint: false` annotation set. Inner row
73
+ shapes use `.passthrough()` / `z.unknown()` to stay permissive on
74
+ real-world rows.
75
+
76
+ ### Test infrastructure
77
+
78
+ - **Snapshot assertion widened** — `tools-registry.test.ts` now checks
79
+ `outputSchema` presence on all 9 read tools (was 6 in v0.5.3). Any
80
+ future migration that drops a schema fails CI.
81
+
82
+ ## [0.5.3] - 2026-04-11
83
+
84
+ Audit follow-through: schema contracts on hot read tools, registration
85
+ drift guard, and test-suite widening.
86
+
87
+ ### Structured output
88
+
89
+ - **`registerTool()` migration + `outputSchema` on 6 hot read tools**
90
+ (M6 completion) — `kirjapro_list_invoices`, `kirjapro_get_invoice`,
91
+ `kirjapro_list_transactions`, `kirjapro_get_dashboard`,
92
+ `kirjapro_get_income_statement`, and `kirjapro_get_alv_summary` now
93
+ register via the modern `server.registerTool()` API, declare typed
94
+ `outputSchema` (zod raw shapes), and carry `readOnlyHint` /
95
+ `idempotentHint` / `openWorldHint: false` annotations. MCP clients
96
+ see the schemas at `list_tools` time — agents can validate return
97
+ shapes without "forgot field name" loops.
98
+
99
+ ### Test infrastructure
100
+
101
+ - **Tool registration snapshot test** (M16 follow-through) — new
102
+ `tools/tools-registry.test.ts` asserts that exactly 52 tool names
103
+ are registered (catches accidental unregister or rename drift) and
104
+ that the 6 hot read tools all declare `outputSchema`. Verifies
105
+ `kirjapro_send_offer` and `kirjapro_convert_offer_to_invoice` are
106
+ in the bundle (closes the M16 regression concern).
107
+
108
+ ### Notes
109
+
110
+ - Output schemas are intentionally lax on row-level fields (use
111
+ `.passthrough()` or `z.unknown()` for nested shapes) to avoid
112
+ runtime validation failures on edge-case rows. The envelope shape
113
+ (`results` / `total_count` / `has_more` / `next_offset`) and the
114
+ top-level report blocks are precise; inner rows are descriptive
115
+ rather than strict. Tighten over time as real usage reveals stable
116
+ shapes.
117
+ - Write tools still use `server.tool()`. Migrating writes to
118
+ `registerTool()` is deferred — the annotations (`destructiveHint`)
119
+ would be valuable, but the schema complexity (zod refinements on
120
+ invoice line items, etc.) needs a dedicated pass.
121
+
122
+ ## [0.5.2] - 2026-04-11
123
+
124
+ Round 3 of `ENHANCEMENT-AUDIT-2026-04-11.md`: idempotency + dry-run on
125
+ writes, structured content on hot read tools, atomic booking RPCs, and a
126
+ salary rounding fix.
127
+
128
+ ### Reliability
129
+
130
+ - **Idempotency keys on every write tool** (M4) — new
131
+ `mcp_idempotency_keys` table (`20260411132733_add_mcp_idempotency_keys.sql`)
132
+ stores `(company_id, key) → response_payload` with a 24h TTL. Every write
133
+ tool now accepts an optional `idempotencyKey` (8–128 chars). Retries with
134
+ the same key return the cached response verbatim — a retried
135
+ `kirjapro_create_invoice` on a transient network blip will no longer
136
+ create a duplicate invoice. Cache misses pass through; infra errors
137
+ fall through (the wrapper never masks a write). Covered by the new
138
+ `withIdempotency()` helper in `utils.ts`.
139
+ - **Dry-run previews on destructive tools** (M4) — `kirjapro_delete_invoice`,
140
+ `kirjapro_delete_offer`, `kirjapro_delete_recurring_invoice`, and
141
+ `kirjapro_update_offer_status` now accept `dryRun: true`. They validate
142
+ the operation and return `{ dry_run: true, requires_confirmation: true,
143
+ message, preview }` without writing. Agents should always call with
144
+ `dryRun: true` first for irreversible actions, relay the preview to the
145
+ user, and only re-call with `dryRun: false` after confirmation.
146
+ - **Atomic `book_salary` + `book_vat_settlement`** (M9) — both booking
147
+ tools now call `book_salary_atomic` / `book_vat_settlement_atomic`
148
+ SECURITY DEFINER RPCs guarded by `pg_advisory_xact_lock`. Serializes
149
+ concurrent callers per `(company, fiscal_year, period)` so parallel
150
+ tool invocations cannot each write a salary journal for the same pay
151
+ period.
152
+ - **`book_salary` rounding residual** (M15) — employer's TyEL + employee's
153
+ TyEL now use residual-method rounding (last group = total − sum of
154
+ others) so the journal balances to the cent. Parametrized test added
155
+ covering 2026 rates + a handful of adversarial gross amounts.
156
+
157
+ ### Structured output
158
+
159
+ - **`structuredContent` on 6 hot read tools** (M6) — new `toResult<T>()`
160
+ helper returns both the JSON-stringified `content` (backward compat)
161
+ and a typed `structuredContent` object. Rolled out to
162
+ `kirjapro_list_invoices`, `kirjapro_get_invoice`,
163
+ `kirjapro_list_transactions`, `kirjapro_get_dashboard`,
164
+ `kirjapro_get_income_statement`, and `kirjapro_get_alv_summary`. Modern
165
+ MCP clients consume `structuredContent` without `JSON.parse`. Declaring
166
+ `outputSchema` via `registerTool()` is deferred to a later version
167
+ since it requires migrating away from the deprecated `server.tool()`
168
+ overload.
169
+
170
+ ### Migrations
171
+
172
+ - `20260411132733_add_mcp_idempotency_keys.sql` — `mcp_idempotency_keys`
173
+ table, RLS (`private.has_company_access`), and
174
+ `cleanup_expired_mcp_idempotency_keys()` maintenance function.
175
+
176
+ ## [0.5.1] - 2026-04-11
177
+
178
+ Security + compliance + race hardening bundle. Based on
179
+ `ENHANCEMENT-AUDIT-2026-04-11.md` — Round 1 (M1/M2/M5/M8/M10/M14/M16) and
180
+ Round 2 (M3/M7/M11/M12/M13).
181
+
182
+ ### Security
183
+
184
+ - **Prompt injection defense** (M3) — new `tagUntrusted()` utility wraps
185
+ attacker-controlled free text in `<untrusted-external>...</untrusted-external>`
186
+ tags. Applied to `kirjapro_list_bank_transactions` (counterparty_name,
187
+ reference, message), `kirjapro_list_received_invoices` /
188
+ `kirjapro_get_received_invoice` (sender_name, sender_business_id,
189
+ invoice_number, payment_reference), and `kirjapro_lookup_business`
190
+ (PRH free-text fields). The helper also strips zero-width characters,
191
+ control chars, and common injection markers (`system:`,
192
+ `<|im_start|>`, "ignore previous", etc.) before wrapping.
193
+ - **`kirjapro://security/data-handling` resource** (M3) — documents the
194
+ wrapper contract, lists every wrapped field per tool, and gives safe
195
+ handling rules. Intended as a session-start read.
196
+ - **Multi-company JWT scoping guard** (M1) — every tool call verifies
197
+ the JWT's `company_id` matches the MCP session's selected company
198
+ before executing, closing the cross-company data leak described in
199
+ CLAUDE.md pitfall #13.
200
+ - **Stdio token-refresh hardening** (M2) — mutex + single-flight refresh
201
+ prevents race between concurrent tool calls and the background refresh
202
+ timer; all 401s now retry once with a fresh token.
203
+
204
+ ### Correctness
205
+
206
+ - **Advisory-locked number generators** (M12) — new migration
207
+ `20260411120919_add_next_customer_offer_number_rpcs` adds
208
+ `get_next_customer_number(company_id)` and
209
+ `get_next_offer_number(company_id, type)` RPCs mirroring the
210
+ `pg_advisory_xact_lock(hashtext(...))` pattern from
211
+ `get_next_invoice_number`. `customers.ts` and `offers.ts` now call the
212
+ RPCs instead of read-then-write — fixes 23505 unique-index collisions
213
+ under concurrent creates.
214
+ - **Compliance rates single source of truth** (M7) — new
215
+ `src/compliance/rates.ts` exports `FINNISH_RATES_2026` (VAT, TyEL,
216
+ sotu, TTV, tapaturma, ryhmähenki) with a validity window.
217
+ `bookings.ts`, `templates.ts`, and `resources/compliance.ts` now
218
+ import from it instead of duplicating literals. Every compliance
219
+ resource emits an `_meta` envelope (`published_at`, `valid_through`,
220
+ `stale`, `days_until_expiry`); new `kirjapro://compliance/_freshness`
221
+ index resource lets the agent detect expired rates in one read at
222
+ session start.
223
+ - **Report tools auto-resolve fiscal year** (M11) — `get_dashboard`,
224
+ `get_income_statement`, `get_balance_sheet`, and `get_general_ledger`
225
+ now accept `fiscalYearId` as optional. When omitted, the single open
226
+ fiscal year is resolved via `resolveOpenFiscalYear()`; tools error
227
+ with a clear hint when multiple fiscal years are open.
228
+
229
+ ### Fixed
230
+
231
+ - Various small bugs (M5/M8/M10/M14/M16) — field selection drift,
232
+ error-message sanitization, pagination off-by-ones, and type narrowing
233
+ cleanups from Round 1 of the audit.
234
+
235
+ ### Internal
236
+
237
+ - New helper: `tagUntrusted(value, maxLen)` in `src/utils.ts`
238
+ - New helper: `resolveOpenFiscalYear(supabase, companyId)` in
239
+ `src/utils.ts`
240
+ - New module: `src/compliance/rates.ts` with `FINNISH_RATES_2026` +
241
+ `freshnessMeta()`
242
+ - New resource module: `src/resources/security.ts`
243
+ - `database.types.ts` augmented with `get_next_customer_number` and
244
+ `get_next_offer_number` RPC signatures
245
+
246
+ ### Notes
247
+
248
+ - M13 (`record_payment` TOCTOU) reviewed and downgraded to a nit — the
249
+ existing `record_invoice_payment` and `confirm_reconciliation_match`
250
+ RPCs already `SELECT … FOR UPDATE` the invoice row, so concurrent
251
+ callers are serialized at the DB layer.
252
+ - Verified: `tsc --noEmit` clean, 101/101 unit tests pass, `esbuild`
253
+ bundle clean (885 KB).
254
+
3
255
  ## [0.5.0] - 2026-03-28
4
256
 
5
257
  ### Added
package/README.md CHANGED
@@ -2,32 +2,38 @@
2
2
 
3
3
  MCP server for Finnish accounting. Exposes Kirjapro bookkeeping, invoicing, and reporting tools to Claude Code, Claude Desktop, and any MCP client.
4
4
 
5
- > **Full documentation:** [docs/mcp-server.md](../docs/mcp-server.md) — complete tool reference with parameters, usage examples, error guide, and multi-client setup.
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 with **Company** or **Custom** subscription tier
10
+ - Kirjapro account with **Entrepreneur**, **Company**, or **Custom** subscription tier
11
11
  - API key (generate at Settings > API-avaimet)
12
12
 
13
13
  ## Quick Start
14
14
 
15
15
  ### 1. Generate an API Key
16
16
 
17
- 1. Go to **Settings > API-avaimet** in the Kirjapro app
17
+ 1. Go to **Asetukset > API-avaimet** in the [Kirjapro app](https://kirjapro.fi)
18
18
  2. Click **"Luo uusi avain"**
19
- 3. Copy the key (shown only once)
19
+ 3. Copy the key (starts with `kp_`, shown only once)
20
20
 
21
21
  ### 2. Configure your MCP client
22
22
 
23
23
  #### Claude Code
24
24
 
25
- Add to `.claude/mcp.json`:
25
+ Add to your project's `.mcp.json` (recommended) or global config:
26
+
27
+ | OS | Project-level (recommended) | Global |
28
+ |----|----------------------------|--------|
29
+ | macOS / Linux | `.mcp.json` in project root | `~/.claude/mcp.json` |
30
+ | Windows | `.mcp.json` in project root | `%USERPROFILE%\.claude\mcp.json` |
26
31
 
27
32
  ```json
28
33
  {
29
34
  "mcpServers": {
30
35
  "kirjapro": {
36
+ "type": "stdio",
31
37
  "command": "npx",
32
38
  "args": ["-y", "@kirjapro/mcp-server"],
33
39
  "env": {
@@ -38,10 +44,18 @@ Add to `.claude/mcp.json`:
38
44
  }
39
45
  ```
40
46
 
47
+ Verify with `/mcp` in Claude Code.
48
+
41
49
  #### Claude Desktop
42
50
 
43
51
  Add to `claude_desktop_config.json`:
44
52
 
53
+ | OS | Path |
54
+ |----|------|
55
+ | macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
56
+ | Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
57
+ | Linux | `~/.config/Claude/claude_desktop_config.json` |
58
+
45
59
  ```json
46
60
  {
47
61
  "mcpServers": {
@@ -56,119 +70,48 @@ Add to `claude_desktop_config.json`:
56
70
  }
57
71
  ```
58
72
 
73
+ Restart Claude Desktop after saving.
74
+
75
+ #### Other clients
76
+
77
+ See [full setup guide](https://kirjapro.fi/docs/mcp/) for Cursor, VS Code / Copilot, Windsurf, and generic stdio.
78
+
59
79
  ### 3. Verify
60
80
 
61
- In Claude Code, run `/mcp` to see the available Kirjapro tools.
62
-
63
- ## Environment Variables
64
-
65
- | Variable | Required | Description |
66
- |----------|----------|-------------|
67
- | `KIRJAPRO_API_KEY` | Yes* | API key from Settings > API-avaimet |
68
-
69
- ### Legacy (development only)
70
-
71
- | Variable | Required | Description |
72
- |----------|----------|-------------|
73
- | `SUPABASE_URL` | Yes* | Supabase project URL |
74
- | `SUPABASE_ACCESS_TOKEN` | Yes* | User's JWT access token |
75
- | `KIRJAPRO_COMPANY_ID` | Yes* | Company UUID to operate on |
76
-
77
- *Either `KIRJAPRO_API_KEY` or all three legacy variables must be set.
78
-
79
- ## Tools (40)
80
-
81
- ### Read Tools
82
-
83
- | Tool | Description |
84
- |------|-------------|
85
- | `kirjapro_list_accounts` | List chart of accounts with filtering by type |
86
- | `kirjapro_list_transactions` | List transactions with journal entries for a fiscal year |
87
- | `kirjapro_search_transactions` | Search transactions by text, date range, or amount |
88
- | `kirjapro_get_transaction` | Get single transaction with journal entries and account details |
89
- | `kirjapro_list_invoices` | List invoices with customer names, filter by status |
90
- | `kirjapro_get_invoice` | Get single invoice with lines, payments, and VAT breakdown |
91
- | `kirjapro_list_customers` | List customers with search |
92
- | `kirjapro_get_customer` | Get single customer with invoice stats |
93
- | `kirjapro_list_bank_accounts` | List active bank accounts with balances |
94
- | `kirjapro_list_bank_transactions` | List bank transactions with filtering |
95
- | `kirjapro_list_fiscal_years` | List fiscal years with open/closed status |
96
- | `kirjapro_get_dashboard` | Financial dashboard: revenue, expenses, invoice stats, bank balances |
97
- | `kirjapro_get_income_statement` | Income statement (tuloslaskelma) for a date range |
98
- | `kirjapro_get_balance_sheet` | Balance sheet (tase) as of a specific date |
99
- | `kirjapro_get_ar_aging` | Accounts receivable aging (0-30, 31-60, 61-90, 90+ days) |
100
- | `kirjapro_get_general_ledger` | General ledger (pääkirja) for one account with running balance |
101
- | `kirjapro_list_templates` | List transaction templates for common bookkeeping patterns |
102
- | `kirjapro_list_offers` | List offers/contracts with customer names |
103
- | `kirjapro_get_offer` | Get offer detail with lines, events, and VAT breakdown |
104
-
105
- ### Write Tools
106
-
107
- | Tool | Description |
108
- |------|-------------|
109
- | `kirjapro_create_transaction` | Create an accounting transaction with journal entries |
110
- | `kirjapro_create_transactions_batch` | Bulk create up to 50 transactions (partial success) |
111
- | `kirjapro_create_invoice` | Create invoice with auto-generated number and reference |
112
- | `kirjapro_create_customer` | Create customer with Y-tunnus validation |
113
- | `kirjapro_update_customer` | Update customer fields (partial update, re-validates Y-tunnus) |
114
- | `kirjapro_record_payment` | Record payment against an invoice |
115
- | `kirjapro_update_invoice_status` | Update invoice status with state machine validation |
116
- | `kirjapro_delete_invoice` | Delete draft invoices (audit-safe) |
117
- | `kirjapro_match_bank_transaction` | Match bank transaction to an invoice |
118
- | `kirjapro_create_from_template` | Create transaction from template with VAT splitting |
119
- | `kirjapro_create_from_template_batch` | Bulk create from templates (up to 50) |
120
- | `kirjapro_book_sale` | Book a sale with automatic VAT splitting (invoice/cash/prepaid) |
121
- | `kirjapro_book_purchase` | Book a purchase with VAT, reverse charge, or edustus |
122
- | `kirjapro_book_salary` | Book salary with 2026 Finnish social insurance rates |
123
- | `kirjapro_book_vat_settlement` | Book ALV-tilitys from journal entries |
124
- | `kirjapro_create_offer` | Create offer/contract with auto-generated number |
125
- | `kirjapro_update_offer_status` | Update offer status with state machine validation |
126
- | `kirjapro_delete_offer` | Delete draft offers/contracts |
127
-
128
- ### Validation Tools
129
-
130
- | Tool | Description |
131
- |------|-------------|
132
- | `kirjapro_validate_business_id` | Validate Finnish Y-tunnus |
133
- | `kirjapro_validate_iban` | Validate Finnish IBAN |
134
- | `kirjapro_generate_reference` | Generate viitenumero with check digit |
135
-
136
- ## Resources (4)
137
-
138
- | URI | Description |
139
- |-----|-------------|
140
- | `kirjapro://accounts/chart` | Finnish standard chart of accounts (YSE 2017) |
141
- | `kirjapro://vat-rates` | Finnish VAT rates (25.5%, 13.5%, 10%, 0%) |
142
- | `kirjapro://company/info` | Current company details |
143
- | `kirjapro://fiscal-years` | Fiscal years with open/closed status |
144
-
145
- ## Development
146
-
147
- ```bash
148
- cd mcp-server
149
- npm install
150
- npm run dev # Run with tsx
151
- npm run build # Build with esbuild
152
- npm test # Run vitest
153
- npm run lint # Type check
154
- ```
81
+ Ask your AI assistant: *"list my fiscal years"* — it should call `kirjapro_list_fiscal_years` and return your company's accounting periods.
82
+
83
+ ## What's included
155
84
 
156
- ## Publishing
85
+ **52 tools** across 13 domains:
157
86
 
158
- Releases are automated via GitHub Actions. To publish:
87
+ | Domain | Tools | Examples |
88
+ |--------|-------|---------|
89
+ | Accounts | 1 | List chart of accounts with filtering |
90
+ | Transactions | 5 | Create, search, get detail, batch import |
91
+ | Templates | 3 | Auto-balanced entries with VAT splitting |
92
+ | Invoices | 6 | Create, send, record payments, status management |
93
+ | Customers | 5 | CRUD + PRH business lookup |
94
+ | Banking | 3 | List accounts/transactions, match to invoices |
95
+ | Reports | 6 | Dashboard, income statement, balance sheet, AR aging, general ledger, ALV summary |
96
+ | Bookings | 4 | Purchase, sale, salary, VAT settlement — with automatic double-entry |
97
+ | Offers | 7 | Offer/contract lifecycle, email send, convert to invoice |
98
+ | Recurring | 6 | Recurring invoice templates |
99
+ | Received | 2 | Received (purchase) invoices |
100
+ | Fiscal Years | 1 | List fiscal years with status |
101
+ | Validation | 3 | Y-tunnus, IBAN, viitenumero |
159
102
 
160
- 1. Update version in `package.json`, `server.json`, and `src/index.ts`
161
- 2. Update `CHANGELOG.md`
162
- 3. Commit and tag: `git tag mcp-server/v0.3.0`
163
- 4. Push: `git push origin mcp-server/v0.3.0`
103
+ **9 resources** for reference data: chart of accounts, VAT rates, company info, fiscal years, and 5 Finnish compliance resources.
164
104
 
165
- The workflow validates version consistency, runs tests, publishes to npm, and creates a GitHub Release.
105
+ See the [full tool reference](https://kirjapro.fi/docs/mcp/) for parameters, usage examples, and error handling.
166
106
 
167
107
  ## Security
168
108
 
169
109
  - API keys are hashed with SHA-256; the full key is never stored
170
110
  - Keys exchange for short-lived JWTs (1 hour) via the `mcp-auth` edge function
171
- - All queries use the user's JWT with Row Level Security (RLS)
172
- - Automatic token refresh keeps long-running MCP sessions alive
173
- - Feature gate: requires `hasApiAccess` (Company/Custom tier)
111
+ - All queries use Row Level Security (RLS) — users can only access their own company's data
112
+ - Automatic token refresh keeps long-running sessions alive
174
113
  - Rate limiting: 10 auth requests per minute per key
114
+
115
+ ## License
116
+
117
+ MIT