MCP tool reference
The server registers twelve business tools; the hosted OAuth server also adds get_connection_profile (thirteen total). Every tool publishes a title and readOnlyHint, destructiveHint, idempotentHint and openWorldHint annotations. Clients may prefix their displayed names with the server name. Inputs below use the server's actual snake-case parameter names. Results are MCP text content containing formatted JSON; failures generally set isError. Reconcile ambiguous writes before issuing another operation.
Parameters#
| Tool | Required inputs | Optional inputs and defaults | Effect |
|---|---|---|---|
get_protocol_info | None ({}) | None | Reads protocol information and attempts live stats |
get_dashboard | None ({}) | None | Reads balance, invoice stats, and five recent invoices |
list_invoices | None | status: issued, paid, canceled, all (default all); customer: string; since, until: ISO dates; limit: integer 1–50 (default 20); cursor: string | Lists one page with continuation metadata |
get_invoice | invoice_id: string | None | Reads one invoice |
check_payment | At least one of invoice_id or customer | Both are strings; invoice takes precedence if both supplied | Reads one invoice's payment state or a limited customer summary |
get_pay_link | invoice_id: string | None | Reads the tokenized payment link |
send_invoice | customer: string, amount: string, description: string | due_days: number (default 30); send_email: boolean (default false); idempotency_key: string, maximum 128 characters | Creates an invoice, optionally emails it |
cancel_invoice | invoice_id: string | None | Cancels an Issued invoice |
list_customers | None | search: string (name or email) | Reads up to 100 customers |
get_customer | customer_id: string | None | Reads one customer |
create_customer | name, email, address; entities also registration_number | type, vat_number, trade_name, tax_id, wallet_address, notes | Creates a customer (does not contact them) |
update_customer | customer_id: string | name, email, address, registration_number, vat_number, trade_name, tax_id, wallet_address, notes | Updates a customer (does not contact them) |
customer can be a name, email, or UUID. Prefer a known UUID to avoid ambiguous name/email matching. send_invoice.amount is a human-readable USDC amount such as "500.00", unlike the REST raw-unit amount. Supply valid decimal strings and a whole-number due_days. The REST description limit is 500 characters.
The MCP amount parser uses JavaScript Number and rounds to cents before converting to USDC units. It is not an exact six-decimal or arbitrary-precision input path. Use REST raw integer strings when sub-cent precision or large exact amounts matter.
Read examples#
On the hosted server, get_connection_profile accepts {} and returns a stable opaque connection profile ID with optional display fields. It is read-only and does not return an authorization scope list. Review permissions in Cleared Settings.
{ "limit": 5, "status": "issued" }Use that input with list_invoices, then use the returned numeric ID with get_invoice, check_payment, or get_pay_link:
{ "invoice_id": "42" }Invoice tools also accept formatted numbers such as INV-2026-000007. They resolve the merchant's sequential number and issuance year within your authenticated studio. For example, merchant invoice number 7 can resolve to global invoice ID 42. Missing, wrong-year, or ambiguous matches fail explicitly; the suffix is never used as a fallback ID. Numeric IDs remain exact decimal strings.
list_invoices returns invoices, count, summary, and page containing has_next_page, next_cursor, and limit. The default limit is 20; valid limits are integers from 1 through 50. To fetch the next page, pass page.next_cursor as cursor with the same filters. Stop when has_next_page is false. Counts and summaries describe the returned page only. Invalid or obsolete cursors return an error; restart without a cursor.
since and until filter the invoice issuance timestamp. Use ISO dates or date-times with a timezone. Invalid calendar dates and reversed ranges are rejected. Date-only until values represent midnight, not the end of that day. Lists remain subject to indexer lag; keep filters unchanged while paging, and restart if the underlying list changes during traversal.
Customer-mode check_payment reads at most 20 outstanding and 10 recently paid invoices. Those totals are partial. get_dashboard uses bounded statistics and degrades when component reads fail; a zero or empty summary can reflect unavailable data. Its recent-activity display may omit customer names/dates because it expects fields that differ from invoice responses. Use REST reads/exports for reconciliation, not these summaries as a complete audit.
get_protocol_info reports a configured chain label and the retail/enterprise fee model. Live stats come from the protocol-stats route on the deployment's default chain (Base on the hosted server) and can be unavailable when the indexer is. It is not a merchant-specific fee quote; see fees.
Invoice mutation example#
The following input to send_invoice creates an on-chain invoice. It is not a dry run. Replace the UUID with an existing customer in a test organization before intentional testing.
{
"customer": "123e4567-e89b-42d3-a456-426614174000",
"amount": "500.00",
"description": "Consulting services",
"due_days": 30,
"send_email": false,
"idempotency_key": "billing-example-order-1042"
}Issuance requires a completed studio business profile, deployed Safe, invoice:write, and active server signer/write access. The tool converts the amount to raw units and sends due_days as a relative term. The API anchors the effective due date to the original durable idempotency record. A confirmed result includes invoice_id, display invoice_number when known, amount/customer/due date, pay_link, status, idempotency_key, and idempotency metadata, plus email delivery when returned. Unknown due dates or merchant invoice numbers remain null rather than being invented.
A pending result contains status: "pending" and user_op_hash rather than a shareable invoice. Do not treat it as failure or share a fabricated URL. Preserve the full returned pay link, including ?token=....
Retry the same operation with the same key and business inputs. Keep customer, amount, description, due_days, and send_email unchanged. The due date remains stable across later calls and process restarts. Changed intent with the same key returns IDEMPOTENCY_CONFLICT. Omitting the key intentionally creates a distinct invoice, even for identical inputs.
After an ambiguous submission or unresolved payment link, the tool returns an error result with status: "submission_uncertain" or "issued_link_unresolved", the retained idempotency_key, and a copyable retry object using the tool's parameter names and human-readable amount. Preserve that object instead of issuing again without a key. A crash before the receipt hash is durably recorded can require reconciliation (IDEMPOTENCY_SUBMISSION_UNCERTAIN); the server will not rebuild an operation whose submission outcome is unknown. See errors and retries.
cancel_invoice checks current state and calls the server-signed cancellation endpoint. Paid and already-canceled invoices are rejected. Pending cancellation is reported separately. Confirm state before another attempt; cancellation is not a refund.
Customer tools#
The former mixed manage_customer tool is split so each tool has one accurate read/write annotation and one scope.
list_customers: optionalsearch; reads up to 100 customers and does not expose pagination.get_customer: requirescustomer_id.update_customer: requirescustomer_id; accepts the editable billing fields below.namemaps tolegalName. Customertypeis immutable and rejected on updates. Supply a complete address when changing it.create_customer: requiresname,email, andaddresswith nonemptystreet,city,postal, and a two-letter country code. Defaultstypetoentity, which additionally requiresregistration_number. Person customers usetype: "person"and do not require registration data.
Optional billing fields are vat_number, trade_name (entities), tax_id (people), wallet_address, and notes. These map to the corresponding camel-case REST fields. A wallet address must be a valid EVM address. Required billing information is validated before sending the create request.
Example input to create_customer:
{
"type": "entity",
"name": "Example Studio",
"email": "[email protected]",
"registration_number": "EXAMPLE-123",
"address": {
"street": "1 Main Street",
"city": "Austin",
"postal": "78701",
"country": "US"
}
}Hosted connection limits#
On the hosted server (https://api.clearedpay.xyz/mcp), write tools are available only when the user grants write access at consent. Invoices only request payment; they never move the user's funds. Granting invoice:write sets limits for that connection: a maximum per invoice, a number of invoices and a total amount per rolling 24 hours, plus a fixed maximum of 3 invoices to the same customer per 24 hours. When a limit stops send_invoice, nothing is submitted and the tool returns an error result such as:
{
"status": "write_limit_exceeded",
"limit": "daily_invoice_count",
"message": "This connection has reached its limit of 10 invoices in 24 hours. Nothing was submitted.",
"limit_value": "10",
"used": "10",
"retry_after": "2026-10-13T10:00:00.000Z",
"guidance": "Ask the user to reconnect Cleared ... or wait for the rolling 24-hour window."
}limit is one of max_invoice_amount, daily_invoice_count, daily_invoice_amount, customer_daily_count or limits_not_configured. Do not retry with a new idempotency key to get around a limit. Retrying the same invoice with the same idempotency_key never counts twice. The user changes limits by reconnecting and choosing to upgrade the existing connection, and can revoke a connection at any time in Settings.
Hosted OAuth checks all required scopes before each operation. Invoice reads need invoice:read; customer reads need customer:read; customer mutations need customer:write. get_dashboard needs both dashboard:read and invoice:read. send_invoice needs invoice:write and customer:read; cancel_invoice needs invoice:write. Customer-filtered invoice lists and customer-mode payment checks additionally need customer:read. Write scopes imply the corresponding read scope. Invoice writes also require an active signer.
The legacy HMAC API-key path has separate scope gaps on some REST routes; see the authorization matrix. Those gaps do not apply to hosted OAuth.