fortnox-mcp
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@fortnox-mcpshow me all overdue customer invoices and which customers owe us"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
fortnox-mcp
Open-source MCP server for Fortnox, the Swedish accounting system. Ask Claude, ChatGPT, Cursor or any MCP client about your books in plain language: unpaid invoices, the result for the quarter, what you owe suppliers, cash in the bank.
Read-only by default. Write tools are not even registered unless you turn them on.
Reports Fortnox has no endpoint for: income statement, balance sheet, receivables and payables ageing, monthly totals per account. Built from one SIE export per financial year, so they match the books exactly.
The whole API for reading. 24 curated tools, plus
fortnox_getfor any of Fortnox's ~140 other read endpoints (assets, contracts, employees, price lists, warehouse…), checked against an allowlist generated from Fortnox's published OpenAPI document. Nothing that sends, prints or deletes is reachable.Drafts, not actions. With writes enabled, the server can create customers, offers, orders and unbooked, unsent invoice drafts. Every write returns a preview first and needs
confirm: true. Bookkeeping, payments, sending and deleting stay in Fortnox, with a person.Built for Fortnox's quirks: rotating refresh tokens saved before use, a shared refresh for concurrent calls, requests paced under Fortnox's 25-per-5-seconds limit, CP437 SIE decoding.
Built and maintained by Walma. The setup guide is Fortnox MCP on walma.ai.
Tools
Area | Tools |
Company |
|
Customer invoices |
|
Supplier invoices |
|
Registers |
|
Bookkeeping |
|
Reports |
|
Everything else (read) |
|
Writes (opt-in, drafts) |
|
Related MCP server: bokio-mcp
Setup
1. Create a Fortnox app
Sign up as an integration developer at apps.fortnox.se/integration-developer. You get a free test company to try against.
Create an app. Set the redirect URI to
http://localhost:8765/callback.Enable the scopes you need. The default set is
companyinformation bookkeeping invoice customer supplierinvoice supplier article payment settings. Each scope also has to be covered by a licence on the Fortnox account that approves it, so ask only for what you use.Note the client ID and client secret.
2. Connect your company
git clone https://github.com/Walma-Labs/fortnox-mcp.git
cd fortnox-mcp && npm install
FORTNOX_CLIENT_ID=… FORTNOX_CLIENT_SECRET=… node dist/cli.js loginOpen the printed URL, sign in to Fortnox and approve. Tokens are saved to ~/.config/fortnox-mcp/tokens.json (mode 600). The server refreshes them on its own; a connection used at least once every 45 days never needs a new login. node dist/cli.js status shows which company is connected.
3. Add it to your client
Claude Code
claude mcp add fortnox \
-e FORTNOX_CLIENT_ID=… -e FORTNOX_CLIENT_SECRET=… \
-- node /path/to/fortnox-mcp/dist/cli.jsClaude Desktop / Cursor (claude_desktop_config.json, .cursor/mcp.json)
{
"mcpServers": {
"fortnox": {
"command": "node",
"args": ["/path/to/fortnox-mcp/dist/cli.js"],
"env": {
"FORTNOX_CLIENT_ID": "…",
"FORTNOX_CLIENT_SECRET": "…"
}
}
}
}Then ask, for example:
Vilka kundfakturor är förfallna, och hos vilka kunder?
Show the income statement for Q3 compared with Q2.
What did we spend on external services (5000–6999) per month this year?
Hur mycket har vi på företagskontot, och vad ska betalas till leverantörer de närmaste två veckorna?
Configuration
Variable | Meaning |
| From your app in the Developer Portal |
| Default |
| Space-separated scopes requested at login (default above) |
|
|
| Default |
| A ready access token instead of the token file; no refresh |
|
|
HTTP
node dist/http.js serves streamable HTTP (stateless) on PORT (default 8080). With FORTNOX_TOKEN_FROM_HEADER=true each request carries its own token in X-Fortnox-Access-Token, for hosts that run OAuth per customer. The HTTP server has no authentication of its own: put an authenticating gateway in front of it and never expose it publicly.
Safety model
Read tools carry
readOnlyHint; write tools are absent unlessFORTNOX_ENABLE_WRITES=true.Writes return a dry-run preview of the exact request body. The model is instructed to show it and wait for approval before calling again with
confirm: true.A
POSTis never retried after a server error, since Fortnox may already have created the document.fortnox_getonly reaches paths insrc/paths.ts, generated from Fortnox's OpenAPI document byscripts/gen-paths.py, minus endpoints that send (email, e-print, e-invoice), return files, or belong to the bank and developer programmes.Tokens never reach the model; error text is scrubbed of anything that looks like a credential.
Your accounting data goes from Fortnox to the MCP client you use and from there to that client's model provider. If that matters (it usually does for bookkeeping), run the client through a gateway with an EU region and a log. That is what Walma AI Hub does.
Development
npm install
npm test # vitest, no network or credentials needed
npm run buildTo refresh the endpoint allowlist after Fortnox changes its API:
curl -sL https://apps.fortnox.se/apidocs -o /tmp/apidocs.html
python3 scripts/gen-paths.py /tmp/apidocs.html > src/paths.tsStatus
Built from Fortnox's API reference and the patterns of Walma's own production Fortnox integration (OAuth, rotating tokens, SIE). The test suite covers the wire protocol, pagination, the allowlist, token rotation and the reports. Not yet verified end to end against a live Fortnox test company; issues and pull requests are welcome.
Not affiliated with or endorsed by Fortnox AB.
License
MIT © Walma AI AB
Available Tools
26 toolsaccount_totals_by_monthAccount totals by monthARead-onlyIdempotent
Monthly net movement for an account range, e.g. 3000–3999 for revenue per month, 5000–6999 for external costs, 7000–7699 for personnel, 1930–1930 for the business account. Revenue accounts (3xxx+) are sign-flipped so income reads positive.
| Name | Required | Description | Default |
|---|---|---|---|
| to_date | Yes | ||
| from_date | Yes | ||
| account_to | Yes | ||
| account_from | Yes |
balance_sheetBalance sheet (balansräkning)BRead-onlyIdempotent
Assets, equity and liabilities on a date, per account, plus the year's result not yet closed to equity. Cash and bank are the 19xx accounts.
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Default today |
fortnox_getRead any Fortnox endpointARead-onlyIdempotent
GET a Fortnox API path that matches one of the templates from list_endpoints, with {placeholders} filled in, e.g. /3/assets or /3/employees/12. Read-only: nothing that sends, prints or changes data is reachable.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Concrete path, e.g. /3/pricelists/A | |
| query | No | Query parameters, e.g. {"limit": 100} |
get_company_infoCompany, financial years and locked periodARead-onlyIdempotent
Who the connected Fortnox company is (name, org number, address, VAT number), its financial years, and the locked period (the date through which the books are closed). Call this first to orient.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
get_customerGet customerBRead-onlyIdempotent
One customer in full: addresses, terms of payment, VAT type, default references.
| Name | Required | Description | Default |
|---|---|---|---|
| customer_number | Yes |
get_invoiceGet customer invoiceBRead-onlyIdempotent
One customer invoice in full: rows, Net (excl. VAT), VAT, Balance, due date, references, booked/sent state.
| Name | Required | Description | Default |
|---|---|---|---|
| document_number | Yes |
get_supplierGet supplierBRead-onlyIdempotent
One supplier in full, including bank details as registered in Fortnox.
| Name | Required | Description | Default |
|---|---|---|---|
| supplier_number | Yes |
get_supplier_invoiceGet supplier invoiceARead-onlyIdempotent
One supplier invoice in full, with its accounting rows. given_number is Fortnox's own serial number for it.
| Name | Required | Description | Default |
|---|---|---|---|
| given_number | Yes |
get_voucherGet voucherCRead-onlyIdempotent
One voucher with its debit/credit rows.
| Name | Required | Description | Default |
|---|---|---|---|
| number | Yes | ||
| series | Yes | ||
| financial_year | No |
income_statementIncome statement (resultaträkning)ARead-onlyIdempotent
Profit and loss for any date range, grouped by BAS account class with per-account lines: revenue, goods, external costs, personnel, depreciation, financial items, tax. Revenue positive, costs negative. Built from the SIE export, so it matches the books exactly, including manual vouchers.
| Name | Required | Description | Default |
|---|---|---|---|
| to_date | Yes | ||
| from_date | Yes |
list_accountsList accountsBRead-onlyIdempotent
Chart of accounts (kontoplan) for a financial year, with opening (BalanceBroughtForward) and closing (BalanceCarriedForward) balances.
| Name | Required | Description | Default |
|---|---|---|---|
| only_used | No | Skip accounts with zero balances (default true) | |
| financial_year | No | Financial year id from list_financial_years; default the current year |
list_articlesList articlesCRead-onlyIdempotent
Article (product/service) register with prices and stock.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) | |
| filter | No | ||
| description | No |
list_cost_centersList cost centersCRead-onlyIdempotent
Cost centers (kostnadsställen).
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
list_customersList customersCRead-onlyIdempotent
Customer register. Search by name, org number or email.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) | |
| name | No | ||
| No | |||
| filter | No | ||
| organisation_number | No |
list_endpointsList Fortnox read endpointsARead-onlyIdempotent
Search the read-only Fortnox endpoints fortnox_get can call (assets, contracts, employees, salary, time, warehouse, price lists, currencies, …). Returns path templates and summaries.
| Name | Required | Description | Default |
|---|---|---|---|
| search | No | Word to match in the path or summary, e.g. 'asset', 'salary', 'price' |
list_financial_yearsList financial yearsARead-onlyIdempotent
All financial years (räkenskapsår) with id and date range. The id is what SIE and voucher calls take.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
list_invoice_paymentsList customer invoice paymentsBRead-onlyIdempotent
Payments registered against customer invoices (inbetalningar). Optionally for one invoice.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) | |
| invoice_number | No |
list_invoicesList customer invoicesARead-onlyIdempotent
Customer invoices (kundfakturor), newest first unless sorted otherwise. Filter by status (unpaid, unpaidoverdue, fullypaid, unbooked, cancelled), invoice date range and customer. Total includes VAT; Balance is the amount still unpaid according to Fortnox.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) | |
| filter | No | ||
| sort_by | No | ||
| to_date | No | Invoice date to (inclusive) | |
| from_date | No | Invoice date from (inclusive) | |
| sort_order | No | ||
| customer_number | No |
list_offersList offersDRead-onlyIdempotent
Quotes/offers (offerter).
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) | |
| filter | No | ||
| to_date | No | ||
| from_date | No | ||
| customer_number | No |
list_ordersList ordersCRead-onlyIdempotent
Customer orders. Filter invoicenotcreated shows orders not yet invoiced.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) | |
| filter | No | ||
| to_date | No | ||
| from_date | No | ||
| customer_number | No |
list_projectsList projectsCRead-onlyIdempotent
Projects, used to tag invoices, vouchers and costs.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) |
list_supplier_invoicesList supplier invoicesBRead-onlyIdempotent
Supplier invoices (leverantörsfakturor). Filter by status (unpaid, unpaidoverdue, fullypaid, unbooked, cancelled, pendingpayment, authorizepending = awaiting attest), date range and supplier.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) | |
| filter | No | ||
| to_date | No | ||
| from_date | No | ||
| supplier_number | No |
list_suppliersList suppliersCRead-onlyIdempotent
Supplier register.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) |
list_vouchersList vouchersARead-onlyIdempotent
Vouchers (verifikationer) by date range or series. Rows are not included; use get_voucher for one, or the report tools for totals.
| Name | Required | Description | Default |
|---|---|---|---|
| max | No | Max rows to return (default 100, up to 2000) | |
| series | No | Voucher series, e.g. A | |
| to_date | No | ||
| from_date | No | ||
| financial_year | No |
payables_agingAccounts payable ageing (leverantörsreskontra)BRead-onlyIdempotent
Unpaid supplier invoices bucketed by days past due, per supplier, with the most overdue.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | No | Default today |
receivables_agingAccounts receivable ageing (kundreskontra)ARead-onlyIdempotent
Unpaid customer invoices bucketed by days past due (not due, 1–30, 31–60, 61–90, 90+), per customer, with the most overdue invoices.
| Name | Required | Description | Default |
|---|---|---|---|
| as_of | No | Default today |
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
26 tool updates
v0.1.0- First observed
account_totals_by_month - First observed
balance_sheet - First observed
fortnox_get - First observed
get_company_info - First observed
get_customer - First observed
get_invoice - First observed
get_supplier - First observed
get_supplier_invoice - First observed
get_voucher - First observed
income_statement - First observed
list_accounts - First observed
list_articles - First observed
list_cost_centers - First observed
list_customers - First observed
list_endpoints - First observed
list_financial_years - First observed
list_invoice_payments - First observed
list_invoices - First observed
list_offers - First observed
list_orders - First observed
list_projects - First observed
list_supplier_invoices - First observed
list_suppliers - First observed
list_vouchers - First observed
payables_aging - First observed
receivables_aging
TDQS
Scored across 26 tools
Most tools target distinct resources or actions, with clear list-vs-get pairs for invoices, suppliers, customers, vouchers, and supplier invoices. The generic list_endpoints/fortnox_get pair overlaps somewhat with the specific list/get tools, which could cause occasional misselection, but descriptions distinguish their intended use.
The resource tools consistently use snake_case with list_* for collections and get_* for single records, which is predictable. Report tools use noun phrases such as income_statement and balance_sheet, and fortnox_get uses a provider-prefixed verb-last form, creating minor deviations from the dominant pattern.
26 tools is on the heavy side for an MCP server, and the generic fortnox_get tool means some specific list/get tools could be consolidated. However, the broad Fortnox accounting domain legitimately covers many resources, so most tools have a defensible place.
The server provides broad read-only coverage across core accounting resources, including registers, transactions, reports, aging, and a generic read-only endpoint fallback. Some resources lack dedicated get/list tools, but agents can usually work around this via list_endpoints/fortnox_get; write operations are absent but appear intentionally out of scope.
Maintenance
Related MCP Connectors
Fortnox accounting for one company: invoices, reports, ledger, documents. Read-only until enabled.
Headless API-first double-entry accounting & bookkeeping engine. 84 MCP tools over HTTP.
Read Bokio accounts, invoices and customers; create drafts and journal entries.
Fjordova MCP gateway for Fortnox accounting data and tools, with OAuth-based user authorization.
Related MCP Servers
- AlicenseAqualityDmaintenanceAn MCP server for integrating with the Fortnox Swedish accounting system. Enables LLMs to manage invoices, customers, suppliers, orders, accounts, vouchers, and provides business intelligence analytics.5168 npm47MIT
- AlicenseAqualityDmaintenanceEnables MCP clients to read and write Bokio accounting data for one company through 85 tools covering invoices, customers, suppliers, journal entries, chart of accounts, fiscal years, items, tags, uploads, SIE export, and bank payments.4096 npmMIT
- FlicenseNot gradedqualityBmaintenanceExposes Visma e-conomic REST API as 73 MCP tools for managing customers, suppliers, products, invoices, quotes, orders, accounting, and reference data, with secure authentication, allowlist, read-only mode, and audit logging.-

epago MCP Serverofficial
AlicenseNot gradedqualityCmaintenanceEnables MCP-capable clients to read and write directly in epago accounting, including chart of accounts, transactions, invoices, payments, receipts, and tax reports.MIT