toconline-mcp
Optional integration for archiving invoice PDFs from email via Gmail.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@toconline-mcplist my recent invoices"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
TOCOnline MCP
Unofficial. This is an independent, community-built project. It is not affiliated with, endorsed by, or supported by TOCOnline or Cloudware S.A. "TOCOnline" is a trademark of its respective owner. Use at your own risk — see the warranty disclaimer.
Local MCP server wrapping the TOCOnline accounting/invoicing API. Lets AI assistants list customers, look up products, draft sales documents, and call arbitrary TOCOnline endpoints on your behalf — after a one-time OAuth login.
Quick start
The whole setup is four steps. Each links to its full section below.
Install the launcher (needs Python 3.11+ and
uv):git clone https://github.com/themiguelamador/toconline-mcp.git cd toconline-mcp && uv tool install --from . toconline-mcp→ puts a
toconline-mcplauncher on yourPATH. Details.Get your TOCOnline API credentials — in the TOCOnline web app, Empresa → Configurações → Dados API, request access and set the redirect URL to
http://127.0.0.1:53682/callback. You'll end up with five values (client_id,client_secret, two OAuth URLs, an API URL). Details.Register the server with your client — one line for Claude Code, a small JSON block for Claude Desktop. Details.
Log in — ask your assistant "Log in to TOCOnline" (paste the five values), or run
toconline-mcp setup. A browser opens, you approve, done. Details.
That's it — read-only use works on any plan. Creating/editing documents needs an active GC license. Gmail is a separate, optional add-on for archiving invoice PDFs from email — skip it unless you want it (details).
Related MCP server: buchpilot-mcp
Status
Alpha. Covers the most common read and write operations for customers, suppliers,
products, and commercial sales documents, plus a generic api_request escape
hatch.
Prerequisites
macOS or Linux (Windows untested).
Python 3.11+.
A TOCOnline account with admin access and, for anything beyond
GETrequests, an active GC (Gestão Comercial) license.GET-only use works on any plan.An API integration configured in TOCOnline — see Getting TOCOnline API credentials below.
uv(recommended) orpipxor plainpython3 -m venv.
Install
Not yet published to PyPI — install from source:
git clone https://github.com/themiguelamador/toconline-mcp.git
cd toconline-mcp
# Recommended: uv
uv tool install --from . toconline-mcp
# → installs to ~/.local/share/uv/tools/toconline-mcp/
# → launcher at /Users/<you>/.local/bin/toconline-mcp
# Or pipx
pipx install .
# Or vanilla Python
python3 -m venv ~/.local/toconline-mcp
~/.local/toconline-mcp/bin/pip install .macOS sandbox note. Claude Desktop is sandboxed and cannot execute binaries whose Python installation lives under
~/Documents/,~/Desktop/, or~/Downloads/. The server will fail to start withPermissionError: … /.venv/pyvenv.cfg. Always install via one of the methods above — they all land outside the TCC-protected folders. Do not point Claude Desktop at a.venv/bin/toconline-mcpthat lives inside your cloned repo if the repo sits in~/Documents/.
Updating after code changes
When you pull new commits or edit the source, refresh the installed tool:
uv tool install --from . toconline-mcp --reinstallThen restart whichever client is using the server.
Getting TOCOnline API credentials
Based on the official TOCOnline API docs. These steps are one-time per company/tenant.
1. Request API access
In the TOCOnline web app, go to Empresa → Configurações → Dados API (Company → Settings → API Data). Fill in the integrator details (company info + contact email) and submit.
TOCOnline will email the integrator address a temporary link (valid ~72h) where you can view and edit the API credentials and integration settings.
2. Read the values off the email link page
The link page shows five values you will need:
TOCOnline variable | What it is | Use in this MCP |
| OAuth client id |
|
| OAuth client secret |
|
| Your tenant's OAuth base URL |
|
| Your tenant's API base URL |
|
| Callback URL (pre-set by TOCOnline; editable) | must match what this MCP uses — see next step |
The
OAUTH_URL/API_URLvalues are tenant-specific. Use the exact values shown on the email link page — the defaultapi_basebaked into this tool (https://apiv1.toconline.com) is a generic placeholder and may not match your tenant.
3. Set the redirect URL to match this MCP
This is the single step most people get wrong. TOCOnline pre-fills
OAUTH_REDIRECT_URL with something like http://127.0.0.1:4080/oauth/callback.
This MCP expects http://127.0.0.1:53682/callback (different port,
different path).
On the email link page (or later, back in Empresa → Configurações → Dados API),
overwrite OAUTH_REDIRECT_URL with exactly:
http://127.0.0.1:53682/callbackSave. That's it.
If port 53682 is taken on your machine, pick any free port and pass it as
redirect_port to the login tool (or --port N to the CLI). The path
must remain /callback.
4. Log in
Two equivalent ways — pick whichever fits your workflow.
A. From inside your AI client (recommended)
After registering the server with Claude, ask:
Log in to TOCOnline. Here are the values from Empresa → Configurações → Dados API: client_id =
..., client_secret =..., auth_url =<OAUTH_URL>/auth, token_url =<OAUTH_URL>/token, api_base =<API_URL>.
Claude invokes the login tool, your browser opens to TOCOnline consent,
you approve, and credentials land in
~/.config/toconline-mcp/credentials.json (mode 0600). No separate
terminal step.
Any time later, ask Claude to run auth_status to see whether credentials
are configured and how long until the access token expires, or logout
to clear them.
B. From the command line
toconline-mcp setupPrompts for each value interactively, opens the browser, writes the credentials file. You can also set them in the environment first to skip the prompts:
export TOCONLINE_CLIENT_ID='...'
export TOCONLINE_CLIENT_SECRET='...'
export TOCONLINE_AUTH_URL='<OAUTH_URL>/auth'
export TOCONLINE_TOKEN_URL='<OAUTH_URL>/token'
export TOCONLINE_API_BASE='<API_URL>'
toconline-mcp setupToken lifetime
Access tokens issued by TOCOnline are long-lived (~91 days) and this MCP
refreshes them automatically before each request. You should only need to
re-run login / setup if you revoke the integration, rotate the client
secret, or change OAUTH_REDIRECT_URL.
Register with Claude
Both clients need the absolute path to the installed launcher. Find yours with:
which toconline-mcp
# → e.g. /Users/<you>/.local/bin/toconline-mcpClaude Code
claude mcp add toconline -- /Users/<you>/.local/bin/toconline-mcpClaude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json and
add the toconline entry under mcpServers:
{
"mcpServers": {
"toconline": {
"command": "/Users/<you>/.local/bin/toconline-mcp"
}
}
}Fully quit Claude Desktop (⌘Q — closing the window is not enough) and
reopen it. toconline should now appear in your connectors list with a
DESKTOP badge.
If the server doesn't show up
Check the log:
tail -50 ~/Library/Logs/Claude/mcp-server-toconline.logTwo common errors:
PermissionError: … /.venv/pyvenv.cfg— sandbox blocked the venv. Install viauv tool install --from . toconline-mcp(see above) and point the config at~/.local/bin/toconline-mcp, not a.venvunder~/Documents/.ENOENT/ command not found — the path in the config is wrong. Runwhich toconline-mcpagain and paste that exact path into the config.
Once this package is published to PyPI
After a uv publish, the config can use the shorter portable form that doesn't
depend on a specific user's filesystem:
{
"mcpServers": {
"toconline": { "command": "uvx", "args": ["toconline-mcp"] }
}
}Tools
34 typed tools plus a generic escape hatch. All filters are exact match — TOCOnline does not expose range or substring operators.
Authentication
Tool | Purpose |
| Check whether credentials are configured and when the access token expires. |
| Run the OAuth browser flow and store credentials. |
| Delete stored credentials. |
Customers, suppliers, products
Tool | Purpose |
| Customer CRUD. |
| Suppliers read-only. |
| Products/services read-only. |
Addresses & contacts
Addresses and contacts are separate JSON:API resources with an owning
customer_id or supplier_id (exactly one, not both).
Tool | Purpose |
| Address CRUD. Scope listings by |
| Contact CRUD with the same scoping. |
delete_address / delete_contact require confirm=true.
Sales documents & receipts
Tool | Purpose |
| Filter by |
| Single document, with its line items merged by default. |
| Draft document with line items. For credit/debit notes, set |
| Customer-payment receipts. |
Purchases
Tool | Purpose |
| Supplier invoices. |
| Supplier payments. |
Escape hatch
Tool | Purpose |
| Generic |
Response shape
Responses are flattened from JSON:API — data.attributes.* fields are hoisted
to the top level, and relationships.<name>.data.id becomes <name>_id:
{
"items": [
{"id": "1", "type": "customers", "business_name": "ACME", "country_code": "PT"}
],
"meta": {"total": 1}
}Document actions (PDF, email, finalize, void)
Tool | Purpose |
| Get a signed public URL to the PDF of a sales document, sales receipt, or purchase document. The URL works unauthenticated for a short time — share it with a user and they can download. |
| Email a sales document or receipt to a recipient via TOCOnline's mail servers. |
| Issue a draft document. Irreversible — requires |
| Void (anular) a document. Irreversible — requires |
These endpoints aren't in the public API docs but are discoverable via the Postman collection TOCOnline provides from Empresa → Configurações → Dados API.
Not yet implemented
AT document communication (Portuguese tax authority reporting) — endpoint is
PATCH /api/send_document_at_webservicebut requires a pre-existing communication status/code workflow we haven't mapped.Settlement linking between a payment/receipt and the documents it settles —
create_*_payment/create_*_receiptcreate the payment record itself but don't attach settlement lines. TOCOnline exposescommercial_*_payment_lines/commercial_sales_receipt_linesfor this; useapi_requestuntil we add typed tools.Product create/update, supplier create/update — endpoints exist (
POST/PATCH /api/products,POST/PATCH /api/suppliers) and can be called viaapi_request.Auxiliary APIs as typed tools (tax descriptors at
/api/tax_descriptors, item families at/api/item_families, countries, units of measure, bank accounts, cash accounts) — all readable viaapi_request.
If any of these becomes important, ask and we'll promote it to a typed tool.
Gmail integration (optional)
Most people don't need this. It's a separate add-on for one workflow: pulling supplier-invoice PDFs out of email and archiving them into a folder (local or Google-Drive/iCloud-synced), so you can then enter them in TOCOnline. It's invoice-archiving only — not a general Gmail client (no send, no delete). Completely independent of the TOCOnline tools.
Off by default — nothing to do if you don't want it. The 10
gmail_*tools only appear once Gmail credentials exist (or you setTOCONLINE_GMAIL=1). If you do want it, the three steps are below:
One-time Google Cloud setup — create an OAuth client (you bring your own Google credentials).
Log in once via the CLI —
toconline-mcp gmail-setup.Restart your client — the
gmail_*tools now show up.
One-time Google Cloud setup
Go to https://console.cloud.google.com/ and create (or pick) a project.
APIs & Services → Library → enable Gmail API.
APIs & Services → OAuth consent screen → set up a "Desktop"/"External" consent screen with your email as a test user.
APIs & Services → Credentials → Create Credentials → OAuth client ID → Desktop app (or Web app). Register
http://127.0.0.1:53683/callbackas an Authorized redirect URI.Copy the Client ID and Client secret.
Log in
First login must use the CLI (the in-Claude gmail_* tools don't exist until
credentials are present):
toconline-mcp gmail-setupTokens are saved to ~/.config/toconline-mcp/gmail-credentials.json (0600),
separate from the TOCOnline credentials. Restart your client afterwards — the
gmail_* tools (including gmail_login for re-auth) now appear.
Scope
gmail.modify — covers reading messages, downloading attachments, and
adding/removing labels. It does not allow permanent deletion or sending
messages. Narrower scopes (like gmail.readonly or gmail.labels) can't
label messages, which breaks the "mark as imported" workflow.
Gmail tools (10)
Tool | Purpose |
| Auth lifecycle (mirrors TOCOnline's auth trio). |
| Search with Gmail query syntax ( |
| Fetch a single message's metadata + attachment list. |
| Download one attachment to an absolute local path. Handles filename collisions with |
| Discover and create labels. |
| Mark messages as processed (e.g. apply an |
Example workflow: bulk-download supplier invoices
Ask Claude:
Search my Gmail for unread messages from
billing@senders with PDF attachments since 2026-04-01. For each one, download every PDF to/Users/me/Google Drive/Invoices/2026-04/and apply the labelImported/TOCOnline. Then print a summary table.
Claude uses: gmail_search_messages → gmail_list_labels (or gmail_create_label
if missing) → for each result gmail_download_attachment + gmail_add_label_to_message.
Using a Google-Drive-synced folder for save_dir gives you cloud sync for free.
Gmail env vars
TOCONLINE_GMAIL_CREDENTIALS_PATH— override the credentials file location.GMAIL_CLIENT_ID/GMAIL_CLIENT_SECRET— skip the CLI prompts duringgmail-setup.
Config file (~/.config/toconline-mcp/.env)
Rather than exporting env vars in your shell every time, drop them in a
.env file and the MCP loads it at startup. Values from real environment
variables always win — the file is a fallback.
Loader checks these paths in order (first existing one wins):
Whatever
TOCONLINE_ENV_FILEpoints at (if set).~/.config/toconline-mcp/.env— primary location (next tocredentials.json)../.envin the current working directory (dev convenience).
Example file — all fields optional, include only what you want cached:
# ~/.config/toconline-mcp/.env
# --- TOCOnline ---
TOCONLINE_CLIENT_ID=ptNNNNNNNNN_cNNNNNN-xxxxxxxxxxxxxxxx
TOCONLINE_CLIENT_SECRET=your-rotated-secret
TOCONLINE_AUTH_URL=https://app14.toconline.pt/oauth/auth
TOCONLINE_TOKEN_URL=https://app14.toconline.pt/oauth/token
TOCONLINE_API_BASE=https://api14.toconline.pt
# --- Gmail (Google OAuth client from console.cloud.google.com) ---
GMAIL_CLIENT_ID=1234...apps.googleusercontent.com
GMAIL_CLIENT_SECRET=GOCSPX-xxxxxxxxxxxxxxxxxxxxFormat:
KEY=VALUEper line.#comments and blank lines are fine.Quote values with spaces:
NAME="with spaces".export KEY=VALUEis accepted (for shell-compatibility).No variable interpolation (
$VAR/${VAR}) — export from shell if you need that.
After creating the file, toconline-mcp setup and toconline-mcp gmail-setup
skip the interactive prompts for any field the file already provides.
Permissions: the file contains OAuth client secrets, which are less sensitive than access tokens but still not public. Chmod it:
chmod 600 ~/.config/toconline-mcp/.envThe MCP prints a warning: on stderr if it detects looser permissions.
Development
uv venv --python 3.11
uv pip install -e '.[dev]'
pytestEnvironment variables:
TOCONLINE_CREDENTIALS_PATH— override the credentials file location.TOCONLINE_LOG_LEVEL—DEBUG,INFO,WARNING, etc. Logs go to stderr.
Iteration workflow (picking up code changes)
uv tool install --reinstall updates the binary on disk, but does not
restart already-running MCP processes — Python imports modules at startup,
so a live server keeps serving the old code until killed. After editing the
source:
# 1. Run the test suite (catches regressions before they hit the live server)
pytest
# 2. Refresh the installed launcher
uv tool install --from . toconline-mcp --reinstall
# 3. Find Claude Desktop's MCP server process and kill it
ps aux | grep toconline-mcp | grep -v grep
kill <pid>
# 4. Start a new chat in Claude Desktop (Cmd-N). The first tool call
# in that new chat causes Claude Desktop to respawn the MCP with the
# new code — and the new chat's LLM is given the fresh tool list.Why "new chat" matters even more than "kill the server"
There are two layers that cache things:
The MCP server process caches the registered tool list in memory (modules are imported at startup). Killing the process forces a respawn that re-imports the latest code.
The chat session caches the tool list it got from the server at chat start, baked into the LLM's context. Newly-added tools don't appear in an existing chat even after the server respawns.
So if you've added a tool (list_services for example) and you want the
LLM to be able to call it, you need both:
The kill+respawn (so the server exposes the new tool at all), AND
A new chat (so the LLM is told the new tool exists).
Editing an existing tool's behaviour or fixing a bug is different — the tool's name is the same, the LLM already knows about it, so just kill+respawn is enough; the next call hits the new code. Adding or renaming tools requires a new chat.
The same applies to Claude Code: the deferred tools list shown at session
start is locked in for that chat. New tools require a new Claude Code session
(/clear or starting fresh).
Stale processes
Stray uvx toconline-mcp processes from old terminals can linger and serve
stale code. ps aux | grep toconline-mcp shows them; kill <pid> clears
them. They're harmless when idle but confusing if you claude mcp add more
than one server pointing at the same binary.
Security
Tokens and client secrets stored in
~/.config/toconline-mcp/credentials.json(0600). The server refuses to start if permissions are looser.All logging is to stderr (stdout is reserved for MCP stdio framing). Authorization headers and token fields are redacted from log messages.
api_requestpath is constrained to^/api/...with no..; write methods require an explicitconfirm=true.
License
MIT.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/themiguelamador/toconline-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server