Developers

Overview

What the Invoia MCP server is, and what an agent can and cannot do with it.

Invoia speaks MCP. Point an AI client at one URL and it can read your invoicing — customers, invoices, retainers, logged hours, revenue recognition — and propose changes to it. Nothing is written until you say so.

https://invoia.io/api/mcp

What it is

A remote MCP server over streamable HTTP, stateless: every call is one POST carrying its own credential, so there is no session to keep alive and no local process to run. GET and DELETE return 405 — if your client insists on opening an SSE stream first, it is talking to the wrong kind of server.

The server registers itself as invoia. Its tools self-describe over tools/list, so this documentation does not repeat the catalogue — ask your client what it can do and it will tell you, accurately, for the scopes you granted.

One way to connect: OAuth

Every client below connects the same way. Paste the URL, sign in at invoia.io, approve the scopes you are willing to grant. The client keeps the token and refreshes it on its own; you never handle a secret, and nothing you paste into a config file is one.

The consent screen is also how the server learns who you are — which is what lets it answer "my clients" with your clients rather than the account's. See Auth and scopes.

There is no headless path

Consent needs a live browser session, so CI, cron jobs, containers and server-side agents cannot connect over MCP at all — there is no key, flag or long-lived token that skips it. Run that work against the REST API on /api/v1, which authenticates with a Bearer key and has no consent step. Existing REST integrations are untouched by any of this and need no action.

What an agent can do

  • Read — sixteen list_* / get_* tools covering the acting user's own work, customers, products, invoices and their lines, recurring series and occurrences, logged work, revenue recognition and month-end accruals.
  • Propose — eleven plan_* tools that draft a change and hand back a plan for you to read, from plan_upsert_customer to plan_register_work to plan_issue_invoice.
  • Commit — one commit tool that applies a plan you approved.

Twenty-eight tools on a full-scope connection; sixteen on a read-only one, because the rest are never registered.

Names, not UUIDs

Every tool takes the reference a human would use — Bredgade SEO, ext:your-id, email:someone@example.com — so you never have to look up an id to ask a question. me is one of them: it is you, resolved without a lookup. An ambiguous name comes back as a list of candidates rather than a guess.

Your work is the default answer

Reads answer from the work you are assigned to, not from the whole account. get_my_work returns your lines in one call, ranked by what needs attention; the customer, invoice, retainer and credit-note rosters take a scope, defaulting to mine, and every result opens by saying which view produced it and how many rows sit outside it.

Widening is yours to ask for, and which views you may ask for follows your role in the app — the account-wide one is an admin's. Connecting a client grants no more authority than you already have.

Beyond tools

Two more MCP surfaces come with the connection, and clients expose them differently — often as slash commands or an attachable context menu.

  • Promptssetup_invoicing_from_contract turns a contract into a recurring series; monthly_close walks the occurrences due this period. Both are written to stop and show you a plan before anything is committed.
  • A resourceinvoia://config carries the connected integration's base currency and its WIP / deferred-revenue account numbers. Pin it and the agent stops guessing which currency your figures are in.

What it cannot do

  • Write anything without a separate, explicit commit — see The propose → commit contract.
  • Exceed the scopes you granted. Issuing (booking to Dinero and emailing a customer) is its own scope you can withhold — see Auth and scopes.
  • Run without a person. Every request is authenticated as one, which is the same fact as the headless limit above.
  • Register another person's hours, unless you are an admin and name them.
  • Invite users, change roles, or alter billing. Those stay in the app, behind a signed-in admin session.

Connect your client

Prefer to write the integration yourself, or need it to run unattended? The same product is a REST API — start at Getting started.