AI assistants (MCP)
Essentio runs an MCP server at https://mcp.essentio.pro. Add Essentio to Claude or ChatGPT, or give that address to any other assistant that speaks MCP, connect it to one of your Businesses, and the assistant can find your Clients, documents and Products, read a document, your Business setup and your reports, create and change Clients, Drafts and Products, delete Drafts, issue, send, cancel and convert documents, and record, amend and reverse Payments.
The assistant acts as the person who connected it, in the one Business they chose, with a Role no higher than theirs — exactly as a Connected app does, because it is one. It reads and writes the same data, in the same shape, as the Public API, through the same rules and with the same Refusals: amounts are decimal strings, and every list pages by cursor. Connect it as a Viewer and it reads everything and changes nothing.
Connect Claude
The quickest way is Add Essentio to Claude: it opens Claude's Add custom connector dialog with the name and the address filled in, for you to check and confirm. Claude shows Essentio as a custom connector.
To add it by hand, open Customize → Connectors in Claude, choose Add custom connector and enter:
The server address
https://mcp.essentio.pro
Enter it exactly so, with no / at the end: Claude renders Essentio's document card only for the address its sandbox was declared for, and https://mcp.essentio.pro/ is another address to it.
Claude then sends you to Essentio. Sign in if you are not, and the consent screen asks which of your Businesses the assistant may reach and with which Role — Admin, Member or Viewer, never higher than yours. Choose Viewer for an assistant that should only read. Once you connect it, Claude lists Essentio's tools and uses them when a conversation needs them. Nothing to register first: Claude introduces itself to Essentio on its own.
On a Team or Enterprise plan, an Owner adds the connector for the organization and each person connects their own Essentio account.
Claude Code
In Claude Code, Essentio's plugin brings the connector and two skills: draft-and-send-invoice drafts, checks, issues and sends an Invoice in that order, issuing and sending only when you say so, and close-vat-month reads a month's Reported VAT and Income and names the Drafts and unpaid documents left. Add Essentio's marketplace, then install the plugin from it:
Claude Code
/plugin marketplace add essentio-pro/essentio-plugin
/plugin install essentio@essentio
Then run /mcp to sign in to Essentio: Claude Code opens Essentio's consent screen in your browser, where you choose the Business and the Role as for Claude.
Connect ChatGPT
The quickest way is Open Essentio in ChatGPT: it opens Essentio's page in ChatGPT's plugin directory.
- On that page, add the plugin. ChatGPT sends you to Essentio's consent screen, where you choose the Business and the Role as for Claude.
- In a new chat, add Essentio from the tools menu beside the message box and ask, for example, for a draft invoice.
ChatGPT has no Essentio skills, so it may write without asking first — creating a Draft, for example. Your tool permissions in ChatGPT decide; connect it as a Viewer for an assistant that should only read.
ChatGPT introduces itself to Essentio by its client metadata document and returns to https://chatgpt.com/connector_platform_oauth_redirect, which Essentio accepts; nothing has to be registered first.
Connect another assistant
Any assistant that speaks MCP over HTTP with OAuth can connect the same way: give it https://mcp.essentio.pro and follow its sign-in. In Claude Code, install the plugin, which brings the connector and its two skills:
Claude Code
/plugin marketplace add essentio-pro/essentio-plugin
/plugin install essentio@essentio
Then run /mcp to sign in to Essentio. For the connector only, without the skills, add it from the command line and sign in through /mcp the same way:
Claude Code: connector only
claude mcp add --transport http essentio https://mcp.essentio.pro
What an assistant finds on its own, if you are building one:
- The server answers at the root,
https://mcp.essentio.pro/, over MCP's Streamable HTTP transport, and keeps no session: every request carries its access token and stands alone. - A request with no token, or with one not issued for this server, is answered
401withWWW-Authenticate: Bearer resource_metadata="https://mcp.essentio.pro/.well-known/oauth-protected-resource". That document nameshttps://mcp.essentio.proas the resource andhttps://essentio.proas its authorization server. - The authorization server takes a Client ID Metadata Document as the
client_id, or registers the assistant by Dynamic Client Registration athttps://essentio.pro/oauth/register. An assistant that registered itself may send the person back only to Claude's or ChatGPT's callback, or to anhttp://loopback address on the person's own machine (localhost,127.0.0.1or[::1], any port) — the details are on OAuth apps. - The authorization request names the server with
resource=https://mcp.essentio.pro, with PKCE andS256(OAuth apps). A token asked for the MCP server works only there, and one asked for the Public API only there: each answers the other's401. An API key is never taken by the MCP server.
The tools
Twenty-two tools: eight read and fourteen write. Each asks what the Public API's operation of the same thing asks of the connection's Role, and answers with that operation's JSON, both as the tool's structured content and as its text. Nothing of another Business is ever reached, whatever a tool is sent: an id of another Business's record is not found.
The reading tools are marked read-only, so an assistant may use them without asking. A Viewer may use them all.
essentio_search_clients
Search Clients. Lists the Business's Clients, oldest first, narrowed by search over their name, legal name, email, account code and VAT number. Each Client is as List Clients answers it; the result is {"data": [...], "next_cursor": ...}.
essentio_get_client
Get Client. Reads one Client by its client_id, as Retrieve a Client answers it.
essentio_search_documents
Search Documents. Lists the Business's Invoices, Proforma Invoices, Credit Notes and Quotes, oldest first, narrowed by document_type, status (with overdue, and awaiting_payment for every document that still takes a Payment, overdue ones included), client_id, issued_from and issued_to, and search, as List documents narrows them. Each document is whole: its Lines, VAT, totals, money received, Amount due and the Actions the connection may take.
essentio_get_document
Get Document. Reads one document by its document_id — its id, not its document number — as Retrieve a document answers it. A Deleted document is not found. It is shown as the document card.
essentio_search_products
Search Products. Lists the Business's Products, oldest first, narrowed by search over their name, code, SKU and description, as List Products answers them.
essentio_get_business_setup
Get Business Setup. Reads the connected Business's setup — its name and address as its documents print them, its currency, its active VAT rates and its bank accounts — as Retrieve the Business setup answers it.
essentio_search_payments
Search Payments. Lists the Business's Payments, oldest first, only one document's with document_id, each with its Receipt, as List Payments answers them. A Payment's id is what essentio_amend_payment and essentio_reverse_payment take.
essentio_get_report
Get Report. Reads one of the Business's reports, the dashboard's own figures: report is income or vat (with from and to), overdue (as of today, no period) or statement (with client_id, from and to). A Statement longer than one answer holds (60,000 characters of JSON) is refused as invalid_request: ask for a shorter period. Each is answered as Income, Reported VAT, Overdue or Statement answers it, so an assistant never adds up documents itself — currencies, Credit Notes and Proforma Invoices are counted as Essentio counts them.
The writing tools are marked destructive, so Claude asks you before each call unless you chose Always allow for that tool; Essentio adds no confirmation of its own. Three are also marked open-world, because they reach outside Essentio: essentio_send_document emails your Client, and essentio_create_client and essentio_update_client check a VAT number with the EU's VIES service. None of them moves money — recording a Payment records one already received.
essentio_create_client
Create Client. Creates a Client with the fields Create a Client takes, in its rules and words, and answers the Client. Asks the Create capability (Owner, Admin, Member).
essentio_update_client
Update Client. Changes a Client by its client_id with the fields Update a Client takes; a field not sent keeps its value. Asks the Edit capability.
essentio_create_draft
Create Draft. Creates a Draft Invoice, Proforma Invoice, Credit Note or Quote with its lines, as Create a Draft does — the same rules and the same Business defaults — and answers it with Essentio's VAT and totals. A Draft has no number yet and is sent nowhere. It is shown as the document card. Asks the Create capability.
essentio_update_draft
Update Draft. Changes a Draft by its document_id, as Update a Draft does: a field not sent keeps its value, and lines, when sent, replaces every Line. An issued document is refused. It issues nothing, except a Draft still linked to the Proforma Invoice it was made from, which its save issues or which is refused when the Proforma does not convert into it. It is shown as the document card. Asks the Edit capability.
essentio_delete_draft
Delete Draft. Deletes a Draft by its document_id, as Delete a Draft does. The Public API answers that with no body, so the tool answers {"id": …, "deleted": true}. An issued document is refused (issued_not_deleted): it is cancelled instead. Asks the Delete capability (Owner, Admin, Member).
essentio_issue_document
Issue Document. Issues a Draft by its document_id, as Issue a Draft does: it takes its number and today's issue date for good. Asks the Edit capability.
essentio_send_document
Send Document. Emails a document by its document_id to its Client's address on record through the Business's mail account, issuing a Draft first, as Send a document does. It takes an optional subject and message, and no address: it never mails anyone but the Client. Asks the Send capability.
essentio_cancel_document
Cancel Document. Cancels an issued document by its document_id, as Cancel a document does. Asks the Edit capability.
essentio_convert_proforma
Convert Proforma. Converts an issued Proforma Invoice by its document_id into its Invoice, issued at once, as Convert a Proforma Invoice does. Asks the Create capability.
essentio_record_payment
Record Payment. Records a Payment already received on an issued Invoice or Proforma Invoice by its document_id, with the fields Record a Payment takes, and answers the Payment with its Receipt. Asks the Record payment capability.
essentio_amend_payment
Amend Payment. Corrects a Payment by its payment_id with the fields Amend a Payment takes; a field not sent keeps its value, and its Receipt keeps its number and says what the Payment now says. A reversed Payment is refused (payment_reversed). Asks the Record payment capability.
essentio_reverse_payment
Reverse Payment. Reverses a Payment by its payment_id, as Reverse a Payment does: it is voided and its Receipt keeps its number. Asks the Record payment capability.
essentio_create_product
Create Product. Creates a Product or service with the fields Create a Product takes, in the Product form's rules and words, and answers the Product; with no code it is given one. Asks the Create capability.
essentio_update_product
Update Product. Changes a Product by its product_id with the fields Update a Product takes; a field not sent keeps its value. Asks the Edit capability.
The document card
Creating a Draft, changing it or reading any document shows it in Claude or ChatGPT as a card — an MCP App that essentio_create_draft, essentio_update_draft and essentio_get_document name in their _meta.ui.resourceUri, ui://essentio/document-card.html. It shows the document's type, number and status, its Client, its Lines, VAT by rate and Total, as the tool answered them and worded as Essentio words them (€3,570.00, a credit note's Total with its minus). It is drawn in Essentio's colours, light or dark as the assistant is.
Under it are Issue and Send, each drawn only when the document's actions offer it. They call essentio_issue_document and essentio_send_document with the document's id, so they do only what the connection's Role allows, and Claude asks you before each one as it does in the chat. Essentio sends a Business's email from its own mail server unless the Business connects its own mailbox. When Send is refused because the Business has no way to send — no email address of its own for Essentio to send with, a mailbox it chose that is not set up or has lost its access, or no recipients left for the day through Essentio — the card draws Connect email instead, which opens the Business's Settings → Email in Essentio (the answer's remedy_url). A Refusal — the document is already issued, for instance — is shown on the card in its own words; once issued or sent, the card shows the document as it now is.
The card loads nothing from anywhere and carries no data of its own: its content security policy names no domain, and what it shows arrives as the tool's result. An assistant that does not show MCP Apps reads the same result as JSON.
Refusals and errors
Every tool error — a read's or a write's — is a tool error whose text is the Public API's error JSON: {"error": {"type": "refusal", "code": "no_client_address", "message": "…"}}. A write the Business's rules refuse is a refusal with the Refusal's words and its Refusal code, and a remedy where the Business can put it right in Essentio. A write the Business's plan does not allow carries its code and words and the remedy choose_plan; no tool's answer links to where a plan is chosen — a document's actions carry remedy_url with connect_mail_provider alone on the MCP server, where the Public API also sends it with choose_plan. Fields the rules refuse are invalid_request with errors naming each field, in the same words as the Public API; a Role without the capability is permission; an id the Business does not have is not_found. Nothing is written by a refused call.
Retrying a write
An assistant may make the same call twice — a retry after a lost answer, or a slip. Essentio makes sure that does not create a second Client, Draft or Product, send a document twice or record a Payment twice:
- An identical call within 10 minutes.
essentio_create_client,essentio_create_draft,essentio_create_product,essentio_send_documentandessentio_record_payment, called again by the same connection with the same arguments (in any order) within 10 minutes and with noidempotency_key, write nothing again: the answer is the first call's, marked as a repeat — its_metaholds"pro.essentio/idempotent_replayed": trueand a second text says so. To make a second, identical one on purpose, such as two equal Payments on one day, send it with anidempotency_keyof its own. - With an
idempotency_key. Those five andessentio_issue_document,essentio_cancel_document,essentio_convert_proformaandessentio_reverse_paymenttake an optionalidempotency_key, as their Public API operations take an Idempotency-Key. The same call made again with the same key and the same arguments within 24 hours answers what the first call answered, marked the same way, and writes nothing again; the same key with other arguments is refused (idempotency). - A call made while an identical one, or one with its key, is still being performed is refused as
idempotency_in_flight; a refused or failed call keeps nothing, so it may be corrected and made again. - Issuing, cancelling, converting, reversing and deleting need no more than that: made a second time, each is refused by what the first one did — the document is already issued, cancelled or converted, the Payment already reversed, the Draft no longer found. The updates and a Payment's amendment set the same values again and change nothing.
Pages and sizes
A search takes limit (1 to 25, 10 when it is left out) and cursor, the next_cursor of the page before; next_cursor is null on the last page. A page holds fewer than limit when its documents are long: an answer is kept under 60,000 characters of JSON so it fits an assistant's result, and the next page starts after the last one it holds, so a walk still meets every record once. A page always holds at least one record: a document longer than that on its own comes alone, whole.
Limits and the request log
Each connection has the rate limit of any Connected app, 120 requests a minute; every MCP request counts, a tool call or not. The Business's request log names each one by what it asked — mcp tools/list, mcp tools/call essentio_search_clients — never by what it was sent. What an assistant sends about the person beside a call, such as ChatGPT's locale, location or anonymous id, is neither kept nor logged.
Disconnecting
The person who connected the assistant disconnects it under Profile → Apps in Essentio; the Owner and the Admins of the Business can revoke it under Settings → API Keys. It stops at once: its next request is answered 401. It also stops when the person leaves the Business, and after 90 days unused.
Support
Write to support@essentio.pro: we answer within two working days, Cyprus time. Support says what to include and how to disconnect an assistant.