{"_id":"@aiwerk/mcp-server-bexio","_rev":"2-c6875fecb3d886da993beec7b2fe4c3c","name":"@aiwerk/mcp-server-bexio","dist-tags":{"latest":"0.1.1"},"versions":{"0.1.0":{"name":"@aiwerk/mcp-server-bexio","version":"0.1.0","keywords":["mcp","mcp-server","bexio","aiwerk","swiss","accounting","invoicing","erp"],"author":{"name":"AIWerk","email":"kontakt@aiwerk.ch"},"license":"MIT","_id":"@aiwerk/mcp-server-bexio@0.1.0","maintainers":[{"name":"agbergsmann","email":"kontakt@aiwerk.ch"}],"homepage":"https://aiwerkmcp.com","bugs":{"url":"https://github.com/AIWerk/mcp-server-bexio/issues"},"bin":{"mcp-server-bexio":"dist/src/server.js"},"dist":{"shasum":"4f3638ce8410f8ac9ecb4a4d51d2147605ee4320","tarball":"https://registry.npmjs.org/@aiwerk/mcp-server-bexio/-/mcp-server-bexio-0.1.0.tgz","fileCount":9,"integrity":"sha512-lISqzuSJExLHuhCjLoPB3PAwLlSdodN5nJ5mrCYtdHmHfB7xZKj8md/Lr2k3FYKpi+gclZBLVhFFpd2FKgP3QA==","signatures":[{"sig":"MEYCIQCmesP7+hBEMWCAQ+E/Zse+nrHudaGxgiyAzxtreaB4zAIhAIEwstglkpvnONViZW/LIs4rFgDr7zxVym2tGK8nzf+3","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":403109},"main":"dist/src/server.js","type":"module","engines":{"node":">=18.0.0"},"gitHead":"bab2eec38c9d7b255f4abbe98e60dc8fdbd017d0","scripts":{"dev":"tsc --watch","test":"vitest run","build":"tsc -p tsconfig.json","smoke":"node scripts/live-smoke.mjs","start":"node dist/src/server.js","predev":"npm run gen-version","pretest":"npm run gen-version && bash -c 'pkill -9 -f \"[n]ode.*vitest\" 2>/dev/null; pkill -9 -f \"[e]sbuild.*--service\" 2>/dev/null; true'","posttest":"bash -c 'pkill -9 -f \"[n]ode.*vitest\" 2>/dev/null; pkill -9 -f \"[e]sbuild.*--service\" 2>/dev/null; true'","prebuild":"npm run gen-version","gen-tools":"node scripts/generate-tools.mjs","gen-naming":"node scripts/gen-naming.mjs spec/bexio-openapi-3.0.0.json spec/bexio-tool-naming.json","gen-version":"node scripts/gen-version.mjs","prepublishOnly":"bash scripts/prepublish-safety.sh && npm run build && npm test"},"_npmUser":{"name":"agbergsmann","email":"kontakt@aiwerk.ch"},"repository":{"url":"git+https://github.com/AIWerk/mcp-server-bexio.git","type":"git"},"_npmVersion":"9.2.0","description":"bexio API MCP server for Swiss SME business software. 310 tools generated from the official OpenAPI specification.","directories":{},"_nodeVersion":"18.19.1","dependencies":{"zod":"^3.25.76","@modelcontextprotocol/sdk":"^1.19.1"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^3.2.1","typescript":"^5.5.0","@types/node":"^22.0.0"},"_npmOperationalInternal":{"tmp":"tmp/mcp-server-bexio_0.1.0_1786296264848_0.5447385151364497","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@aiwerk/mcp-server-bexio","version":"0.1.1","description":"bexio API MCP server for Swiss SME business software. 310 tools generated from the official OpenAPI specification.","type":"module","main":"dist/src/server.js","bin":{"mcp-server-bexio":"dist/src/server.js"},"scripts":{"gen-version":"node scripts/gen-version.mjs","gen-naming":"node scripts/gen-naming.mjs spec/bexio-openapi-3.0.0.json spec/bexio-tool-naming.json","gen-tools":"node scripts/generate-tools.mjs","prebuild":"npm run gen-version","build":"tsc -p tsconfig.json","start":"node dist/src/server.js","predev":"npm run gen-version","dev":"tsc --watch","pretest":"npm run gen-version && bash -c 'pkill -9 -f \"[n]ode.*vitest\" 2>/dev/null; pkill -9 -f \"[e]sbuild.*--service\" 2>/dev/null; true'","test":"vitest run","posttest":"bash -c 'pkill -9 -f \"[n]ode.*vitest\" 2>/dev/null; pkill -9 -f \"[e]sbuild.*--service\" 2>/dev/null; true'","smoke":"node scripts/live-smoke.mjs","prepublishOnly":"bash scripts/prepublish-safety.sh && npm run build && npm test"},"engines":{"node":">=18.0.0"},"keywords":["mcp","mcp-server","bexio","aiwerk","swiss","accounting","invoicing","erp"],"author":{"name":"AIWerk","email":"kontakt@aiwerk.ch"},"license":"MIT","repository":{"type":"git","url":"git+https://github.com/AIWerk/mcp-server-bexio.git"},"homepage":"https://aiwerkmcp.com","bugs":{"url":"https://github.com/AIWerk/mcp-server-bexio/issues"},"publishConfig":{"access":"public"},"dependencies":{"@modelcontextprotocol/sdk":"^1.19.1","zod":"^3.25.76"},"devDependencies":{"@types/node":"^22.0.0","typescript":"^5.5.0","vitest":"^3.2.1"},"gitHead":"63c30b4eff01f9811d412865fca66e740cda242a","_id":"@aiwerk/mcp-server-bexio@0.1.1","_nodeVersion":"18.19.1","_npmVersion":"9.2.0","dist":{"integrity":"sha512-DD49DdApPumqf6Ay+p5jkudImKLwKvej1waYCt3VYBS3/wTgVytDefhyF8xicXV1u4HE3Uhg+UfVtQOAc6/dNg==","shasum":"d41898f0005f95bdd3a5947a1b4ae795466660b6","tarball":"https://registry.npmjs.org/@aiwerk/mcp-server-bexio/-/mcp-server-bexio-0.1.1.tgz","fileCount":9,"unpackedSize":405075,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDXd2THmof5AlGepAtgPaqIoK/JaHFBiBHSo3gEntzEAAiAocVk9QDYd7/2umjunumQAlnY16Wfhx4fkbVhqsWXMqQ=="}]},"_npmUser":{"name":"agbergsmann","email":"kontakt@aiwerk.ch"},"directories":{},"maintainers":[{"name":"agbergsmann","email":"kontakt@aiwerk.ch"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/mcp-server-bexio_0.1.1_1786299011814_0.21184592314399842"},"_hasShrinkwrap":false}},"time":{"created":"2026-08-09T17:24:24.701Z","modified":"2026-08-09T18:10:12.115Z","0.1.0":"2026-08-09T17:24:25.019Z","0.1.1":"2026-08-09T18:10:11.960Z"},"bugs":{"url":"https://github.com/AIWerk/mcp-server-bexio/issues"},"author":{"name":"AIWerk","email":"kontakt@aiwerk.ch"},"license":"MIT","homepage":"https://aiwerkmcp.com","keywords":["mcp","mcp-server","bexio","aiwerk","swiss","accounting","invoicing","erp"],"repository":{"type":"git","url":"git+https://github.com/AIWerk/mcp-server-bexio.git"},"description":"bexio API MCP server for Swiss SME business software. 310 tools generated from the official OpenAPI specification.","maintainers":[{"name":"agbergsmann","email":"kontakt@aiwerk.ch"}],"readme":"# @aiwerk/mcp-server-bexio\n\nMCP server for the [bexio](https://www.bexio.com) API, the Swiss business software for\ninvoicing, accounting, CRM, projects and payroll.\n\n310 tools covering the complete public API surface across all three API versions,\ngenerated from bexio's official OpenAPI 3.0.2 specification.\n\n```\nContacts        Quotes        Invoices       Bills          Projects\nOrders          Deliveries    Payments       Expenses       Timesheets\nItems           Reminders     Banking        Payroll        Files\nAccounting      Taxes         Currencies     Users          Notes\n```\n\n## Why generated\n\nEvery endpoint, HTTP verb, parameter and field name comes from the official\nspecification rather than from prose documentation. Hand written API clients drift:\nthey call routes that do not exist, use the wrong verb, target the wrong API version,\nor advertise fields the server rejects. None of that can be introduced here, because\nnone of it is written by hand.\n\nWhat a specification cannot tell you are the business rules, so the write paths are\nalso exercised against a live account. See [Testing](#testing).\n\n## Install\n\n```bash\nnpm install -g @aiwerk/mcp-server-bexio\n```\n\nRequires Node.js 18 or newer.\n\n## Authentication\n\nThere are two ways in, and which one is appropriate depends on whose account it is.\n\n### OAuth 2.0, for an account you do not own\n\nbexio runs its identity layer on Keycloak with PKCE and refresh tokens. Signing in\ngrants only the permissions the integration asks for, and the authorisation does not\nexpire on a fixed schedule.\n\nThis is the **only appropriate route for a client's account**. It is available through\nthe [AIWerk hosted service](https://aiwerkmcp.com), which owns the authorisation flow\nand the token lifecycle and passes the access token to the server in\n`BEXIO_API_TOKEN`. Running the server standalone with your own OAuth client is\npossible, but you have to refresh the token yourself.\n\n### Personal access token, for your own account\n\nCreate one at [developer.bexio.com/pat](https://developer.bexio.com/pat).\n\n```bash\nexport BEXIO_API_TOKEN=\"your-token\"\n```\n\nTwo things to know:\n\n- It is valid for **60 days** and cannot be renewed, only replaced.\n- It carries **every scope**, so it grants full access to the company data. bexio\n  documents personal access tokens as strictly personal and not to be shared, so do\n  not ask a client for theirs.\n\nThe server accepts either kind of token in the same variable, since both are sent as\na bearer credential.\n\n## Usage\n\n### Claude Code\n\n```bash\nclaude mcp add bexio --env BEXIO_API_TOKEN=your-token -- npx -y @aiwerk/mcp-server-bexio\n```\n\n### Claude Desktop\n\n```json\n{\n  \"mcpServers\": {\n    \"bexio\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"@aiwerk/mcp-server-bexio\"],\n      \"env\": { \"BEXIO_API_TOKEN\": \"your-token\" }\n    }\n  }\n}\n```\n\n### AIWerk hosted service\n\nInstall it from the catalogue at [aiwerkmcp.com](https://aiwerkmcp.com) and add your\ntoken in the interface. No local setup required.\n\n## Safety features\n\nAccounting data is not a good place to find out that a tool did something unexpected,\nso three guards ship by default.\n\n### Dry run\n\n```bash\nexport BEXIO_DRY_RUN=1\n```\n\nEvery write is stopped inside the process and returns a description of the request\nthat would have been sent. Reads still work normally. Useful for letting an agent plan\na change before you allow it to happen.\n\n### Pre write snapshots\n\nBefore modifying or deleting an existing record, the server fetches its current state\nand writes it to `~/.aiwerk/bexio-snapshots/`. The tool result carries the file path in\n`_snapshot`, so the previous state is always recoverable.\n\nSeveral bexio edit endpoints replace the whole record, which means an omitted field\nbecomes empty. The snapshot is what makes that reversible.\n\nIf the snapshot cannot be taken, the write is refused. Set\n`BEXIO_SNAPSHOT_FAIL_OPEN=1` to downgrade that to a warning, or `BEXIO_NO_SNAPSHOT=1`\nto switch snapshots off entirely.\n\n### Rate limit handling\n\nbexio applies a per minute limit per company, and the limit is **not the same for every\nendpoint**. Measured against a live account, the items endpoint allows 400 requests per\nminute while contacts, accounts and currencies allow 1000.\n\nThe server therefore tracks the remaining allowance separately for each endpoint group,\nwaits out short windows, retries on 429 with the reset hint, and fails with a clear\nmessage rather than hanging when the wait would be long.\n\n## Configuration\n\n| Variable | Default | Purpose |\n|---|---|---|\n| `BEXIO_API_TOKEN` | required | Personal access token |\n| `BEXIO_API_BASE_URL` | `https://api.bexio.com` | Override the host, applies to all API versions |\n| `BEXIO_API_TIMEOUT_MS` | `30000` | Per request timeout |\n| `BEXIO_DRY_RUN` | off | `1` blocks all writes |\n| `BEXIO_NO_SNAPSHOT` | off | `1` disables pre write snapshots |\n| `BEXIO_SNAPSHOT_FAIL_OPEN` | off | `1` allows a write when the snapshot fails |\n| `BEXIO_SNAPSHOT_DIR` | `~/.aiwerk/bexio-snapshots` | Where snapshots are written |\n| `BEXIO_MAX_RATE_LIMIT_WAIT_MS` | `10000` | Longest wait before failing on a rate limit |\n| `BEXIO_ENABLED_TAGS` | all | Comma separated domain filter, for example `Contacts,Invoices` |\n\n### Narrowing the tool set\n\nAll 310 tools are registered by default. A client that prefers a smaller surface can\nrestrict the server to specific domains:\n\n```bash\nexport BEXIO_ENABLED_TAGS=\"Contacts,Invoices,Quotes,Items\"\n```\n\nUnknown domain names are reported on startup rather than silently ignored.\n\n## Tool naming\n\nTools follow a predictable shape, so an agent that knows one name can guess the rest:\n\n```\nlist_contacts      get_contact      create_contact\nsearch_contacts    update_contact   delete_contact\n```\n\nCollection verbs (`list_`, `search_`) take a plural noun, single record verbs take a\nsingular one. Document actions keep their own verb: `issue_invoice`, `cancel_invoice`,\n`send_invoice`, `mark_as_sent_invoice`, `revert_issue_quote`.\n\n## A few bexio specifics worth knowing\n\n- **Three API versions coexist.** Contacts, sales documents, items and projects live on\n  2.0, files and expenses on 3.0, bills and banking on 4.0. The server handles this\n  transparently, but it explains why paths look inconsistent in error messages.\n- **Document positions require a tax id.** The specification does not mark `tax_id` as\n  required, yet bexio rejects a position without one. Fetch a valid id with `list_taxes`.\n- **A 403 does not always mean permissions.** bexio also answers 403 when the record's\n  state forbids the operation, for example deleting an invoice that has been issued.\n- **Contacts have no single address field.** Use `street_name`, `house_number`,\n  `postcode` and `city`.\n- **`contact_type_id`** is `1` for a company and `2` for a person.\n\n## Testing\n\n```bash\nnpm test          # unit tests\nnpm run smoke     # read only, against a live account\n```\n\nThe write paths are covered by a separate script that creates and deletes real records,\nso it refuses to run without an explicit confirmation:\n\n```bash\nBEXIO_WRITE_SMOKE=yes node scripts/write-smoke.mjs\n```\n\nPoint it at a throwaway trial account, never at production data. It exercises the full\nlifecycle of contacts, items, invoices and quotes, then cleans up after itself.\n\n## Development\n\nThe tool layer is generated and must not be edited by hand:\n\n```bash\nnpm run gen-naming   # specification  ->  tool names\nnpm run gen-tools    # specification  ->  zod schemas and call sites\nnpm run build\n```\n\n## Licence\n\nMIT, see [LICENSE](LICENSE).\n\nBuilt by [AIWerk](https://aiwerkmcp.com). Not affiliated with bexio AG.\n","readmeFilename":"README.md"}