TypeScript MCP server exposing 40+ tools for Dolibarr's REST API including third parties, invoices, proposals, orders, products, projects, tasks, users, categories, warehouses, and more. Multi-connection support with interactive setup wizard. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
5.1 KiB
Architecture
Overview
dolibarr-api-mcp is a Model Context Protocol (MCP) server that bridges AI assistants (Claude Code, Cursor, etc.) with Dolibarr's built-in REST API.
AI Assistant <--> MCP (stdio) <--> DolibarrClient <--> Dolibarr REST API
/api/index.php
Components
src/index.ts — Server Entry Point
Registers all MCP tools with the McpServer from @modelcontextprotocol/sdk. Each tool maps to one or more Dolibarr API endpoints. Uses Zod schemas for input validation.
Includes shared helpers:
formatResponse()— normalizes Dolibarr error responses and success payloads into MCP text contentpaginationQuery()— buildslimit,page,sortfield,sortorderquery paramsbuildSqlFilter()— constructs Dolibarr'ssqlfiltersparameter from structured clauses (supports AND/OR joins, proper escaping)searchFilter()— shortcut forLIKE '%term%'filters on a single field
src/client.ts — HTTP Client
The DolibarrClient class handles all HTTP communication with Dolibarr instances:
- Uses
node:https/node:httpfor requests (notfetch) to support self-signed TLS certificates on Node.js 24+ - Authenticates via
DOLAPIKEYheader (Dolibarr's native API key mechanism) - Sends
Accept: application/jsonandContent-Type: application/json - Supports GET, POST, PUT, and DELETE methods
src/config.ts — Configuration Loader
Loads connection details from ~/.dolibarr-api-mcp.json. Supports multiple named connections with a configurable default. Respects the DOLIBARR_API_MCP_CONFIG environment variable for custom config paths.
src/types.ts — Type Definitions
TypeScript interfaces for DolibarrConnection, DolibarrConfig, and ApiResponse.
scripts/setup.mjs — Interactive Setup
Node.js script using readline/promises that walks users through creating the config file. Supports adding multiple connections incrementally.
Design Decisions
Why node:https instead of fetch?
Node.js 24's built-in fetch (undici-based) does not honor NODE_TLS_REJECT_UNAUTHORIZED=0 for self-signed certificate bypass. The classic node:https module with rejectUnauthorized: false works reliably across all Node.js versions.
Why DOLAPIKEY instead of Bearer tokens?
Dolibarr's REST API authenticates via the DOLAPIKEY HTTP header, not OAuth or Bearer tokens. This is Dolibarr's native mechanism — each user has a per-user API key that inherits that user's permissions. There is no token expiration; keys persist until manually regenerated.
Why PUT instead of PATCH?
Dolibarr's API uses PUT for updates (full or partial), not PATCH. The API accepts partial payloads via PUT — only the fields you send are updated.
Why sqlfilters with a builder?
Dolibarr's API supports a custom sqlfilters query parameter that allows server-side filtering with SQL-like expressions (e.g. (t.nom:like:'%acme%')). The buildSqlFilter() helper:
- Handles single-quote escaping to prevent injection
- Supports combining multiple clauses with AND/OR
- Provides
searchFilter()as a concise shortcut for the commonLIKEpattern
Why per-connection API keys?
Each Dolibarr instance requires its own API key scoped to a specific user. Multi-instance support is a core use case — managing staging, production, and dev ERP environments from a single MCP server.
Data Flow
- AI assistant sends a tool call via MCP stdio transport
index.tsvalidates parameters with Zod and resolves the connectionDolibarrClientconstructs the API URL, attaches theDOLAPIKEYheader, and makes the HTTP request- Response is parsed as JSON and returned as MCP tool output
API Module Coverage
| Dolibarr Module | Tools | Endpoints |
|---|---|---|
| Third Parties | 5 | /thirdparties |
| Invoices | 6 | /invoices, /invoices/{id}/lines, /invoices/{id}/validate, /invoices/{id}/settopaid |
| Proposals | 7 | /proposals, /proposals/{id}/lines, /proposals/{id}/validate, /proposals/{id}/close |
| Orders | 4 | /orders, /orders/{id}/validate |
| Products | 5 | /products, /products/{id}/stock |
| Contacts | 2 | /contacts |
| Projects | 3 | /projects |
| Tasks | 2 | /tasks |
| Users | 2 | /users |
| Categories | 1 | /categories |
| Bank Accounts | 1 | /bankaccounts |
| Supplier Invoices | 1 | /supplierinvoices |
| Supplier Orders | 1 | /supplierorders |
| Warehouses | 1 | /warehouses |
| Setup | 2 | /setup/company, /status |
| Generic | 2 | Any endpoint, connection listing |
Revision History
| Date | Version | Author | Notes |
|---|---|---|---|
| 2026-05-07 | 0.0.1 | jmiller | Initial architecture document |