---
title: "Connect an AI assistant (MCP)"
description: "Let Claude, Cursor or any MCP client read your billing data: customers, subscriptions, invoices, payments and metrics, with a read-only API key."
canonical_url: "https://twominutebilling.com/help/developers/getting-started/connect-ai-assistants"
---
# Connect an AI assistant (MCP)

> Let Claude, Cursor or any MCP client read your billing data: customers, subscriptions, invoices, payments and metrics, with a read-only API key.

Two Minute Billing has a built-in MCP server. An AI assistant that supports the Model Context
Protocol can use it to answer questions about one business: "Which customers have unpaid
invoices?", "Why did this payment fail?", "Why did MRR drop last month?", "What would an upgrade to Pro
cost this customer today?"

Every tool is read-only. The assistant can look things up and ask the engine for estimates. It
cannot change anything. (To get answers inside the dashboard, and to have changes prepared for
you to confirm, use [Billy](https://twominutebilling.com/help/guides/ask-billy).)

## The server address

- **Two Minute Billing Cloud:** `https://mcp.twominutebilling.com/mcp`
- **Your own installation:** your API host followed by `/mcp`, for example
`https://api.example.com/mcp`. To serve it from a host of its own, point that host at the API
and set `MCP_PUBLIC_URL` (for example `https://mcp.example.com`) in the engine's environment,
so every address the server gives to a client uses that host.

## Connect by signing in

Clients that connect by signing in (OAuth), such as the Claude and ChatGPT apps, need only the
server address. Add the server address above as a custom connector. The client then sends you
to Two Minute Billing:

1. Sign in, if you are not signed in.
2. Select the business the assistant can read, and select **Connect**.
3. You return to the assistant, which is now connected.

The connection reads only what you can read in that business, and it is read-only. Every
connected app shows in **Settings → Developer → Connected apps**, where you can disconnect it.
Disconnecting stops its access at once.

## Connect with an API key

For developer tools that send a header (Claude Code, editors, scripts), use a read-only API key.

1. In the dashboard, go to **Settings → Developer**.
2. Create an API key. Set **Access** to **Read only**, and select test or live mode.
3. Copy the key. You see it one time only.

The server refuses a key that can change data. A key with per-resource access needs **MCP** set
to **Read**, and the assistant then sees only the tools for the resources the key can read.

### Add the server

With a key, add `/` and the business id to the server address:

```text
https://mcp.twominutebilling.com/mcp/biz_XXXXXXXXXXXX01
```

If the key reaches only one business, the address without the business id also works. On your
own installation, use your own server address in place of `https://mcp.twominutebilling.com`.

**Claude Code**

```sh [terminal]
claude mcp add --transport http billing https://mcp.twominutebilling.com/mcp/biz_XXXXXXXXXXXX01 \
  --header "Authorization: Bearer <read-only key>"
```

**Other clients** take the same two things: the server URL and an `Authorization` header. In a
client that keeps its servers in an `mcpServers` JSON file, the entry looks like this:

```json [mcp.json]
{
  "mcpServers": {
    "billing": {
      "url": "https://mcp.twominutebilling.com/mcp/biz_XXXXXXXXXXXX01",
      "headers": { "Authorization": "Bearer <read-only key>" }
    }
  }
}
```

## Tools

<table>
<thead>
  <tr>
    <th>
      Tool
    </th>
    
    <th>
      What it does
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        get_business
      </code>
    </td>
    
    <td>
      The business: name, currency, timezone, mode and billing settings
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        search_customers
      </code>
    </td>
    
    <td>
      Find customers by text or filters (unpaid invoices, expiring cards, MRR…)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        get_customer
      </code>
    </td>
    
    <td>
      One customer with subscriptions, recent invoices and payment methods
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        list_subscriptions
      </code>
      
       / <code>
        get_subscription
      </code>
    </td>
    
    <td>
      Subscriptions, scheduled changes and the next renewal estimate
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        list_invoices
      </code>
      
       / <code>
        get_invoice
      </code>
    </td>
    
    <td>
      Invoices with lines, taxes and the dunning journey
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        list_payments
      </code>
      
       / <code>
        get_payment_attempts
      </code>
    </td>
    
    <td>
      Payments and refunds, and each attempt with its decline reason
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        get_metrics
      </code>
    </td>
    
    <td>
      MRR, ARR and the revenue series from the metric store
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        explain_invoice
      </code>
    </td>
    
    <td>
      Why an invoice is what it is: the totals, each line's facts, and what changed from the previous invoice
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        explain_payment
      </code>
    </td>
    
    <td>
      Why an invoice is unpaid: each attempt with its decline reason, and what dunning does next
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        explain_mrr_change
      </code>
    </td>
    
    <td>
      How MRR moved over a range: opening, the change by reason with the largest movements, closing
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        explain_balance
      </code>
    </td>
    
    <td>
      A customer's promotional credits, excess payments, credit grants and wallet
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        preview_subscription_change
      </code>
    </td>
    
    <td>
      What a plan or quantity change would cost, without making it
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        preview_cancellation
      </code>
    </td>
    
    <td>
      What a cancellation would do to money, without cancelling
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        search_docs
      </code>
    </td>
    
    <td>
      Search the help and the API reference, with a link to each page
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        get_api_reference
      </code>
    </td>
    
    <td>
      The exact definition of one API operation
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        find_screen
      </code>
    </td>
    
    <td>
      Where something is in the dashboard: the screen, its menu path, a link, and its buttons and fields
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        read_api
      </code>
    </td>
    
    <td>
      Any other read endpoint of the business, by path
    </td>
  </tr>
</tbody>
</table>

List tools take filters in the same `field[op]` form as the API's list endpoints, and page with
`starting_after`.

## What the assistant can see

- One business, in the mode of the key. A test key never reaches live data.
- Only what the key can read. Each tool call goes through the same API route, permission check
and rate limit as any other call with that key, and is in **Developer → Logs**.
- Not documents (invoice PDFs), bulk exports, or connection settings for email and gateways.

The data a tool returns goes to the AI provider your client uses. Customer names, notes and
metadata come back with invisible formatting characters removed, and the server tells the
assistant to treat them as data, not instructions.


## Sitemap

See the full [sitemap](https://twominutebilling.com/sitemap.md) for all pages.
