bexio-mcp
OfficialThis server provides comprehensive access to the bexio Swiss business software API, enabling full management of contacts, sales documents, purchasing, accounting, banking, projects, time tracking, payroll, and more.
Contact Management: Create, update, delete, search, and bulk-manage contacts (companies and persons), contact relations, groups, sectors, and additional addresses.
Sales Documents: Full lifecycle management for quotes, orders, deliveries, and invoices — create, issue, accept/cancel, send via email, copy, convert (e.g., quote to order/invoice), and generate PDFs. Manage line items (custom, article, text, subtotal, discount, pagebreak, subposition), comments, and document settings.
Invoice Payments & Reminders: Record payments on invoices, and create/send payment reminders with PDF generation.
Purchasing: Manage supplier bills, expenses, and purchase orders including status changes, duplication, and outgoing payments (IBAN, QR, manual, cash discount).
Accounting: Access and manage chart of accounts, account groups, business/calendar years, VAT periods, taxes, accounting journal, currencies, exchange rates, and manual accounting entries (with file attachments).
Banking: Read configured bank accounts and manage outgoing bank payments.
Items & Stock: Create, update, delete, and search products/services; read stock locations and areas.
Projects & Time Tracking: Create, update, archive, and search projects; manage planning milestones and work packages; track time entries by project, user, or service.
Files: Upload, download, preview, search, update, and delete files; check where files are attached within bexio.
Payroll: Manage employees and absences; download paystub PDFs.
Master Data: Manage lookup tables — salutations, titles, countries, languages, units, payment types, business activities, and communication types.
Notes & Tasks: Create, read, update, delete, and search notes and tasks/todos linked to contacts or projects.
Users & Permissions: List regular users, manage fictional users, and check permissions.
Company Profile: Read company profile information.
Configuration: Supports OAuth2 and personal access tokens, read-only mode, tool group filtering, language settings, rate limit retries, and streamable HTTP transport for server-side deployment.
Click on "Install 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., "@bexio-mcplist my recent contacts"
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.
bexio-mcp
MCP server and typed TypeScript client for the bexio API — the Swiss business software for contacts, quotes, orders, invoicing, purchasing, accounting, banking, projects, time tracking and payroll.
Complete: covers all 310 documented operations of the bexio API through 35 well-described MCP tools (enforced by a coverage test against the official OpenAPI spec).
Reusable: the typed API client is a standalone entry point (
bexio-mcp/client) with zero MCP dependencies — use it in any Node.js project.Safe: read-only and conservative draft-only write modes, destructive-action annotations, tool-group filtering, and API errors mapped to actionable messages (expired token, missing scope, rate limit) instead of crashes.
Robust: automatic retry on rate limits (honouring
RateLimit-Reset), retries for transient GET failures, request timeouts, typed error hierarchy.
Get started in two minutes
You need:
Node.js 18 or newer — check with
node --versionClaude Code — or choose another MCP client
A bexio Personal Access Token (PAT) from developer.bexio.com/pat
Add the server to Claude Code, replacing YOUR_BEXIO_TOKEN with your PAT:
claude mcp add --env BEXIO_API_TOKEN=YOUR_BEXIO_TOKEN \
--transport stdio bexio -- npx -y github:nolen-ai/bexio-mcpVerify the connection:
claude mcp listThe result should include:
bexio: npx -y github:nolen-ai/bexio-mcp - ✔ ConnectedThe first start downloads and builds the server and can take a few seconds. After that, open Claude Code and try:
List my 10 most recent open invoices in bexio.
No clone or global install is required. Claude Code stores the token in its local MCP configuration and passes it only to the local server process. Do not commit the token to a repository or paste it into prompts.
Start in read-only mode
For a safer first look, use this command instead of the one above. It disables all create, update, send, and delete actions:
claude mcp add \
--env BEXIO_API_TOKEN=YOUR_BEXIO_TOKEN BEXIO_READ_ONLY=true \
--transport stdio bexio -- npx -y github:nolen-ai/bexio-mcpClaude Desktop and other clients
For Claude Desktop, Cursor, VS Code, Windsurf, Gemini CLI, Codex CLI, Pi, n8n, and agent SDKs, use the matching copy-paste integration guide. Every guide uses an installation method that works today.
Related MCP server: mcp-server-smallinvoice
Authentication
Personal Access Token
A Personal Access Token is the fastest option
for personal use. It has the same access as your bexio user and expires after
six months. Configure it as BEXIO_API_TOKEN.
OAuth app workflow
Use OAuth when you need scoped permissions, automatic token refresh, or a long-running deployment:
Create an app at developer.bexio.com and add
http://127.0.0.1:33771/callbackto its Allowed redirect URLs.Reveal the Client ID and Client Secret under App Details.
Authorize once:
BEXIO_CLIENT_ID=YOUR_CLIENT_ID \ BEXIO_CLIENT_SECRET=YOUR_CLIENT_SECRET \ npx -y github:nolen-ai/bexio-mcp loginA browser opens for consent. Tokens are stored in
~/.bexio-mcp/tokens.json; treat this file like a password.Add the server to your MCP client with
BEXIO_CLIENT_IDandBEXIO_CLIENT_SECRETinstead ofBEXIO_API_TOKEN. The server loads the stored token and refreshes it automatically.
Requested scopes are derived from the enabled tool groups and write mode.
Read-only omits separate write scopes; drafts requests only the edit scopes
needed for its allowlist. Override them with BEXIO_SCOPES or --scopes.
Use the full GitHub command with whoami to verify the authenticated bexio
user, or logout to revoke and remove the stored tokens:
BEXIO_CLIENT_ID=YOUR_CLIENT_ID BEXIO_CLIENT_SECRET=YOUR_CLIENT_SECRET \
npx -y github:nolen-ai/bexio-mcp whoamiTroubleshooting
Claude reports Failed to reconnect … -32000
Make sure the configured command includes the GitHub package specifier. The
short form npx -y bexio-mcp does not work until this project is published on
the npm registry.
Reset an incorrect Claude Code entry with:
claude mcp remove bexio
claude mcp add --env BEXIO_API_TOKEN=YOUR_BEXIO_TOKEN \
--transport stdio bexio -- npx -y github:nolen-ai/bexio-mcp
claude mcp listCheck the server outside your MCP client
This command should print 35 tools and exit:
BEXIO_API_TOKEN=YOUR_BEXIO_TOKEN \
npx -y github:nolen-ai/bexio-mcp --list-toolsThen verify that bexio accepts the token:
BEXIO_API_TOKEN=YOUR_BEXIO_TOKEN \
npx -y github:nolen-ai/bexio-mcp whoamiIf tool listing fails, check node --version is 18 or newer and read the error
printed by npx. If whoami returns 401, create a new PAT and update the token
in your MCP client.
Configuration
Environment variable | CLI flag | Description |
|
| Static token (PAT or OAuth access token). Wins over the app workflow. |
|
| OAuth app client id (app workflow). |
|
| OAuth app client secret (app workflow). |
|
| Scopes for |
|
| Loopback redirect URI (default |
|
| OAuth token file (default |
|
|
|
|
| Comma-separated groups to enable (default: all). See groups below. |
|
| Write policy: |
|
| Compatibility alias that forces |
|
|
|
|
| API host override (default |
|
| Per-request timeout in milliseconds (default 30000). |
Add these variables to your MCP client's env block or --env options. Run
npx -y github:nolen-ai/bexio-mcp --help for every CLI option.
Write modes
Use BEXIO_WRITE_MODE to choose the server-side write policy:
read-onlydisables every write.draftspermits contact create/update, contact-relation create/delete, draft-quote create/update, and custom-position changes on unissued draft quotes. Inline quote positions must also be custom positions. It blocks contact/quote deletion, issue/send/accept/decline, all order/invoice writes, and every other business mutation.fullexposes every operation allowed by the token (the default for backward compatibility).
BEXIO_API_TOKEN=YOUR_BEXIO_TOKEN BEXIO_WRITE_MODE=drafts \
npx -y github:nolen-ai/bexio-mcp --list-toolsPolicy-disabled actions are removed from the advertised action enums and are
also rejected server-side without touching the API. In read-only and
drafts, save_path is blocked because it writes to the server filesystem;
omit it to return a PDF inline.
BEXIO_READ_ONLY=true and --read-only remain supported as aliases for
read-only.
Tool groups
contacts, sales, purchase, accounting, banking, items, projects, files, payroll, misc
BEXIO_API_TOKEN=YOUR_BEXIO_TOKEN BEXIO_TOOL_GROUPS=contacts,sales,items \
npx -y github:nolen-ai/bexio-mcp --list-toolsTools
Tools are grouped per resource with an action argument; each tool's description documents every action and its required arguments.
Group | Tools |
contacts |
|
sales |
|
purchase |
|
accounting |
|
banking |
|
items |
|
projects |
|
files |
|
payroll |
|
misc |
|
Highlights:
Full document lifecycle: create → issue → send/mark-as-sent → payments/reminders → PDF, for quotes, orders, deliveries and invoices — including converting quotes to orders/invoices and orders to deliveries/invoices.
All seven position types (item, custom, text, subtotal, discount, pagebreak, sub-position) on quotes, orders and invoices via one generic
bexio_document_positionstool.PDF and file downloads accept a
save_pathargument so large documents go to disk instead of the context window.Legacy search endpoints take
search_criteria:[{ "field": "name_1", "value": "Muster", "criteria": "like" }], combined with AND.
Server-side & Docker
Use the published Docker image when your MCP client cannot start a local stdio server, or when several clients need the same deployment.
Start the server:
docker run -d --name bexio-mcp -p 8722:8722 \
ghcr.io/nolen-ai/bexio-mcp:latestCheck it:
curl http://127.0.0.1:8722/healthzThe MCP endpoint is http://127.0.0.1:8722/mcp. In this default multi-user
mode, each client sends its own bexio token as
Authorization: Bearer YOUR_BEXIO_TOKEN. Follow the relevant
integration guide for the exact client config.
HTTP authentication modes
Multi-user (pass-through): don't configure any server credentials. Every client sends its own
Authorization: Bearer <bexio PAT or OAuth access token>header; each MCP session acts as that user against bexio, and nothing is stored server-side. Sessions without a token are rejected with 401.Shared identity (single-tenant): configure
BEXIO_API_TOKENor the app credentials — then sessions without their own bearer use the server's identity. This grants unauthenticated, full access to that bexio account to anyone who can reach the port. On non-loopback binds (including Docker) it therefore stays off until you explicitly setBEXIO_HTTP_SHARED_IDENTITY=true; publish the port to loopback or a private network only (-p 127.0.0.1:8722:8722).
For a local, single-account deployment with a PAT:
docker run -d --name bexio-mcp \
-p 127.0.0.1:8722:8722 \
-e BEXIO_API_TOKEN=YOUR_BEXIO_TOKEN \
-e BEXIO_HTTP_SHARED_IDENTITY=true \
ghcr.io/nolen-ai/bexio-mcp:latestDo not expose shared-identity mode to an untrusted network: anyone who can reach it can use the configured bexio account.
Long-running OAuth deployment
Obtain a refresh token once with the OAuth app workflow, then seed the container. The server refreshes and persists rotated tokens in the named volume:
docker run -d --name bexio-mcp \
-p 127.0.0.1:8722:8722 \
-v bexio-tokens:/data \
-e BEXIO_CLIENT_ID=YOUR_CLIENT_ID \
-e BEXIO_CLIENT_SECRET=YOUR_CLIENT_SECRET \
-e BEXIO_REFRESH_TOKEN=YOUR_REFRESH_TOKEN \
-e BEXIO_HTTP_SHARED_IDENTITY=true \
ghcr.io/nolen-ai/bexio-mcp:latestFor remote deployments, terminate TLS in a reverse proxy: bearer tokens must
not cross networks over plain HTTP. Behind a proxy, list its public hostname in
BEXIO_HTTP_ALLOWED_HOSTS. Environment variables are visible through
docker inspect; use your platform's secret mechanism in production.
Environment variable | CLI flag | Description |
|
| Bind address (default |
|
| Port (default |
|
| Endpoint path (default |
|
| Opt-in: anonymous sessions may use the server identity on non-loopback binds (unauthenticated account access — see above). |
|
| Max concurrent MCP sessions (default 64). |
|
| Accepted |
|
| Headless bootstrap: seed the token store from a refresh token. |
Using the client without MCP
Install directly from GitHub:
npm install github:nolen-ai/bexio-mcpThe typed client is dependency-free (uses global fetch) and importable on its
own:
import { BexioClient } from 'bexio-mcp/client';
const bexio = new BexioClient({
token: process.env.BEXIO_API_TOKEN!, // string or async () => string
language: 'de',
});The OAuth building blocks are exported too — BexioOAuth (authorization URL with PKCE, code exchange, refresh with rotation) and OAuthTokenProvider (auto-refreshing token source) from bexio-mcp/client, plus FileTokenStore and runLoginFlow from bexio-mcp:
import { BexioClient, BexioOAuth, OAuthTokenProvider } from 'bexio-mcp/client';
import { FileTokenStore } from 'bexio-mcp';
const oauth = new BexioOAuth({ clientId, clientSecret });
const provider = new OAuthTokenProvider(oauth, new FileTokenStore());
const bexio = new BexioClient({ token: provider.accessTokenProvider() });
// Typed resource APIs mirroring the bexio docs
const contacts = await bexio.contacts.search([{ field: 'name_1', value: 'Muster' }]);
const invoice = await bexio.invoices.createInvoice({ contact_id: contacts[0]!.id, positions: [/* … */] });
await bexio.invoices.issueInvoice(invoice.id);
// Escape hatch for anything else
const me = await bexio.http.get('/3.0/users/me');Errors are typed: BexioApiError (with status, errorCode, body, plus isAuthError/isPermissionError/isNotFound/isRateLimit), BexioRateLimitError, BexioNetworkError, BexioConfigError.
Embedding the server in your own process:
import { BexioClient, createBexioMcpServer } from 'bexio-mcp';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
const server = createBexioMcpServer({
client: new BexioClient({ token: myToken }),
groups: ['contacts', 'sales'],
writeMode: 'drafts',
});
await server.connect(new StdioServerTransport());Development
npm install
npm run typecheck # tsc --noEmit
npm test # vitest (includes the API coverage gate)
npm run build # tsup → dist/ (ESM + CJS + d.ts)With just: just check runs the full gate, just docker-build builds the image.
Releasing
Releases are tag-driven: pushing vX.Y.Z triggers the release workflow, which verifies the tag against package.json, runs the full gate, pushes the multi-arch Docker image to ghcr.io/nolen-ai/bexio-mcp (latest, X.Y, X.Y.Z), creates the GitHub release with generated notes, and publishes to npm when the NPM_TOKEN secret is configured.
just bump minor # bump package.json + src/version.ts, commit "Release vX.Y.Z"
git push # let CI pass on main
just tag # tag vX.Y.Z (verifies clean tree, main, pushed, version sync) and push itSee docs/ARCHITECTURE.md for the layering and module conventions. The API surface is pinned in tests/fixtures/operations.json (extracted from the official docs); tests/coverage.test.ts fails when bexio documents operations this package does not cover.
Notes & limitations
The bexio API rate limit is per company; heavy parallel use of tools can hit 429s — the client waits and retries automatically.
bexio deletes are permanent (no trash). Destructive tool actions are annotated and blocked in read-only mode, but be deliberate.
Credit notes and a handful of business processes are not exposed by the bexio API itself (see their FAQ).
This is an unofficial project; not affiliated with bexio AG.
License
MIT
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Servers
- Alicense-qualityAmaintenanceComplete Swiss accounting integration for Bexio via MCP. Works with Claude Desktop, n8n, and any MCP client. 221 tools for invoices, contacts, projects & more. Created by Lukas Hertig.Last updated26MIT
- AlicenseBqualityCmaintenanceMCP server for smallinvoice.ch — Swiss SME invoicing and accounting with 146 tools and OAuth2 BYOC authentication.Last updated10030MIT
- AlicenseBqualityDmaintenanceAn MCP server for interacting with the Swiss Commercial Register via Zefix REST API and UID Webservice, enabling company search, validation, SOGC publications, and due diligence reports.Last updated94MIT
- AlicenseBqualityDmaintenanceAn MCP server that enables LLMs to interact with Moxie CRM. Provides comprehensive tools for managing clients, contacts, projects, invoices, time tracking, and more.Last updated30212MIT
Related MCP Connectors
MCP server exposing the Backtest360 engine API as tools for AI agents.
34 production API tools over one hosted MCP endpoint.
Markdown-first MCP server for Notion API with 8 composite tools and 39 actions.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/nolen-ai/bexio-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server