# MCP server

uninvoice.app ships a **Model Context Protocol (MCP)** server so AI agents and MCP-aware tools can read your company data, create invoices and expenses, and generate business reports directly. It exposes the same operations as the [HTTP API](https://docs.uninvoice.app/api/reference), authenticated the same way, but shaped as MCP **resources** and **tools**.

info

The MCP server is a distinct process from the HTTP API. It speaks MCP over the **streamable-HTTP** transport: your MCP client connects to a single HTTP endpoint, exposed at its own MCP endpoint URL.

## Authentication

Every MCP request must carry a **Bearer token** in the `Authorization` header: the same [tokens](https://docs.uninvoice.app/api/overview#authentication) the HTTP API accepts. The token is validated on every operation, including listing resources and tools. A missing or malformed header, or an invalid or revoked token, is rejected.

The token determines the acting user and company; every resource you read and every invoice you create is scoped to that company.

MCP is always gated by AI Audit

The MCP server is **always** treated as an AI. Its write tools never execute directly: each one records a pending **[AI Audit](https://docs.uninvoice.app/api/ai-audit)** entry that a person must approve before it takes effect. Unlike an API token, the MCP server **cannot** present the `X-Human-Proof` header to opt out; there is no way to make an MCP mutation skip the review queue.

Configure your MCP client with the endpoint URL and the header, for example:

```
{  
    "mcpServers" :   {  
      "uninvoice" :   {  
        "url" :   "https://mcp.uninvoice.app" ,  
        "headers" :   {   "Authorization" :   "Bearer <api-token>"   }  
      }  
    }  
  } 
```

## Resources

Resources are read-only views of your data under the `uninvoice://` URI scheme. They return `application/json`.

| URI                                  | Description                                                 |
| ------------------------------------ | ----------------------------------------------------------- |
| `uninvoice://company`                | Your company configuration.                                 |
| `uninvoice://entities`               | All entities (clients / suppliers).                         |
| `uninvoice://entities/{id}`          | A single entity by ID.                                      |
| `uninvoice://entities/{id}/invoices` | The invoices emitted to a given recipient entity.           |
| `uninvoice://entities/{id}/expenses` | The expenses (bills) received from a given supplier entity. |
| `uninvoice://invoices`               | All invoices (each with its `lineCount`).                   |
| `uninvoice://invoices/{id}`          | A single invoice with its lines.                            |
| `uninvoice://proformas`              | All proformas (each with its `lineCount`).                  |
| `uninvoice://proformas/{id}`         | A single proforma with its lines.                           |
| `uninvoice://expenses`               | All expenses (bills received from suppliers).               |
| `uninvoice://expenses/{id}`          | A single expense with its lines.                            |
| `uninvoice://reports`                | All generated business reports (status / metadata).         |
| `uninvoice://reports/{id}`           | A single generated report by its ID.                        |

The `.../{id}` forms (and the `entities/{id}/…` sub-collections) are advertised as resource templates; the top-level collection forms are listed as plain resources.

## Tools

### `create_invoice`

Creates a new **draft** invoice for a recipient, with line items. Taxes are calculated automatically from the company and recipient. This mirrors [`POST /v1/invoices`](https://docs.uninvoice.app/api/#tag/Invoices/operation/create-invoice); the resulting invoice is a draft until you issue it through the HTTP API.

Input schema:

| Field          | Type                      | Required | Description                                   |
| -------------- | ------------------------- | -------- | --------------------------------------------- |
| `recipient_id` | string                    | yes      | Entity ID of the recipient.                   |
| `supply_type`  | `"services"` \| `"goods"` | yes      | Whether the invoice covers services or goods. |
| `lines`        | array                     | yes      | Line items (see below).                       |

Each entry in `lines`:

| Field           | Type    | Required | Description                                                                |
| --------------- | ------- | -------- | -------------------------------------------------------------------------- |
| `concept`       | string  | yes      | Description of the service or product.                                     |
| `quantity`      | number  | no       | Number of units (decimals allowed, e.g. `95.6`).                           |
| `quantity_unit` | string  | no       | Unit label (e.g. `hours`, `days`).                                         |
| `unit_price`    | integer | no       | Price per unit, in [cents](https://docs.uninvoice.app/api/overview#money). |
| `unit_unit`     | string  | no       | Currency unit label.                                                       |
| `is_tax`        | boolean | no       | Whether this is an explicit tax line.                                      |
| `tax_amount`    | integer | no       | Tax amount in cents.                                                       |
| `subtotal`      | integer | no       | Line subtotal in cents.                                                    |

Lines appear on the invoice in the order you list them.

Example arguments:

```
{  
    "recipient_id" :   "ent_..." ,  
    "supply_type" :   "services" ,  
    "lines" :   [  
      {   "concept" :   "Consulting (June 2026)" ,   "quantity" :   10 ,   "quantity_unit" :   "hours" ,   "unit_price" :   20000   }  
    ]  
  } 
```

Because the MCP server is always gated, this tool does **not** create the invoice immediately. It records a pending **[AI Audit](https://docs.uninvoice.app/api/ai-audit)** entry and returns a message with the entry id; the draft is created only once a person approves it.

Issuing happens over the HTTP API

The MCP tool creates drafts only. To assign the invoice number and (for Spanish issuers) report it to the AEAT, issue it with [`POST /v1/invoices/{id}/issue`](https://docs.uninvoice.app/api/#tag/Invoices/operation/issue-invoice). The same [Veri\*Factu authorization gate](https://docs.uninvoice.app/verifactu/authorize) applies: business errors, including the authorization requirement, are surfaced to the MCP caller with their actionable message.

### `create_expense`

Records an **expense** (a bill received from a supplier) with line items. This mirrors [`POST /v1/expenses`](https://docs.uninvoice.app/api/#tag/Expenses/operation/create-expense).

Input schema:

| Field               | Type              | Required | Description                                                               |
| ------------------- | ----------------- | -------- | ------------------------------------------------------------------------- |
| `supplier_id`       | string            | yes      | Entity ID of the supplier the bill was received from.                     |
| `invoice_reference` | string            | yes      | The supplier invoice's reference/number (non-empty, unique per supplier). |
| `lines`             | array             | yes      | Line items (see below).                                                   |
| `expense_date`      | string (RFC 3339) | no       | When the expense was incurred.                                            |
| `currency_code`     | string            | no       | ISO currency code. Defaults to the supplier's currency.                   |
| `category`          | string            | no       | Expense category.                                                         |
| `description`       | string            | no       | Free-text note about the expense.                                         |

Each entry in `lines`:

| Field           | Type    | Required | Description                                                              |
| --------------- | ------- | -------- | ------------------------------------------------------------------------ |
| `concept`       | string  | yes      | Line description.                                                        |
| `subtotal`      | integer | yes      | Line subtotal in [cents](https://docs.uninvoice.app/api/overview#money). |
| `quantity`      | number  | no       | Number of units (decimals allowed, e.g. `95.6`).                         |
| `quantity_unit` | string  | no       | Unit label (e.g. `hours`, `days`).                                       |
| `unit_price`    | integer | no       | Price per unit, in cents.                                                |
| `unit_unit`     | string  | no       | Currency unit label.                                                     |
| `is_tax`        | boolean | no       | Whether this is an explicit tax line.                                    |
| `tax_amount`    | integer | no       | Tax amount in cents.                                                     |

Receipts can't be attached over MCP

Receipt files (PDF / image) cannot be uploaded through this MCP server. Attach them from the uninvoice.app web app or HTTP API instead.

Like `create_invoice`, this records a pending **[AI Audit](https://docs.uninvoice.app/api/ai-audit)** entry and returns the entry id; the expense is created only once a person approves it.

### `generate_report`

Generates a background **PDF business report** for a timeframe. This mirrors [`POST /v1/reports`](https://docs.uninvoice.app/api/#tag/Reports/operation/request-report). Once approved, the report renders in the background and the requester is emailed a download link; ready reports also appear as [`uninvoice://reports`](#resources) resources.

Input schema:

| Field          | Type              | Required | Description                                                                                                                                                                                                                 |
| -------------- | ----------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `report_type`  | enum              | yes      | One of `business_overview`, `vat_summary`, `profit_loss`, `client_revenue`, `expense_supplier`.                                                                                                                             |
| `period_start` | string (RFC 3339) | yes      | Start of the reporting window (inclusive).                                                                                                                                                                                  |
| `period_end`   | string (RFC 3339) | yes      | End of the reporting window (exclusive).                                                                                                                                                                                    |
| `locales`      | array of strings  | no       | Locale(s) to render in (e.g. `en`, `es`, `es_ES`). **One report is generated per locale**, and numbers format per region (so `es_ES` and `es_MX` differ). Omit to render a single report in the requesting user's language. |

Like the other tools, this records a pending **[AI Audit](https://docs.uninvoice.app/api/ai-audit)** entry and returns the entry id; generation starts only once a person approves it.

### `delete_report`

Deletes a generated report (and its stored PDF) by id. This mirrors [`DELETE /v1/reports/{id}`](https://docs.uninvoice.app/api/#tag/Reports/operation/delete-report).

Input schema:

| Field       | Type   | Required | Description                                                  |
| ----------- | ------ | -------- | ------------------------------------------------------------ |
| `report_id` | string | yes      | The id of the report to delete (from `uninvoice://reports`). |

Like the other tools, this records a pending **[AI Audit](https://docs.uninvoice.app/api/ai-audit)** entry and returns the entry id; the report is removed only once a person approves it.
