Connect Claude Code
Add the Invoia MCP server to Claude Code and authenticate with OAuth.
Claude Code talks to remote MCP servers over HTTP. One command adds Invoia; the OAuth flow opens in your browser. That browser step is not optional — see Not from CI if that is where you were heading.
Add the server
claude mcp add --transport http invoia https://invoia.io/api/mcpThen start Claude Code and run /mcp. Pick invoia and authenticate —
the browser opens an invoia.io sign-in followed by the consent screen.
Check where it landed:
claude mcp listinvoia should read ✔ Connected. ! Needs authentication means the
entry is written but you have not run /mcp yet.
Scope it to a project or your user
Claude Code stores servers in one of three scopes:
| Scope | Stored in | Reaches |
|---|---|---|
local (default) | ~/.claude.json, under this project's path | Only you, only this project |
project | .mcp.json in the repo root | Everyone who clones it |
user | ~/.claude.json | Only you, every project |
Invoia is account-wide, not repo-specific, so the user scope is usually the right one:
claude mcp add --transport http --scope user invoia https://invoia.io/api/mcpNothing here holds a secret
The entry records the URL only — the token lives in Claude Code's own
credential store, and each person who authenticates gets their own. That
makes --scope project safe to commit, with one caveat below.
Project scope commits a file
--scope project writes .mcp.json into the repository. Every
collaborator will be prompted to authenticate against your Invoia account,
and non-interactive runs (claude -p, the Agent SDK, cloud sessions) load
it without asking — where it will simply never connect, because none of
them can complete a browser sign-in. Reset the approvals with
claude mcp reset-project-choices.
Not from CI
There is no headless way in. The OAuth consent screen needs a live browser
session, and Invoia accepts no other MCP credential — no key, no
--header, no long-lived token. A build agent, a cron runner or a
claude -p job on a server has no path to a connection.
Point that work at the REST API instead: it authenticates
with a Bearer key on /api/v1, reaches the same product, and speaks the same
error vocabulary. If you already have a REST integration, nothing about it
changed.
Verify it works
> How much have we recognised on the Bredgade SEO retainer this quarter?Claude Code lists the tools it used. A read answer that names real
figures means the credential is live and carries mcp:read.
What it answers by default
> What clients do I have?You get your clients — the customers reached through the invoice lines you are assigned to — not every customer on the account, and the answer says so along with how many sit outside the view. Ask for the account-wide version explicitly if you need it; that one is available to admins only. See Auth and scopes.
Two prompts come with it
/mcp also exposes the server's prompts as commands — one to turn a
contract into a recurring series, one to walk a monthly close. Both show
you a plan and wait before committing anything.
Troubleshooting
! Needs authentication— run/mcp, select invoia, and authenticate. A non-interactive session cannot, and will not connect.- The write tools are missing —
/mcpshows the tool count per server. Sixteen means a read-only grant; twenty-eight is the full set. Re-authenticate and grant more. - A tool call times out — an HTTP server gets 60 seconds to first
byte by default, and issuing waits on Dinero. Raise it for this server
only with a
timeoutfield in the config entry (milliseconds), or setMCP_TOOL_TIMEOUT. - "MCP tool output exceeds 10,000 tokens" — a
list_invoicesacross a busy account will do that. Ask for a narrower query, or raiseMAX_MCP_OUTPUT_TOKENS(the default ceiling is 25,000). - Two entries, one name — local beats project beats user, and the
entries are not merged.
claude mcp get invoiashows which one won.
Remove it
claude mcp remove invoiaAdd --scope user or --scope project if that is where you put it.
Removing the entry does not revoke the grant — do that in Settings →
Developers in the app.