# Mcp Server Acube

> MCP server from nick-preda/mcp-server-acube.

- **Type:** MCP server
- **Install:** `agentstack add mcp-nick-preda-mcp-server-acube`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [nick-preda](https://agentstack.voostack.com/s/nick-preda)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [nick-preda](https://github.com/nick-preda)
- **Source:** https://github.com/nick-preda/mcp-server-acube

## Install

```sh
agentstack add mcp-nick-preda-mcp-server-acube
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# mcp-server-acube

[](https://www.npmjs.com/package/mcp-server-acube)
[](https://opensource.org/licenses/MIT)
[](https://modelcontextprotocol.io)

A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that provides **38 tools** for interacting with the [A-Cube API](https://www.acubeapi.com/) -- the Italian electronic invoicing platform for SDI (Sistema di Interscambio), FatturaPA, smart receipts, company verification, and more.

Connect this server to Claude Desktop, Claude Code, or any MCP-compatible client to manage Italian electronic invoicing through natural language.

## Features

- **Electronic Invoicing** -- Send, list, and retrieve FatturaPA invoices via SDI, with support for JSON, XML, PDF, and HTML formats
- **AI-Powered PDF Extraction** -- Convert PDF invoices to FatturaPA format using A-Cube's AI extraction pipeline
- **Smart Receipts** -- Issue, void, and manage electronic receipts (scontrini elettronici)
- **Company Verification** -- Look up Italian companies by P.IVA or codice fiscale, verify fiscal IDs, and check split payment status
- **SDI Notifications** -- Monitor delivery receipts, rejections, and all other SDI notification types
- **Cassetto Fiscale** -- Schedule recurring or one-time bulk downloads from the Agenzia delle Entrate tax drawer
- **Webhooks** -- Configure real-time event callbacks for 13 different event types
- **Business Registry & ADE Appointees** -- Manage company profiles and fiscal intermediary configurations
- **Token-Optimized Responses** -- Compact JSON output with null stripping and field selection to minimize LLM token consumption
- **Automatic Authentication** -- JWT token management with automatic refresh (24h token lifetime)
- **Sandbox & Production** -- Seamlessly switch between A-Cube sandbox and production environments

## Quick Start

### Prerequisites

You need an [A-Cube API](https://www.acubeapi.com/) account. Sign up at [acubeapi.com](https://www.acubeapi.com/) to get your credentials.

### Claude Desktop

Add the following to your Claude Desktop configuration file (`claude_desktop_config.json`):

```json
{
  "mcpServers": {
    "acube": {
      "command": "npx",
      "args": ["-y", "mcp-server-acube"],
      "env": {
        "ACUBE_EMAIL": "your-email@example.com",
        "ACUBE_PASSWORD": "your-password",
        "ACUBE_ENVIRONMENT": "sandbox"
      }
    }
  }
}
```

### Claude Code

```bash
claude mcp add acube -- npx -y mcp-server-acube \
  -e ACUBE_EMAIL=your-email@example.com \
  -e ACUBE_PASSWORD=your-password \
  -e ACUBE_ENVIRONMENT=sandbox
```

Or add it manually to `.mcp.json` in your project root:

```json
{
  "mcpServers": {
    "acube": {
      "command": "npx",
      "args": ["-y", "mcp-server-acube"],
      "env": {
        "ACUBE_EMAIL": "your-email@example.com",
        "ACUBE_PASSWORD": "your-password",
        "ACUBE_ENVIRONMENT": "sandbox"
      }
    }
  }
}
```

## Configuration

The server is configured through environment variables:

| Variable | Required | Default | Description |
|---|---|---|---|
| `ACUBE_EMAIL` | Yes | -- | Your A-Cube account email |
| `ACUBE_PASSWORD` | Yes | -- | Your A-Cube account password |
| `ACUBE_ENVIRONMENT` | No | `sandbox` | API environment: `sandbox` or `production` |

## Production vs Sandbox

A-Cube uses the **same account credentials** for both environments. The only
thing that switches environment is the `ACUBE_ENVIRONMENT` variable, which
routes requests to the matching base URLs:

| Environment | Auth (`common`) | API (`govIt`) |
|---|---|---|
| `sandbox` | `common-sandbox.api.acubeapi.com` | `api-sandbox.acubeapi.com` |
| `production` | `common.api.acubeapi.com` | `api.acubeapi.com` |

So to use the same credentials for testing, just set
`ACUBE_ENVIRONMENT=sandbox` — no separate sandbox login is required.

**Running both at once.** Register **two MCP servers**, one per environment,
with identical credentials and different `ACUBE_ENVIRONMENT` values:

```jsonc
{
  "mcpServers": {
    "acube-sandbox": {
      "command": "npx",
      "args": ["-y", "mcp-server-acube"],
      "env": { "ACUBE_EMAIL": "...", "ACUBE_PASSWORD": "...", "ACUBE_ENVIRONMENT": "sandbox" }
    },
    "acube-production": {
      "command": "npx",
      "args": ["-y", "mcp-server-acube"],
      "env": { "ACUBE_EMAIL": "...", "ACUBE_PASSWORD": "...", "ACUBE_ENVIRONMENT": "production" }
    }
  }
}
```

**Knowing which environment you are in.** To prevent an agent from confusing the
two on irreversible operations, the server makes the active environment visible
in three ways:

- The server **instructions** state the active environment.
- Every **tool description** is prefixed with `[SANDBOX]` or `[PRODUCTION]`
  (live-write tools in production get `[PRODUCTION - LIVE WRITE, irreversible]`).
- `send_invoice` / `send_simplified_invoice` echo an `"environment"` field in
  their response.

> ⚠️ **Always test a new invoice in sandbox first, then resend in production.**
> A production `send_invoice` submits a real, irreversible invoice to SDI;
> correcting it requires issuing a credit note.

## Available Tools

### Invoices (4 tools)

| Tool | Description |
|---|---|
| `send_invoice` | Send a FatturaPA electronic invoice to SDI. Accepts the complete FatturaPA JSON object. Returns the UUID assigned by SDI (HTTP 202). Supports optional digital signing. |
| `send_simplified_invoice` | Send a simplified FatturaPA invoice (fattura semplificata) for amounts up to 400 EUR. |
| `list_invoices` | List and filter invoices with 20+ filters (sender/recipient name, VAT, status, date ranges, invoice series, etc.). Returns a **compact default view** -- see [Response Optimization](#response-optimization). |
| `get_invoice` | Retrieve a specific invoice by UUID. Output formats: JSON, XML (FatturaPA), PDF (base64), or HTML. Supports field selection. |

### Invoice Extraction (3 tools)

| Tool | Description |
|---|---|
| `extract_invoice_from_pdf` | Upload a PDF invoice (base64-encoded) for AI-powered conversion to FatturaPA format. Returns a job UUID. |
| `get_extraction_status` | Poll the status of a PDF extraction job by UUID. |
| `get_extraction_result` | Retrieve the converted FatturaPA invoice from a completed extraction job. Available in JSON or XML format. |

### Notifications (3 tools)

| Tool | Description |
|---|---|
| `list_notifications` | List SDI notifications with filtering by type (NS, MT, RC, MC, EC, SE, NE, DT, AT) and download status. |
| `get_notification` | Get a specific SDI notification by UUID in JSON or original XML format. |
| `mark_notifications_downloaded` | Mark one or more notifications as downloaded by providing their UUIDs. |

### Verification (4 tools)

| Tool | Description |
|---|---|
| `verify_fiscal_id` | Validate an Italian codice fiscale or P.IVA against the Agenzia delle Entrate. |
| `verify_company` | Full company lookup by P.IVA or codice fiscale. Returns name, PEC, SDI code, address, ATECO code, shareholders, and more. |
| `verify_simple_company` | Basic company info lookup -- a lightweight alternative to `verify_company`. |
| `verify_split_payment` | Check if a company has split payment (scissione dei pagamenti) status for public administration invoicing. |

### Smart Receipts (4 tools)

| Tool | Description |
|---|---|
| `send_receipt` | Issue an electronic receipt (scontrino elettronico) with items, payment amounts, and fiscal ID. |
| `get_receipt_details` | Get receipt transaction details including document number. |
| `void_receipt` | Void/cancel an electronic receipt (annullamento). |
| `return_receipt_items` | Process item returns against an existing receipt. |

### Webhooks (5 tools)

| Tool | Description |
|---|---|
| `list_webhook_configs` | List all webhook configurations. |
| `create_webhook_config` | Subscribe to events by specifying an event type and target URL. Supports 13 event types including supplier-invoice, customer-invoice, receipt, and more. |
| `get_webhook_config` | Get a specific webhook configuration by ID. |
| `update_webhook_config` | Update webhook settings (event type, URL, authentication). |
| `delete_webhook_config` | Remove a webhook configuration. |

### Business Registry & ADE Appointees (8 tools)

| Tool | Description |
|---|---|
| `list_business_registries` | List all business registry configurations (anagrafiche aziendali). |
| `create_business_registry` | Create a new company profile for electronic invoicing, including fiscal ID, signature, and legal storage settings. |
| `get_business_registry` | Get a specific business registry configuration by ID. |
| `update_business_registry` | Update an existing company profile. |
| `list_appointees` | List all ADE tax appointees (intermediari fiscali). |
| `create_appointee` | Register a new fiscal intermediary authorized to operate with the Agenzia delle Entrate. |
| `get_appointee` | Get a specific ADE appointee by ID. |
| `update_appointee` | Update an existing fiscal intermediary. |

### Cassetto Fiscale & Rejected Invoices (7 tools)

| Tool | Description |
|---|---|
| `schedule_invoice_download` | Set up recurring daily invoice downloads from the Cassetto Fiscale (tax drawer) at 03:00 UTC. |
| `get_download_schedule` | Check the status of an invoice download schedule (active, auto-renewal, last execution). |
| `update_download_schedule` | Modify download schedule options. |
| `delete_download_schedule` | Stop recurring invoice downloads. |
| `download_invoices_once` | Trigger a one-time bulk invoice download by date range from the Agenzia delle Entrate. |
| `count_rejected_invoices` | Count invoices that were rejected during Cassetto Fiscale processing. |
| `recover_rejected_invoices` | Reprocess previously rejected invoices for a given fiscal ID and date range. |

## Response Optimization

This server is designed to minimize LLM token consumption. Every response goes through three optimizations:

### 1. Payload parsing

The A-Cube API returns the FatturaPA invoice data as a raw JSON string in the `payload` field. The server automatically parses this string into a structured object, which enables null stripping to work on the ~60 null fields inside it. This eliminates double-encoding overhead (`\"` escapes) and typically cuts payload token usage by ~50%.

### 2. Null stripping

All `null` and `undefined` values are recursively removed from responses -- including inside the parsed payload. A typical invoice `sender` object has ~40 fields, of which ~30 are null. After stripping, only the 5--8 populated fields remain.

### 3. Compact JSON

Responses are serialized without indentation (`JSON.stringify(data)` instead of `JSON.stringify(data, null, 2)`). This eliminates whitespace tokens that provide no information to the LLM.

### 4. Default field selection on `list_invoices`

The `list_invoices` tool returns a **compact default view** (10 items per page) instead of the full A-Cube response. The raw API response includes the entire FatturaPA payload (~2000 tokens per invoice) and full sender/recipient objects. The compact view extracts only the essential fields:

| Default field | Description |
|---|---|
| `uuid` | Invoice UUID |
| `created_at` | Creation timestamp on A-Cube |
| `document_type` | FatturaPA type code (TD01, TD04, etc.) |
| `marking` | SDI status (delivered, rejected, sent, etc.) |
| `notice` | Error message from SDI (if rejected) |
| `invoice_number` | Invoice number (extracted from payload) |
| `invoice_date` | Invoice date (extracted from payload) |
| `total_amount` | Total document amount (extracted from payload) |
| `currency` | Currency code (extracted from payload) |
| `sender.business_name` | Sender company name |
| `sender.business_vat_number_code` | Sender P.IVA |
| `recipient.business_name` | Recipient company name |
| `recipient.business_vat_number_code` | Recipient P.IVA |
| `notifications` | Array of SDI notifications (type + date) |

The `invoice_number`, `invoice_date`, `total_amount`, and `currency` fields are **computed** by parsing the FatturaPA payload JSON on the server side, so they're available without transferring the entire payload.

### Filtering by invoice series

Italian invoice numbers often include a series suffix (e.g. `1/Servizi`, `2026/100/CI`, `3/cipay`). The API's `invoice_number` filter does a partial match, which can return unrelated series. The `invoice_series` parameter solves this by post-filtering results to match only invoices whose number ends with the exact series suffix:

```
# Only returns "1/Servizi", "2/Servizi", etc. -- not "2026/100/CI"
list_invoices(sender_vat: "01234567890", invoice_series: "Servizi")

# Only returns invoices in the /CI series
list_invoices(sender_vat: "01234567890", invoice_series: "CI")
```

The match is exact on the part after the last `/` in the invoice number.

### Using the `fields` parameter

Both `list_invoices` and `get_invoice` accept an optional `fields` parameter to control which fields are returned:

```
# Default compact view (no fields parameter needed)
list_invoices(marking: "rejected")

# Request specific fields
list_invoices(marking: "rejected", fields: ["uuid", "notice", "recipient.business_name"])

# Request all fields (payload parsed + nulls stripped)
list_invoices(marking: "rejected", fields: ["*"])

# Get specific fields from a single invoice
get_invoice(uuid: "...", fields: ["payload", "sender", "recipient"])
```

The `fields` parameter supports **dot-notation** for nested objects (e.g., `sender.business_name`).

> **Tip:** Prefer the default compact view or specific fields over `["*"]`. Even with `["*"]`, the server parses payloads and strips nulls, but the full FatturaPA structure is still large. Use `["*"]` only when you truly need the complete invoice data.

### Pagination

`list_invoices` defaults to **10 items per page** (`items_per_page`, max 30). Use the `page` parameter to navigate through results.

### Estimated token savings

For a typical `list_invoices` call returning 10 invoices:

| Scenario | Without optimization | With optimization |
|---|---|---|
| **Default view** (compact fields) | ~25,000 tokens | **~1,500 tokens** |
| **`fields: ["*"]`** (full data) | ~25,000 tokens | **~10,000 tokens** |

Key reductions with `fields: ["*"]`:

| Metric | Before | After |
|---|---|---|
| Null fields per invoice | ~60 | 0 (stripped) |
| Payload encoding | Double-encoded string (`\"`) | Parsed object (no escaping) |
| Payload null fields | ~60 (hidden in string) | 0 (stripped) |

## Usage Examples

Once the server is connected, you can ask Claude things like:

### Invoicing
> "Send this invoice to SDI for customer ACME Srl with P.IVA 01234567890"
>
> "List all my invoices from January 2025 that were rejected"
>
> "Show me invoice abc-123-def in XML format"

### PDF Extraction
> "Convert this PDF invoice to FatturaPA format"
>
> "Check if my PDF extraction job is done yet"

### Company Verification
> "Look up the company with P.IVA 01234567890 -- I need their PEC and SDI code"
>
> "Is this codice fiscale valid: RSSMRA85M01H501Z?"
>
> "Does this company use split payment?"

### Smart Receipts
> "Issue an electronic receipt for 3 items totaling 45.50 EUR paid by card"
>
> "Void receipt number 12345"

### Notifications
> "Show me all undownloaded SDI notifications"
>
> "Are there any rejected notifications (NS type) from last week?"

### Cassetto Fiscale
> "Set up daily invoice downloads for fiscal ID 01234567890"
>
> "Download all invoices from Q1 2025 for my company"
>
> "How many rejected invoices do I have?"

### Configuration
> "List all my webhook configurations"
>
> "Set up a webhook for new supplier invoices pointing to https://my-app.com/webhooks/acube"
>
> "Show me all my business registry profiles"

## Development

### Setup

```bash
git clone https://github.com/nick-preda/mcp-server-acube.git
cd mcp-server-acube
npm install
```

### Build

```bash
npm run build
```

### Run in development mode

```bash
ACUBE_EMAIL=you@example.com ACUBE_PASSWORD=secret npm run dev
```

### T

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [nick-preda](https://github.com/nick-preda)
- **Source:** [nick-preda/mcp-server-acube](https://github.com/nick-preda/mcp-server-acube)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-nick-preda-mcp-server-acube
- Seller: https://agentstack.voostack.com/s/nick-preda
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
