Skip to main content
Glama
AxLabs

Banana Accounting MCP Server

by AxLabs
README.md
# Banana Accounting MCP Server

A [Model Context Protocol](https://modelcontextprotocol.io) (MCP) server, written in
TypeScript, that exposes the **Banana Accounting Plus
[Integrated Web Server](https://www.banana.ch/doc/en/node/4867) API V2** to LLMs. Point
your MCP-capable client (Claude Desktop, Cursor, etc.) at this server and the model can
read your accounts, balances, journals, reports and VAT data — and create new accounting
files — directly from your locally running Banana Accounting instance.

Every documented endpoint from the
[API V2 Get Data](https://www.banana.ch/doc10/en/node/10022) and
[Send Data](https://www.banana.ch/doc10/en/node/9841) references is exposed as a dedicated
tool. See the [full tool reference](#tool-reference) below.

> The Banana Integrated Web Server is **read-only for existing files** — for security it
> cannot modify an open accounting file. The only write operation it offers is creating a
> *new* file (which Banana opens for you to review). This server mirrors that capability
> faithfully.

## Requirements

- **Node.js >= 18** (uses the built-in global `fetch`).
- **Banana Accounting Plus 10.1.7+** with the **Advanced plan** (the
  [Web Server feature](https://www.banana.ch/doc/en/node/4867) requires it).
- The [Integrated Web Server](https://www.banana.ch/doc/en/node/4867) enabled and reachable
  (see below).

## Enabling the Banana Web Server

1. In Banana Accounting Plus: **Tools → Program Options → General**, check
   **Start Web Server** (on macOS also **Start Web Server with SSL** — see the
   [macOS setup guide](https://www.banana.ch/doc/en/node/10029)).
2. Edit `httpconfig.ini` and set an `accessToken` under the `[Banana]` section, and set
   `accessControlAllowOrigin=*` (see [Web Server security](https://www.banana.ch/doc/en/node/4867)).
   To locate the file: **Tools → Program Options → Advanced → System info → Web Server →
   Settings file path → Open path**.
3. Restart Banana Accounting Plus.

Default base URLs:

| Platform | Base URL |
| --- | --- |
| Windows (plain HTTP) | `http://127.0.0.1:8081` |
| macOS (SSL)          | `https://127.0.0.1:8089` |

Authentication uses the `X-Banana-Access-Token` HTTP header. A wrong/missing token returns
`401 unauthorized`.

See the official docs: [Integrated Web Server](https://www.banana.ch/doc/en/node/4867),
[Setup (macOS)](https://www.banana.ch/doc/en/node/10029),
[API V2 Get Data](https://www.banana.ch/doc10/en/node/10022), and
[API V2 Send Data](https://www.banana.ch/doc10/en/node/9841).

## Installation

The published package is [`@axlabs/banana-mcp-server`](https://www.npmjs.com/package/@axlabs/banana-mcp-server).
You usually don't need to install it explicitly — MCP clients can run it on demand with
`npx`:

```bash
npx -y @axlabs/banana-mcp-server
```

Or install it globally to get the `banana-mcp-server` command:

```bash
npm install -g @axlabs/banana-mcp-server
banana-mcp-server
```

To build from source instead:

```bash
npm install
npm run build
```

## Configuration

The server is configured entirely through environment variables:

| Variable | Default | Description |
| --- | --- | --- |
| `BANANA_BASE_URL` | `http://127.0.0.1:8081` | Base URL of the Banana web server (no trailing slash). |
| `BANANA_ACCESS_TOKEN` | _(empty)_ | Access token from `httpconfig.ini`. Sent as `X-Banana-Access-Token`. |
| `BANANA_DEFAULT_DOC` | _(none)_ | Optional default document name so tools can omit the `doc` argument. |
| `BANANA_TIMEOUT_MS` | `30000` | Per-request timeout in milliseconds. |
| `BANANA_INSECURE_TLS` | `false` | Set to `true` to accept the self-signed certificate used by the macOS SSL server. |

Copy `.env.example` to get started.

## Usage

### As a standalone command

```bash
BANANA_BASE_URL="http://127.0.0.1:8081" \
BANANA_ACCESS_TOKEN="my-super-secret-access-token" \
npx -y @axlabs/banana-mcp-server
```

(Or `node dist/index.js` when running from a local build.) The server speaks MCP over
**stdio**. Diagnostic output goes to `stderr` so it never corrupts the JSON-RPC stream on
`stdout`.

### Claude Desktop / Cursor configuration

Add an entry to your MCP client config (e.g. Claude Desktop's
`claude_desktop_config.json`, or `.cursor/mcp.json`):

```json
{
  "mcpServers": {
    "banana": {
      "command": "npx",
      "args": ["-y", "@axlabs/banana-mcp-server"],
      "env": {
        "BANANA_BASE_URL": "http://127.0.0.1:8081",
        "BANANA_ACCESS_TOKEN": "my-super-secret-access-token"
      }
    }
  }
}
```

> Prefer a pinned version in production, e.g. `"@axlabs/banana-mcp-server@0.1.0"`. To run a
> local build instead, use `"command": "node"` with
> `"args": ["/absolute/path/to/banana-mcp-server/dist/index.js"]`.

> On macOS with the SSL web server, use `https://127.0.0.1:8089` and add
> `"BANANA_INSECURE_TLS": "true"` (or trust the `banana.localhost` certificate in
> Keychain Access).

## How an LLM should use it

1. Call **`banana_list_documents`** to discover the open accounting files.
2. Pass the returned file name (e.g. `accounting.ac2`) as the **`doc`** argument to other
   tools — or set `BANANA_DEFAULT_DOC` and omit it.
3. Use the read tools to answer questions, and `banana_create_document` to create new
   files.

[Conventions](https://www.banana.ch/doc/en/node/4867) used throughout the API: dates are
ISO 8601 (`YYYY-MM-DD`), decimals use a dot separator with no thousands separator (see the
"Data formats" section of the docs), and previous-year files are addressed by suffixing
the document name with `_p1`, `_p2`, etc. Many `period` arguments accept abbreviations
like `Q1`, `3M`, `1Y` or explicit ranges like `2024-01-01/2024-03-31`.

## Tool reference

All tools are namespaced with the `banana_` prefix. Reads default to JSON output where the
API supports it. The read tools map to the
[API V2 Get Data](https://www.banana.ch/doc10/en/node/10022) reference; the file-creation
tools map to the [API V2 Send Data](https://www.banana.ch/doc10/en/node/9841) reference.

### Application & discovery

| Tool | Endpoint | Description |
| --- | --- | --- |
| `banana_application` | `/v2/application[/{value}]` | App info (version, serial, OS); optionally a single field. |
| `banana_application_version` | `/v2/application/version` | Application version string. |
| `banana_list_documents` | `/v2/docs` | List open accounting documents. |
| `banana_document_requests` | `/v2/doc/{doc}` | List available requests for a document (HTML). |
| `banana_table_names` | `/v2/doc/{doc}/tablenames` | List the tables in a document. |

### Tables

| Tool | Endpoint | Description |
| --- | --- | --- |
| `banana_table` | `/v2/doc/{doc}/table/{table}` | Read a table (view/columns/format). |
| `banana_table_rowcount` | `.../rowcount` | Number of rows in a table. |
| `banana_table_columns` | `.../columnnames` | Column XML names of a table. |
| `banana_cell` | `.../row/{row}/column/{col}` | A single cell value (row number or `Account=1000`). |
| `banana_rowlist_names` | `.../rowlistnames` | Named row lists of a table. |
| `banana_rowlist` | `.../rowlist/{name}` | Read a named row list. |
| `banana_rowlist_rowcount` | `.../rowlist/{name}/rowcount` | Row count of a row list. |
| `banana_rowlist_cell` | `.../rowlist/{name}/row/{row}/column/{col}` | A cell within a row list. |

### Chart of accounts

| Tool | Endpoint | Description |
| --- | --- | --- |
| `banana_accounts` | `/v2/doc/{doc}/accounts` | List accounts. |
| `banana_account_description` | `/v2/doc/{doc}/accountdescription/{acc\|Gr=id}[/{col}]` | Account/group description. |
| `banana_groups` | `/v2/doc/{doc}/groups` | List groups. |
| `banana_segments` | `/v2/doc/{doc}/segments` | List segments. |
| `banana_vatcodes` | `/v2/doc/{doc}/vatcodes` | List VAT codes. |
| `banana_vat_description` | `/v2/doc/{doc}/vatdescription/{code}[/{col}]` | VAT code description. |

### Balances, budget, interest & projection

| Tool | Endpoint | Description |
| --- | --- | --- |
| `banana_balance` | `/v2/doc/{doc}/balance/{acc}/{type}` | Current balance figure. |
| `banana_budget` | `/v2/doc/{doc}/budget/{acc}/{type}` | Budget figure. |
| `banana_interest` | `/v2/doc/{doc}/interest/{acc}` | Calculated interest (requires `rate`). |
| `banana_budget_interest` | `/v2/doc/{doc}/budgetinterest/{acc}` | Interest on budget transactions. |
| `banana_projection` | `/v2/doc/{doc}/projection/{acc}/{type}` | Projection figure (requires `projectionstart`). |
| `banana_vat_balance` | `/v2/doc/{doc}/vatbalance/{code}/{type}` | Current VAT balance. |
| `banana_vat_budget` | `/v2/doc/{doc}/vatbudget/{code}/{type}` | Budget VAT figure. |
| `banana_vat_projection` | `/v2/doc/{doc}/vatprojection/{code}/{type}` | VAT projection (requires `projectionstart`). |

`{type}` is one of `opening`, `credit`, `debit`, `total`, `balance`,
`openingcurrency`, `creditcurrency`, `debitcurrency`, `totalcurrency`,
`balancecurrency`, `rowcount`. VAT types are `taxable`, `amount`, `notdeductible`,
`posted`, `rowcount`. The `{acc}` selector accepts an account id, `Gr=<group>`,
`BClass=<class>`, or pipe-separated accounts like `1000|1010`.

### Account cards (ledgers)

| Tool | Endpoint | Description |
| --- | --- | --- |
| `banana_account_card` | `/v2/doc/{doc}/accountcard/{acc}` | Transactions making up an account. |
| `banana_budget_card` | `/v2/doc/{doc}/budgetcard/{acc}` | Budget transactions for an account. |
| `banana_projection_card` | `/v2/doc/{doc}/projectioncard/{acc}` | Projection card (requires `projectionstart`). |
| `banana_vat_card` | `/v2/doc/{doc}/vatcard/{code}` | Account card for a VAT code. |

### Reports & document metadata

| Tool | Endpoint | Description |
| --- | --- | --- |
| `banana_accounting_report` | `/v2/doc/{doc}/accreport` | Accounting report (with `subdivision`). |
| `banana_vat_report` | `/v2/doc/{doc}/vatreport` | VAT report. |
| `banana_journal` | `/v2/doc/{doc}/journal` | Journal of all transactions. |
| `banana_start_period` | `/v2/doc/{doc}/startperiod` | Start date of accounting/period. |
| `banana_end_period` | `/v2/doc/{doc}/endPeriod` | End date of accounting/period. |
| `banana_info_table` | `/v2/doc/{doc}/info` | File info table. |
| `banana_info_value` | `/v2/doc/{doc}/info/{section}/{id}` | A single file-info value. |
| `banana_infos` | `/v2/doc/{doc}/infos` | All file infos as JSON. |
| `banana_messages` | `/v2/doc/{doc}/messages` | Validation/error messages (`recheck`). |
| `banana_messages_count` | `/v2/doc/{doc}/messages/count` | Count of error messages. |

### Web-app data & system

| Tool | Endpoint | Description |
| --- | --- | --- |
| `banana_appdata_get` | `GET /v2/appdata/{id}` | Read stored web-app data. |
| `banana_appdata_put` | `PUT /v2/appdata/{id}` | Save web-app data. |
| `banana_appdata_delete` | `DELETE /v2/appdata/{id}` | Delete web-app data. |
| `banana_appdata_form` | `/v2/appdataform` | HTML form to manage app data. |
| `banana_settings` | `/v2/settings` | Web server settings page. |
| `banana_help` | `/v2/help` | Web server help page. |
| `banana_file` | `/v2/files/{name}` | Read a file from the user data folder. |
| `banana_run_script` | `/v2/script` | Execute a Banana JavaScript file. |
| `banana_www_app` | `/v2/doc/{doc}/apps/{name}` | Built-in WWW app (`charts`, `dashboard`). |
| `banana_api_js` | `/v2/doc/{doc}/bananaapiv2.js` | The JavaScript API helper file. |

### Creating files ([Send Data](https://www.banana.ch/doc10/en/node/9841))

| Tool | Endpoint | Description |
| --- | --- | --- |
| `banana_create_document` | `POST /v2/doc?show` | Create & show a new file from a high-level list of per-table row changes. |
| `banana_create_document_raw` | `POST /v2/doc?show` | Post a raw `{ fileType, data }` payload (escape hatch). |

`banana_create_document` accepts either an `accountingType`
(`{ docGroup, docApp, decimals }` — e.g. `docGroup: 100` double entry, `docApp: 100`
without VAT / `110` with VAT) or an `ac2_base64` template plus a `title`, and a `tables`
array describing the rows to `add` / `modify` / `delete`. Internally it builds a Banana
[`DocumentChange`](https://www.banana.ch/doc10/en/node/9841) envelope (see also
[Modify Data](https://www.banana.ch/doc/en/node/10161) and the
[Excel Office Script example](https://www.banana.ch/doc10/en/node/10154)).

## Development

```bash
npm run dev        # run from source with watch (tsx)
npm run typecheck  # tsc --noEmit
npm run lint       # eslint
npm test           # vitest (unit + in-memory MCP integration tests)
npm run build      # compile to dist/
```

Tests run fully offline against a mocked `fetch` and an in-memory MCP transport, so they
do not require a running Banana instance.

### Publishing (maintainers)

The package is published to npm as the public scoped package
`@axlabs/banana-mcp-server`. `prepublishOnly` compiles the TypeScript to `dist/` first.

```bash
npm version <patch|minor|major>
npm publish            # access:public is set via publishConfig
```

## Project layout

```
src/
  index.ts          # stdio entry point
  server.ts         # builds the McpServer and registers tools
  config.ts         # environment configuration
  client.ts         # HTTP client for the Banana web server
  types.ts          # DocumentChange types + builder
  tools/            # one module per API area, all registered via tools/index.ts
test/               # vitest suites
```

## License

Apache License 2.0 © [AxLabs](https://axlabs.com). See [LICENSE](./LICENSE) and
[NOTICE](./NOTICE).

TDQS

A3.5/5.0

Scored across 53 tools

Disambiguation4/5

Most tools have clearly distinct purposes, such as table vs. rowlist operations and various financial figures. However, there are some overlapping utilities like banana_infos, banana_info_table, and banana_info_value, which could cause confusion. Overall, descriptions help clarify boundaries.

Naming Consistency5/5

All tool names start with the 'banana_' prefix and use underscores consistently. The naming follows a resource-oriented hierarchy (e.g., banana_vat_balance, banana_table_rowcount), making it predictable and easy to navigate.

Tool Count2/5

With 53 tools, the server is heavily over the typical range for an MCP server. While the accounting domain is broad, many tools are highly specialized or could be consolidated, and the count feels excessive for most use cases.

Completeness4/5

The server provides comprehensive read access to accounting data, including tables, financial figures, reports, and documents, plus document creation. Minor gaps exist, such as lacking update/delete operations for accounting data (aside from appdata) and some discovery endpoints, but these are acceptable for a read-heavy API.

Maintenance

ActivityInactive
ResponsivenessUnresponsive