MCP Server
Billabex exposes a Model Context Protocol (MCP) server so AI tools can access Billabex data using OAuth 2.1. This guide explains discovery, authorization, available tools and resources, and how to connect.
MCP Endpoint
The MCP server uses Streamable HTTP (stateless):
POST [baseURL]/mcp
OAuth Discovery Flow
MCP clients follow RFC 9728 (Protected Resource Metadata) and RFC 8414 (OAuth Authorization Server Metadata):
- Call
POST /mcpwithout a token. - The server responds with
WWW-Authenticateincludingresource_metadataandscope. - Fetch the resource metadata URL to discover
authorization_serversandscopes_supportedfor/mcp. - Fetch the authorization server metadata to locate the authorization and registration endpoints.
Example 401 Response
The MCP server returns:
WWW-Authenticate: Bearer resource_metadata="[baseURL]/.well-known/oauth-protected-resource", scope="mcp:read mcp:write"
Protected Resource Metadata (Path-Aware)
For /mcp, request:
[baseURL]/.well-known/oauth-protected-resource/mcp
The response includes:
{
"resource": "[baseURL]",
"authorization_servers": ["[baseURL]"],
"scopes_supported": ["mcp:read", "mcp:write"],
"bearer_methods_supported": ["header"]
}
Authorization Server Metadata
GET [baseURL]/.well-known/oauth-authorization-server
This returns the authorization_endpoint, token_endpoint, and
registration_endpoint needed for OAuth 2.1 + PKCE.
Scopes
MCP uses two scopes:
| Scope | Access | Description |
|---|---|---|
mcp:read |
Read | List and get invoices, accounts, communications. |
mcp:write |
Write | Create, update, delete operations. |
Consent Behavior
If an authorization request omits the scope parameter, Billabex defaults to
mcp:read mcp:write for MCP clients.
Protocol Details
- Transport: Streamable HTTP (stateless mode).
- Authentication:
Authorization: Bearer <token>header (required). - Rate limiting: 300 requests/minute per token (sliding window).
- CORS header: Clients may send
Mcp-Protocol-Versionheader.
Resources
MCP resources provide metadata that AI tools can read to understand Billabex capabilities.
| URI | Description |
|---|---|
billabex://about |
Platform overview, value proposition, key features |
billabex://concepts |
Key entities, statuses, relationships, and business rules |
billabex://workflow |
Step-by-step dunning workflow, task handling, and processes |
These resources help AI agents understand:
- About: What Billabex is, how it helps businesses manage invoice collection
- Concepts: Domain model including invoices, accounts, customer balances, communications, and tasks
- Workflow: Standard dunning workflow from invoice overdue to payment recovery
Prompts
MCP prompts provide business-oriented templates for AI agents to perform common tasks. Unlike tools, prompts use human-readable parameters (account names, organization names) instead of technical IDs.
| Prompt | Parameters | Use Case |
|---|---|---|
financial-snapshot |
organizationName?, period? (7/30/all days) |
Overview of outstanding balances, top accounts, cash flow |
account-360 |
accountName, organizationName? |
Complete account summary with invoices, communications, tasks |
daily-plan |
organizationName? |
Daily action plan: tasks, reminders, follow-ups |
daily-digest |
organizationName? |
Summary of today’s activities and updates |
communication-intelligence |
accountName?, organizationName? |
Recent replies, payment promises, accounts that replied but didn’t pay |
risk-report |
organizationName? |
Accounts at risk, silent accounts, accounts without contacts |
silent-accounts |
organizationName?, period? (30/90/all days) |
Accounts that never replied to a follow-up email |
blocked-accounts |
organizationName? |
Accounts whose emails bounced or were marked as spam |
inbound-email-digest |
organizationName?, period? (7/30/90 days) |
Synthesis of the incoming emails over a recent period |
How Prompts Work
- User provides names: You call a prompt with an account name like “Acme Corp” instead of a UUID
- Agent resolves IDs: The prompt instructs the AI agent to use tools like
list-accountsandlist-organizationsto find the matching IDs - Agent gathers data: The agent calls multiple tools to gather relevant data
- Agent presents results: Results are formatted naturally without exposing technical IDs
Example: Financial Snapshot
{
"name": "financial-snapshot",
"arguments": {
"organizationName": "My Company",
"period": "30days"
}
}
The agent will:
- Use
list-organizationsto find “My Company” - Use
list-customer-balancesto get outstanding balances - Use
list-invoicesto find upcoming due invoices - Present a formatted overview of your financial position
Tools Reference
Tools are grouped by domain. Read tools require mcp:read; Write tools require mcp:write.
Tool outputs include human-friendly fields such as displayName and summary where available. Prefer those fields for user-facing responses and keep IDs for follow-up tool calls.
All tools include annotations (readOnlyHint, destructiveHint, idempotentHint, openWorldHint) to help AI agents understand their behavior.
Invoicing
| Tool | Access | Description |
|---|---|---|
list-invoices |
Read | List invoices with the account payment method (paginated). |
get-invoice |
Read | Get invoice by ID or by number. |
create-invoice |
Write | Create invoice with base64 file upload. |
update-invoice-paid-amount |
Write | Update paid amount on an invoice. |
delete-invoice |
Write | Delete an invoice. |
list-accounts |
Read | List customer accounts with their type and payment method. |
get-account |
Read | Get account type, details and contacts. |
create-account |
Write | Create a customer account with an optional account type. |
update-account |
Write | Update account type, name, currency, address or payment method. |
delete-account |
Write | Delete a customer account. |
list-contacts |
Read | List contacts on an account. |
get-contact |
Read | Get a specific contact. |
create-contact |
Write | Add a contact to an account. |
update-contact |
Write | Update a contact. |
delete-contact |
Write | Remove a contact. |
upsert-contact |
Write | Create or update contact by email/name match. |
set-contact-enabled |
Write | Enable or disable a contact on an account. |
list-credit-notes |
Read | List credit notes with the account payment method (paginated). |
get-credit-note |
Read | Get credit note details. |
create-credit-note |
Write | Create a credit note. |
update-credit-note-refunded-amount |
Write | Record a partial or full cash refund. |
delete-credit-note |
Write | Delete a credit note. |
apply-credit-allocation |
Write | Apply credit from a credit note to an invoice. |
remove-credit-allocation |
Write | Remove a credit allocation. |
add-account-tags |
Write | Attach existing labels to an account. |
remove-account-tag |
Write | Detach a label from an account. |
link-account-source |
Write | Link an external source to an account. |
update-account-source |
Write | Update account source last-sync timestamp. |
unlink-account-source |
Write | Unlink an external source. |
A disabled contact is never contacted proactively by the agent. Re-enabling one is a human decision, so set-contact-enabled should not be used to undo a disable the client asked for.
create-contact, update-contact and upsert-contact take a phones list of { number, countryCode? }. A number starting with + or 00 carries its own country code; any other number is national and requires countryCode (ISO 3166-1 alpha-2), because Billabex never guesses a country. Contacts are returned with phones: [{ number, type, country, origin }], where type (Mobile / Landline / Unknown) and country are derived from the number itself and read-only. Writing phones replaces only what a human entered, never the numbers a connector brought (origin: "Connector"); omit the field to leave everything alone, send [] to clear the manual ones. Only a French mobile can receive an SMS. See Contacts for the full model.
Documents created by create-invoice and create-credit-note carry the Mcp channel, distinct from the PublicApi one the REST API stamps. They can live on an organization that is also synced with one or more connectors: see Sources for why an account’s source never tells you where one of its documents came from.
list-invoices and list-credit-notes return accountPaymentMethod as
DIRECT_DEBIT, BANK_TRANSFER, or null. The value is read from the account
when the list is requested, so changing the account does not require updating
each document.
Account tools expose accountType as Professional, Consumer, or Unknown.
create-account and update-account accept the same field. Omit it at creation to infer
Professional from a legal identifier, otherwise the account remains Unknown. A standard
connector controls the value and cannot be overridden through MCP; a Custom source remains
editable. Consumer accounts are not checked against BODACC, while their SIREN and VAT number,
if present, remain available through the API.
Dunning
| Tool | Access | Description |
|---|---|---|
list-customer-balances |
Read | List customer outstanding balances (paginated). |
get-customer-balance |
Read | Get balance details with invoices/credit notes. |
list-communications |
Read | List incoming and outgoing emails at once, filterable server-side. |
list-silent-accounts |
Read | List accounts emailed at least once that have never replied. |
list-outgoing-communications |
Read | List outgoing dunning emails (paginated). |
get-outgoing-communication |
Read | Get outgoing communication details. |
list-outgoing-communications-by-account |
Read | List outgoing communications for an account. |
update-outgoing-communication |
Write | Update a scheduled outgoing email. |
send-outgoing-communication |
Write | Send an email immediately on behalf of the agent, to free-form recipients. |
preview-outgoing-letter |
Read | Preview and price a tracked or registered postal reminder. |
send-outgoing-letter |
Write | Send a paid postal reminder with selected evidence. |
list-incoming-communications |
Read | List incoming (reply) communications. |
get-incoming-communication |
Read | Get incoming communication details. |
list-incoming-communications-by-account |
Read | List incoming communications for an account. |
pause-account-dunning |
Write | Suspend reminders with a fact reason, or until a date for a dated wait. |
resume-account-dunning |
Write | Lift human-resumable pauses and return any protections that remain. |
list-communications reads a pre-joined projection and filters by account, type, delivery status
(bounced, complained) and date range on the server. Prefer it over paging the incoming and outgoing
lists separately.
| Tool | Access | Description |
|---|---|---|
list-emails |
Read | List all emails (incoming + outgoing). |
list-incoming-emails |
Read | List incoming emails (paginated). |
get-incoming-email |
Read | Get incoming email with simplified body. |
list-outgoing-emails |
Read | List outgoing emails (paginated). |
get-outgoing-email |
Read | Get outgoing email with simplified body. |
Platform
| Tool | Access | Description |
|---|---|---|
list-organizations |
Read | List organizations for the user, with their credits. |
get-organization |
Read | Get organization details, including the credit balance. |
update-organization |
Write | Update organization name or email domain. |
update-organization-settings |
Write | Update reminder delay settings. |
set-organization-logo |
Write | Set or remove the organization logo (base64 image). |
list-organization-members |
Read | List members and their profile picture metadata. |
remove-organization-member |
Write | Remove a member from an organization. |
set-my-avatar |
Write | Set or replace the authenticated user’s profile picture. |
remove-my-avatar |
Write | Remove the authenticated user’s profile picture. |
create-organization-invitation |
Write | Invite a user to an organization. |
cancel-organization-invitation |
Write | Cancel a pending invitation. |
list-tags |
Read | List the organization’s labels plus the standard ones. |
create-tag |
Write | Create a label owned by the organization. |
Both organization tools return credits, the prepaid balance that pays for the SMS and postal
letter reminders Billabex sends. See Credits below.
They also return the two effective first-reminder rules,
firstReminderDelayForDirectDebit and firstReminderDelayForBankTransfer, each
{ days, direction } with direction being BEFORE or AFTER the due date, or null when
neither an override nor firstReminderDelayDays is set. update-organization-settings writes them
under the same names: an absent key leaves that mode alone, an explicit null records that the
mode has no rule of its own and falls back on firstReminderDelayDays. An account whose payment
method is unknown follows firstReminderDelayDays alone, never either of these two.
They also return logo, the image uploaded for the organization, or null. null does not mean
no logo is shown: with none uploaded, one is derived from the organization’s email domain at
display time and nothing is stored. set-organization-logo takes a base64 PNG, JPEG or WebP up to
2 MB, or file: null to remove it. The real file signature is checked, not the declared type, so
an SVG is refused.
Tasking
| Tool | Access | Description |
|---|---|---|
list-account-tasks |
Read | List active tasks requiring user input. |
get-account-task |
Read | Get task details and required input format. |
cancel-account-task |
Write | Cancel an account task. |
add-account-task-text-interaction |
Write | Add a text response to a task. |
add-account-task-structured-interaction |
Write | Add a structured response to a task. |
Credits
get-organization and list-organizations return a credits field: the prepaid balance that
pays for the SMS and postal letter reminders Billabex sends on your behalf. Emails are free and
never consume it.
{
"id": "123e4567-e89b-12d3-a456-426614174000",
"name": "Acme Corporation",
"credits": 250
}
At zero, SMS and letters stop going out; email reminders keep running. Nothing else in the API signals that, which is why the balance is worth reading if you build a dashboard or an alert on top of Billabex.
The field is read-only, but send-outgoing-letter spends it after rendering the selected
invoices and credit notes. Call preview-outgoing-letter first to obtain the exact page count and
credit price without spending anything. send-outgoing-communication still sends a free email.
Topping the balance up is not self-service; Billabex handles it manually.
Pagination
Tools returning lists use cursor-based pagination:
- Parameters:
first(items per page, max 100),after(cursor). - Response:
nodesarray +pageInfo.endCursor.
Notes
- OAuth is required for all MCP access.
- Tokens must be sent in the
Authorization: Bearer <token>header. - Rate limiting applies to MCP requests (300/min per token).
update-outgoing-communicationacceptsmessagein markdown. Do not include a signature; the platform renders HTML/text and appends the agent signature automatically.