bokio-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., "@bokio-mcplist the last 10 journal entries"
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.
bokio-mcp
Model Context Protocol server for the Bokio accounting API.
Auth: private self-serve Bearer token (single company). No OAuth.
Scope: journal entries, invoices, customers, items, uploads, chart of accounts, fiscal years, SIE export.
Safety: all write operations are blocked unless
BOKIO_ALLOW_WRITES=1.
Built for driving a Swedish AB's books alongside a YNAB budget. Read-only by default so it is safe to point at live accounting data.
Prerequisites
A Bokio private API token: Bokio → Inställningar → API Tokens (free up to 5,000 requests/month).
Your company id — copy it from the Bokio browser URL (
.../companies/<companyId>/...).Node.js ≥ 22.13 and pnpm (
corepack enable).
Related MCP server: sevdesk-mcp
Install & build (local)
git clone https://github.com/diblaze/bokio-mcp.git ~/git/bokio-mcp
cd ~/git/bokio-mcp
pnpm install
pnpm run build # → dist/
pnpm test # mocked unit tests
pnpm run smoke # MCP handshake, asserts tools register
pnpm run lint # biome check (lint + format)Configure in Claude Code
Add to ~/.claude.json under mcpServers (or use claude mcp add):
{
"mcpServers": {
"bokio": {
"command": "node",
"args": ["/home/denis/git/bokio-mcp/dist/index.js"],
"env": {
"BOKIO_TOKEN": "${BOKIO_TOKEN}",
"BOKIO_COMPANY_ID": "your_company_id",
"BOKIO_ALLOW_WRITES": ""
}
}
}
}Leave BOKIO_ALLOW_WRITES empty for read-only. Set it to 1 only when you intend to mutate the books.
Do not hardcode the token in a committed file. Use
${BOKIO_TOKEN}env expansion, matching how the YNAB MCP token is handled.
Environment
Var | Required | Purpose |
| yes (at call time) | Private Bearer token |
| default company | Omit a tool's |
| no |
|
| no | Confines SIE/upload downloads to this dir (rejects path traversal) |
| no | Defaults to |
Tools
Meta: bokio_company_info, bokio_list_fiscal_years, bokio_get_fiscal_year, bokio_chart_of_accounts, bokio_get_account, bokio_download_sie
Journal: bokio_list_journal_entries (from/to/query), bokio_get_journal_entry, bokio_create_journal_entry (write), bokio_reverse_journal_entry (write)
Invoices: bokio_list_invoices, bokio_get_invoice, bokio_create_invoice (write), bokio_update_invoice (write), bokio_delete_invoice (write), bokio_publish_invoice (write), bokio_record_invoice (write), bokio_create_invoice_payment (write)
Customers: bokio_list_customers, bokio_get_customer, bokio_create_customer (write), bokio_update_customer (write)
Items: bokio_list_items, bokio_get_item, bokio_create_item (write), bokio_update_item (write)
Uploads: bokio_list_uploads, bokio_get_upload, bokio_upload_file (write), bokio_download_upload
Escape hatch: bokio_raw_get — GET any Bokio path (read-only).
Notes
Journal entries are double-entry: debit total must equal credit total.
SIE download is great for reconciling the AB ledger against an external budget.
[Preview]Bokio endpoints (supplier-invoices, suppliers, tag-groups) are not yet wrapped; reach them viabokio_raw_get.API reference: https://docs.bokio.se · specs: https://github.com/bokio/bokio-api
Contributing
main is protected — external changes land via pull request.
Fork, branch, commit.
Ensure
pnpm exec biome ci,pnpm run typecheck,pnpm test,pnpm run build, andpnpm run smokeall pass (CI runs the same on Node 22).Open a PR against
main. CI must be green and a maintainer (@diblaze, perCODEOWNERS) must approve before merge.
Toolchain: TypeScript + pnpm, Biome for lint/format, Vitest for tests.
Available Tools
6 toolsbokio_chart_of_accountsBRead-only
Get the chart of accounts (BAS).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-based) | |
| pageSize | No | Items per page | |
| companyId | No | Bokio company id. Defaults to BOKIO_COMPANY_ID if omitted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, which the description aligns with ('get'). The description adds no extra behavioral context beyond what annotations provide, so it meets the baseline but does not exceed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single sentence that conveys the core purpose efficiently. It is appropriately concise for a simple read operation with no complex behavior.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description lacks details about the response format or pagination behavior, which could be inferred from the schema. Given the simplicity of the tool and presence of annotations, it is minimally complete but could benefit from clarifying what the chart of accounts contains or how pagination works.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, with all three parameters documented in the schema. The description does not add any additional meaning or usage guidance for the parameters, so the baseline score of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool retrieves the chart of accounts (BAS). It uses a specific verb and resource, but does not explicitly differentiate from sibling tools like bokio_list_fiscal_years or bokio_list_items. However, the resource name is distinct enough to avoid confusion.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is provided on when to use this tool versus alternatives. The description does not mention context, prerequisites, or scenarios where this tool is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bokio_get_customerBRead-only
Get a customer by id.
| Name | Required | Description | Default |
|---|---|---|---|
| companyId | No | Bokio company id. Defaults to BOKIO_COMPANY_ID if omitted. | |
| customerId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint, so the description adds no behavioral context beyond what is already provided. It does not contradict annotations, but also does not disclose any additional traits (e.g., response format, error handling).
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is very short and front-loaded, with no unnecessary words. However, it could be slightly more informative without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple get-by-id operation, the description is minimally adequate given the annotations and schema. However, it lacks details about return values, error cases, or behavior when the customer does not exist.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Only 50% of parameters have descriptions in the schema (companyId has a description, customerId does not). The description does not add any meaning beyond the schema, such as explaining what the customerId represents or constraints on it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action (Get) and resource (a customer) with a unique identifier (by id). It is specific and distinguishes from sibling tools like bokio_list_items or bokio_get_fiscal_year.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. The description does not mention prerequisites, when not to use it, or how it relates to other customer-related operations (e.g., listing customers).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bokio_get_fiscal_yearARead-only
Get a single fiscal year by id.
| Name | Required | Description | Default |
|---|---|---|---|
| companyId | No | Bokio company id. Defaults to BOKIO_COMPANY_ID if omitted. | |
| fiscalYearId | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true. Description adds no extra behavioral context beyond what annotations provide.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Single sentence, no wasted words. Maximally concise and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-by-id tool with annotations and no output schema, description captures core function. Could mention companyId optionality but schema covers it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50%; description implies fiscalYearId is the identifier but does not detail companyId or format. Adds minimal value over schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Get a single fiscal year by id,' providing a specific verb and resource. It directly distinguishes from sibling 'bokio_list_fiscal_years' which lists multiple.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this vs alternatives. While it's implied for ID-based lookup, no exclusions or context are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bokio_get_itemCRead-only
Get an item by id.
| Name | Required | Description | Default |
|---|---|---|---|
| itemId | Yes | ||
| companyId | No | Bokio company id. Defaults to BOKIO_COMPANY_ID if omitted. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint and openWorldHint. The description adds no behavioral context beyond what annotations provide, such as return format, error handling, or response structure. With annotations present, the description should add value but fails to do so.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise single sentence. It is front-loaded and contains no fluff. However, it may be slightly too brief given the need for parameter guidance, but the structure is appropriate for a simple get-by-id operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given low schema coverage, no output schema, and sibling tools that list items, the description is incomplete. It does not mention that companyId defaults to an environment variable, nor does it describe the returned item object. The simplicity of the tool does not excuse the lack of helpful context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (companyId has description, itemId does not). The description does not explain itemId format or how to obtain it. It adds no semantic value beyond the schema's minimal documentation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'Get an item by id' clearly identifies the action (get) and resource (item) with a specific lookup method (by id). It distinguishes from sibling bokio_list_items, which lists items, making the tool's unique purpose evident.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives. It does not mention that bokio_list_items should be used for listing all items, nor does it specify prerequisites like needing an itemId from a list call first.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bokio_list_fiscal_yearsARead-only
List fiscal years (needed for SIE export ids).
| Name | Required | Description | Default |
|---|---|---|---|
| companyId | No | Bokio company id. Defaults to BOKIO_COMPANY_ID if omitted. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | |
| totalItems | No | |
| totalPages | No | |
| currentPage | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and openWorldHint=true. The description adds context about SIE export IDs but does not disclose additional behavioral traits beyond what annotations provide. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single, well-structured sentence that immediately conveys the action and purpose. Every word is necessary and informative.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple list tool with one optional parameter and existing output schema, the description covers the essential purpose and context (SIE export). No additional information is needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so baseline is 3. The description does not add any detail beyond what the schema provides for the optional 'companyId' parameter.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses verb 'list' specifying the resource 'fiscal years' and explicitly states the purpose 'needed for SIE export ids'. This clearly differentiates it from siblings like 'bokio_get_fiscal_year' which retrieves a single fiscal year.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description hints at the use case (SIE export) but does not explicitly state when to use this tool vs alternatives, nor does it mention when not to use it. No exclusions or alternative tools are mentioned, leaving the agent to infer usage context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
bokio_list_itemsBRead-only
List items (articles).
| Name | Required | Description | Default |
|---|---|---|---|
| page | No | Page number (1-based) | |
| pageSize | No | Items per page | |
| companyId | No | Bokio company id. Defaults to BOKIO_COMPANY_ID if omitted. |
Output Schema
| Name | Required | Description |
|---|---|---|
| items | No | |
| totalItems | No | |
| totalPages | No | |
| currentPage | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations provide readOnlyHint and openWorldHint, covering safety and pagination behavior. The description adds no further behavioral details beyond the schema, so transparency is adequate but not enhanced.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Extremely concise and front-loaded with the core action. No wasted words, but could include a brief note on pagination or defaults without losing conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With output schema present and all input parameters documented, the description is minimally adequate. It misses summarizing pagination or default companyId behavior, but not critically incomplete.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with clear parameter descriptions. The tool description does not add any extra parameter meaning, so baseline of 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the verb 'list' and resource 'items (articles)'. It distinguishes from siblings by implication (bokio_get_item is for a single item), but lacks explicit differentiation, so not a 5.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance on when to use this tool versus alternatives like bokio_get_item. No context on prerequisites or appropriate scenarios.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
6 tool updates
v0.1.0- First observed
bokio_chart_of_accounts - First observed
bokio_get_customer - First observed
bokio_get_fiscal_year - First observed
bokio_get_item - First observed
bokio_list_fiscal_years - First observed
bokio_list_items
TDQS
Scored across 6 tools
Each tool targets a distinct entity or operation: fiscal years (list/get), chart of accounts, customer (get), items (list/get). No overlapping purposes; list/get pairs are clearly distinguished.
Most tools follow a consistent 'bokio_verb_noun' pattern (e.g., list_fiscal_years, get_item). The exception is 'bokio_chart_of_accounts', which lacks a verb, but still clearly conveys its purpose. Overall pattern is mostly predictable.
6 tools is a reasonable size for a focused accounting integration. The set covers core read operations without being too sparse or bloated. Slightly on the low side but appropriate for a read-only subset.
The tool surface is heavily read-only, missing common write operations like creating/updating customers, items, transactions, or generating reports. For a full accounting MCP, these gaps would cause agent failures in most workflows.
Maintenance
Related MCP Connectors
Query and add to your Fibalo bookkeeping: documents, bank transactions, suppliers, access.
Connect Claude or Cursor to books, invoices, bills, payroll, and sealed closes.
Read-only NuMetric.work accounting & ERP data: statements, KPIs, reports, invoices, documents.
Read-only access to your bank, investment, and crypto accounts: balances, transactions, holdings.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceEnables AI agents to read and write Cynco accounting data, including querying books, creating invoices, reconciling transactions, and generating financial reports.4 npm1MIT
- AlicenseNot gradedqualityCmaintenanceEnables interaction with the sevDesk accounting API for managing contacts, invoices, credit notes, orders, vouchers, transactions, and parts.3 npm1MIT
- FlicenseBqualityBmaintenanceConnects AI assistants to Big Red Cloud accounting data, enabling read-only lookups and safe write operations with confirmation drafts.100-
- AlicenseAqualityBmaintenanceConnects AI assistants to the Danish accounting platform Billy (billy.dk) for managing invoices, journal entries, balances, and receipts, with built-in human approval for all write operations.4031 npm1MIT