MCP server for Holded — invoicing, accounting, CRM, projects, and team
Holded MCP Server
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.
Table of Contents
- Features
- Installation
- Configuration
- Usage
- Available Tools
- Document Types
- Response Formats
- Error Handling
- Performance
- Development
- Contributing
- License
- Support
Features
Invoicing Module
- Documents: Full CRUD operations for documents (invoices, estimates, purchases, etc.) plus pay, send, PDF export, tracking, and pipeline management
- Contacts: Full CRUD operations for contacts and contact groups
- Products: Manage products, variants, and stock levels
- Payments: Full CRUD operations for payments
- Numbering Series: Full CRUD operations for document numbering series
- Treasury: Create, list, and retrieve treasury/bank accounts
- Payment Methods: List available payment methods
- Expenses Accounts: Full CRUD operations for expenses accounts
- Sales Channels: Full CRUD operations for sales channels
- Services: Full CRUD operations for services
- Taxes: Get tax information and rates
- Warehouses: Full CRUD operations for warehouses
CRM Module
- Leads: Create, list, get, update, delete leads; manage stages, notes, and tasks
- Funnels: Full CRUD operations for sales funnels with custom stages
- Events: Full CRUD operations for CRM events
- Bookings: Full CRUD operations for bookings and manage locations
Projects Module
- Projects: Full CRUD operations for projects plus project summaries
- Tasks: Full CRUD operations for project tasks
- Time Tracking: Full CRUD operations for project time tracking entries
Accounting Module
- Accounts: List and create accounting accounts with prefix-based numbering
- Daily Ledger: List daily ledger entries and create accounting entries
Team Module
- Employees: Full CRUD operations for employees
- Time Tracking: List all time trackings, list by employee, get, create, update, and delete time tracking entries
Installation
Prerequisites
- Node.js >= 20 (check with
node --version) - Holded API Key - Get yours from Holded API Settings or go to Configuration (top bar) → API
Quick Start (npx)
The easiest way to use this MCP server is via npx - no installation or build required! Just configure your MCP client as shown below.
Setup for Claude Desktop
Add the following to your Claude Desktop configuration file:
- macOS:
~/Library/Application Support/Claude/claude_desktop_config.json - Windows:
%APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"holded": {
"command": "npx",
"args": ["-y", "@energio/holded-mcp"],
"env": {
"HOLDED_API_KEY": "your_api_key_here"
}
}
}
}
Restart Claude Desktop to load the server.
Setup for Claude Code
Add the server with a single command:
claude mcp add holded -- npx -y @energio/holded-mcp
Then set the API key in your environment:
export HOLDED_API_KEY=your_api_key_here
Setup for Cursor
Add the following to your Cursor MCP settings file:
- macOS:
~/.cursor/mcp.json - Windows:
%APPDATA%\Cursor\mcp.json - Linux:
~/.config/cursor/mcp.json
{
"mcpServers": {
"holded": {
"command": "npx",
"args": ["-y", "@energio/holded-mcp"],
"env": {
"HOLDED_API_KEY": "your_api_key_here"
}
}
}
}
After saving, restart Cursor or reload the MCP servers from the settings.
Setup for VS Code
Add the following to your VS Code user settings (settings.json) or workspace settings (.vscode/mcp.json):
User settings (settings.json):
{
"mcp": {
"servers": {
"holded": {
"command": "npx",
"args": ["-y", "@energio/holded-mcp"],
"env": {
"HOLDED_API_KEY": "your_api_key_here"
}
}
}
}
}
Workspace settings (.vscode/mcp.json):
{
"servers": {
"holded": {
"command": "npx",
"args": ["-y", "@energio/holded-mcp"],
"env": {
"HOLDED_API_KEY": "your_api_key_here"
}
}
}
}
Setup for Windsurf
Add the following to your Windsurf MCP configuration file:
- macOS:
~/.codeium/windsurf/mcp_config.json - Windows:
%APPDATA%\Codeium\windsurf\mcp_config.json - Linux:
~/.codeium/windsurf/mcp_config.json
{
"mcpServers": {
"holded": {
"command": "npx",
"args": ["-y", "@energio/holded-mcp"],
"env": {
"HOLDED_API_KEY": "your_api_key_here"
}
}
}
}
Setup for Other MCP-Compatible Agents
Any MCP-compatible agent can use this server via npx. The general configuration requires:
- Command:
npx - Arguments:
["-y", "@energio/holded-mcp"] - Environment variable:
HOLDED_API_KEYwith your API key
Example configuration:
{
"mcpServers": {
"holded": {
"command": "npx",
"args": ["-y", "@energio/holded-mcp"],
"env": {
"HOLDED_API_KEY": "your_api_key_here"
}
}
}
}
The server communicates via stdio using the MCP protocol and can be integrated with any client that supports the Model Context Protocol.
Configuration
The server requires a HOLDED_API_KEY environment variable. This is typically set in your MCP client configuration (see installation sections above).
For manual/development usage, you can set it directly:
export HOLDED_API_KEY=your_api_key_here
Module Selection
By default, all modules are enabled. To load only specific modules, set the HOLDED_MODULES environment variable with a comma-separated list:
Available modules: invoicing, crm, projects, accounting, team
Example - enable only invoicing module:
{
"mcpServers": {
"holded": {
"command": "npx",
"args": ["-y", "@energio/holded-mcp"],
"env": {
"HOLDED_API_KEY": "your_api_key_here",
"HOLDED_MODULES": "invoicing"
}
}
}
}
Configuration examples:
- All modules (default): Omit
HOLDED_MODULESor leave it empty - Only CRM:
"HOLDED_MODULES": "crm" - Only invoicing:
"HOLDED_MODULES": "invoicing" - Multiple modules:
"HOLDED_MODULES": "invoicing,crm"
Debug Mode
Enable debug logging for API requests and retries by setting the HOLDED_DEBUG environment variable:
{
"mcpServers": {
"holded": {
"command": "npx",
"args": ["-y", "@energio/holded-mcp"],
"env": {
"HOLDED_API_KEY": "your_api_key_here",
"HOLDED_DEBUG": "true"
}
}
}
}
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.
Usage
Running the Server Manually
npm start
Or for development with auto-reload:
npm run dev
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.
Available Tools
Contact Tools
holded_invoicing_list_contacts- List all contactsholded_invoicing_get_contact- Get a specific contactholded_invoicing_create_contact- Create a new contactholded_invoicing_update_contact- Update a contactholded_invoicing_delete_contact- Delete a contactholded_invoicing_list_contact_groups- List contact groupsholded_invoicing_get_contact_group- Get a contact groupholded_invoicing_create_contact_group- Create a contact groupholded_invoicing_update_contact_group- Update a contact groupholded_invoicing_delete_contact_group- Delete a contact groupholded_invoicing_list_contact_attachments- List attachments for a contactholded_invoicing_get_contact_attachment- Get a specific contact attachmentholded_invoicing_upload_contact_attachment- Upload an attachment to a contact
Product Tools
holded_invoicing_list_products- List all productsholded_invoicing_get_product- Get a specific productholded_invoicing_create_product- Create a new productholded_invoicing_update_product- Update a productholded_invoicing_delete_product- Delete a productholded_invoicing_list_products_stock- List product stock levels for a specific warehouseholded_invoicing_update_product_stock- Update product stockholded_invoicing_get_product_image- Get main product imageholded_invoicing_list_product_images- List all product imagesholded_invoicing_get_product_secondary_image- Get a secondary product imageholded_invoicing_upload_product_image- Upload an image to a product
Document Tools
holded_invoicing_list_documents- List documents by typeholded_invoicing_get_document- Get a specific documentholded_invoicing_create_document- Create a new documentholded_invoicing_update_document- Update a documentholded_invoicing_delete_document- Delete a documentholded_invoicing_pay_document- Record a payment for a documentholded_invoicing_send_document- Send a document via emailholded_invoicing_get_document_pdf- Get PDF version of a documentholded_invoicing_update_document_tracking- Update document tracking infoholded_invoicing_update_document_pipeline- Update document pipeline stageholded_invoicing_ship_all_items- Ship all items from a sales orderholded_invoicing_ship_items_by_line- Ship specific items by line from a sales orderholded_invoicing_get_shipped_items- Get shipped items for a documentholded_invoicing_attach_document_file- Attach a file to a document
Payment & Treasury Tools
holded_invoicing_list_payments- List all paymentsholded_invoicing_get_payment- Get a specific paymentholded_invoicing_create_payment- Create a paymentholded_invoicing_update_payment- Update a paymentholded_invoicing_delete_payment- Delete a paymentholded_invoicing_get_numbering_series- Get numbering series by typeholded_invoicing_create_numbering_serie- Create a numbering seriesholded_invoicing_update_numbering_serie- Update a numbering seriesholded_invoicing_delete_numbering_serie- Delete a numbering seriesholded_invoicing_create_treasury- Create a treasury accountholded_invoicing_list_treasuries- List treasury accountsholded_invoicing_get_treasury- Get a treasury accountholded_invoicing_list_payment_methods- List available payment methods
Expenses Account Tools
holded_invoicing_list_expenses_accounts- List all expenses accountsholded_invoicing_get_expenses_account- Get a specific expenses accountholded_invoicing_create_expenses_account- Create a new expenses accountholded_invoicing_update_expenses_account- Update an expenses accountholded_invoicing_delete_expenses_account- Delete an expenses account
Sales Channel Tools
holded_invoicing_list_sales_channels- List all sales channelsholded_invoicing_get_sales_channel- Get a specific sales channelholded_invoicing_create_sales_channel- Create a new sales channelholded_invoicing_update_sales_channel- Update a sales channelholded_invoicing_delete_sales_channel- Delete a sales channel
Services Tools
holded_invoicing_list_services- List all servicesholded_invoicing_get_service- Get a specific serviceholded_invoicing_create_service- Create a new serviceholded_invoicing_update_service- Update a serviceholded_invoicing_delete_service- Delete a service
Remittances Tools
holded_invoicing_list_remittances- List all remittancesholded_invoicing_get_remittance- Get a specific remittance
Taxes Tools
holded_invoicing_get_taxes- Get all taxes information
Warehouse Tools
holded_invoicing_list_warehouses- List all warehousesholded_invoicing_get_warehouse- Get a specific warehouseholded_invoicing_create_warehouse- Create a new warehouseholded_invoicing_update_warehouse- Update a warehouseholded_invoicing_delete_warehouse- Delete a warehouse
CRM Tools
Lead Tools
holded_crm_list_leads- List all leadsholded_crm_get_lead- Get a specific leadholded_crm_create_lead- Create a new leadholded_crm_update_lead- Update a leadholded_crm_delete_lead- Delete a leadholded_crm_update_lead_stage- Move lead to a different stageholded_crm_list_lead_notes- List all notes for a leadholded_crm_create_lead_note- Add a note to a leadholded_crm_update_lead_note- Update a lead noteholded_crm_delete_lead_note- Delete a lead noteholded_crm_list_lead_tasks- List all tasks for a leadholded_crm_create_lead_task- Create a task for a leadholded_crm_update_lead_task- Update a lead taskholded_crm_delete_lead_task- Delete a lead taskholded_crm_update_lead_dates- Update lead dates
Funnel Tools
holded_crm_list_funnels- List all funnelsholded_crm_get_funnel- Get a specific funnelholded_crm_create_funnel- Create a funnelholded_crm_update_funnel- Update a funnelholded_crm_delete_funnel- Delete a funnel
Event Tools
holded_crm_list_events- List all eventsholded_crm_get_event- Get a specific eventholded_crm_create_event- Create an eventholded_crm_update_event- Update an eventholded_crm_delete_event- Delete an event
Booking Tools
holded_crm_list_bookings- List all bookingsholded_crm_get_booking- Get a specific bookingholded_crm_create_booking- Create a bookingholded_crm_update_booking- Update a bookingholded_crm_delete_booking- Delete/cancel a bookingholded_crm_list_booking_locations- List booking locationsholded_crm_get_available_slots- Get available booking slots
Project Tools
holded_projects_list_projects- List all projectsholded_projects_get_project- Get a specific projectholded_projects_create_project- Create a projectholded_projects_update_project- Update a projectholded_projects_delete_project- Delete a projectholded_projects_get_project_summary- Get project summary/overviewholded_projects_list_tasks- List all tasksholded_projects_get_task- Get a specific taskholded_projects_create_task- Create a taskholded_projects_delete_task- Delete a task
Project Time Tracking Tools
holded_projects_list_project_time_trackings- List all time trackings for a projectholded_projects_get_project_time_tracking- Get a specific project time tracking entryholded_projects_create_project_time_tracking- Create a time tracking entry for a projectholded_projects_update_project_time_tracking- Update a project time tracking entryholded_projects_delete_project_time_tracking- Delete a project time tracking entryholded_projects_list_all_times- List all time trackings across all projects
Accounting Tools
holded_accounting_list_accounts- List all accounting accounts (chart of accounts/PGC accounts)holded_accounting_get_account- Get a specific accounting accountholded_accounting_create_account- Create an accounting accountholded_accounting_update_account- Update an accounting accountholded_accounting_delete_account- Delete an accounting accountholded_accounting_list_daily_ledger- List daily ledger entriesholded_accounting_create_entry- Create a daily ledger entry
Team Tools
Employee Tools
holded_team_list_employees- List all employeesholded_team_get_employee- Get a specific employeeholded_team_create_employee- Create a new employeeholded_team_update_employee- Update an employeeholded_team_delete_employee- Delete an employee
Time Tracking Tools
holded_team_list_all_time_trackings- List all time trackings for all employeesholded_team_list_employee_time_trackings- List all time trackings for a specific employeeholded_team_get_time_tracking- Get a specific time tracking entryholded_team_create_employee_time_tracking- Create a time tracking entry for an employeeholded_team_update_time_tracking- Update a time tracking entryholded_team_delete_time_tracking- Delete a time tracking entryholded_team_employee_clock_in- Clock in an employeeholded_team_employee_clock_out- Clock out an employeeholded_team_employee_pause- Pause employee time trackingholded_team_employee_unpause- Unpause employee time tracking
Document Types
The following document types are supported:
invoice- Sales invoicessalesreceipt- Sales receiptscreditnote- Sales refundsreceiptnote- Ticket sales refundsestimate- Sales estimates/quotessalesorder- Sales orderswaybill- Packing listsproform- Proforma invoicespurchase- Purchasespurchaserefund- Purchase refundspurchaseorder- Purchase orders
Response Formats
All tools support two response formats:
json(default) - Structured JSON data for programmatic processingmarkdown- Human-readable formatted text
Error Handling
The server provides clear, actionable error messages for common scenarios:
- Authentication errors (401) - Check your API key
- Not found errors (404) - Verify resource IDs
- Rate limiting (429) - Wait before retrying
- Validation errors (422) - Check input parameters
Performance
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 above):
- Reduced token usage: Fewer tool definitions means less context sent to the LLM
- Faster responses: The model spends less time parsing available tools
- Lower costs: Smaller prompts reduce API costs for token-based billing
For example, if you only work with invoicing, you can set HOLDED_MODULES=invoicing to disable CRM, Projects, Accounting, and Team modules.
Troubleshooting
Common Issues
1. API Key Not Found
Error: ERROR: HOLDED_API_KEY environment variable is required.
Solution: Ensure your API key is properly configured in your MCP client settings:
- Check that
HOLDED_API_KEYis set in theenvsection - Verify the key is correct (no extra spaces or quotes)
- Get your API key from Configuration → API in Holded
2. 401 Unauthorized
Error: API returns 401 status code
Solution:
- Verify your API key is valid and not expired
- Check that the key has the necessary permissions
- Regenerate the API key if needed
3. 422 Validation Error
Error: API returns 422 status code
Solution:
- Check that all required parameters are provided
- Verify parameter types match expectations (string vs number)
- For nested objects (stock updates, custom fields), ensure correct structure
4. Module Not Loading
Error: Tools from a specific module are missing
Solution:
- Check if you've set
HOLDED_MODULESenvironment variable - If set, ensure the module name is included (e.g.,
"HOLDED_MODULES": "invoicing,crm") - Remove
HOLDED_MODULESor leave it empty to load all modules
Complex Operation Examples
Stock Updates
Updating product stock requires a nested object structure where you specify warehouse ID and product/variant IDs:
// Stock update structure: stock[warehouseId][productId/variantId] = quantity
{
"product_id": "abc123",
"stock": {
"warehouse1": {
"productId1": 100,
"variantId1": 50
},
"warehouse2": {
"productId1": 75
}
}
}
Example: Set stock for product "abc123" to 100 units in warehouse "wh1":
{
"product_id": "abc123",
"stock": {
"wh1": {
"abc123": 100
}
}
}
Booking Creation
Bookings require specific custom fields with key-value pairs:
{
"locationId": "location123",
"serviceId": "service456",
"dateTime": 1730109600, // Unix timestamp
"timezone": "Europe/Madrid",
"language": "es",
"customFields": [
{
"key": "name",
"value": "John Doe"
},
{
"key": "email",
"value": "john@example.com"
},
{
"key": "phone",
"value": "+34612345678"
}
]
}
Task Creation
Tasks require both project ID and list ID (the list/column within the project):
{
"name": "New Task",
"project_id": "proj123",
"list_id": "list456" // Get this from project details
}
Note: To get available list IDs, first fetch the project details using holded_projects_get_project.
Accounting Entries
Daily ledger entries must have balanced debits and credits:
{
"date": 1730109600, // Unix timestamp
"lines": [
{
"account": 4300, // Account number (integer)
"debit": 1000,
"description": "Sales revenue"
},
{
"account": 5700, // Account number (integer)
"credit": 1000,
"description": "Bank account"
}
],
"notes": "Monthly sales entry"
}
Requirements:
- Minimum 2 lines
- Total debits must equal total credits
- Each line must have either debit OR credit (not both)
- Account numbers must be positive integers
Parameter Naming Convention
This MCP server uses a consistent parameter naming convention:
- Path/Query parameters: Use
snake_case(e.g.,employee_id,doc_type) - Request body fields: Use
camelCasematching the API (e.g.,lastName,sendInvite)
The tool handlers automatically transform parameters to the format expected by the Holded API.
Workflow Examples
This section demonstrates common real-world workflows combining multiple API operations.
Creating a Complete Invoice
// 1. First, ensure you have a contact
const contact = await holded_invoicing_create_contact({
name: "Acme Corp",
email: "billing@acme.com",
code: "B12345678" // Tax ID
});
// 2. Create the invoice with line items
const invoice = await holded_invoicing_create_document({
doc_type: "invoice",
contactId: contact.id,
contactName: "Acme Corp",
date: 1730109600, // Unix timestamp
items: [
{
name: "Web Development Service",
units: 40,
subtotal: 4000, // 40 hours × €100/hour
tax: 21 // 21% VAT
},
{
name: "Hosting Service (Annual)",
units: 1,
subtotal: 500,
tax: 21
}
],
notes: "Payment due within 30 days"
});
// 3. Send the invoice via email
await holded_invoicing_send_document({
doc_type: "invoice",
document_id: invoice.id,
emails: ["billing@acme.com"]
});
// 4. Record payment when received
await holded_invoicing_pay_document({
doc_type: "invoice",
document_id: invoice.id,
paid: 5445, // Total with VAT (€4,500 × 1.21)
date: 1732701600 // Payment date
});
Managing Lead Lifecycle
// 1. Create a new lead
const lead = await holded_crm_create_lead({
name: "Enterprise Client Prospect",
funnelId: "funnel123",
stageId: "stage_initial_contact",
contactName: "Jane Smith",
email: "jane.smith@enterprise.com",
phone: "+34912345678"
});
// 2. Add initial contact notes
await holded_crm_create_lead_note({
lead_id: lead.id,
note: "Initial call: Interested in enterprise plan. Budget: €50k/year. Decision timeline: Q2 2026."
});
// 3. Create follow-up task
await holded_crm_create_lead_task({
lead_id: lead.id,
task: "Send proposal and pricing",
dueDate: 1730800000 // 1 week from now
});
// 4. Update lead stage after proposal sent
await holded_crm_update_lead_stage({
lead_id: lead.id,
stageId: "stage_proposal_sent"
});
// 5. Add proposal notes
await holded_crm_create_lead_note({
lead_id: lead.id,
note: "Sent proposal via email. Includes: Enterprise tier, custom integrations, dedicated support."
});
// 6. When deal is won, convert to contact
const contact = await holded_invoicing_create_contact({
name: "Enterprise Client Inc",
email: "jane.smith@enterprise.com",
phone: "+34912345678"
});
// 7. Move lead to won stage
await holded_crm_update_lead_stage({
lead_id: lead.id,
stageId: "stage_won"
});
Employee Onboarding Workflow
// 1. Create new employee
const employee = await holded_team_create_employee({
name: "María",
lastName: "García",
email: "maria.garcia@company.com",
sendInvite: true // Sends email invitation
});
// 2. Update employee details after onboarding
await holded_team_update_employee({
employee_id: employee.id,
phone: "+34666123456",
mobile: "+34666123456",
dateOfBirth: "15/03/1990",
nationality: "Spanish",
iban: "ES1234567890123456789012",
address: {
address: "Calle Mayor 123",
city: "Madrid",
postalCode: "28013",
province: "Madrid",
country: "Spain"
},
workplace: "office_madrid_001",
teams: ["team_engineering", "team_backend"]
});
// 3. Set up first time tracking entry
await holded_team_create_employee_time_tracking({
employee_id: employee.id,
startTmp: "1730109600", // 9:00 AM (Unix timestamp as string)
endTmp: "1730138400" // 5:00 PM (Unix timestamp as string)
});
// 4. Use clock-in/clock-out for daily tracking
await holded_team_employee_clock_in({
employee_id: employee.id,
location: "Madrid Office"
});
// Later in the day...
await holded_team_employee_clock_out({
employee_id: employee.id,
latitude: "40.4168",
longitude: "-3.7038"
});
Multi-Warehouse Stock Management
// 1. Create warehouses
const warehouseMadrid = await holded_invoicing_create_warehouse({
name: "Madrid Warehouse",
address: {
address: "Polígono Industrial Sur",
city: "Madrid",
postalCode: "28021",
country: "Spain"
}
});
const warehouseBarcelona = await holded_invoicing_create_warehouse({
name: "Barcelona Warehouse",
address: {
address: "Zona Franca",
city: "Barcelona",
postalCode: "08040",
country: "Spain"
}
});
// 2. Create a product
const product = await holded_invoicing_create_product({
name: "Wireless Mouse MX Master",
sku: "TECH-MOUSE-001",
price: 89.99,
tax: 21
});
// 3. Update stock across multiple warehouses
await holded_invoicing_update_product_stock({
product_id: product.id,
stock: {
[warehouseMadrid.id]: {
[product.id]: 150 // 150 units in Madrid
},
[warehouseBarcelona.id]: {
[product.id]: 200 // 200 units in Barcelona
}
}
});
// 4. Check stock levels for a specific warehouse
const madridStock = await holded_invoicing_list_products_stock({
warehouse_id: warehouseMadrid.id
});
// 5. Transfer stock between warehouses (reduce Madrid, increase Barcelona)
await holded_invoicing_update_product_stock({
product_id: product.id,
stock: {
[warehouseMadrid.id]: {
[product.id]: 125 // Reduced by 25
},
[warehouseBarcelona.id]: {
[product.id]: 225 // Increased by 25
}
}
});
Document Shipping Workflow
// 1. Create a sales order
const salesOrder = await holded_invoicing_create_document({
doc_type: "salesorder",
contactId: "contact123",
contactName: "Tech Store SL",
date: 1730109600,
items: [
{
name: "Laptop HP ProBook",
sku: "LAPTOP-HP-001",
units: 5,
subtotal: 3500,
tax: 21
},
{
name: "USB-C Dock",
sku: "DOCK-USBC-001",
units: 5,
subtotal: 500,
tax: 21
}
],
warehouseId: "warehouse_madrid_001"
});
// 2. Add tracking information
await holded_invoicing_update_document_tracking({
doc_type: "salesorder",
document_id: salesOrder.id,
carrier: "DHL Express",
trackingNumber: "1234567890",
trackingUrl: "https://dhl.com/track/1234567890"
});
// 3. Ship all items at once
const shipment = await holded_invoicing_ship_all_items({
document_id: salesOrder.id
});
// Alternative: Ship items line by line (partial shipments)
// await holded_invoicing_ship_items_by_line({
// document_id: salesOrder.id,
// lines: [
// { lineId: "line1", units: 3 }, // Ship 3 laptops now
// { lineId: "line2", units: 5 } // Ship all docks now
// ]
// });
// 4. Check shipped items
const shippedItems = await holded_invoicing_get_shipped_items({
doc_type: "salesorder",
document_id: salesOrder.id
});
// 5. Update pipeline stage
await holded_invoicing_update_document_pipeline({
doc_type: "salesorder",
document_id: salesOrder.id,
pipelineStage: "shipped"
});
// 6. Create invoice from the sales order
const invoice = await holded_invoicing_create_document({
doc_type: "invoice",
contactId: "contact123",
salesorderId: salesOrder.id, // Link to sales order
date: 1730196000
});
Development
Build from Source
If you want to build from source (for development or contributions):
git clone https://github.com/energio-es/holded-mcp.git
cd holded-mcp
npm install
npm run build
Then use the built server in your MCP client configuration:
{
"mcpServers": {
"holded": {
"command": "node",
"args": ["/absolute/path/to/holded-mcp/dist/index.js"],
"env": {
"HOLDED_API_KEY": "your_api_key_here"
}
}
}
}
Development Commands
# Install dependencies
npm install
# Build TypeScript
npm run build
# Run in development mode with auto-reload
npm run dev
# Clean build artifacts
npm run clean
Contributing
Contributions are welcome! Please read our Contributing Guide for details on the process for submitting pull requests.
Quick Start for Contributors
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Make your changes
- Commit using Conventional Commits (
git commit -m 'feat: add amazing feature') - Push to your branch (
git push origin feature/amazing-feature) - Open a Pull Request
License
This project is licensed under the MIT License - see the LICENSE file for details.
Community & Governance
Support
- Holded API Documentation: https://developers.holded.com/reference
- Issues: GitHub Issues - Response time: 1-2 weeks
- Discussions: GitHub Discussions
- Security: Report a Vulnerability - Response time: 72 hours