Developers

Usetally MCP server

Usetally makes branded quotes, invoices and receipts for small businesses. Its remote MCP server lets AI assistants (ChatGPT, Claude, Grok and any MCP client) work in a customer's Usetally: create and send quotes and invoices, record payments, and answer questions about money owed. Every customer connects their own account.

Connection

Server URL
https://usetally.cc/mcp
Transport
Streamable HTTP (stateless, JSON responses). POST only; no SSE stream or session ID.
Protocol
Model Context Protocol, revisions 2025-06-18 and 2025-11-25
Authentication
OAuth 2.1, authorization code with PKCE (S256). Each customer signs in with their own Usetally account.
Client registration
Dynamic Client Registration (RFC 7591) or Client ID Metadata Documents (CIMD). Public clients, token_endpoint_auth_method "none".
Scopes
usetally.read (view only) · usetally.write (create, send, record payments). offline_access for refresh tokens.
Tokens
Access tokens last 1 hour. Refresh tokens last 90 days, are single use and rotate; reusing one ends the connection.

How sign-in works

  1. The client calls POST /mcp without a token and gets 401 with WWW-Authenticate: Bearer resource_metadata=….
  2. It reads the metadata documents below, then registers (DCR) or presents its CIMD URL as the client ID.
  3. The customer signs in to Usetally, picks one of their businesses and chooses Full access or View only.
  4. The client swaps the code (with its PKCE verifier) for tokens and calls /mcp with Authorization: Bearer ….

Redirect URIs must be https, or http on localhost / 127.0.0.1 (matched on any port). Customers can see and disconnect every connection in Usetally under Settings → AI & MCP.

Protected resource metadata (RFC 9728)
https://usetally.cc/.well-known/oauth-protected-resource/mcp
Authorization server metadata (RFC 8414)
https://usetally.cc/.well-known/oauth-authorization-server
Authorize
https://usetally.cc/oauth/authorize
Token
https://usetally.cc/oauth/token
Register (DCR)
https://usetally.cc/oauth/register
Revoke (RFC 7009)
https://usetally.cc/oauth/revoke

Tools

12 tools. View-only connections get only the read tools. Connecting needs a Usetally trial or paid plan; a business on the Free plan gets one tool that explains how to upgrade, and no access to its data. Every change runs as the signed-in person, so their team role, approval rules and plan limits apply exactly as in the app. Amounts are normal amounts in the document's currency (150000 means ₦150,000).

get_business_overview

Read only

What's happening in your business: money owed, overdue invoices, payments this month, quotes waiting for an answer, drafts, and whether it can send. Start here when asked how the business is doing.

list_documents

Read only

Find quotes and invoices, newest first. Filter by kind, status (unpaid and overdue included) or customer.

ParameterTypeNotes
kindquote | invoice | all
statusall | draft | awaiting_approval | sent | viewed | accepted | declined | unpaid | overdue | partially_paid | paid | void
customerstringPart of the customer's name or company.
limitinteger

get_document

Read only

Everything on one quote or invoice: items, totals, what's been paid, and its links (the customer's link and PDF once it's sent).

ParameterTypeNotes
document*stringThe document's number (e.g. INV-0042, QT-0007) or id.

find_customers

Read only

Search the business's saved customers by name, company, email or phone.

ParameterTypeNotes
querystring
limitinteger

find_products

Read only

Search the business's price list (saved products and services) to use their names and prices on documents.

ParameterTypeNotes
querystring
limitinteger

create_invoice

Changes data · asks first

Create a draft invoice in your business, branded with the business's template. Nothing is sent: show the person the total and ask before using send_document. Prices are normal amounts in the document's currency.

ParameterTypeNotes
customer*objectWho the document is for.
customer.idstringAn existing customer's id from find_customers. Leave out to use a name.
customer.namestringCustomer's name. An existing customer with exactly this name or email is reused.
customer.companystring
customer.emailstringNeeded to email the document to them.
customer.phonestring
customer.addressstring
items*arrayWhat the customer pays for, 1 to 200 lines.
items[].description*stringWhat it is, e.g. "Logo design".
items[].quantitynumber
items[].unit_pricenumber or stringPrice for one, in the document's currency as a normal amount (150000 means ₦150,000, not kobo). Leave out when using product_id.
items[].detailsstringA second line under the description.
items[].vatstandard | zero | exemptOnly for VAT-registered businesses: zero-rated or exempt items.
items[].product_idstringA product from find_products; its name and price are used unless given.
titlestringOptional heading, e.g. "Website redesign".
currencystring3-letter code (NGN, USD, GBP…). Leave out for the business's usual currency.
discountnumber or stringA discount off the total, as an amount.
tax_ratenumberTax percentage. Leave out to use the business's usual tax.
tax_labelstringThe tax's name, e.g. VAT.
notesstringA note shown to the customer.
termsstringPayment terms. Leave out for the business's usual terms.
due_datestringYYYY-MM-DD. Leave out for the business's usual payment terms.

create_quote

Changes data · asks first

Create a draft quote in your business, branded with the business's template. Nothing is sent: show the person the total and ask before using send_document. Prices are normal amounts in the document's currency.

ParameterTypeNotes
customer*objectWho the document is for.
customer.idstringAn existing customer's id from find_customers. Leave out to use a name.
customer.namestringCustomer's name. An existing customer with exactly this name or email is reused.
customer.companystring
customer.emailstringNeeded to email the document to them.
customer.phonestring
customer.addressstring
items*arrayWhat the customer pays for, 1 to 200 lines.
items[].description*stringWhat it is, e.g. "Logo design".
items[].quantitynumber
items[].unit_pricenumber or stringPrice for one, in the document's currency as a normal amount (150000 means ₦150,000, not kobo). Leave out when using product_id.
items[].detailsstringA second line under the description.
items[].vatstandard | zero | exemptOnly for VAT-registered businesses: zero-rated or exempt items.
items[].product_idstringA product from find_products; its name and price are used unless given.
titlestringOptional heading, e.g. "Website redesign".
currencystring3-letter code (NGN, USD, GBP…). Leave out for the business's usual currency.
discountnumber or stringA discount off the total, as an amount.
tax_ratenumberTax percentage. Leave out to use the business's usual tax.
tax_labelstringThe tax's name, e.g. VAT.
notesstringA note shown to the customer.
termsstringPayment terms. Leave out for the business's usual terms.
valid_untilstringYYYY-MM-DD. Leave out for the business's usual validity.

update_draft

Changes data · asks first

Change a draft quote or invoice. Only the fields given change; items, if given, replace all the items. Sent documents can't be edited here.

ParameterTypeNotes
document*stringThe document's number (e.g. INV-0042, QT-0007) or id.
customerobjectWho the document is for.
customer.idstringAn existing customer's id from find_customers. Leave out to use a name.
customer.namestringCustomer's name. An existing customer with exactly this name or email is reused.
customer.companystring
customer.emailstringNeeded to email the document to them.
customer.phonestring
customer.addressstring
itemsarrayWhat the customer pays for, 1 to 200 lines.
items[].description*stringWhat it is, e.g. "Logo design".
items[].quantitynumber
items[].unit_pricenumber or stringPrice for one, in the document's currency as a normal amount (150000 means ₦150,000, not kobo). Leave out when using product_id.
items[].detailsstringA second line under the description.
items[].vatstandard | zero | exemptOnly for VAT-registered businesses: zero-rated or exempt items.
items[].product_idstringA product from find_products; its name and price are used unless given.
titlestringOptional heading, e.g. "Website redesign".
currencystring3-letter code (NGN, USD, GBP…). Leave out for the business's usual currency.
discountnumber or stringA discount off the total, as an amount.
tax_ratenumberTax percentage. Leave out to use the business's usual tax.
tax_labelstringThe tax's name, e.g. VAT.
notesstringA note shown to the customer.
termsstringPayment terms. Leave out for the business's usual terms.
due_datestringInvoices: YYYY-MM-DD.
valid_untilstringQuotes: YYYY-MM-DD.

send_document

Changes data · asks firstEmails the customer

Send a quote or invoice: it's marked sent, gets its customer link and PDF, and is emailed to the customer (or the email given). Already-sent documents are emailed again. Always confirm with the person first. If the person's role needs approval, it's sent for approval instead.

ParameterTypeNotes
document*stringThe document's number (e.g. INV-0042, QT-0007) or id.
emailstringSend to this address instead of the customer's saved email.
messagestringA short personal message for the email.
email_customerbooleanfalse: just mark it sent and return the link, e.g. to share on WhatsApp.

convert_quote_to_invoice

Changes data · asks first

Make an invoice from a sent or accepted quote, with the same customer and items. Like in the app, the invoice is live straight away (its customer link and PDF work) but isn't emailed: use send_document to email it.

ParameterTypeNotes
document*stringThe quote's number or id.

record_payment

Changes data · asks first

Record money the customer paid outside Usetally (bank transfer, cash, POS). A receipt is issued automatically. Confirm the amount first.

ParameterTypeNotes
document*stringThe invoice's number or id.
amount*number or stringThe amount received, as a normal amount.
methodbank_transfer | cash | pos | other
datestringYYYY-MM-DD when it was paid. Leave out for today.
referencestringBank or teller reference.
notestring

void_document

Destructive · asks first

Cancel a sent quote or invoice so it can't be paid or accepted. It stays in the records, marked void. This can't be undone, so confirm first.

ParameterTypeNotes
document*stringThe document's number (e.g. INV-0042, QT-0007) or id.

Try it

With the MCP Inspector: npx @modelcontextprotocol/inspector, choose Streamable HTTP, enter https://usetally.cc/mcp and connect. It walks the same OAuth sign-in a customer sees.

Questions: signed-in customers can write to us from Ideas & help in the app. See also the privacy policy and terms.