MCP Holded
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| HOLDED_API_KEY | Yes | Your Holded API key (get it from Holded Settings > API) |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_documentsA | List documents of a specific type (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. NOTE: purchaserefund is not listable in v2 — only creation is supported (POST /purchases/refund). |
| create_documentA | Create a new document (invoice, estimate, purchase, etc.). By default the document is approved (finalized) so it appears in the Holded UI; pass approveDoc:false to create a draft instead. Set the expense/income account at document level via |
| get_documentB | Get a specific document by ID |
| get_document_paymentsA | Get the payments registered against a specific document via the Holded API v2 GET endpoint. Returns |
| update_documentC | Update an existing document |
| delete_documentC | Delete a document |
| pay_documentA | Register a payment for a document (Holded API v2). Supported docTypes: invoice, salesreceipt, creditnote, receiptnote, purchase — others throw an unsupported error. IMPORTANT: this may AUTO-APPROVE the document as a side effect (status 0→1). |
| send_documentA | Send a document by email (Holded API v2). Supported docTypes: invoice, salesreceipt, creditnote, receiptnote, estimate, proform, salesorder, waybill, purchaseorder. purchase and purchaserefund are not supported in v2. |
| get_document_pdfA | Get the PDF of a document as base64-encoded binary (Holded API v2). Returns { contentType, base64, bytes, filename }. Supported docTypes: invoice, salesreceipt, creditnote, receiptnote, estimate, proform, salesorder, waybill, purchaseorder. purchase is NOT supported — GET /purchases/{id}/pdf returns 404 for all purchases. purchaserefund has no CRUD support in v2. |
| ship_all_itemsA | Ship all items of a document (Holded API v2). salesorder → POST /sales-orders/{id}/ship. purchaseorder → POST /purchase-orders/{id}/receive (receive from supplier). All other docTypes are not supported in v2. |
| ship_items_by_lineA | Ship specific items by line (Holded API v2). salesorder only → POST /sales-orders/{id}/ship-by-lines. purchaseorder line-level receive is UNVERIFIED in v2 and throws unsupported. All other docTypes are not supported. |
| get_shipped_unitsA | Get shipped/received units for a document (Holded API v2). salesorder → GET /sales-orders/{id}/shipped-items. purchaseorder → GET /purchase-orders/{id}/received-items. All other docTypes are not supported. |
| attach_file_to_documentA | Attach a file to a document (Holded API v2). POST ${docBase}/{id}/attachments multipart. Supported for all docTypes except purchaserefund (v2 has no purchase-refund CRUD beyond creation). |
| update_document_trackingA | Update tracking information for a document (Holded API v2). Supported docTypes: salesorder (PUT /sales-orders/{id}/tracking) and waybill (PUT /waybills/{id}/tracking). All other types have NO EQUIVALENT in v2 and will throw an unsupported error. NOTE: this is a discrepancy with the task brief (which stated "all types unsupported") — the normative annex tables show salesorder and waybill do have tracking in v2. |
| update_document_pipelineA | Update pipeline stage for a document (Holded API v2). Uses PUT — verb changed from POST in v1. Supported for all docTypes except purchaserefund (v2 limitation). Route: PUT ${docBase}/{id}/pipeline. |
| list_payment_methodsA | List available payment methods (Holded API v2). GET /payment-methods. Returns an array of {id, name, type, status, isDefault, bankingAccountId} — the v2 {items:[...]} envelope is normalized to a bare array. |
| list_contactsA | List contacts (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. |
| create_contactC | Create a new contact (Holded API v2) |
| get_contactB | Get a specific contact by ID (Holded API v2) |
| update_contactC | Update an existing contact (Holded API v2) |
| delete_contactC | Delete a contact (Holded API v2) |
| list_contact_attachmentsA | Get list of attachments for a contact (Holded API v2). Use the filenames from the response with get_contact_attachment. |
| get_contact_attachmentA | Get a specific attachment from a contact by filename (Holded API v2). BREAKING CHANGE from v1: the path parameter changed from attachmentId (numeric/UUID) to filename (string). Obtain filenames from list_contact_attachments first. |
| list_productsA | List products (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Server-paginated; use limit to control page size. Response fields are snake_case; amounts are strings with decimal comma. |
| create_productC | Create a new product (Holded API v2) |
| get_productB | Get a specific product by ID (Holded API v2) |
| update_productC | Update an existing product (Holded API v2) |
| delete_productC | Delete a product (Holded API v2) |
| get_product_main_imageC | Get the main image of a product (Holded API v2) |
| list_product_imagesB | List all images of a product (Holded API v2) |
| get_product_secondary_imageB | Get a secondary image of a product (Holded API v2) |
| update_product_stockB | Update stock quantity for a product (Holded API v2). BREAKING CHANGE from v1: |
| list_treasuriesA | List all treasury accounts (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. WARNING: the |
| create_treasuryC | Create a new treasury account (Holded API v2). Overlaps with list_bank_accounts/get_bank_account/create_bank_account (official treasury tools); consolidation planned for 2.1. |
| get_treasuryA | Get a specific treasury account by ID (Holded API v2). WARNING: the |
| list_expenses_accountsA | List expenses accounts (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. Each account has |
| create_expenses_accountC | Create a new expenses account (Holded API v2) |
| get_expenses_accountA | Get a single account by its Holded id (Holded API v2). Despite the "expenses" name, this endpoint serves ANY account (including income/group-7 accounts that list_expenses_accounts omits) when you already know its id. |
| update_expenses_accountC | Update an existing expenses account (Holded API v2) |
| delete_expenses_accountC | Delete an expenses account (Holded API v2) |
| get_numbering_seriesA | List numbering series for a specific document type (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. |
| create_numbering_serieC | Create a new numbering serie (Holded API v2) |
| update_numbering_serieC | Update an existing numbering serie (Holded API v2) |
| delete_numbering_serieC | Delete a numbering serie (Holded API v2) |
| list_sales_channelsA | List all sales channels (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. Supports field filtering to reduce response size. |
| create_sales_channelC | Create a new sales channel (Holded API v2) |
| get_sales_channelC | Get a specific sales channel by ID (Holded API v2) |
| update_sales_channelC | Update an existing sales channel (Holded API v2) |
| delete_sales_channelC | Delete a sales channel (Holded API v2) |
| list_paymentsA | List all payments (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. NOTE: this endpoint is filtered to the ACTIVE fiscal year, so payments made in a prior year do NOT appear here even if they are linked to documents. For cross-year payment audits, read a document's payments via get_document_payments (the document |
| create_paymentC | Create a new payment (Holded API v2) |
| get_paymentA | Get a specific payment by ID (Holded API v2) |
| update_paymentA | Update an existing payment (Holded API v2). IMPORTANT: Holded's PUT /payments/{id} REPLACES the record rather than merging, so any field omitted from the body is blanked. To prevent that, this tool first re-reads the current payment and merges your changes over it, preserving fields you did not pass (contactId, bankId, date, ...). |
| delete_paymentC | Delete a payment (Holded API v2) |
| get_taxesA | Get all available taxes (Holded API v2). The v2 /taxes endpoint returns the complete tax list in one response (no cursor, no pagination). Supports |
| list_contact_groupsB | List contact groups (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. |
| create_contact_groupC | Create a new contact group (Holded API v2) |
| get_contact_groupB | Get a specific contact group by ID (Holded API v2) |
| update_contact_groupC | Update an existing contact group (Holded API v2) |
| delete_contact_groupC | Delete a contact group (Holded API v2) |
| list_remittancesA | List all remittances (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. NOTE: namespace relocated from /remittances to /treasury/remittances in v2. |
| get_remittanceB | Get a specific remittance by ID (Holded API v2). NOTE: route relocated to /treasury/remittances/{id} in v2. |
| list_servicesA | List all services (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Response fields are snake_case; amounts are strings with decimal comma. Supports field filtering to reduce response size. |
| create_serviceC | Create a new service (Holded API v2) |
| get_serviceB | Get a specific service by ID (Holded API v2) |
| update_serviceC | Update an existing service (Holded API v2) |
| delete_serviceC | Delete a service (Holded API v2) |
| list_warehousesA | List all warehouses (Holded API v2). All warehouses are returned in a single call (no cursor pagination). Supports field filtering and summary mode. |
| create_warehouseC | Create a new warehouse (Holded API v2) |
| list_warehouse_stockB | List all products stock in a specific warehouse (Holded API v2). Cursor-paginated: pass the previous response nextCursor as cursor. Server-paginated; use limit to control page size. Supports field filtering to reduce response size. |
| get_warehouseA | Get a specific warehouse by ID (Holded API v2) |
| update_warehouseA | Update an existing warehouse (Holded API v2). BREAKING CHANGE from v1: HTTP verb changed from PUT to PATCH. |
| delete_warehouseC | Delete a warehouse (Holded API v2) |
| list_project_timesA | List time-tracking entries across all Holded projects (Projects API v2). Returns a cursor-paginated flat list of entries; pass the previous |
| list_project_times_by_projectA | List time-tracking entries for a single Holded project (Projects API v2). Returns a cursor-paginated flat list of entries for the given projectId. Pass the previous |
| get_project_timeA | Get a single time-tracking entry by project ID and time-tracking ID (Projects API v2). Read-only. |
| get_chart_of_accountsA | Get accounting accounts (Holded API v2, GET /accounting-accounts). Returns every account with |
| get_daily_ledgerA | Get ledger entries / journal (asientos) for a date range (Holded API v2, GET /ledger-entries). Returns one row per ledger line with entryNumber, line, timestamp, type (collect/payment/purchase/…), description, account (PGC num), debit, and credit. This is the authoritative source for balance-sheet and tax-return figures. Date arguments (at least one form of each bound is required — the v2 API returns 422 without both):
• Primary form : If both forms are supplied for the same bound, the ISO string takes precedence. Cursor-paginated: pass |
| list_employeesA | List employees (Holded API v2, section Equipo y RRHH). Cursor-paginated: pass the previous response |
| get_employeeC | Get a single employee by ID (Holded API v2). |
| create_employeeA | WRITE: creates a real employee record in Holded (API v2). |
| update_employeeB | WRITE: updates a real employee record in Holded (API v2). |
| delete_employeeA | DESTRUCTIVE: permanently deletes an employee record in Holded (API v2). This cannot be undone. |
| get_employee_contractA | Get the contract details of an employee (Holded API v2). A 404 response means the employee has no contract configured in Holded, not that the employee ID is wrong. |
| update_employee_contractB | WRITE: updates an employee's contract in Holded (API v2) — affects real HR/payroll data. |
| clock_in_employeeB | WRITE: registers a clock-in for an employee in Holded time tracking (API v2). Affects real working-time records. |
| clock_out_employeeB | WRITE: registers a clock-out for an employee in Holded time tracking (API v2). |
| pause_employeeB | WRITE: starts a pause in the current working session of an employee (Holded API v2). |
| unpause_employeeA | WRITE: ends the current pause of an employee working session (Holded API v2). |
| list_employee_timesA | List time-tracking records (Holded API v2). Without |
| get_employee_timeB | Get a single time-tracking record by ID (Holded API v2). |
| create_employee_timeA | WRITE: creates a manual time-tracking record for an employee (Holded API v2). |
| update_employee_timeC | WRITE: updates a time-tracking record (Holded API v2). |
| delete_employee_timeA | DESTRUCTIVE: permanently deletes a time-tracking record in Holded (API v2). This cannot be undone. |
| list_salary_recordsA | List payroll salary records (Holded API v2, requires scope accounting:payrolls.read). Each record has employee info, earnings/deductions lines, totals and payment status (PENDING, PAID, PARTIALLY_PAID). Cursor-paginated. |
| get_salary_recordA | Get a payroll salary record by ID (Holded API v2, scope accounting:payrolls.read). Returns line-by-line earnings and deductions, accounting accounts, totals and payment status. |
| create_salary_recordA | WRITE: creates a real payroll record in Holded (API v2) — affects accounting and HR data. Use get_salary_record_defaults first to obtain a valid base payload. |
| update_salary_recordA | WRITE: updates a payroll record in Holded (API v2) — affects accounting and HR data. |
| delete_salary_recordA | DESTRUCTIVE: permanently deletes a payroll record in Holded (API v2). This cannot be undone and affects accounting data. |
| get_salary_record_defaultsA | Get the default data for creating a payroll record (Holded API v2). Useful as a base payload for create_salary_record. |
| list_ledger_entriesA | List journal/ledger entries (Holded API v2). Cursor-paginated: pass the previous response |
| create_ledger_entryA | WRITE: creates a real journal entry in Holded accounting (API v2). Incorrect entries directly distort the company books — double-check accounts and amounts. |
| list_accounting_accountsA | List accounting accounts (Holded API v2). Cursor-paginated. For the v1 read-only chart of accounts see get_chart_of_accounts. |
| create_accounting_accountB | WRITE: creates a real accounting account in the Holded chart of accounts (API v2). |
| list_bank_accountsB | List treasury bank accounts (Holded API v2, official endpoint). Cursor-paginated. |
| get_bank_accountB | Get a treasury bank account by ID (Holded API v2). |
| create_bank_accountB | WRITE: creates a real treasury bank account in Holded (API v2). |
| update_bank_accountB | WRITE: updates a treasury bank account in Holded (API v2). |
| delete_bank_accountA | DESTRUCTIVE: permanently deletes a treasury bank account in Holded (API v2). Prefer archive_bank_account to keep history. This cannot be undone. |
| archive_bank_accountA | WRITE: archives a treasury bank account in Holded (API v2). Reversible alternative to delete_bank_account. |
| list_bank_movementsA | List bank movements of a treasury account (Holded API v2, official endpoint — replaces the experimental internal banking tools). Cursor-paginated. |
| create_bank_movementC | WRITE: creates a real bank movement in a treasury account (Holded API v2). |
| reconcile_bank_movementA | WRITE: reconciles a bank movement against documents/entries (Holded API v2, official endpoint — replaces the experimental reconcile_bank_transaction from the internal API when v2 is enabled). |
| list_cash_movementsA | List cash movements of a treasury account (Holded API v2). Cursor-paginated. This endpoint applies to cash-type treasury accounts only; bank and card account types return 404. |
| list_invoicing_forecastsB | List cashflow invoicing forecasts (Holded API v2). Cursor-paginated. |
| get_invoicing_forecastB | Get a cashflow invoicing forecast by ID (Holded API v2). |
| create_invoicing_forecastA | WRITE: creates an invoicing forecast in Holded cashflow (API v2). |
| update_invoicing_forecastB | WRITE: updates an invoicing forecast in Holded cashflow (API v2). |
| delete_invoicing_forecastA | DESTRUCTIVE: permanently deletes an invoicing forecast in Holded cashflow (API v2). |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 119 tools
Many tools are cleanly distinct by resource and action, but several overlap explicitly: list_treasuries vs the bank_account tools, list_ledger_entries vs get_daily_ledger (same endpoint), and get_chart_of_accounts vs list_accounting_accounts (same endpoint). The descriptions helpfully flag these duplications and consolidation plans, which mitigates some misselection risk, but the boundaries remain unclear in practice.
Most tools follow a predictable list_/get_/create_/update_/delete_ + resource pattern (list_contacts, get_product, delete_payment, etc.). Some deviations exist (ship_all_items, clock_in_employee, reconcile_bank_movement, get_taxes plural, and the 'serie'/'series' inconsistency), but they are action verbs that stay readable.
119 tools is very high even for a full ERP surface covering contacts, documents, payroll, accounting, and treasury. Redundant pairs (treasury vs bank accounts, ledger vs daily ledger, chart of accounts vs ledger accounts) show bloat rather than strictly additive scope, with consolidation explicitly deferred to a later release.
Coverage is broad and lifecycle-complete across most domains (contacts, products, documents, payments, treasury, warehouses, payroll, accounting, contact groups, numbering series). A few gaps exist — purchaserefund has no full CRUD, purchase PDFs unsupported — but these are largely upstream API limitations that agents can work around.