@energio/holded-mcp 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1040 -0
- package/dist/constants.d.ts +60 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +72 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +11 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +86 -0
- package/dist/index.js.map +1 -0
- package/dist/schemas/accounting/account-balances.d.ts +19 -0
- package/dist/schemas/accounting/account-balances.d.ts.map +1 -0
- package/dist/schemas/accounting/account-balances.js +28 -0
- package/dist/schemas/accounting/account-balances.js.map +1 -0
- package/dist/schemas/accounting/accounts.d.ts +49 -0
- package/dist/schemas/accounting/accounts.d.ts.map +1 -0
- package/dist/schemas/accounting/accounts.js +50 -0
- package/dist/schemas/accounting/accounts.js.map +1 -0
- package/dist/schemas/accounting/daily-ledger.d.ts +45 -0
- package/dist/schemas/accounting/daily-ledger.d.ts.map +1 -0
- package/dist/schemas/accounting/daily-ledger.js +57 -0
- package/dist/schemas/accounting/daily-ledger.js.map +1 -0
- package/dist/schemas/common.d.ts +118 -0
- package/dist/schemas/common.d.ts.map +1 -0
- package/dist/schemas/common.js +126 -0
- package/dist/schemas/common.js.map +1 -0
- package/dist/schemas/crm/bookings.d.ts +108 -0
- package/dist/schemas/crm/bookings.d.ts.map +1 -0
- package/dist/schemas/crm/bookings.js +96 -0
- package/dist/schemas/crm/bookings.js.map +1 -0
- package/dist/schemas/crm/events.d.ts +57 -0
- package/dist/schemas/crm/events.d.ts.map +1 -0
- package/dist/schemas/crm/events.js +53 -0
- package/dist/schemas/crm/events.js.map +1 -0
- package/dist/schemas/crm/funnels.d.ts +60 -0
- package/dist/schemas/crm/funnels.d.ts.map +1 -0
- package/dist/schemas/crm/funnels.js +48 -0
- package/dist/schemas/crm/funnels.js.map +1 -0
- package/dist/schemas/crm/leads.d.ts +146 -0
- package/dist/schemas/crm/leads.d.ts.map +1 -0
- package/dist/schemas/crm/leads.js +129 -0
- package/dist/schemas/crm/leads.js.map +1 -0
- package/dist/schemas/invoicing/contacts.d.ts +352 -0
- package/dist/schemas/invoicing/contacts.d.ts.map +1 -0
- package/dist/schemas/invoicing/contacts.js +187 -0
- package/dist/schemas/invoicing/contacts.js.map +1 -0
- package/dist/schemas/invoicing/documents.d.ts +424 -0
- package/dist/schemas/invoicing/documents.d.ts.map +1 -0
- package/dist/schemas/invoicing/documents.js +217 -0
- package/dist/schemas/invoicing/documents.js.map +1 -0
- package/dist/schemas/invoicing/expenses-accounts.d.ts +47 -0
- package/dist/schemas/invoicing/expenses-accounts.d.ts.map +1 -0
- package/dist/schemas/invoicing/expenses-accounts.js +43 -0
- package/dist/schemas/invoicing/expenses-accounts.js.map +1 -0
- package/dist/schemas/invoicing/numbering-series.d.ts +94 -0
- package/dist/schemas/invoicing/numbering-series.d.ts.map +1 -0
- package/dist/schemas/invoicing/numbering-series.js +43 -0
- package/dist/schemas/invoicing/numbering-series.js.map +1 -0
- package/dist/schemas/invoicing/payments.d.ts +50 -0
- package/dist/schemas/invoicing/payments.d.ts.map +1 -0
- package/dist/schemas/invoicing/payments.js +46 -0
- package/dist/schemas/invoicing/payments.js.map +1 -0
- package/dist/schemas/invoicing/products.d.ts +176 -0
- package/dist/schemas/invoicing/products.d.ts.map +1 -0
- package/dist/schemas/invoicing/products.js +149 -0
- package/dist/schemas/invoicing/products.js.map +1 -0
- package/dist/schemas/invoicing/remittances.d.ts +21 -0
- package/dist/schemas/invoicing/remittances.d.ts.map +1 -0
- package/dist/schemas/invoicing/remittances.js +20 -0
- package/dist/schemas/invoicing/remittances.js.map +1 -0
- package/dist/schemas/invoicing/sales-channels.d.ts +45 -0
- package/dist/schemas/invoicing/sales-channels.d.ts.map +1 -0
- package/dist/schemas/invoicing/sales-channels.js +41 -0
- package/dist/schemas/invoicing/sales-channels.js.map +1 -0
- package/dist/schemas/invoicing/services.d.ts +55 -0
- package/dist/schemas/invoicing/services.d.ts.map +1 -0
- package/dist/schemas/invoicing/services.js +51 -0
- package/dist/schemas/invoicing/services.js.map +1 -0
- package/dist/schemas/invoicing/taxes.d.ts +12 -0
- package/dist/schemas/invoicing/taxes.d.ts.map +1 -0
- package/dist/schemas/invoicing/taxes.js +12 -0
- package/dist/schemas/invoicing/taxes.js.map +1 -0
- package/dist/schemas/invoicing/treasury.d.ts +42 -0
- package/dist/schemas/invoicing/treasury.d.ts.map +1 -0
- package/dist/schemas/invoicing/treasury.js +39 -0
- package/dist/schemas/invoicing/treasury.js.map +1 -0
- package/dist/schemas/invoicing/warehouses.d.ts +61 -0
- package/dist/schemas/invoicing/warehouses.d.ts.map +1 -0
- package/dist/schemas/invoicing/warehouses.js +43 -0
- package/dist/schemas/invoicing/warehouses.js.map +1 -0
- package/dist/schemas/projects/projects.d.ts +60 -0
- package/dist/schemas/projects/projects.d.ts.map +1 -0
- package/dist/schemas/projects/projects.js +55 -0
- package/dist/schemas/projects/projects.js.map +1 -0
- package/dist/schemas/projects/tasks.d.ts +68 -0
- package/dist/schemas/projects/tasks.d.ts.map +1 -0
- package/dist/schemas/projects/tasks.js +64 -0
- package/dist/schemas/projects/tasks.js.map +1 -0
- package/dist/schemas/projects/time-tracking.d.ts +80 -0
- package/dist/schemas/projects/time-tracking.d.ts.map +1 -0
- package/dist/schemas/projects/time-tracking.js +75 -0
- package/dist/schemas/projects/time-tracking.js.map +1 -0
- package/dist/schemas/team/employees.d.ts +135 -0
- package/dist/schemas/team/employees.d.ts.map +1 -0
- package/dist/schemas/team/employees.js +144 -0
- package/dist/schemas/team/employees.js.map +1 -0
- package/dist/schemas/team/time-tracking.d.ts +98 -0
- package/dist/schemas/team/time-tracking.d.ts.map +1 -0
- package/dist/schemas/team/time-tracking.js +89 -0
- package/dist/schemas/team/time-tracking.js.map +1 -0
- package/dist/services/api.d.ts +118 -0
- package/dist/services/api.d.ts.map +1 -0
- package/dist/services/api.js +441 -0
- package/dist/services/api.js.map +1 -0
- package/dist/tools/accounting/account-balances.d.ts +44 -0
- package/dist/tools/accounting/account-balances.d.ts.map +1 -0
- package/dist/tools/accounting/account-balances.js +240 -0
- package/dist/tools/accounting/account-balances.js.map +1 -0
- package/dist/tools/accounting/accounts.d.ts +18 -0
- package/dist/tools/accounting/accounts.d.ts.map +1 -0
- package/dist/tools/accounting/accounts.js +131 -0
- package/dist/tools/accounting/accounts.js.map +1 -0
- package/dist/tools/accounting/daily-ledger.d.ts +9 -0
- package/dist/tools/accounting/daily-ledger.d.ts.map +1 -0
- package/dist/tools/accounting/daily-ledger.js +117 -0
- package/dist/tools/accounting/daily-ledger.js.map +1 -0
- package/dist/tools/accounting/index.d.ts +9 -0
- package/dist/tools/accounting/index.d.ts.map +1 -0
- package/dist/tools/accounting/index.js +15 -0
- package/dist/tools/accounting/index.js.map +1 -0
- package/dist/tools/crm/bookings.d.ts +18 -0
- package/dist/tools/crm/bookings.d.ts.map +1 -0
- package/dist/tools/crm/bookings.js +272 -0
- package/dist/tools/crm/bookings.js.map +1 -0
- package/dist/tools/crm/events.d.ts +18 -0
- package/dist/tools/crm/events.d.ts.map +1 -0
- package/dist/tools/crm/events.js +134 -0
- package/dist/tools/crm/events.js.map +1 -0
- package/dist/tools/crm/funnels.d.ts +18 -0
- package/dist/tools/crm/funnels.d.ts.map +1 -0
- package/dist/tools/crm/funnels.js +113 -0
- package/dist/tools/crm/funnels.js.map +1 -0
- package/dist/tools/crm/index.d.ts +9 -0
- package/dist/tools/crm/index.d.ts.map +1 -0
- package/dist/tools/crm/index.js +17 -0
- package/dist/tools/crm/index.js.map +1 -0
- package/dist/tools/crm/leads.d.ts +18 -0
- package/dist/tools/crm/leads.d.ts.map +1 -0
- package/dist/tools/crm/leads.js +519 -0
- package/dist/tools/crm/leads.js.map +1 -0
- package/dist/tools/factory.d.ts +55 -0
- package/dist/tools/factory.d.ts.map +1 -0
- package/dist/tools/factory.js +145 -0
- package/dist/tools/factory.js.map +1 -0
- package/dist/tools/invoicing/contacts.d.ts +26 -0
- package/dist/tools/invoicing/contacts.d.ts.map +1 -0
- package/dist/tools/invoicing/contacts.js +358 -0
- package/dist/tools/invoicing/contacts.js.map +1 -0
- package/dist/tools/invoicing/documents.d.ts +18 -0
- package/dist/tools/invoicing/documents.d.ts.map +1 -0
- package/dist/tools/invoicing/documents.js +578 -0
- package/dist/tools/invoicing/documents.js.map +1 -0
- package/dist/tools/invoicing/expenses-accounts.d.ts +25 -0
- package/dist/tools/invoicing/expenses-accounts.d.ts.map +1 -0
- package/dist/tools/invoicing/expenses-accounts.js +111 -0
- package/dist/tools/invoicing/expenses-accounts.js.map +1 -0
- package/dist/tools/invoicing/index.d.ts +9 -0
- package/dist/tools/invoicing/index.d.ts.map +1 -0
- package/dist/tools/invoicing/index.js +33 -0
- package/dist/tools/invoicing/index.js.map +1 -0
- package/dist/tools/invoicing/numbering-series.d.ts +9 -0
- package/dist/tools/invoicing/numbering-series.d.ts.map +1 -0
- package/dist/tools/invoicing/numbering-series.js +161 -0
- package/dist/tools/invoicing/numbering-series.js.map +1 -0
- package/dist/tools/invoicing/payments.d.ts +18 -0
- package/dist/tools/invoicing/payments.d.ts.map +1 -0
- package/dist/tools/invoicing/payments.js +175 -0
- package/dist/tools/invoicing/payments.js.map +1 -0
- package/dist/tools/invoicing/products.d.ts +18 -0
- package/dist/tools/invoicing/products.d.ts.map +1 -0
- package/dist/tools/invoicing/products.js +389 -0
- package/dist/tools/invoicing/products.js.map +1 -0
- package/dist/tools/invoicing/remittances.d.ts +17 -0
- package/dist/tools/invoicing/remittances.d.ts.map +1 -0
- package/dist/tools/invoicing/remittances.js +76 -0
- package/dist/tools/invoicing/remittances.js.map +1 -0
- package/dist/tools/invoicing/sales-channels.d.ts +24 -0
- package/dist/tools/invoicing/sales-channels.d.ts.map +1 -0
- package/dist/tools/invoicing/sales-channels.js +105 -0
- package/dist/tools/invoicing/sales-channels.js.map +1 -0
- package/dist/tools/invoicing/services.d.ts +29 -0
- package/dist/tools/invoicing/services.d.ts.map +1 -0
- package/dist/tools/invoicing/services.js +124 -0
- package/dist/tools/invoicing/services.js.map +1 -0
- package/dist/tools/invoicing/taxes.d.ts +18 -0
- package/dist/tools/invoicing/taxes.d.ts.map +1 -0
- package/dist/tools/invoicing/taxes.js +58 -0
- package/dist/tools/invoicing/taxes.js.map +1 -0
- package/dist/tools/invoicing/treasury.d.ts +9 -0
- package/dist/tools/invoicing/treasury.d.ts.map +1 -0
- package/dist/tools/invoicing/treasury.js +196 -0
- package/dist/tools/invoicing/treasury.js.map +1 -0
- package/dist/tools/invoicing/warehouses.d.ts +18 -0
- package/dist/tools/invoicing/warehouses.d.ts.map +1 -0
- package/dist/tools/invoicing/warehouses.js +133 -0
- package/dist/tools/invoicing/warehouses.js.map +1 -0
- package/dist/tools/projects/index.d.ts +9 -0
- package/dist/tools/projects/index.d.ts.map +1 -0
- package/dist/tools/projects/index.js +15 -0
- package/dist/tools/projects/index.js.map +1 -0
- package/dist/tools/projects/projects.d.ts +18 -0
- package/dist/tools/projects/projects.d.ts.map +1 -0
- package/dist/tools/projects/projects.js +203 -0
- package/dist/tools/projects/projects.js.map +1 -0
- package/dist/tools/projects/tasks.d.ts +18 -0
- package/dist/tools/projects/tasks.d.ts.map +1 -0
- package/dist/tools/projects/tasks.js +154 -0
- package/dist/tools/projects/tasks.js.map +1 -0
- package/dist/tools/projects/time-tracking.d.ts +14 -0
- package/dist/tools/projects/time-tracking.d.ts.map +1 -0
- package/dist/tools/projects/time-tracking.js +291 -0
- package/dist/tools/projects/time-tracking.js.map +1 -0
- package/dist/tools/team/employees.d.ts +18 -0
- package/dist/tools/team/employees.d.ts.map +1 -0
- package/dist/tools/team/employees.js +149 -0
- package/dist/tools/team/employees.js.map +1 -0
- package/dist/tools/team/index.d.ts +9 -0
- package/dist/tools/team/index.d.ts.map +1 -0
- package/dist/tools/team/index.js +13 -0
- package/dist/tools/team/index.js.map +1 -0
- package/dist/tools/team/time-tracking.d.ts +18 -0
- package/dist/tools/team/time-tracking.d.ts.map +1 -0
- package/dist/tools/team/time-tracking.js +398 -0
- package/dist/tools/team/time-tracking.js.map +1 -0
- package/dist/tools/utilities.d.ts +45 -0
- package/dist/tools/utilities.d.ts.map +1 -0
- package/dist/tools/utilities.js +55 -0
- package/dist/tools/utilities.js.map +1 -0
- package/dist/types.d.ts +640 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +29 -0
- package/dist/types.js.map +1 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,1040 @@
|
|
|
1
|
+
# Holded MCP Server
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@energio/holded-mcp)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://github.com/energio-es/holded-mcp/actions/workflows/ci.yml)
|
|
6
|
+
[](package.json)
|
|
7
|
+
|
|
8
|
+
A Model Context Protocol (MCP) server for integrating with the Holded API. This server provides comprehensive access to Holded's business management platform, including invoicing, accounting, CRM, projects, and team functionality.
|
|
9
|
+
|
|
10
|
+
## Table of Contents
|
|
11
|
+
|
|
12
|
+
- [Features](#features)
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Configuration](#configuration)
|
|
15
|
+
- [Usage](#usage)
|
|
16
|
+
- [Available Tools](#available-tools)
|
|
17
|
+
- [Document Types](#document-types)
|
|
18
|
+
- [Response Formats](#response-formats)
|
|
19
|
+
- [Error Handling](#error-handling)
|
|
20
|
+
- [Performance](#performance)
|
|
21
|
+
- [Development](#development)
|
|
22
|
+
- [Contributing](#contributing)
|
|
23
|
+
- [License](#license)
|
|
24
|
+
- [Support](#support)
|
|
25
|
+
|
|
26
|
+
## Features
|
|
27
|
+
|
|
28
|
+
### Invoicing Module
|
|
29
|
+
- **Documents**: Full CRUD operations for documents (invoices, estimates, purchases, etc.) plus pay, send, PDF export, tracking, and pipeline management
|
|
30
|
+
- **Contacts**: Full CRUD operations for contacts and contact groups
|
|
31
|
+
- **Products**: Manage products, variants, and stock levels
|
|
32
|
+
- **Payments**: Full CRUD operations for payments
|
|
33
|
+
- **Numbering Series**: Full CRUD operations for document numbering series
|
|
34
|
+
- **Treasury**: Create, list, and retrieve treasury/bank accounts
|
|
35
|
+
- **Payment Methods**: List available payment methods
|
|
36
|
+
- **Expenses Accounts**: Full CRUD operations for expenses accounts
|
|
37
|
+
- **Sales Channels**: Full CRUD operations for sales channels
|
|
38
|
+
- **Services**: Full CRUD operations for services
|
|
39
|
+
- **Taxes**: Get tax information and rates
|
|
40
|
+
- **Warehouses**: Full CRUD operations for warehouses
|
|
41
|
+
|
|
42
|
+
### CRM Module
|
|
43
|
+
- **Leads**: Create, list, get, update, delete leads; manage stages, notes, and tasks
|
|
44
|
+
- **Funnels**: Full CRUD operations for sales funnels with custom stages
|
|
45
|
+
- **Events**: Full CRUD operations for CRM events
|
|
46
|
+
- **Bookings**: Full CRUD operations for bookings and manage locations
|
|
47
|
+
|
|
48
|
+
### Projects Module
|
|
49
|
+
- **Projects**: Full CRUD operations for projects plus project summaries
|
|
50
|
+
- **Tasks**: Full CRUD operations for project tasks
|
|
51
|
+
- **Time Tracking**: Full CRUD operations for project time tracking entries
|
|
52
|
+
|
|
53
|
+
### Accounting Module
|
|
54
|
+
- **Accounts**: List and create accounting accounts with prefix-based numbering
|
|
55
|
+
- **Daily Ledger**: List daily ledger entries and create accounting entries
|
|
56
|
+
|
|
57
|
+
### Team Module
|
|
58
|
+
- **Employees**: Full CRUD operations for employees
|
|
59
|
+
- **Time Tracking**: List all time trackings, list by employee, get, create, update, and delete time tracking entries
|
|
60
|
+
|
|
61
|
+
## Installation
|
|
62
|
+
|
|
63
|
+
### Prerequisites
|
|
64
|
+
|
|
65
|
+
1. **Node.js** >= 20 (check with `node --version`)
|
|
66
|
+
2. **Holded API Key** - Get yours from [Holded API Settings](https://app.holded.com/api) or go to Configuration (top bar) → API
|
|
67
|
+
|
|
68
|
+
### Quick Start (npx)
|
|
69
|
+
|
|
70
|
+
The easiest way to use this MCP server is via `npx` - no installation or build required! Just configure your MCP client as shown below.
|
|
71
|
+
|
|
72
|
+
### Setup for Claude Desktop
|
|
73
|
+
|
|
74
|
+
Add the following to your Claude Desktop configuration file:
|
|
75
|
+
|
|
76
|
+
- **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
77
|
+
- **Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
78
|
+
|
|
79
|
+
```json
|
|
80
|
+
{
|
|
81
|
+
"mcpServers": {
|
|
82
|
+
"holded": {
|
|
83
|
+
"command": "npx",
|
|
84
|
+
"args": ["-y", "@energio/holded-mcp"],
|
|
85
|
+
"env": {
|
|
86
|
+
"HOLDED_API_KEY": "your_api_key_here"
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Restart Claude Desktop to load the server.
|
|
94
|
+
|
|
95
|
+
### Setup for Claude Code
|
|
96
|
+
|
|
97
|
+
Add the server with a single command:
|
|
98
|
+
|
|
99
|
+
```bash
|
|
100
|
+
claude mcp add holded -- npx -y @energio/holded-mcp
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Then set the API key in your environment:
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
export HOLDED_API_KEY=your_api_key_here
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### Setup for Cursor
|
|
110
|
+
|
|
111
|
+
Add the following to your Cursor MCP settings file:
|
|
112
|
+
|
|
113
|
+
- **macOS**: `~/.cursor/mcp.json`
|
|
114
|
+
- **Windows**: `%APPDATA%\Cursor\mcp.json`
|
|
115
|
+
- **Linux**: `~/.config/cursor/mcp.json`
|
|
116
|
+
|
|
117
|
+
```json
|
|
118
|
+
{
|
|
119
|
+
"mcpServers": {
|
|
120
|
+
"holded": {
|
|
121
|
+
"command": "npx",
|
|
122
|
+
"args": ["-y", "@energio/holded-mcp"],
|
|
123
|
+
"env": {
|
|
124
|
+
"HOLDED_API_KEY": "your_api_key_here"
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
After saving, restart Cursor or reload the MCP servers from the settings.
|
|
132
|
+
|
|
133
|
+
### Setup for VS Code
|
|
134
|
+
|
|
135
|
+
Add the following to your VS Code user settings (`settings.json`) or workspace settings (`.vscode/mcp.json`):
|
|
136
|
+
|
|
137
|
+
**User settings (`settings.json`):**
|
|
138
|
+
|
|
139
|
+
```json
|
|
140
|
+
{
|
|
141
|
+
"mcp": {
|
|
142
|
+
"servers": {
|
|
143
|
+
"holded": {
|
|
144
|
+
"command": "npx",
|
|
145
|
+
"args": ["-y", "@energio/holded-mcp"],
|
|
146
|
+
"env": {
|
|
147
|
+
"HOLDED_API_KEY": "your_api_key_here"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Workspace settings (`.vscode/mcp.json`):**
|
|
156
|
+
|
|
157
|
+
```json
|
|
158
|
+
{
|
|
159
|
+
"servers": {
|
|
160
|
+
"holded": {
|
|
161
|
+
"command": "npx",
|
|
162
|
+
"args": ["-y", "@energio/holded-mcp"],
|
|
163
|
+
"env": {
|
|
164
|
+
"HOLDED_API_KEY": "your_api_key_here"
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### Setup for Windsurf
|
|
172
|
+
|
|
173
|
+
Add the following to your Windsurf MCP configuration file:
|
|
174
|
+
|
|
175
|
+
- **macOS**: `~/.codeium/windsurf/mcp_config.json`
|
|
176
|
+
- **Windows**: `%APPDATA%\Codeium\windsurf\mcp_config.json`
|
|
177
|
+
- **Linux**: `~/.codeium/windsurf/mcp_config.json`
|
|
178
|
+
|
|
179
|
+
```json
|
|
180
|
+
{
|
|
181
|
+
"mcpServers": {
|
|
182
|
+
"holded": {
|
|
183
|
+
"command": "npx",
|
|
184
|
+
"args": ["-y", "@energio/holded-mcp"],
|
|
185
|
+
"env": {
|
|
186
|
+
"HOLDED_API_KEY": "your_api_key_here"
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
### Setup for Other MCP-Compatible Agents
|
|
194
|
+
|
|
195
|
+
Any MCP-compatible agent can use this server via npx. The general configuration requires:
|
|
196
|
+
|
|
197
|
+
1. **Command**: `npx`
|
|
198
|
+
2. **Arguments**: `["-y", "@energio/holded-mcp"]`
|
|
199
|
+
3. **Environment variable**: `HOLDED_API_KEY` with your API key
|
|
200
|
+
|
|
201
|
+
Example configuration:
|
|
202
|
+
|
|
203
|
+
```json
|
|
204
|
+
{
|
|
205
|
+
"mcpServers": {
|
|
206
|
+
"holded": {
|
|
207
|
+
"command": "npx",
|
|
208
|
+
"args": ["-y", "@energio/holded-mcp"],
|
|
209
|
+
"env": {
|
|
210
|
+
"HOLDED_API_KEY": "your_api_key_here"
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
```
|
|
216
|
+
|
|
217
|
+
The server communicates via stdio using the MCP protocol and can be integrated with any client that supports the [Model Context Protocol](https://modelcontextprotocol.io/).
|
|
218
|
+
|
|
219
|
+
## Configuration
|
|
220
|
+
|
|
221
|
+
The server requires a `HOLDED_API_KEY` environment variable. This is typically set in your MCP client configuration (see installation sections above).
|
|
222
|
+
|
|
223
|
+
For manual/development usage, you can set it directly:
|
|
224
|
+
|
|
225
|
+
```bash
|
|
226
|
+
export HOLDED_API_KEY=your_api_key_here
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Module Selection
|
|
230
|
+
|
|
231
|
+
By default, all modules are enabled. To load only specific modules, set the `HOLDED_MODULES` environment variable with a comma-separated list:
|
|
232
|
+
|
|
233
|
+
**Available modules**: `invoicing`, `crm`, `projects`, `accounting`, `team`
|
|
234
|
+
|
|
235
|
+
Example - enable only invoicing module:
|
|
236
|
+
|
|
237
|
+
```json
|
|
238
|
+
{
|
|
239
|
+
"mcpServers": {
|
|
240
|
+
"holded": {
|
|
241
|
+
"command": "npx",
|
|
242
|
+
"args": ["-y", "@energio/holded-mcp"],
|
|
243
|
+
"env": {
|
|
244
|
+
"HOLDED_API_KEY": "your_api_key_here",
|
|
245
|
+
"HOLDED_MODULES": "invoicing"
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Configuration examples**:
|
|
253
|
+
|
|
254
|
+
- **All modules (default)**: Omit `HOLDED_MODULES` or leave it empty
|
|
255
|
+
- **Only CRM**: `"HOLDED_MODULES": "crm"`
|
|
256
|
+
- **Only invoicing**: `"HOLDED_MODULES": "invoicing"`
|
|
257
|
+
- **Multiple modules**: `"HOLDED_MODULES": "invoicing,crm"`
|
|
258
|
+
|
|
259
|
+
### Debug Mode
|
|
260
|
+
|
|
261
|
+
Enable debug logging for API requests and retries by setting the `HOLDED_DEBUG` environment variable:
|
|
262
|
+
|
|
263
|
+
```json
|
|
264
|
+
{
|
|
265
|
+
"mcpServers": {
|
|
266
|
+
"holded": {
|
|
267
|
+
"command": "npx",
|
|
268
|
+
"args": ["-y", "@energio/holded-mcp"],
|
|
269
|
+
"env": {
|
|
270
|
+
"HOLDED_API_KEY": "your_api_key_here",
|
|
271
|
+
"HOLDED_DEBUG": "true"
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
When enabled, the server will log retry attempts and API request failures to stderr, which can be helpful for troubleshooting connection issues or rate limiting.
|
|
279
|
+
|
|
280
|
+
## Usage
|
|
281
|
+
|
|
282
|
+
### Running the Server Manually
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
npm start
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
Or for development with auto-reload:
|
|
289
|
+
|
|
290
|
+
```bash
|
|
291
|
+
npm run dev
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
**Note**: In most cases, you won't run the server manually. Your MCP client (Cursor, Claude Desktop, etc.) will start and manage the server process automatically based on your configuration.
|
|
295
|
+
|
|
296
|
+
## Available Tools
|
|
297
|
+
|
|
298
|
+
### Contact Tools
|
|
299
|
+
- `holded_invoicing_list_contacts` - List all contacts
|
|
300
|
+
- `holded_invoicing_get_contact` - Get a specific contact
|
|
301
|
+
- `holded_invoicing_create_contact` - Create a new contact
|
|
302
|
+
- `holded_invoicing_update_contact` - Update a contact
|
|
303
|
+
- `holded_invoicing_delete_contact` - Delete a contact
|
|
304
|
+
- `holded_invoicing_list_contact_groups` - List contact groups
|
|
305
|
+
- `holded_invoicing_get_contact_group` - Get a contact group
|
|
306
|
+
- `holded_invoicing_create_contact_group` - Create a contact group
|
|
307
|
+
- `holded_invoicing_update_contact_group` - Update a contact group
|
|
308
|
+
- `holded_invoicing_delete_contact_group` - Delete a contact group
|
|
309
|
+
- `holded_invoicing_list_contact_attachments` - List attachments for a contact
|
|
310
|
+
- `holded_invoicing_get_contact_attachment` - Get a specific contact attachment
|
|
311
|
+
- `holded_invoicing_upload_contact_attachment` - Upload an attachment to a contact
|
|
312
|
+
|
|
313
|
+
### Product Tools
|
|
314
|
+
- `holded_invoicing_list_products` - List all products
|
|
315
|
+
- `holded_invoicing_get_product` - Get a specific product
|
|
316
|
+
- `holded_invoicing_create_product` - Create a new product
|
|
317
|
+
- `holded_invoicing_update_product` - Update a product
|
|
318
|
+
- `holded_invoicing_delete_product` - Delete a product
|
|
319
|
+
- `holded_invoicing_list_products_stock` - List product stock levels for a specific warehouse
|
|
320
|
+
- `holded_invoicing_update_product_stock` - Update product stock
|
|
321
|
+
- `holded_invoicing_get_product_image` - Get main product image
|
|
322
|
+
- `holded_invoicing_list_product_images` - List all product images
|
|
323
|
+
- `holded_invoicing_get_product_secondary_image` - Get a secondary product image
|
|
324
|
+
- `holded_invoicing_upload_product_image` - Upload an image to a product
|
|
325
|
+
|
|
326
|
+
### Document Tools
|
|
327
|
+
- `holded_invoicing_list_documents` - List documents by type
|
|
328
|
+
- `holded_invoicing_get_document` - Get a specific document
|
|
329
|
+
- `holded_invoicing_create_document` - Create a new document
|
|
330
|
+
- `holded_invoicing_update_document` - Update a document
|
|
331
|
+
- `holded_invoicing_delete_document` - Delete a document
|
|
332
|
+
- `holded_invoicing_pay_document` - Record a payment for a document
|
|
333
|
+
- `holded_invoicing_send_document` - Send a document via email
|
|
334
|
+
- `holded_invoicing_get_document_pdf` - Get PDF version of a document
|
|
335
|
+
- `holded_invoicing_update_document_tracking` - Update document tracking info
|
|
336
|
+
- `holded_invoicing_update_document_pipeline` - Update document pipeline stage
|
|
337
|
+
- `holded_invoicing_ship_all_items` - Ship all items from a sales order
|
|
338
|
+
- `holded_invoicing_ship_items_by_line` - Ship specific items by line from a sales order
|
|
339
|
+
- `holded_invoicing_get_shipped_items` - Get shipped items for a document
|
|
340
|
+
- `holded_invoicing_attach_document_file` - Attach a file to a document
|
|
341
|
+
|
|
342
|
+
### Payment & Treasury Tools
|
|
343
|
+
- `holded_invoicing_list_payments` - List all payments
|
|
344
|
+
- `holded_invoicing_get_payment` - Get a specific payment
|
|
345
|
+
- `holded_invoicing_create_payment` - Create a payment
|
|
346
|
+
- `holded_invoicing_update_payment` - Update a payment
|
|
347
|
+
- `holded_invoicing_delete_payment` - Delete a payment
|
|
348
|
+
- `holded_invoicing_get_numbering_series` - Get numbering series by type
|
|
349
|
+
- `holded_invoicing_create_numbering_serie` - Create a numbering series
|
|
350
|
+
- `holded_invoicing_update_numbering_serie` - Update a numbering series
|
|
351
|
+
- `holded_invoicing_delete_numbering_serie` - Delete a numbering series
|
|
352
|
+
- `holded_invoicing_create_treasury` - Create a treasury account
|
|
353
|
+
- `holded_invoicing_list_treasuries` - List treasury accounts
|
|
354
|
+
- `holded_invoicing_get_treasury` - Get a treasury account
|
|
355
|
+
- `holded_invoicing_list_payment_methods` - List available payment methods
|
|
356
|
+
|
|
357
|
+
### Expenses Account Tools
|
|
358
|
+
- `holded_invoicing_list_expenses_accounts` - List all expenses accounts
|
|
359
|
+
- `holded_invoicing_get_expenses_account` - Get a specific expenses account
|
|
360
|
+
- `holded_invoicing_create_expenses_account` - Create a new expenses account
|
|
361
|
+
- `holded_invoicing_update_expenses_account` - Update an expenses account
|
|
362
|
+
- `holded_invoicing_delete_expenses_account` - Delete an expenses account
|
|
363
|
+
|
|
364
|
+
### Sales Channel Tools
|
|
365
|
+
- `holded_invoicing_list_sales_channels` - List all sales channels
|
|
366
|
+
- `holded_invoicing_get_sales_channel` - Get a specific sales channel
|
|
367
|
+
- `holded_invoicing_create_sales_channel` - Create a new sales channel
|
|
368
|
+
- `holded_invoicing_update_sales_channel` - Update a sales channel
|
|
369
|
+
- `holded_invoicing_delete_sales_channel` - Delete a sales channel
|
|
370
|
+
|
|
371
|
+
### Services Tools
|
|
372
|
+
- `holded_invoicing_list_services` - List all services
|
|
373
|
+
- `holded_invoicing_get_service` - Get a specific service
|
|
374
|
+
- `holded_invoicing_create_service` - Create a new service
|
|
375
|
+
- `holded_invoicing_update_service` - Update a service
|
|
376
|
+
- `holded_invoicing_delete_service` - Delete a service
|
|
377
|
+
|
|
378
|
+
### Remittances Tools
|
|
379
|
+
- `holded_invoicing_list_remittances` - List all remittances
|
|
380
|
+
- `holded_invoicing_get_remittance` - Get a specific remittance
|
|
381
|
+
|
|
382
|
+
### Taxes Tools
|
|
383
|
+
- `holded_invoicing_get_taxes` - Get all taxes information
|
|
384
|
+
|
|
385
|
+
### Warehouse Tools
|
|
386
|
+
- `holded_invoicing_list_warehouses` - List all warehouses
|
|
387
|
+
- `holded_invoicing_get_warehouse` - Get a specific warehouse
|
|
388
|
+
- `holded_invoicing_create_warehouse` - Create a new warehouse
|
|
389
|
+
- `holded_invoicing_update_warehouse` - Update a warehouse
|
|
390
|
+
- `holded_invoicing_delete_warehouse` - Delete a warehouse
|
|
391
|
+
|
|
392
|
+
### CRM Tools
|
|
393
|
+
|
|
394
|
+
#### Lead Tools
|
|
395
|
+
- `holded_crm_list_leads` - List all leads
|
|
396
|
+
- `holded_crm_get_lead` - Get a specific lead
|
|
397
|
+
- `holded_crm_create_lead` - Create a new lead
|
|
398
|
+
- `holded_crm_update_lead` - Update a lead
|
|
399
|
+
- `holded_crm_delete_lead` - Delete a lead
|
|
400
|
+
- `holded_crm_update_lead_stage` - Move lead to a different stage
|
|
401
|
+
- `holded_crm_list_lead_notes` - List all notes for a lead
|
|
402
|
+
- `holded_crm_create_lead_note` - Add a note to a lead
|
|
403
|
+
- `holded_crm_update_lead_note` - Update a lead note
|
|
404
|
+
- `holded_crm_delete_lead_note` - Delete a lead note
|
|
405
|
+
- `holded_crm_list_lead_tasks` - List all tasks for a lead
|
|
406
|
+
- `holded_crm_create_lead_task` - Create a task for a lead
|
|
407
|
+
- `holded_crm_update_lead_task` - Update a lead task
|
|
408
|
+
- `holded_crm_delete_lead_task` - Delete a lead task
|
|
409
|
+
- `holded_crm_update_lead_dates` - Update lead dates
|
|
410
|
+
|
|
411
|
+
#### Funnel Tools
|
|
412
|
+
- `holded_crm_list_funnels` - List all funnels
|
|
413
|
+
- `holded_crm_get_funnel` - Get a specific funnel
|
|
414
|
+
- `holded_crm_create_funnel` - Create a funnel
|
|
415
|
+
- `holded_crm_update_funnel` - Update a funnel
|
|
416
|
+
- `holded_crm_delete_funnel` - Delete a funnel
|
|
417
|
+
|
|
418
|
+
#### Event Tools
|
|
419
|
+
- `holded_crm_list_events` - List all events
|
|
420
|
+
- `holded_crm_get_event` - Get a specific event
|
|
421
|
+
- `holded_crm_create_event` - Create an event
|
|
422
|
+
- `holded_crm_update_event` - Update an event
|
|
423
|
+
- `holded_crm_delete_event` - Delete an event
|
|
424
|
+
|
|
425
|
+
#### Booking Tools
|
|
426
|
+
- `holded_crm_list_bookings` - List all bookings
|
|
427
|
+
- `holded_crm_get_booking` - Get a specific booking
|
|
428
|
+
- `holded_crm_create_booking` - Create a booking
|
|
429
|
+
- `holded_crm_update_booking` - Update a booking
|
|
430
|
+
- `holded_crm_delete_booking` - Delete/cancel a booking
|
|
431
|
+
- `holded_crm_list_booking_locations` - List booking locations
|
|
432
|
+
- `holded_crm_get_available_slots` - Get available booking slots
|
|
433
|
+
|
|
434
|
+
### Project Tools
|
|
435
|
+
- `holded_projects_list_projects` - List all projects
|
|
436
|
+
- `holded_projects_get_project` - Get a specific project
|
|
437
|
+
- `holded_projects_create_project` - Create a project
|
|
438
|
+
- `holded_projects_update_project` - Update a project
|
|
439
|
+
- `holded_projects_delete_project` - Delete a project
|
|
440
|
+
- `holded_projects_get_project_summary` - Get project summary/overview
|
|
441
|
+
- `holded_projects_list_tasks` - List all tasks
|
|
442
|
+
- `holded_projects_get_task` - Get a specific task
|
|
443
|
+
- `holded_projects_create_task` - Create a task
|
|
444
|
+
- `holded_projects_delete_task` - Delete a task
|
|
445
|
+
|
|
446
|
+
### Project Time Tracking Tools
|
|
447
|
+
- `holded_projects_list_project_time_trackings` - List all time trackings for a project
|
|
448
|
+
- `holded_projects_get_project_time_tracking` - Get a specific project time tracking entry
|
|
449
|
+
- `holded_projects_create_project_time_tracking` - Create a time tracking entry for a project
|
|
450
|
+
- `holded_projects_update_project_time_tracking` - Update a project time tracking entry
|
|
451
|
+
- `holded_projects_delete_project_time_tracking` - Delete a project time tracking entry
|
|
452
|
+
- `holded_projects_list_all_times` - List all time trackings across all projects
|
|
453
|
+
|
|
454
|
+
### Accounting Tools
|
|
455
|
+
- `holded_accounting_list_accounts` - List all accounting accounts (chart of accounts/PGC accounts)
|
|
456
|
+
- `holded_accounting_get_account` - Get a specific accounting account
|
|
457
|
+
- `holded_accounting_create_account` - Create an accounting account
|
|
458
|
+
- `holded_accounting_update_account` - Update an accounting account
|
|
459
|
+
- `holded_accounting_delete_account` - Delete an accounting account
|
|
460
|
+
- `holded_accounting_list_daily_ledger` - List daily ledger entries
|
|
461
|
+
- `holded_accounting_create_entry` - Create a daily ledger entry
|
|
462
|
+
|
|
463
|
+
### Team Tools
|
|
464
|
+
|
|
465
|
+
#### Employee Tools
|
|
466
|
+
- `holded_team_list_employees` - List all employees
|
|
467
|
+
- `holded_team_get_employee` - Get a specific employee
|
|
468
|
+
- `holded_team_create_employee` - Create a new employee
|
|
469
|
+
- `holded_team_update_employee` - Update an employee
|
|
470
|
+
- `holded_team_delete_employee` - Delete an employee
|
|
471
|
+
|
|
472
|
+
#### Time Tracking Tools
|
|
473
|
+
- `holded_team_list_all_time_trackings` - List all time trackings for all employees
|
|
474
|
+
- `holded_team_list_employee_time_trackings` - List all time trackings for a specific employee
|
|
475
|
+
- `holded_team_get_time_tracking` - Get a specific time tracking entry
|
|
476
|
+
- `holded_team_create_employee_time_tracking` - Create a time tracking entry for an employee
|
|
477
|
+
- `holded_team_update_time_tracking` - Update a time tracking entry
|
|
478
|
+
- `holded_team_delete_time_tracking` - Delete a time tracking entry
|
|
479
|
+
- `holded_team_employee_clock_in` - Clock in an employee
|
|
480
|
+
- `holded_team_employee_clock_out` - Clock out an employee
|
|
481
|
+
- `holded_team_employee_pause` - Pause employee time tracking
|
|
482
|
+
- `holded_team_employee_unpause` - Unpause employee time tracking
|
|
483
|
+
|
|
484
|
+
## Document Types
|
|
485
|
+
|
|
486
|
+
The following document types are supported:
|
|
487
|
+
- `invoice` - Sales invoices
|
|
488
|
+
- `salesreceipt` - Sales receipts
|
|
489
|
+
- `creditnote` - Sales refunds
|
|
490
|
+
- `receiptnote` - Ticket sales refunds
|
|
491
|
+
- `estimate` - Sales estimates/quotes
|
|
492
|
+
- `salesorder` - Sales orders
|
|
493
|
+
- `waybill` - Packing lists
|
|
494
|
+
- `proform` - Proforma invoices
|
|
495
|
+
- `purchase` - Purchases
|
|
496
|
+
- `purchaserefund` - Purchase refunds
|
|
497
|
+
- `purchaseorder` - Purchase orders
|
|
498
|
+
|
|
499
|
+
## Response Formats
|
|
500
|
+
|
|
501
|
+
All tools support two response formats:
|
|
502
|
+
- `json` (default) - Structured JSON data for programmatic processing
|
|
503
|
+
- `markdown` - Human-readable formatted text
|
|
504
|
+
|
|
505
|
+
## Error Handling
|
|
506
|
+
|
|
507
|
+
The server provides clear, actionable error messages for common scenarios:
|
|
508
|
+
- Authentication errors (401) - Check your API key
|
|
509
|
+
- Not found errors (404) - Verify resource IDs
|
|
510
|
+
- Rate limiting (429) - Wait before retrying
|
|
511
|
+
- Validation errors (422) - Check input parameters
|
|
512
|
+
|
|
513
|
+
## Performance
|
|
514
|
+
|
|
515
|
+
This server provides 143 tools covering all Holded API modules. If you only need a subset of functionality, you can improve performance by enabling only the modules you need using the `HOLDED_MODULES` environment variable (see [Module Selection](#module-selection) above):
|
|
516
|
+
|
|
517
|
+
- **Reduced token usage**: Fewer tool definitions means less context sent to the LLM
|
|
518
|
+
- **Faster responses**: The model spends less time parsing available tools
|
|
519
|
+
- **Lower costs**: Smaller prompts reduce API costs for token-based billing
|
|
520
|
+
|
|
521
|
+
For example, if you only work with invoicing, you can set `HOLDED_MODULES=invoicing` to disable CRM, Projects, Accounting, and Team modules.
|
|
522
|
+
|
|
523
|
+
## Troubleshooting
|
|
524
|
+
|
|
525
|
+
### Common Issues
|
|
526
|
+
|
|
527
|
+
#### 1. API Key Not Found
|
|
528
|
+
**Error**: `ERROR: HOLDED_API_KEY environment variable is required.`
|
|
529
|
+
|
|
530
|
+
**Solution**: Ensure your API key is properly configured in your MCP client settings:
|
|
531
|
+
- Check that `HOLDED_API_KEY` is set in the `env` section
|
|
532
|
+
- Verify the key is correct (no extra spaces or quotes)
|
|
533
|
+
- Get your API key from Configuration → API in Holded
|
|
534
|
+
|
|
535
|
+
#### 2. 401 Unauthorized
|
|
536
|
+
**Error**: API returns 401 status code
|
|
537
|
+
|
|
538
|
+
**Solution**:
|
|
539
|
+
- Verify your API key is valid and not expired
|
|
540
|
+
- Check that the key has the necessary permissions
|
|
541
|
+
- Regenerate the API key if needed
|
|
542
|
+
|
|
543
|
+
#### 3. 422 Validation Error
|
|
544
|
+
**Error**: API returns 422 status code
|
|
545
|
+
|
|
546
|
+
**Solution**:
|
|
547
|
+
- Check that all required parameters are provided
|
|
548
|
+
- Verify parameter types match expectations (string vs number)
|
|
549
|
+
- For nested objects (stock updates, custom fields), ensure correct structure
|
|
550
|
+
|
|
551
|
+
#### 4. Module Not Loading
|
|
552
|
+
**Error**: Tools from a specific module are missing
|
|
553
|
+
|
|
554
|
+
**Solution**:
|
|
555
|
+
- Check if you've set `HOLDED_MODULES` environment variable
|
|
556
|
+
- If set, ensure the module name is included (e.g., `"HOLDED_MODULES": "invoicing,crm"`)
|
|
557
|
+
- Remove `HOLDED_MODULES` or leave it empty to load all modules
|
|
558
|
+
|
|
559
|
+
## Complex Operation Examples
|
|
560
|
+
|
|
561
|
+
### Stock Updates
|
|
562
|
+
|
|
563
|
+
Updating product stock requires a nested object structure where you specify warehouse ID and product/variant IDs:
|
|
564
|
+
|
|
565
|
+
```typescript
|
|
566
|
+
// Stock update structure: stock[warehouseId][productId/variantId] = quantity
|
|
567
|
+
{
|
|
568
|
+
"product_id": "abc123",
|
|
569
|
+
"stock": {
|
|
570
|
+
"warehouse1": {
|
|
571
|
+
"productId1": 100,
|
|
572
|
+
"variantId1": 50
|
|
573
|
+
},
|
|
574
|
+
"warehouse2": {
|
|
575
|
+
"productId1": 75
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
}
|
|
579
|
+
```
|
|
580
|
+
|
|
581
|
+
**Example**: Set stock for product "abc123" to 100 units in warehouse "wh1":
|
|
582
|
+
```typescript
|
|
583
|
+
{
|
|
584
|
+
"product_id": "abc123",
|
|
585
|
+
"stock": {
|
|
586
|
+
"wh1": {
|
|
587
|
+
"abc123": 100
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
}
|
|
591
|
+
```
|
|
592
|
+
|
|
593
|
+
### Booking Creation
|
|
594
|
+
|
|
595
|
+
Bookings require specific custom fields with key-value pairs:
|
|
596
|
+
|
|
597
|
+
```typescript
|
|
598
|
+
{
|
|
599
|
+
"locationId": "location123",
|
|
600
|
+
"serviceId": "service456",
|
|
601
|
+
"dateTime": 1730109600, // Unix timestamp
|
|
602
|
+
"timezone": "Europe/Madrid",
|
|
603
|
+
"language": "es",
|
|
604
|
+
"customFields": [
|
|
605
|
+
{
|
|
606
|
+
"key": "name",
|
|
607
|
+
"value": "John Doe"
|
|
608
|
+
},
|
|
609
|
+
{
|
|
610
|
+
"key": "email",
|
|
611
|
+
"value": "john@example.com"
|
|
612
|
+
},
|
|
613
|
+
{
|
|
614
|
+
"key": "phone",
|
|
615
|
+
"value": "+34612345678"
|
|
616
|
+
}
|
|
617
|
+
]
|
|
618
|
+
}
|
|
619
|
+
```
|
|
620
|
+
|
|
621
|
+
### Task Creation
|
|
622
|
+
|
|
623
|
+
Tasks require both project ID and list ID (the list/column within the project):
|
|
624
|
+
|
|
625
|
+
```typescript
|
|
626
|
+
{
|
|
627
|
+
"name": "New Task",
|
|
628
|
+
"project_id": "proj123",
|
|
629
|
+
"list_id": "list456" // Get this from project details
|
|
630
|
+
}
|
|
631
|
+
```
|
|
632
|
+
|
|
633
|
+
**Note**: To get available list IDs, first fetch the project details using `holded_projects_get_project`.
|
|
634
|
+
|
|
635
|
+
### Accounting Entries
|
|
636
|
+
|
|
637
|
+
Daily ledger entries must have balanced debits and credits:
|
|
638
|
+
|
|
639
|
+
```typescript
|
|
640
|
+
{
|
|
641
|
+
"date": 1730109600, // Unix timestamp
|
|
642
|
+
"lines": [
|
|
643
|
+
{
|
|
644
|
+
"account": 4300, // Account number (integer)
|
|
645
|
+
"debit": 1000,
|
|
646
|
+
"description": "Sales revenue"
|
|
647
|
+
},
|
|
648
|
+
{
|
|
649
|
+
"account": 5700, // Account number (integer)
|
|
650
|
+
"credit": 1000,
|
|
651
|
+
"description": "Bank account"
|
|
652
|
+
}
|
|
653
|
+
],
|
|
654
|
+
"notes": "Monthly sales entry"
|
|
655
|
+
}
|
|
656
|
+
```
|
|
657
|
+
|
|
658
|
+
**Requirements**:
|
|
659
|
+
- Minimum 2 lines
|
|
660
|
+
- Total debits must equal total credits
|
|
661
|
+
- Each line must have either debit OR credit (not both)
|
|
662
|
+
- Account numbers must be positive integers
|
|
663
|
+
|
|
664
|
+
### Parameter Naming Convention
|
|
665
|
+
|
|
666
|
+
This MCP server uses a consistent parameter naming convention:
|
|
667
|
+
|
|
668
|
+
- **Path/Query parameters**: Use `snake_case` (e.g., `employee_id`, `doc_type`)
|
|
669
|
+
- **Request body fields**: Use `camelCase` matching the API (e.g., `lastName`, `sendInvite`)
|
|
670
|
+
|
|
671
|
+
The tool handlers automatically transform parameters to the format expected by the Holded API.
|
|
672
|
+
|
|
673
|
+
## Workflow Examples
|
|
674
|
+
|
|
675
|
+
This section demonstrates common real-world workflows combining multiple API operations.
|
|
676
|
+
|
|
677
|
+
### Creating a Complete Invoice
|
|
678
|
+
|
|
679
|
+
```typescript
|
|
680
|
+
// 1. First, ensure you have a contact
|
|
681
|
+
const contact = await holded_invoicing_create_contact({
|
|
682
|
+
name: "Acme Corp",
|
|
683
|
+
email: "billing@acme.com",
|
|
684
|
+
code: "B12345678" // Tax ID
|
|
685
|
+
});
|
|
686
|
+
|
|
687
|
+
// 2. Create the invoice with line items
|
|
688
|
+
const invoice = await holded_invoicing_create_document({
|
|
689
|
+
doc_type: "invoice",
|
|
690
|
+
contactId: contact.id,
|
|
691
|
+
contactName: "Acme Corp",
|
|
692
|
+
date: 1730109600, // Unix timestamp
|
|
693
|
+
items: [
|
|
694
|
+
{
|
|
695
|
+
name: "Web Development Service",
|
|
696
|
+
units: 40,
|
|
697
|
+
subtotal: 4000, // 40 hours × €100/hour
|
|
698
|
+
tax: 21 // 21% VAT
|
|
699
|
+
},
|
|
700
|
+
{
|
|
701
|
+
name: "Hosting Service (Annual)",
|
|
702
|
+
units: 1,
|
|
703
|
+
subtotal: 500,
|
|
704
|
+
tax: 21
|
|
705
|
+
}
|
|
706
|
+
],
|
|
707
|
+
notes: "Payment due within 30 days"
|
|
708
|
+
});
|
|
709
|
+
|
|
710
|
+
// 3. Send the invoice via email
|
|
711
|
+
await holded_invoicing_send_document({
|
|
712
|
+
doc_type: "invoice",
|
|
713
|
+
document_id: invoice.id,
|
|
714
|
+
emails: ["billing@acme.com"]
|
|
715
|
+
});
|
|
716
|
+
|
|
717
|
+
// 4. Record payment when received
|
|
718
|
+
await holded_invoicing_pay_document({
|
|
719
|
+
doc_type: "invoice",
|
|
720
|
+
document_id: invoice.id,
|
|
721
|
+
paid: 5445, // Total with VAT (€4,500 × 1.21)
|
|
722
|
+
date: 1732701600 // Payment date
|
|
723
|
+
});
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### Managing Lead Lifecycle
|
|
727
|
+
|
|
728
|
+
```typescript
|
|
729
|
+
// 1. Create a new lead
|
|
730
|
+
const lead = await holded_crm_create_lead({
|
|
731
|
+
name: "Enterprise Client Prospect",
|
|
732
|
+
funnelId: "funnel123",
|
|
733
|
+
stageId: "stage_initial_contact",
|
|
734
|
+
contactName: "Jane Smith",
|
|
735
|
+
email: "jane.smith@enterprise.com",
|
|
736
|
+
phone: "+34912345678"
|
|
737
|
+
});
|
|
738
|
+
|
|
739
|
+
// 2. Add initial contact notes
|
|
740
|
+
await holded_crm_create_lead_note({
|
|
741
|
+
lead_id: lead.id,
|
|
742
|
+
note: "Initial call: Interested in enterprise plan. Budget: €50k/year. Decision timeline: Q2 2026."
|
|
743
|
+
});
|
|
744
|
+
|
|
745
|
+
// 3. Create follow-up task
|
|
746
|
+
await holded_crm_create_lead_task({
|
|
747
|
+
lead_id: lead.id,
|
|
748
|
+
task: "Send proposal and pricing",
|
|
749
|
+
dueDate: 1730800000 // 1 week from now
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
// 4. Update lead stage after proposal sent
|
|
753
|
+
await holded_crm_update_lead_stage({
|
|
754
|
+
lead_id: lead.id,
|
|
755
|
+
stageId: "stage_proposal_sent"
|
|
756
|
+
});
|
|
757
|
+
|
|
758
|
+
// 5. Add proposal notes
|
|
759
|
+
await holded_crm_create_lead_note({
|
|
760
|
+
lead_id: lead.id,
|
|
761
|
+
note: "Sent proposal via email. Includes: Enterprise tier, custom integrations, dedicated support."
|
|
762
|
+
});
|
|
763
|
+
|
|
764
|
+
// 6. When deal is won, convert to contact
|
|
765
|
+
const contact = await holded_invoicing_create_contact({
|
|
766
|
+
name: "Enterprise Client Inc",
|
|
767
|
+
email: "jane.smith@enterprise.com",
|
|
768
|
+
phone: "+34912345678"
|
|
769
|
+
});
|
|
770
|
+
|
|
771
|
+
// 7. Move lead to won stage
|
|
772
|
+
await holded_crm_update_lead_stage({
|
|
773
|
+
lead_id: lead.id,
|
|
774
|
+
stageId: "stage_won"
|
|
775
|
+
});
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
### Employee Onboarding Workflow
|
|
779
|
+
|
|
780
|
+
```typescript
|
|
781
|
+
// 1. Create new employee
|
|
782
|
+
const employee = await holded_team_create_employee({
|
|
783
|
+
name: "María",
|
|
784
|
+
lastName: "García",
|
|
785
|
+
email: "maria.garcia@company.com",
|
|
786
|
+
sendInvite: true // Sends email invitation
|
|
787
|
+
});
|
|
788
|
+
|
|
789
|
+
// 2. Update employee details after onboarding
|
|
790
|
+
await holded_team_update_employee({
|
|
791
|
+
employee_id: employee.id,
|
|
792
|
+
phone: "+34666123456",
|
|
793
|
+
mobile: "+34666123456",
|
|
794
|
+
dateOfBirth: "15/03/1990",
|
|
795
|
+
nationality: "Spanish",
|
|
796
|
+
iban: "ES1234567890123456789012",
|
|
797
|
+
address: {
|
|
798
|
+
address: "Calle Mayor 123",
|
|
799
|
+
city: "Madrid",
|
|
800
|
+
postalCode: "28013",
|
|
801
|
+
province: "Madrid",
|
|
802
|
+
country: "Spain"
|
|
803
|
+
},
|
|
804
|
+
workplace: "office_madrid_001",
|
|
805
|
+
teams: ["team_engineering", "team_backend"]
|
|
806
|
+
});
|
|
807
|
+
|
|
808
|
+
// 3. Set up first time tracking entry
|
|
809
|
+
await holded_team_create_employee_time_tracking({
|
|
810
|
+
employee_id: employee.id,
|
|
811
|
+
startTmp: "1730109600", // 9:00 AM (Unix timestamp as string)
|
|
812
|
+
endTmp: "1730138400" // 5:00 PM (Unix timestamp as string)
|
|
813
|
+
});
|
|
814
|
+
|
|
815
|
+
// 4. Use clock-in/clock-out for daily tracking
|
|
816
|
+
await holded_team_employee_clock_in({
|
|
817
|
+
employee_id: employee.id,
|
|
818
|
+
location: "Madrid Office"
|
|
819
|
+
});
|
|
820
|
+
|
|
821
|
+
// Later in the day...
|
|
822
|
+
await holded_team_employee_clock_out({
|
|
823
|
+
employee_id: employee.id,
|
|
824
|
+
latitude: "40.4168",
|
|
825
|
+
longitude: "-3.7038"
|
|
826
|
+
});
|
|
827
|
+
```
|
|
828
|
+
|
|
829
|
+
### Multi-Warehouse Stock Management
|
|
830
|
+
|
|
831
|
+
```typescript
|
|
832
|
+
// 1. Create warehouses
|
|
833
|
+
const warehouseMadrid = await holded_invoicing_create_warehouse({
|
|
834
|
+
name: "Madrid Warehouse",
|
|
835
|
+
address: {
|
|
836
|
+
address: "Polígono Industrial Sur",
|
|
837
|
+
city: "Madrid",
|
|
838
|
+
postalCode: "28021",
|
|
839
|
+
country: "Spain"
|
|
840
|
+
}
|
|
841
|
+
});
|
|
842
|
+
|
|
843
|
+
const warehouseBarcelona = await holded_invoicing_create_warehouse({
|
|
844
|
+
name: "Barcelona Warehouse",
|
|
845
|
+
address: {
|
|
846
|
+
address: "Zona Franca",
|
|
847
|
+
city: "Barcelona",
|
|
848
|
+
postalCode: "08040",
|
|
849
|
+
country: "Spain"
|
|
850
|
+
}
|
|
851
|
+
});
|
|
852
|
+
|
|
853
|
+
// 2. Create a product
|
|
854
|
+
const product = await holded_invoicing_create_product({
|
|
855
|
+
name: "Wireless Mouse MX Master",
|
|
856
|
+
sku: "TECH-MOUSE-001",
|
|
857
|
+
price: 89.99,
|
|
858
|
+
tax: 21
|
|
859
|
+
});
|
|
860
|
+
|
|
861
|
+
// 3. Update stock across multiple warehouses
|
|
862
|
+
await holded_invoicing_update_product_stock({
|
|
863
|
+
product_id: product.id,
|
|
864
|
+
stock: {
|
|
865
|
+
[warehouseMadrid.id]: {
|
|
866
|
+
[product.id]: 150 // 150 units in Madrid
|
|
867
|
+
},
|
|
868
|
+
[warehouseBarcelona.id]: {
|
|
869
|
+
[product.id]: 200 // 200 units in Barcelona
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
// 4. Check stock levels for a specific warehouse
|
|
875
|
+
const madridStock = await holded_invoicing_list_products_stock({
|
|
876
|
+
warehouse_id: warehouseMadrid.id
|
|
877
|
+
});
|
|
878
|
+
|
|
879
|
+
// 5. Transfer stock between warehouses (reduce Madrid, increase Barcelona)
|
|
880
|
+
await holded_invoicing_update_product_stock({
|
|
881
|
+
product_id: product.id,
|
|
882
|
+
stock: {
|
|
883
|
+
[warehouseMadrid.id]: {
|
|
884
|
+
[product.id]: 125 // Reduced by 25
|
|
885
|
+
},
|
|
886
|
+
[warehouseBarcelona.id]: {
|
|
887
|
+
[product.id]: 225 // Increased by 25
|
|
888
|
+
}
|
|
889
|
+
}
|
|
890
|
+
});
|
|
891
|
+
```
|
|
892
|
+
|
|
893
|
+
### Document Shipping Workflow
|
|
894
|
+
|
|
895
|
+
```typescript
|
|
896
|
+
// 1. Create a sales order
|
|
897
|
+
const salesOrder = await holded_invoicing_create_document({
|
|
898
|
+
doc_type: "salesorder",
|
|
899
|
+
contactId: "contact123",
|
|
900
|
+
contactName: "Tech Store SL",
|
|
901
|
+
date: 1730109600,
|
|
902
|
+
items: [
|
|
903
|
+
{
|
|
904
|
+
name: "Laptop HP ProBook",
|
|
905
|
+
sku: "LAPTOP-HP-001",
|
|
906
|
+
units: 5,
|
|
907
|
+
subtotal: 3500,
|
|
908
|
+
tax: 21
|
|
909
|
+
},
|
|
910
|
+
{
|
|
911
|
+
name: "USB-C Dock",
|
|
912
|
+
sku: "DOCK-USBC-001",
|
|
913
|
+
units: 5,
|
|
914
|
+
subtotal: 500,
|
|
915
|
+
tax: 21
|
|
916
|
+
}
|
|
917
|
+
],
|
|
918
|
+
warehouseId: "warehouse_madrid_001"
|
|
919
|
+
});
|
|
920
|
+
|
|
921
|
+
// 2. Add tracking information
|
|
922
|
+
await holded_invoicing_update_document_tracking({
|
|
923
|
+
doc_type: "salesorder",
|
|
924
|
+
document_id: salesOrder.id,
|
|
925
|
+
carrier: "DHL Express",
|
|
926
|
+
trackingNumber: "1234567890",
|
|
927
|
+
trackingUrl: "https://dhl.com/track/1234567890"
|
|
928
|
+
});
|
|
929
|
+
|
|
930
|
+
// 3. Ship all items at once
|
|
931
|
+
const shipment = await holded_invoicing_ship_all_items({
|
|
932
|
+
document_id: salesOrder.id
|
|
933
|
+
});
|
|
934
|
+
|
|
935
|
+
// Alternative: Ship items line by line (partial shipments)
|
|
936
|
+
// await holded_invoicing_ship_items_by_line({
|
|
937
|
+
// document_id: salesOrder.id,
|
|
938
|
+
// lines: [
|
|
939
|
+
// { lineId: "line1", units: 3 }, // Ship 3 laptops now
|
|
940
|
+
// { lineId: "line2", units: 5 } // Ship all docks now
|
|
941
|
+
// ]
|
|
942
|
+
// });
|
|
943
|
+
|
|
944
|
+
// 4. Check shipped items
|
|
945
|
+
const shippedItems = await holded_invoicing_get_shipped_items({
|
|
946
|
+
doc_type: "salesorder",
|
|
947
|
+
document_id: salesOrder.id
|
|
948
|
+
});
|
|
949
|
+
|
|
950
|
+
// 5. Update pipeline stage
|
|
951
|
+
await holded_invoicing_update_document_pipeline({
|
|
952
|
+
doc_type: "salesorder",
|
|
953
|
+
document_id: salesOrder.id,
|
|
954
|
+
pipelineStage: "shipped"
|
|
955
|
+
});
|
|
956
|
+
|
|
957
|
+
// 6. Create invoice from the sales order
|
|
958
|
+
const invoice = await holded_invoicing_create_document({
|
|
959
|
+
doc_type: "invoice",
|
|
960
|
+
contactId: "contact123",
|
|
961
|
+
salesorderId: salesOrder.id, // Link to sales order
|
|
962
|
+
date: 1730196000
|
|
963
|
+
});
|
|
964
|
+
```
|
|
965
|
+
|
|
966
|
+
## Development
|
|
967
|
+
|
|
968
|
+
### Build from Source
|
|
969
|
+
|
|
970
|
+
If you want to build from source (for development or contributions):
|
|
971
|
+
|
|
972
|
+
```bash
|
|
973
|
+
git clone https://github.com/energio-es/holded-mcp.git
|
|
974
|
+
cd holded-mcp
|
|
975
|
+
npm install
|
|
976
|
+
npm run build
|
|
977
|
+
```
|
|
978
|
+
|
|
979
|
+
Then use the built server in your MCP client configuration:
|
|
980
|
+
|
|
981
|
+
```json
|
|
982
|
+
{
|
|
983
|
+
"mcpServers": {
|
|
984
|
+
"holded": {
|
|
985
|
+
"command": "node",
|
|
986
|
+
"args": ["/absolute/path/to/holded-mcp/dist/index.js"],
|
|
987
|
+
"env": {
|
|
988
|
+
"HOLDED_API_KEY": "your_api_key_here"
|
|
989
|
+
}
|
|
990
|
+
}
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
```
|
|
994
|
+
|
|
995
|
+
### Development Commands
|
|
996
|
+
|
|
997
|
+
```bash
|
|
998
|
+
# Install dependencies
|
|
999
|
+
npm install
|
|
1000
|
+
|
|
1001
|
+
# Build TypeScript
|
|
1002
|
+
npm run build
|
|
1003
|
+
|
|
1004
|
+
# Run in development mode with auto-reload
|
|
1005
|
+
npm run dev
|
|
1006
|
+
|
|
1007
|
+
# Clean build artifacts
|
|
1008
|
+
npm run clean
|
|
1009
|
+
```
|
|
1010
|
+
|
|
1011
|
+
## Contributing
|
|
1012
|
+
|
|
1013
|
+
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on the process for submitting pull requests.
|
|
1014
|
+
|
|
1015
|
+
### Quick Start for Contributors
|
|
1016
|
+
|
|
1017
|
+
1. Fork the repository
|
|
1018
|
+
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
|
|
1019
|
+
3. Make your changes
|
|
1020
|
+
4. Commit using [Conventional Commits](https://www.conventionalcommits.org/) (`git commit -m 'feat: add amazing feature'`)
|
|
1021
|
+
5. Push to your branch (`git push origin feature/amazing-feature`)
|
|
1022
|
+
6. Open a Pull Request
|
|
1023
|
+
|
|
1024
|
+
## License
|
|
1025
|
+
|
|
1026
|
+
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
1027
|
+
|
|
1028
|
+
## Community & Governance
|
|
1029
|
+
|
|
1030
|
+
- [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
1031
|
+
- [Governance](GOVERNANCE.md)
|
|
1032
|
+
- [Security Policy](SECURITY.md)
|
|
1033
|
+
|
|
1034
|
+
## Support
|
|
1035
|
+
|
|
1036
|
+
- **Holded API Documentation**: https://developers.holded.com/reference
|
|
1037
|
+
- **Issues**: [GitHub Issues](https://github.com/energio-es/holded-mcp/issues) - *Response time: 1-2 weeks*
|
|
1038
|
+
- **Discussions**: [GitHub Discussions](https://github.com/energio-es/holded-mcp/discussions)
|
|
1039
|
+
- **Security**: [Report a Vulnerability](SECURITY.md) - *Response time: 72 hours*
|
|
1040
|
+
|