io.github.Thourum/billy-mcp
Billy (billy.dk) accounting: invoices, journal entries, trial balance, with write protection.
Open source Open in the app JSON README (API)
About
Billy (billy.dk) accounting: invoices, journal entries, trial balance, with write protection.
Details
- Kind
- MCP servers
- Topic
- Finance & crypto
- Publisher
- thourum
- Origin
- official
- Category
- ferramentas
- Transport
- local
- Version
- 0.3.2
- Stars
- 1
- Last push
- 2026-07-10T01:24:18Z
- Repository state
- ativo
- Language
- TypeScript
- License
- MIT
- Added
- 2026-08-29 03:02:17
- Updated
- 2026-08-29 03:02:17
- Origin id
io.github.Thourum/billy-mcp
README
# billy-mcp — Billy (billy.dk) MCP Server for Claude & AI Assistants
**Connect Claude, Cursor, VS Code, and any MCP-compatible AI assistant to [Billy](https://www.billy.dk/) — the Danish accounting platform (billysbilling).** Create invoices, book journal entries, check account balances, reconcile bank lines, and attach receipts — with built-in human-approval write protection so your AI never books anything without your sign-off.
[](https://www.npmjs.com/package/billy-mcp)
[](LICENSE)
[](https://modelcontextprotocol.io)
> Billy accounting · Billy.dk API · Danish bookkeeping (bogføring/regnskab) · AI bookkeeping agent · Model Context Protocol server · Claude Desktop integration
## What can it do?
Ask your AI assistant things like:
- *"Create an invoice for Acme ApS: 10 consulting hours at 1.200 DKK, due in 14 days"*
- *"What's the balance of account 5211 this quarter?"* (trial balance from live postings)
- *"Book last month's payroll as a journal entry — draft it, I'll approve"*
- *"Void these 34 duplicate entries"* (one call, one approval, per-item results)
- *"Upload this receipt PDF and attach it to journal entry #67"*
- *"Which invoices are overdue and unpaid?"*
**40 tools** covering invoices, supplier bills, contacts, products, bank payments, manual journal entries (daybook transactions), postings, trial balance, bank reconciliation, file attachments, a sandboxed batch-scripting tool, and a raw API escape hatch for everything else.
## Quick start
### 1. Get a Billy access token
Log into [mit.billy.dk](https://mit.billy.dk/) → **Settings → Access tokens → Create access token**. Tokens are per-company and don't expire.
### 2. Add to your MCP client
**Claude Desktop** (`claude_desktop_config.json`) / **Cursor** / any JSON-config host:
```json
{
"mcpServers": {
"billy": {
"command": "npx",
"args": ["-y", "billy-mcp"],
"env": {
"BILLY_ACCESS_TOKEN": "<your token>"
}
}
}
}
```
**Claude Code** (CLI):
```sh
claude mcp add billy -e BILLY_ACCESS_TOKEN=<your token> -- npx -y billy-mcp
```
**VS Code** (`.vscode/mcp.json`):
```json
{
"servers": {
"billy": {
"command": "npx",
"args": ["-y", "billy-mcp"],
"env": { "BILLY_ACCESS_TOKEN": "${input:billy-token}" }
}
}
}
```
That's it — no clone, no build. `npx` fetches the published package.
### From source (development)
```sh
git clone https://github.com/thourum/billy-mcp.git
cd billy-mcp
npm install
cp .env.example .env # paste your token
npm run dev # run over stdio
npm run inspector # try tools in the MCP Inspector UI
```
## Write protection — safe for real financial data
Every write (create/update/approve/void/pay/upload) is gated by `BILLY_WRITE_MODE`:
| Mode | Behavior |
| --- | --- |
| `read-only` | Write tools are not registered at all; raw requests reject non-GET |
| `confirm` **(default)** | Each write pauses and shows **you** a native approval dialog (MCP elicitation) with the full payload — the AI cannot approve its own writes |
| `full` | Writes execute without approval |
Fail-closed: if your MCP host doesn't support elicitation dialogs, `confirm` mode **blocks writes** with instructions instead of executing them. Irreversible operations (approve invoice, void entry, bank payments) are additionally flagged `destructiveHint` so hosts can add their own guardrails. Declining, dismissing, or leaving the checkbox unticked = nothing is booked.
## Environment variables
| Variable | Required | Description |
| --- | --- | --- |
| `BILLY_ACCESS_TOKEN` | yes | Billy API access token (sent as `X-Access-Token`) |
| `BILLY_WRITE_MODE` | no | `read-only`, `confirm` (default), or `full` |
| `BILLY_ORGANIZATION_ID` | no | Auto-resolved when the token maps to one company |
| `BILLY_BASE_URL` | no | Defaults to `https://api.billysbilling.com/v2` |
| `BILLY_LOCALE` | no | `en_US`, `da_DK`, `fr_FR`, `nl_NL`, `de_DE` |
## Tools
<details>
<summary><b>Full tool list (40)</b></summary>
**Organization & contacts** — `get_organization`, `list_contacts`, `get_contact`, `create_contact`, `update_contact`, `list_contact_persons`, `create_contact_person`
**Products** — `list_products`, `get_product`, `create_product`, `update_product`
**Invoices** — `list_invoices`, `get_invoice`, `create_invoice` (embedded lines, draft or approve-immediately), `approve_invoice`, `delete_invoice`
**Bills (expenses)** — `list_bills`, `get_bill`, `create_bill`
**Payments** — `create_bank_payment` (mark invoices/bills paid), `list_bank_payments`, `list_balance_modifiers`
**Journal entries (daybook)** — `create_daybook_transaction` (client-side debit/credit balance validation + idempotency-key safe retry), `void_daybook_transaction`, `batch_void_daybook_transactions` (N voids, one approval), `list_daybook_transactions`, `list_daybooks`
**Reporting & reconciliation** — `get_account_balances` (trial balance / per-account balance from postings), `list_postings`, `list_transactions`, `list_accounts`, `get_account`, `list_bank_lines`, `list_bank_line_matches`
**Files & attachments** — `upload_file` (pdf/jpg/png/gif), `attach_file` (link to invoice/bill/journal entry), `list_files`, `list_attachments`
**Power tools** — `execute_script` (sandboxed JS batch runner with server-enforced mutation log + `dry_run`), `billy_raw_request` (any Billy v2 endpoint)
</details>
### Built for LLM agents, not just humans
- **Compact responses by default** (~90% fewer tokens); pass `verbose: true` for full payloads
- **`appliedFilters` transparency**: Billy silently ignores unknown query params — every list tool reports which filters ran server-side vs client-side, so the agent never mistakes "filter ignored" for "no results"
- **Pre-flight validation**: imbalanced journal entries are rejected client-side with per-currency debit/credit totals before an approval is ever requested
- **Idempotent retries**: `idempotencyKey` on journal entries dedupes safely after timeouts
- **Batch with one approval**: `execute_script` runs loops (e.g. 34 voids) with a full audit log returned even when the script fails mid-run
## FAQ
**Is this an official Billy integration?** No — community project using Billy's public REST API v2.
**Does it work with Billy's free plan?** Yes, any account that can create access tokens at mit.billy.dk.
**Can the AI spend my money?** In default `confirm` mode, no write happens without you clicking approve in a dialog the model can't touch. Use `read-only` for pure analysis sessions.
**Which AI apps are supported?** Anything speaking Model Context Protocol over stdio: Claude Desktop, Claude Code, Cursor, Windsurf, VS Code (GitHub Copilot), Zed, and more.
## Development
```sh
npm run typecheck # tsc --noEmit
npm run build # compile to dist/
npm run inspector # interactive tool testing
```
Stack: TypeScript, [MCP TypeScript SDK v2](https://ts.sdk.modelcontextprotocol.io/v2/), Zod v4 schemas. Billy API reference mirrored in [`docs/billy-api.md`](docs/billy-api.md).
## License
[MIT](LICENSE)
---
*Keywords: Billy MCP server, billy.dk API, billysbilling integration, Danish accounting AI, bogføring automatisering, regnskab AI, Claude accounting, MCP accounting server, AI bookkeeping Denmark, fakturering API.*