tools/call over
POST /uniconta/mcp. It has 21 read tools and 4 write tools, and the write tools
work only on unposted lines in the daily journal (kassekladde). The connector is connected with a form in the portal, with
no OAuth: a dedicated Uniconta Server-Login User (username + password) plus a
Company ID. See Forbind Uniconta.
Endpoint:
https://mcp.consile.ai/uniconta/mcp. Uniconta is its own named
connector with only its own tools. Each tool is exposed as uniconta__<tool>
(e.g. uniconta__get_account_balance); your AI assistant invokes these for you,
so the names below are the bare tool names.Each additional Uniconta company the customer adds as a portal gets its own
endpoint, https://mcp.consile.ai/uniconta-2/mcp, uniconta-3, and so on, with
tools prefixed uniconta-2__ etc. Every tool is listed with a title and
annotations. Read tools carry
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false };
the write tools are described under Write safety.Besides the connector tools, tools/list on this endpoint also returns one
unprefixed system tool, connect_account (no arguments). It returns a link,
valid for 10 minutes, that the user opens in the browser to enter the Uniconta
login in the portal. It does not read any Uniconta data.The read tools, including
query and aggregate, cannot write. Only the four
daily-journal write tools write, and only after
confirm: true. They create, update and delete unposted journal lines and post
explicit lines to the ledger. No tool changes master data (debtors, creditors,
items), invoices or orders, or posted ledger rows.Shared parameters
Most list tools accept a row cap; several support search, exact-account and date-range filtering; and the high-volume reads (list_inventory_items, query)
add sorting, paging and field selection.
integer
default:"50"
Max rows to return, an integer from
1 to 1000 (default 50). Values outside
that range are rejected, not clamped: the call fails with isError: true and
Tool invocation failed., as does any other argument that breaks the tool’s
input schema.string
Name search. Wildcards are added automatically (
acme becomes *acme*); pass your
own * to control matching. Available on the debtor, creditor, G/L-account and
inventory list tools.string
Exact account number to filter on (debtor, creditor or G/L account, depending on
the tool).
string (YYYY-MM-DD)
Inclusive date range, e.g.
"2025-01-01" / "2025-12-31". Available on the
invoice, transaction and posting list tools.integer
Rows to skip before the page is returned. Use with
limit and follow the
result’s nextOffset to page. Available on
list_inventory_items, list_inventory_transactions, list_journal_lines and
query.string[]
Return only these properties per row (trims the payload on wide entities), up
to 40 names. Available on
list_inventory_items and
query. Custom fields only exist on the …ClientUser entity variants.Result shape
A plain list result is{ entity, count, total, items: [...] }, where total is
the full row count before the limit cap and count is the number of rows
returned. When a call sorts (sortBy, orderBy) or pages (offset), the full
count is unknown: total is omitted and the result carries truncated: true on a
full page. offset and nextOffset are added only when the
request itself passed an offset; a sort-only read (no offset) returns
truncated: true on a full page without any cursor. A fields projection that names
a property present in no returned row echoes it in unknownFields.
A broad, unfiltered read of a large posting table can be slow or fail with the
generic Tool invocation failed.. Narrow such reads with account, a date range
or search, or use aggregate for totals.
Companies
list_companies
List the Uniconta companies the connected Server-Login User can access (CompanyId, name, CVR/registration number, country). Arguments: none. Returns
{ count, companies: [...] }. This lists every company the Server-Login User can
access. All other tools read only the Company ID the connection was set up with;
there is no company argument. This tool does not depend on the configured Company
ID, so it also succeeds when that ID is wrong, which makes it a quick way to tell
a bad login from a bad Company ID.
Debtors (customers)
list_debtors
List debtors (customers) with account, name, address, currency, balance (CurBalance), overdue and credit limit.
string
Name search (wildcards added automatically).
string
Exact debtor account number.
string
CVR / registration number (
CompanyRegNo).integer
default:"50"
list_debtor_open_items
Open (unpaid) debtor items (accounts-receivable / aging view): account, voucher, invoice, due date andAmountOpen (outstanding).
string
Exact debtor account number.
integer
default:"50"
list_debtor_invoices
Issued customer invoices (debitorfakturaer):InvoiceNumber, account, dates,
net/VAT/total amounts and Paid flag.
string
Exact debtor account number.
string (YYYY-MM-DD)
From date; pairs with
toDate as a range.string (YYYY-MM-DD)
integer
default:"50"
list_debtor_orders
Sales orders (salgsordrer):OrderNumber, account, name, amounts and status.
string
Exact debtor account number.
integer
default:"50"
list_debtor_transactions
A debtor’s posted ledger movements (debitorposteringer): date, voucher, invoice, amount and text. For the unpaid/overdue view with due dates and outstanding amounts uselist_debtor_open_items instead.
Pass account to limit the result to that debtor; without it the tool returns all
G/L postings, like list_gl_transactions. If a debtor and a creditor share an
account number, rows for both are returned; the rows’ DCType tells them apart.
string
Exact debtor account number.
string (YYYY-MM-DD)
string (YYYY-MM-DD)
integer
default:"50"
Creditors (suppliers)
list_creditors
Creditors (suppliers) for accounts-payable / spend questions: account, name, currency, balance, overdue and payment method.string
Name search (wildcards added automatically).
string
Exact creditor account number.
integer
default:"50"
list_creditor_open_items
Open (unpaid) creditor items (accounts-payable view): account, voucher, due date and outstanding amount.string
Exact creditor account number.
integer
default:"50"
list_creditor_transactions
A creditor’s posted ledger movements (kreditorposteringer): date, voucher, invoice, amount and text. For the unpaid/overdue view uselist_creditor_open_items instead.
Pass account to limit the result to that creditor; without it the tool returns
all G/L postings, like list_gl_transactions. If a debtor and a creditor share an
account number, rows for both are returned; the rows’ DCType tells them apart.
string
Exact creditor account number.
string (YYYY-MM-DD)
string (YYYY-MM-DD)
integer
default:"50"
Finance / general ledger
list_gl_accounts
The chart of accounts (kontoplan):Account, Name, AccountType, Balance and
this-year / last-year figures.
string
Account name search (wildcards added automatically).
string
Exact G/L account number.
integer
default:"50"
get_account_balance
Read one G/L account’s balance and this-year figures by account number: the direct “balance of account X” answer. Returns the single matching account row, ornull if no account matches.
string
required
G/L account number, e.g.
"1010".list_gl_transactions
General-ledger postings (finansposteringer): date, account, voucher, text, amount, VAT and transaction type.string
Exact G/L account number.
string (YYYY-MM-DD)
string (YYYY-MM-DD)
integer
default:"50"
list_vat_codes
VAT / moms codes with rates (Vat, Name, Rate, Account, VatType), needed
to interpret VAT on invoices and postings.
integer
default:"50"
Inventory (products)
list_inventory_items
Products / inventory items (varer):Item, Name, prices (sales/cost/purchase),
unit, group, EAN and quantity on stock. Optionally sort (returns only the top
limit rows), page with offset, trim wide rows with fields, and set
includeCustomFields so the company’s own custom/user-defined fields come along.
Uniconta stores no creation date on items, so
“newest created product” is not answerable here; sortBy: "last_movement" gives the
most recently transacted items instead.
string
Product name search (wildcards added automatically).
string
Exact item number.
string
Exact product group code.
boolean
default:"false"
Read the
InvItemClientUser entity variant so the company’s custom/user-defined
item fields are included in each row (they are absent on the base entity).enum
One of
item, name, sales_price, cost_price, quantity, last_movement.
Sorts and returns only the top limit rows. Uniconta has no item
creation date, so last_movement is the date of the last stock movement.boolean
default:"true"
true = highest/newest first (default); false = ascending.integer
default:"50"
integer
Paging (follow
nextOffset).string[]
Return only these properties per row.
list_product_groups
Inventory product groups (Group, Name) used to categorise items.
integer
default:"50"
list_inventory_transactions
Inventory postings / stock movements (lagerposteringer):Item,
ItemName, Date, Qty (negative on a sale), DCAccount (the debtor/creditor on
the line), AccountName, InvoiceNumber, NetAmount and MovementType. This is how
you read the actual sales lines for an item (qty < 0) with their invoice date and
customer. To count units sold in a product group, first get the item numbers via
list_inventory_items (group=…), then call this filtered to those items plus the
date range and sum the negative Qty.
string
Item number (exact). Multiple via Uniconta list syntax, e.g.
"1001;1002;1003".string
Debtor/creditor account on the line (
DCAccount).string (YYYY-MM-DD)
string (YYYY-MM-DD)
integer
default:"50"
integer
Paging (follow
nextOffset).Daily journals (kassekladde)
list_journals
The company’s daily journals: the key (Journal), name, number series, default
account and offset account with their types, default VAT, the Blocked flag, the
number of unposted lines, the voucher settings (GenerateVoucher,
OneVoucherForAll, NewVoucherPerLine), DateFunction and dimensions. Use it to
find the journal key the line tools need. A blocked journal cannot be changed or
posted through Consile.
string
Exact journal key, to fetch one journal.
integer
default:"50"
list_journal_lines
The unposted lines of one daily journal:RowId (the lineId the write tools
take), date, account type, account and account name, offset account, VAT codes,
text, signed Amount (positive = debit), Debit/Credit, voucher, invoice, due
date, project and dimensions. Only lines of the named journal are returned.
Posted lines are no longer in the journal;
read them with list_gl_transactions. This is the review step before
post_journal_lines. The result is the list shape plus journal.
string
required
Journal key from
list_journals.string
Exact account on the account side.
string (YYYY-MM-DD)
string (YYYY-MM-DD)
integer
default:"50"
integer
Paging (follow
nextOffset).Advanced
query
The read-only escape hatch: fetch rows for any Uniconta Query entity with raw filters. Use it for entities not covered by a dedicated tool (e.g."ProjectClient").
It can only read, never write. Optionally sort via orderBy (returns only the top
limit rows), page with offset, and trim wide rows with fields. Custom/user-defined fields are
only returned, and only filterable, on the …ClientUser entity variants (e.g.
InvItemClientUser); on the base entity a filter on a custom field is silently ignored.
For per-group totals across a whole table, prefer aggregate.
string
required
Uniconta entity / table name, e.g.
"DebtorClient", "GLTransClient". Use the
…ClientUser variant (e.g. "InvItemClientUser") to include custom fields.array
default:"[]"
Uniconta query filters; empty means all rows. Each filter is
{ "PropertyName": string, "FilterValue": string }. FilterValue can be exact,
a wildcard (*abc*), a range (a..b) or a list (a;b;c).string
Property to sort by, e.g.
"Item" or "Date".boolean
default:"true"
When
orderBy is set: true = descending (default), false = ascending.integer
default:"50"
integer
Paging (follow
nextOffset).string[]
Return only these properties per row.
aggregate
Group and sum any Uniconta Query entity and return only the per-group totals, e.g. contribution margin per product group across the whole item catalogue in one call. It reads up to about 50,000 matching rows per call, so use it for totals beyond the per-call row limit of the other tools. It rejects groupings over 1000 groups (the call fails with the genericTool invocation failed.), and if the result says
truncated: true you should narrow the filters or date range rather than retry.
string
required
Uniconta Query entity, e.g.
"InvTransClient" or "InvItemClientUser" (the
…ClientUser variant is required for custom/user-defined fields).array
default:"[]"
Filters applied before aggregating; empty means all rows.
string[]
default:"[]"
Properties to group by (max 3), e.g.
["Group"]. Empty means one grand-total row.string[]
default:"[]"
Numeric properties to sum per group (max 10). Unparseable values are skipped and
counted in the result’s
nonNumeric tally (never summed as 0).string
default:"Date"
Property the
fromDate/toDate range filters on.string (YYYY-MM-DD)
string (YYYY-MM-DD)
string
Stable sort key, recommended on large tables for consistent totals.
{ entity, groupCount, rowsScanned, pages, truncated, groups: [{ key, count, sums }] }. nonNumeric is included only when it is non-empty, and there is no groupBy key in the result.
Recently added items (not yet available)
list_recently_added_items
Meant to list the inventory items that appeared most recently. Uniconta stores no item creation date, solist_inventory_items cannot answer this.
Not available yet: the tool returns a message saying so, as a normal result
(not isError), and no item data. For the most recently transacted items use
list_inventory_items with sortBy: "last_movement".
string (ISO)
Only items from this date on, e.g.
"2026-01-01".integer
default:"50"
Write safety: guardrail model
The four write tools share one confirmation model. Read tools are annotatedreadOnlyHint: true, destructiveHint: false, openWorldHint: false. Write tools
carry readOnlyHint: false, destructiveHint: true and openWorldHint: false;
idempotentHint is true on update_journal_lines and delete_journal_line and
false on create_journal_lines and post_journal_lines.
- Every write is preview-first. A call without
confirm: truenever changes anything. The tools check the journal and the lines you name first, so a dry-run can already fail with a clear message when the journal or a line does not exist. Otherwise you get a preview of the exact request and nothing is written. confirm: trueis required to apply, with no exceptions.post_journal_linesalways takes two calls, because the confirming call must send back theexpectedStatefrom a preview. See Theconfirmargument.- Writes stay in the daily journal. The tools create, update and delete unposted lines and post explicit lines. Nothing else can be changed: no master data (debtors, creditors, items), no invoices or orders and no posted ledger rows.
- Lines are addressed by
lineIdwithin one journal. AlineIdis the line’sRowIdfromlist_journal_lines. Every line must be an unposted line in the journal you name, or the call changes nothing. A journal that is blocked in Uniconta is refused. - Posting has its own gate.
post_journal_linesposts only the explicitlineIdsyou pass (max 50 per call, never the whole journal), and the confirming call must echo the preview’sexpectedState. If a line’s date, account or offset account (or their types), amount, VAT codes, text, voucher, invoice or due date changed in between, nothing is posted. Posting is irreversible. - Updates change only the fields you pass.
update_journal_lineskeeps every field of the line that you do not pass. The confirming call applies your changes to the line as it is at that moment. - Uniconta’s own rights still apply. Read access is enough for every read tool. To create, change and post lines, the Server-Login User needs write access to the daily journal and the right to post in Uniconta. Without them Uniconta refuses the change and nothing happens (see Errors).
Preview shape
When a write is not confirmed (confirm omitted or false), the tool returns this
as a normal (non-error) tool result instead of writing to Uniconta:
string
POST, PUT or DELETE. Every Uniconta preview has a body, including the DELETE of delete_journal_line (the line to delete).string
The Uniconta endpoint the confirming call would send the request to.
object
Only on
post_journal_lines: { expectedState }, which the confirming call sends back as expectedState. Treat the value as an opaque string. This preview also carries its own confirmHint.Write tools (4 guardrailed)
create_journal_lines
Create unposted lines in a daily journal. Nothing is posted.string
required
Journal key from
list_journals.object[]
required
1-50 lines. Each line:
- required:
date(YYYY-MM-DD),account,amount(signed, in the company currency: positive = debit, negative = credit on the account side) - optional:
accountType(ledger,debtororcreditor; defaultledger),offsetAccount,offsetAccountType(same values; defaults toledgerwhenoffsetAccountis given),text(max 250 characters),vat,offsetVat,voucher(integer; omit to let the journal’s number series assign one),invoice,dueDate(YYYY-MM-DD),documentDate(YYYY-MM-DD),project,dimension1todimension5
boolean
Set
true to apply; omit for a dry-run preview.{ created, journal, hint }; read the new
lines and their RowIds with list_journal_lines.
Requires confirmation: always.
update_journal_lines
Update unposted lines bylineId. Only the fields you pass are changed. Posted
lines cannot be changed; post a correcting line instead.
string
required
Journal key from
list_journals.object[]
required
1-50 patches:
lineId plus the fields to change (same fields as create_journal_lines, all optional). A lineId may appear only once.boolean
Set
true to apply; omit for a dry-run preview.{ updated: [lineId, ...], journal }. See rule 6 above.
Requires confirmation: always.
delete_journal_line
Delete one unposted line. The line is fetched first and described in the preview (line id, date, accounts, amount, text). A wrong or already postedlineId fails in
the preview call. Posted ledger rows cannot be deleted.
string
required
Journal key from
list_journals.integer
required
The unposted line to delete (
RowId from list_journal_lines).boolean
Set
true to apply; omit for a dry-run preview.{ deleted, journal }.
Requires confirmation: always.
post_journal_lines
Post specific unposted lines to the ledger (bogfør). This is irreversible: posted rows cannot be edited or deleted, only corrected with new lines.string
required
The journal the lines belong to.
integer[]
required
1-50 exact unposted line ids (duplicates are ignored).
string (YYYY-MM-DD)
Posting date passed to Uniconta (default today). Lines keep their own date unless the journal’s
DateFunction says otherwise.string
Comment stored on the posting, max 250 characters (default
Posted via Consile MCP).string
Copy
preview.state.expectedState from the preview. Required together with confirm: true.boolean
Set
true to post; omit for a dry-run preview.- Call without
confirm. Every id must be an unposted line in that journal; otherwise the call fails naming the ids (Not unposted lines in journal "<key>": … Nothing was changed.). The preview lists each line (id, date, accounts, amount, text) with debit, credit and net totals, says how many other unposted lines in the journal are not included, and returnspreview.state.expectedState. - Re-run with
confirm: trueandexpectedState. WithoutexpectedStatethe call is refused. If one of the values listed in rule 5 of the guardrail model changed since the preview, it fails withLines changed since the preview: <ids>. Re-run without confirm to review the current state. This call posted nothing.
integer[]
The requested line ids that are no longer unposted.
integer[]
Requested line ids that are still in the journal.
integer
Unposted lines left in the journal, including lines you did not select.
string
Present only when
stillUnposted is not empty: Uniconta accepted the request, but those lines are still unposted. Check the journal in Uniconta before retrying.journal, postingDate and result (Uniconta’s response).
If a posting call times out or fails without a clear answer, check
list_journal_lines and list_gl_transactions before retrying, because the lines
may already be posted.
Requires confirmation: always, plus expectedState.
Access levels (per user)
An account administrator chooses one of two access levels for Uniconta per user, on the portal’s Team page, or picks the exact tools under Tilpasset (custom). All levels cost the same. e-conomic has the same levels. A level only gives tools the organization has switched on. For an organization that bought Uniconta before 2026-10-07, the six daily journal tools (list_journals, list_journal_lines and the 4 write tools) are off until an
administrator activates them on the connector’s page in the portal; until then
tools/list holds the other 19 read tools. See
Tools and new tools.
Under Read only:
tools/liston every Uniconta endpoint omits the 4 write tools (connect_accountis still listed).- A direct
tools/callto a write tool returns a tool result withisError: trueexplaining that the tool is not enabled for the user. Nothing is sent to Uniconta. - The
initializeresult carriesinstructionstelling the model the session can only read.
tools/list
should start a new session after a level change; a cached write tool is refused
when called.
A user who holds no seat on Uniconta still sees the tool list, but every
tools/call is refused with a seat message (see Errors).
Errors and timeouts
Tool failures come back as a normal tool result withisError: true and one text
block. A rejected login and the write tools’ failures carry an explanatory message
(Uniconta’s own refusal or the connector’s own checks), so the AI can correct the
call; other read failures return the generic text:
After connecting, make one read call (e.g.
get_account_balance) to confirm that
the login and Company ID work; list_companies tells a bad login from a bad
Company ID. A write that fails with a timeout may still have been applied in
Uniconta, so check there before repeating it. See
Errors & limits for the protocol-level errors and
rate limits shared by all connectors.