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, authenticated the same way, but shaped as MCP resources and tools.
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 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.
The MCP server is always treated as an AI. Its write tools never execute
directly: each one records a pending 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; 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. |
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 entry and returns a message with the entry id; the draft is created only once a person approves it.
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. The same
Veri*Factu authorization gate 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.
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. |
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. |
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 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. Once approved, the report renders in
the background and the requester is emailed a download link; ready reports also
appear as uninvoice://reports 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 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}.
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 entry and returns the entry id; the report is removed only once a person approves it.