@kirjapro/mcp-server
v0.11.0
Published
MCP server for Finnish accounting — exposes Kirjapro bookkeeping, invoicing, and reporting tools to Claude, ChatGPT, Mistral, and other MCP clients.
Maintainers
Readme
@kirjapro/mcp-server
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.
Full documentation: kirjapro.fi/docs/mcp
Requirements
- Node.js 20+
- Kirjapro account on a paid tier with API access — Yrittäjä, Kasvu, Tilitoimisto, or Räätälöity
- API key (generate at Settings > API-avaimet)
Quick Start
1. Generate an API Key
- Go to Asetukset > API-avaimet in the Kirjapro app
- Click "Luo uusi avain"
- Copy the key (starts with
kp_, shown only once)
2. Configure your MCP client
Claude Code
Add to your project's .mcp.json (recommended) or global config:
| OS | Project-level (recommended) | Global |
|----|----------------------------|--------|
| macOS / Linux | .mcp.json in project root | ~/.claude/mcp.json |
| Windows | .mcp.json in project root | %USERPROFILE%\.claude\mcp.json |
{
"mcpServers": {
"kirjapro": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@kirjapro/mcp-server"],
"env": {
"KIRJAPRO_API_KEY": "kp_your_key_here"
}
}
}
}Verify with /mcp in Claude Code.
Claude Desktop
Add to claude_desktop_config.json:
| OS | Path |
|----|------|
| macOS | ~/Library/Application Support/Claude/claude_desktop_config.json |
| Windows | %APPDATA%\Claude\claude_desktop_config.json |
| Linux | ~/.config/Claude/claude_desktop_config.json |
{
"mcpServers": {
"kirjapro": {
"command": "npx",
"args": ["-y", "@kirjapro/mcp-server"],
"env": {
"KIRJAPRO_API_KEY": "kp_your_key_here"
}
}
}
}Restart Claude Desktop after saving.
Mistral Vibe
Add to ~/.vibe/config.toml:
[[mcp_servers]]
name = "kirjapro"
transport = "stdio"
command = "npx"
args = ["-y", "@kirjapro/mcp-server"]
env = { KIRJAPRO_API_KEY = "kp_your_key_here" }Restart Vibe and verify the connection from /mcp.
ChatGPT
ChatGPT requires a remote MCP connection and cannot launch this local stdio package directly. Use OpenAI Secure MCP Tunnel 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 for the tunnel commands and plan limitations.
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.
Other clients
See full setup guide for ChatGPT, Mistral Vibe, Cursor, VS Code / Copilot, Windsurf, and generic stdio.
3. Verify
Ask your AI assistant: "list my fiscal years" — it should call kirjapro_list_fiscal_years and return your company's accounting periods.
4. Try these prompts
A few prompts to feel out the daily workflows the agent handles cleanly:
- "Show my dashboard" — financial snapshot of the current fiscal year
- "Create an invoice for Acme Oy, 5000 € for consulting in March" — full lifecycle from customer lookup to draft invoice
- "Send invoice #42 by email" — server-rendered PDF delivery with an explicit channel
- "Draft a contract for Acme Oy and email it to [email protected], 3-month retainer at 5000 € / month" —
tarjous/sopimuscreate + customer-visible email link - "Record that invoice #42 was paid yesterday" — payment recording + auto status transition
- "What's my VAT for this quarter?" —
kirjapro_get_alv_summarywith OmaVero field codes - "Show overdue invoices" — AR aging report
- "Match this bank deposit to invoice #42" — bank reconciliation in one call
What's included
29 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 55-tool catalog (booking shortcuts, recurring invoices, templates, batch tools, etc.) is available via opt-in:
{
"mcpServers": {
"kirjapro": {
"command": "npx",
"args": ["-y", "@kirjapro/mcp-server"],
"env": {
"KIRJAPRO_API_KEY": "kp_your_key_here",
"KIRJAPRO_MCP_SURFACE": "full" // 55 tools instead of 29
}
}
}
}Why default to 29 instead of 55: large catalogs with overlapping tools cost more context and can make selection harder, but there is no universal tool-count cliff that applies to every model and task. Twenty-seven is a conservative launch default for Kirjapro's daily workflows. Its own usage and error data, not an industry magic number, will determine which deferred tools move into core.
Payroll is intentionally not exposed. Kirjapro does not calculate or book salaries. Direct users to a dedicated payroll service (such as Palkkaus.fi or 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.
| Domain (core) | Tools |
|---|---|
| Read your books | list_fiscal_years, list_accounts, get_dashboard, get_income_statement, get_balance_sheet, get_alv_summary, get_ar_aging |
| Customers | list_customers, get_customer, create_customer, lookup_business (PRH) |
| Invoice lifecycle | list_invoices, get_invoice, create_invoice, send_invoice, record_payment, update_invoice_status |
| Transactions + banking | list_transactions, create_transaction, list_bank_transactions, match_bank_transaction |
| Contracts | create_offer (tarjous / sopimus), send_offer (email link), convert_offer_to_invoice |
| Validators (free) | validate_business_id, validate_iban, generate_reference |
Deferred in core, available with KIRJAPRO_MCP_SURFACE=full: booking shortcuts (book_*), templates, recurring invoices, received invoices, batch tools, delete_*, update_* (besides invoice status), search_transactions, get_transaction, get_general_ledger, list_bank_accounts, get_financial_notes, manual offer status / list / get / delete.
11 resources for reference data: chart of accounts, VAT rates, company info, fiscal years, 5 Finnish compliance resources, compliance freshness index, and security data-handling.
See the full tool reference for parameters, usage examples, and error handling.
Write safety contract
- Every write requires a fresh UUID-v4
idempotencyKey. Reuse that key only for an exact retry of the same tool and arguments. - Writes fail closed if the atomic database claim cannot be confirmed. An
IDEMPOTENCY_OUTCOME_UNKNOWNresponse means the earlier operation may have completed: reconcile with a read tool or the Kirjapro UI and do not invent a new key. - Dry runs have no side effects and are not cached. The two batch tools default
to
dryRun: true;dryRun: falsecommits the complete batch atomically. - Tool responses have a 200 KiB hard context budget. Narrow a range, lower a
limit, or follow the returned cursor if
RESPONSE_BUDGET_EXCEEDEDappears. For writes, the bounded envelope is cached before completion, so the response returned now is also the response replayed by the same key. - Invoice/offer/recurring-document writes accept at most 100 lines. A direct transaction accepts at most 100 journal entries; a transaction batch accepts at most 500 entries across its 50 transactions.
Operational telemetry
Kirjapro records bounded first-party operational metadata by default: company and API-key identifiers, tool/server/client names and versions, timing, outcome class, request/response byte counts, surface, batch/preview flags, idempotency state, and response-budget state. Tool arguments, results, and prompts are never sent, nor are accounting-record identifiers, names, or monetary values. Raw events are deleted after 90 days and application users cannot read them.
Set KIRJAPRO_TELEMETRY=false in the MCP environment to opt out. See the
privacy notice for the complete contract.
Opting out disables metadata delivery only; the 200 KiB local context-safety
limit remains active.
Security
- API keys are hashed with SHA-256; the full key is never stored
- Keys exchange for short-lived JWTs (1 hour) via the
mcp-authedge function; the exchange and guarded write RPCs require write protocol 2 - All queries use Row Level Security (RLS) — users can only access their own company's data
- 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)
- Automatic token refresh keeps long-running sessions alive
- Rate limiting: 10 auth requests per minute per key
- Every write is guarded by a server-owned atomic idempotency claim; direct authenticated access to the replay table is denied
- Write tools advertise
idempotentHint: falsebecause completed replay lasts 24 hours rather than forever; exact retries remain protected inside that documented window - Tool contract fingerprint guard — every tool's
description + annotations + inputSchema + outputSchemais hashed and shipped astool-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.
License
MIT
