Connect an AI assistant

Let Claude, ChatGPT, Cursor or any MCP host run your Borga account from a conversation, with the permissions you choose.

Borga runs an MCP server at https://mcp.borga.is/mcp. Connect it to an assistant and the assistant can send payment links, look up customers, subscriptions and invoices, manage products, prices and webhook endpoints, change settings, read the audit log and report usage on your merchant account, all through the same API the dashboard uses. You decide what it may see and do; Borga enforces it on every call.

This page is for merchants connecting an assistant. If you are building an assistant or another third-party client, see OAuth for third-party clients.

How a connection works

  1. Add https://mcp.borga.is/mcp to your assistant (snippets below).
  2. The assistant sends you to Borga, where you sign in with Kenni.is as on the dashboard.
  3. You pick the merchant and the mode, tick the permissions the assistant may use, and optionally give the connection a label such as "Claude on my laptop".
  4. The assistant receives tokens bound to exactly that: one merchant, one mode, the permissions you ticked. It cannot switch merchant or mode later, and it never sees an API key.

Some rules that hold for every connection:

  • One connection is one merchant in one mode. To use both test and live, connect twice.
  • Test mode never moves money. Live mode is a separate, conscious choice on the consent screen and is only offered once your merchant has live access.
  • Money permissions are never preselected. Refunds and off-session charges have to be ticked on purpose, and only an owner or admin can grant them.
  • Revoke any time under Settings, Connected apps on the merchant, or on your account page for every merchant you belong to. Every call that touches your data is refused as soon as you revoke; the server may keep listing the tools for up to a minute. Removing a member from the merchant revokes their connections too.

Add Borga to your assistant

Open Settings, then Connectors, choose Add custom connector, name it Borga and paste the URL:

https://mcp.borga.is/mcp

Claude discovers the sign-in flow from the server. Click Connect and approve the connection in Borga.

Any other host that supports remote MCP servers with OAuth (the server implements dynamic client registration and client ID metadata documents, so there is nothing to configure on Borga's side) connects the same way.

Permissions

The consent screen lists these in three groups. Read permissions are preselected when the assistant asks for them; manage permissions as well; money permissions never are. A permission is checked on every API call, so a connection can never do more than what was ticked.

PermissionAllowsGroupWho can grant it
account:readMerchant profile, onboarding and live status, and this connectionAlways grantedAny member
payments:readView payments, payment sessions, refunds and saved payment methods (brand, last 4 and expiry only)ReadAny member
customers:readView customers and their billing stateReadAny member
catalog:readView products, prices and metersReadAny member
subscriptions:readView subscriptions and recurring revenueReadAny member
invoices:readView invoices, credit notes and invoice PDFsReadAny member
usage:readView usage events and meter quantitiesReadAny member
webhooks:readView webhook endpoints (without secrets) and deliveriesReadAny member
settings:readView merchant settings, the accounting connection (without credentials) and the API key list (without keys)ReadAny member
audit_log:readView the audit logReadAny member
payments:writeCreate payment linksManageAny member
customers:writeCreate and update customers, customer portal links and payment method defaultsManageAny member
catalog:writeCreate, update and archive products, prices and metersManageAny member
subscriptions:writeCreate, change, pause, resume and cancel subscriptions and their itemsManageAny member
invoices:writeRetry accounting sync for invoicesManageAny member
usage:writeReport usage eventsManageAny member
webhooks:writeCreate, update and delete webhook endpoints and retry deliveriesManageOwners and admins
settings:writeUpdate merchant and accounting settings and revoke API keysManageOwners and admins
refunds:writeRefund paymentsMove money (never preselected)Owners and admins
payments:chargeCharge saved payment methods and retry invoice paymentsMove money (never preselected)Owners and admins

Every connection also has account:read, which covers the merchant's name and id, the mode and the connection itself; the consent screen does not list it.

Tools

What the assistant can do, grouped by the Borga resource each tool works on. The assistant only sees the tools its permissions allow, so it never plans around something it cannot do. Each tool carries hints (read-only, destructive, idempotent) that hosts use to decide what to confirm with you; how a host acts on them is up to the host.

Amounts are integers in the currency's smallest unit (whole krónur for ISK), and every result says which mode it came from.

Account and documentation

ToolWhat it doesPermissionHints
get_account
Get account
The merchant this connection acts for, the mode (test or live), the role of the person who connected, the permissions the connection holds, the live money safeguards (approval threshold and daily cap) set for it, whether live mode is enabled, and the onboarding steps still open. Terms, the live application and verification are completed by the merchant in the dashboard, never here.account:readread-only
search_docs
Search the Borga docs
Searches docs.borga.is, the public documentation of the Borga API, checkout, billing and webhooks. Returns matching pages with a short excerpt; read one in full with get_doc_page.noneread-only
get_doc_page
Read a Borga docs page
One page of docs.borga.is as Markdown, by the slug search_docs returned (for example "webhooks" or "payments/hosted-checkout").noneread-only

Payments

ToolWhat it doesPermissionHints
list_payments
List payments
Payments on the merchant account, newest first, with their status, amount and the card or wallet used (brand and last 4 only).payments:readread-only
get_payment
Get a payment
One payment with its line items and refund total.payments:readread-only
get_payment_session
Get a payment session
A checkout session: whether it is open, complete or expired, the checkout link and the payment it collects.payments:readread-only
create_payment_session
Create a payment link
Creates a hosted checkout session and returns the link the payer opens to pay by card, wallet or bank invoice. Give either a total amount or line items (the amount is then the sum including tax), and optionally the return and cancel URLs (both or neither). Without them the payer stays on Borga's confirmation page after paying, which is right for a link sent by email or chat. In test mode the link charges nothing.payments:write
list_refunds
List refunds
Refunds on the merchant account, optionally for one payment.payments:readread-only
get_refund
Get a refund
One refund with its status and the payment it belongs to.payments:readread-only
list_payment_methods
List saved payment methods
Cards saved for a customer: brand, last 4 digits, expiry and whether the card is still active. Never the card number.payments:readread-only
create_refund
Refund a payment
Refunds a succeeded payment in full or in part; the money goes back to the payer's card and a credit note is issued if the payment was invoiced. In live mode this moves real money: above the connection's approval threshold or daily cap the result is approval_required with a dashboard link, an owner or admin approves it there, and the same call is then made again with approval_id. An identical call within ten minutes returns the earlier refund instead of refunding twice.refunds:writedestructive
charge_payment_method
Charge a saved payment method
Charges a customer's saved card off-session, with the payer not present, and returns the payment. Give a total amount or line items. In live mode this moves real money: above the connection's approval threshold or daily cap the result is approval_required with a dashboard link, an owner or admin approves it there, and the same call is then made again with approval_id. An identical call within ten minutes returns the earlier payment instead of charging twice. Set idempotency_key so a retry can never charge twice.payments:chargedestructive

Customers

ToolWhat it doesPermissionHints
set_default_payment_method
Set the default payment method
Makes a saved card the customer's default for subscription charges and invoice retries. The card must be active. Open invoices whose charge failed are retried with it shortly after.customers:writeidempotent
detach_payment_method
Detach a payment method
Removes a saved card from a customer. It can no longer be charged; if it was the default, subscription charges fail until the customer saves a new card. Detaching an already detached card changes nothing.customers:writedestructive
list_customers
List customers
Customers of the merchant, newest first. Filter by exact email address.customers:readread-only
get_customer
Get a customer
One customer with contact details, billing address and default payment method.customers:readread-only
get_customer_state
Get a customer's billing state
The customer's active subscriptions and meter balances for the current period: what they are entitled to and what they have used.customers:readread-only
create_customer
Create a customer
Creates a customer record to attach payments, saved cards and subscriptions to. Email is required and should be unique per customer.customers:write
update_customer
Update a customer
Changes a customer's contact details, billing address or metadata. Only the fields given are changed.customers:writeidempotent
create_customer_portal_link
Create a customer portal link
A time-limited link to the hosted portal where the customer sees invoices, updates their card and manages subscriptions. Send it to the customer; it signs them in without a password.customers:write

Catalog

ToolWhat it doesPermissionHints
list_products
List products
Products in the merchant's catalog, newest first, including archived ones (active false).catalog:readread-only
get_product
Get a product
One product by id.catalog:readread-only
list_prices
List prices
Prices in the catalog, optionally for one product. A price is one-off or recurring and may be tiered or metered.catalog:readread-only
list_meters
List meters
Usage meters: how usage events aggregate into billable units.catalog:readread-only
get_meter
Get a meter
One usage meter by id.catalog:readread-only
create_product
Create a product
Adds a product to the catalog. Prices are created separately with create_price.catalog:write
update_product
Update a product
Renames, describes or archives a product (active false hides it from new sales). Only the fields given are changed.catalog:writeidempotent
create_price
Create a price
Adds a price to a product: one-off or recurring, a flat unit amount or tiers, optionally metered. Amounts are in the smallest currency unit. A price's amount never changes afterwards; create a new price instead.catalog:write
update_price
Update a price
Archives or reactivates a price, or changes its accounting code or metadata. Amounts cannot change.catalog:writeidempotent
create_meter
Create a meter
Creates a usage meter: which usage events feed it (event_name) and how they aggregate into a billable quantity per period (count events, or sum, max, min, avg or unique over a metadata property). Metered prices then reference the meter. Accepts idempotency_key for safe retries.catalog:write
delete_meter
Archive a meter
Archives a meter: it stops accepting usage events and keeps its history. A meter that a price still uses cannot be archived; archive the price first.catalog:writedestructive

Subscriptions

ToolWhat it doesPermissionHints
list_subscriptions
List subscriptions
Subscriptions on the merchant account, newest first. Filter by customer or status.subscriptions:readread-only
get_subscription
Get a subscription
One subscription with its items, current period and cancellation state.subscriptions:readread-only
create_subscription
Create a subscription
Starts recurring billing for a customer on one or more recurring prices, from now. With charge_automatically the customer's default saved card is charged at the end of each period (and immediately for any cycle that is due), so this can move money; with send_invoice the customer gets a bank invoice instead. An identical call within ten minutes returns the earlier subscription instead of starting a second one.subscriptions:writedestructive
get_mrr
Get recurring revenue
Monthly recurring revenue across active, trialing and past-due subscriptions, one figure per currency; amounts in different currencies are never added together. Licensed items only, so metered usage is not forecast. A point-in-time figure, not a history.subscriptions:readread-only
update_subscription
Update a subscription
Changes how a subscription collects (saved card or bank invoice), its payment terms, its discount or its metadata. Prices and quantities are changed through the subscription item tools; cancellation through cancel_subscription. Only the fields given change.subscriptions:write
cancel_subscription
Cancel a subscription
Cancels a subscription at the end of the current period (default, the customer keeps what they paid for) or right now. An immediate cancel closes the period with a final invoice for usage so far and the elapsed share of licensed items; nothing is refunded. Confirm which the person wants before calling.subscriptions:writedestructive
uncancel_subscription
Undo a scheduled cancellation
Keeps a subscription that was set to cancel at the end of its period. Only possible while the period has not ended; a subscription already canceled cannot be revived.subscriptions:write
pause_subscription
Pause a subscription
Pauses the licensed charge. Periods still close on schedule: usage is invoiced in full, licensed items only for the time before the pause, so a fully paused period with no usage produces no invoice. Canceled subscriptions cannot be paused.subscriptions:writeidempotent
resume_subscription
Resume a subscription
Resumes a paused subscription. Any period that lapsed during the pause is settled first and the paused stretch of the current period is credited, so the time paused is never charged.subscriptions:write
add_subscription_item
Add a subscription item
Adds a recurring price (seats, a plan, a metered add-on) to a subscription. Bills from the next cycle invoice; a mid-period addition is prorated unless told otherwise. An identical call within ten minutes returns the earlier item instead of adding a second one.subscriptions:write
update_subscription_item
Update a subscription item
Changes the quantity (seats) or the included units of a subscription item. Takes effect on the next cycle invoice; a decrease mid-period is prorated unless told otherwise.subscriptions:write
remove_subscription_item
Remove a subscription item
Removes a price from a subscription. The last item cannot be removed; cancel the subscription instead. The dropped quantity is prorated unless told otherwise.subscriptions:writedestructive
add_invoice_item
Add an invoice item
Queues a one-off charge (a setup fee, extra seats for a month) or a credit (a negative amount, a goodwill discount) for a customer's next subscription invoice. Nothing is charged now; the item lands on the next cycle invoice. An identical call within ten minutes returns the earlier item instead of queueing a second one.subscriptions:write

Invoices and credit notes

ToolWhat it doesPermissionHints
list_invoices
List invoices
Invoices Borga recorded with the merchant's accounting system, newest first, with their sync status. sync_failed means the accounting system rejected the invoice.invoices:readread-only
get_invoice
Get an invoice
One invoice with its lines, totals, the accounting system's number and the PDF link when available.invoices:readread-only
list_credit_notes
List credit notes
Credit notes issued against invoices when payments were refunded, optionally for one invoice.invoices:readread-only
get_credit_note
Get a credit note
One credit note by id.invoices:readread-only
get_invoice_pdf
Get an invoice PDF
The PDF of an invoice, as the accounting system rendered it, as an MCP resource link the host can open or attach, plus the provider's own URL when it has one. Only invoices that were synced to the accounting system have a PDF.invoices:readread-only
retry_invoice_sync
Retry accounting sync
Sends an invoice whose sync to the accounting system failed (status sync_failed) there again, for example after the merchant fixed the accounting settings or the customer's details. Any other status is refused.invoices:writeidempotent
retry_invoice_payment
Retry an invoice payment
Charges the customer's saved card now for an open subscription invoice, outside the automatic retry schedule, for example after the customer updated their card. In live mode this moves real money: above the connection's approval threshold or daily cap the result is approval_required with a dashboard link, an owner or admin approves it there, and the same call is then made again with approval_id. Counts as an attempt in the dunning schedule.payments:chargedestructive

Usage

ToolWhat it doesPermissionHints
report_usage
Report usage
Records usage events for metered billing. Each event names the meter's event_name and the customer (by Borga id or the merchant's external id); an idempotency_key per event makes re-sending safe. Up to 1000 events per call.usage:writeidempotent
list_usage_events
List usage events
Raw usage events, newest first. Filter by customer, event name and time range.usage:readread-only
get_meter_quantities
Get a meter's quantity for a customer
The aggregated quantity a meter has recorded for one customer in a period (the current billing period by default).usage:readread-only

Webhooks, settings and audit

ToolWhat it doesPermissionHints
list_webhook_endpoints
List webhook endpoints
The merchant's webhook endpoints in this mode, newest first, with the events each receives and a hint of its signing secret. Secrets are never returned.webhooks:readread-only
list_webhook_deliveries
List webhook deliveries
The latest delivery attempts to the merchant's webhook endpoints, newest first, with the HTTP status and the receiver's reply. Filter by endpoint, status or event type to find failures; the filters apply before the limit, so the result is the newest matches. There is no paging beyond the limit: narrow the filters or raise the limit instead.webhooks:readread-only
create_webhook_endpoint
Create a webhook endpoint
Registers an HTTPS URL to receive the merchant's events. The response carries the signing secret (whsec_...) exactly once: pass it on to the person right away, since Borga cannot show it again, and remind them that it now exists in this conversation. Prefer the merchant creating endpoints in the dashboard when the secret must stay out of transcripts.webhooks:write
update_webhook_endpoint
Update a webhook endpoint
Changes the URL, the events or the status (enabled or disabled) of a webhook endpoint. The signing secret is unchanged.webhooks:writeidempotent
delete_webhook_endpoint
Delete a webhook endpoint
Removes a webhook endpoint and its delivery history. Events stop being sent to it at once. To stop deliveries temporarily, update its status to disabled instead.webhooks:writedestructive
retry_webhook_delivery
Retry a webhook delivery
Queues a delivery for an immediate new attempt, for example after the receiver was fixed. The retry schedule continues from the delivery's attempt count.webhooks:write
get_settings
Get merchant settings
The merchant's settings: name and contact email, enabled payment methods, allowed redirect domains, checkout branding, bank invoice options, subscription dunning (retry schedule and failure action) and the live and verification status.settings:readread-only
update_settings
Update merchant settings
Changes merchant settings. Only the fields given are written; they apply to test and live alike. The legal name, kennitala and terms cannot be changed here. Lists replace the existing list, so include every domain or payment method that should remain.settings:writeidempotent
get_accounting_link
Get the accounting connection
Which accounting system (PayDay or DK+) issues the merchant's invoices in this mode, its status and the chosen settings: payment type, default account and VAT codes. With include_options, also the payment types, accounts and VAT codes the provider offers, for picking valid values. Never credentials. Connecting a provider is done in the dashboard, under Settings, Accounting.settings:readread-only
update_accounting_settings
Update accounting settings
Changes how invoices are booked at the connected accounting system: the payment type card payments go to, the default account code, the default tax rate for payments without line items, and the VAT code per tax rate. Use get_accounting_link with include_options to find valid ids first. Only the fields given change.settings:writeidempotent
list_api_keys
List API keys
The merchant's active API keys in this mode: label, type, prefix and a hint of the value. Key values are never returned, and keys cannot be created or rotated through this connection; that happens in the dashboard under Developers.settings:readread-only
revoke_api_key
Revoke an API key
Revokes an API key. Every integration using it stops working at once and the key cannot be restored; a new one has to be created in the dashboard.settings:writedestructive
list_audit_log
List the audit log
The merchant's audit log in this mode, newest first: who did what to which resource, including this and other assistants' actions (actor_type oauth_grant). Filter by action, resource type or actor type.audit_log:readread-only
list_members
List members
The people on the merchant's team and their roles. Inviting, removing and role changes are done in the dashboard, never through this connection.settings:readread-only

Cards in the conversation

In Claude, ChatGPT, VS Code and other hosts that support MCP Apps, some results come with an interactive card instead of plain text:

  • Payment links show the amount, a QR code to scan and buttons to copy or open the link, and the status updates when the payer pays.
  • Refunds and charges show what moved. When a live move needs an owner's or admin's approval, the card shows the pending request with a link to the dashboard and a button to carry it out once it has been approved.
  • Payments and recurring revenue show a table you can filter and page through, and MRR per currency.
  • Invoices show their status and the accounting system's number, with buttons for the PDF, the customer portal and retrying the sync when the accounting system rejected it.

Everything a card does is an ordinary request on your connection, under the same permissions, safeguards and audit log as the assistant's own requests. Hosts without card support show the same information as text.

Prompts

Hosts that support prompts (Claude's slash commands, for example) also get four ready-made ones, each listed only when the connection holds the permissions its steps need:

PromptWhat it does
send_payment_linkCreates a checkout link for an amount and tells you where to send it.
month_end_summaryPayments, refunds, invoice sync failures and recurring revenue for a period, as a short report.
chase_unpaid_invoicesInvoices still open some days after they were issued, with a customer portal link per customer for the follow-up.
integration_checklistWhat a developer still has to do before going live, from the account, webhooks and recent test payments.

Safeguards

  • Host confirmation. Every tool that moves money, cancels, deletes or detaches carries the destructiveHint annotation. Hosts use it to decide when to ask you first; Claude, for example, confirms destructive calls. The hint informs the host, it does not enforce anything, which is why permissions and the server-side controls below exist.
  • Mode is fixed. A test-mode connection cannot reach live data or the card processor's live rail, whatever the assistant asks for.
  • Approval threshold and daily cap for live refunds and charges, set per connection on the Connected apps page. A refund or charge above the threshold, or one that would take the connection past what it may move in 24 hours, is not carried out: the assistant gets approval_required with a link, an owner or admin approves or denies the request in the dashboard within 24 hours, and the assistant then repeats the same call with the approval id. Both are off until you set them.
  • No double moves. An identical refund, charge, invoice payment retry, new subscription, added subscription item or invoice item asked for twice within ten minutes, after the first one succeeded, is answered with the earlier result (duplicate: true) instead of being carried out again. A call that failed is not remembered, so repeating it tries again. The API's idempotency keys apply on top.
  • Roles keep applying. Permissions that only an owner or admin can grant (webhooks, settings, refunds, charges) stop working the moment that person is demoted to member, even on a connection they approved earlier.
  • Rate limits. A connection is limited to 300 requests per minute per endpoint, well under the API-key limit.
  • Audit log. Every call the assistant makes is an entry in your audit log with the connection's name and label, for example "Claude (Jón's laptop)", and the tool that made it.

Privacy and data

The MCP server is a client of the Borga API and holds no database of its own. It keeps two things in memory: a 60 second cache of each connection's permissions, so that a revoked connection stops within a minute even when the cache is warm, and the results of successful refunds, charges, invoice payment retries, new subscriptions, added subscription items and invoice items for ten minutes, which is what lets it answer an identical repeat with the earlier result instead of moving money again. Nothing else about a tool call is stored.

Results carry what you would see in the dashboard and nothing more: no webhook secrets, no accounting credentials, no processor references, and saved cards only as brand, last four digits and expiry. Customer names, descriptions and other text people typed are returned as data, and the server tells the assistant to treat them that way.

Some things are never offered through the MCP server, whatever permissions a connection holds:

  • Creating, rotating or revealing API keys. A secret in a chat transcript is a leaked secret. Listing keys (by label and hint) and revoking one is allowed.
  • Inviting or removing members, or changing roles. Listing the team is allowed.
  • Connecting an accounting provider or entering its credentials. Reading the connection's status and changing which accounts and VAT codes it books to is allowed.
  • Accepting terms, applying for live mode, signing, and anything else that is a legal act. Those need your own Kenni confirmation in the dashboard.
  • The payer-facing checkout and portal, which stay unauthenticated and separate.

One exception to the no-secrets rule: creating a webhook endpoint returns its signing secret once, exactly as the dashboard does, because the developer asking for it usually needs it in the same session. The tool says so, and the assistant is told to hand the secret over and to point out that it now exists in the conversation. Create endpoints in the dashboard when that is not acceptable.

For client authors

If you are building an assistant, a plugin or another third-party client rather than connecting an existing one, the authorization server, its discovery document and the registration options are described in OAuth for third-party clients. Merchant backends that act for themselves keep using API keys; the MCP server does not accept them.