# MCP (AI agents)

import { Tabs, TabsContent, TabsList, TabsTrigger } from "zudoku/ui/Tabs.js";

The LedgerBee MCP server gives AI agents (Claude, ChatGPT, Cursor, and other
MCP clients) a curated tool set rather than an auto-generated wrapper around
every REST endpoint. Transport is Streamable-HTTP; authorization is OAuth 2.1
with a browser sign-in. Add the server URL to your client and approve the
sign-in — no API keys required.

## One server per company

A LedgerBee MCP connection is scoped to exactly one company: the OAuth grant
behind it binds to a single company, and every tool call runs against that
company's books. Two URL forms exist:

| URL | Use |
|---|---|
| `https://api.ledgerbee.com/api/v1/mcp` | Single company — binds to the company you pick at sign-in |
| `https://api.ledgerbee.com/api/v1/mcp/c/{appCompanyId}` | One connection per company — the path pins which company the grant binds to |

The `/c/{appCompanyId}` discriminator exists for users with access to more
than one company. MCP clients dedupe connections by URL and server name, so
without it only one LedgerBee connection could be registered. With it, each
company gets a distinct URL + server name pair (`ledgerbee-{company}`), and an
agent can hold one connection per company side by side.

> **Marketplace → Connected apps** in the LedgerBee app renders the setup
> below pre-filled for the company you're signed in to — URL, server name,
> and per-client commands, including a one-click **Add to Cursor** button.

## Connect a client

<Tabs defaultValue="single">

<TabsList>
<TabsTrigger value="single">Single company</TabsTrigger>
<TabsTrigger value="multiple">Multiple companies</TabsTrigger>
</TabsList>

<TabsContent value="single">

Use the plain server URL — the connection binds to the company you pick at
sign-in:

```
https://api.ledgerbee.com/api/v1/mcp
```

**Claude (Web / Desktop)** — both share one connector list:

1. Open [claude.ai/customize/connectors](https://claude.ai/customize/connectors)
   (**Settings → Connectors**).
2. Click **Add custom connector** and paste the server URL.
3. Complete the LedgerBee sign-in and approve the requested access.

**Claude Code** — run this in your terminal, then run `/mcp` inside Claude
Code to complete the OAuth sign-in:

```bash
claude mcp add --transport http ledgerbee --scope user https://api.ledgerbee.com/api/v1/mcp
```

**Cursor** — <a href="cursor://anysphere.cursor-deeplink/mcp/install?name=ledgerbee&config=eyJ1cmwiOiJodHRwczovL2FwaS5sZWRnZXJiZWUuY29tL2FwaS92MS9tY3AifQ==">Add to Cursor</a>,
or paste this into your `mcp.json`:

```json
{
  "mcpServers": {
    "ledgerbee": {
      "url": "https://api.ledgerbee.com/api/v1/mcp"
    }
  }
}
```

**VS Code** — run this in your terminal (requires the VS Code CLI):

```bash
code --add-mcp '{"name":"ledgerbee","url":"https://api.ledgerbee.com/api/v1/mcp"}'
```

**Codex**:

```bash
codex mcp add ledgerbee --url https://api.ledgerbee.com/api/v1/mcp
```

**Other clients** — most accept the universal installer; the JSON snippet
above also works in most clients' MCP config. The full client list is at
[modelcontextprotocol.io/clients](https://modelcontextprotocol.io/clients).

```bash
npx add-mcp https://api.ledgerbee.com/api/v1/mcp
```

</TabsContent>

<TabsContent value="multiple" forceMount>

Register one connection per company with the company-pinned URL. The commands
below carry two placeholders — `{appCompanyId}` and the server name
`ledgerbee-{company}` — replace both, or copy the pre-filled commands from
**Marketplace → Connected apps**. To add the next company, switch company in
the app and reopen the card.

```
https://api.ledgerbee.com/api/v1/mcp/c/{appCompanyId}
```

**Claude (Web / Desktop)** — both share one connector list:

1. Open [claude.ai/customize/connectors](https://claude.ai/customize/connectors)
   (**Settings → Connectors**).
2. Click **Add custom connector** and paste the company-pinned URL.
3. Complete the LedgerBee sign-in and approve the requested access.

**Claude Code** — run this in your terminal, then run `/mcp` inside Claude
Code to complete the OAuth sign-in:

```bash
claude mcp add --transport http ledgerbee-{company} --scope user https://api.ledgerbee.com/api/v1/mcp/c/{appCompanyId}
```

**Cursor** — the one-click **Add to Cursor** button lives in the in-app card
(the deep link needs a concrete URL). Or paste this into your `mcp.json`:

```json
{
  "mcpServers": {
    "ledgerbee-{company}": {
      "url": "https://api.ledgerbee.com/api/v1/mcp/c/{appCompanyId}"
    }
  }
}
```

**VS Code** — run this in your terminal (requires the VS Code CLI):

```bash
code --add-mcp '{"name":"ledgerbee-{company}","url":"https://api.ledgerbee.com/api/v1/mcp/c/{appCompanyId}"}'
```

**Codex**:

```bash
codex mcp add ledgerbee-{company} --url https://api.ledgerbee.com/api/v1/mcp/c/{appCompanyId}
```

**Other clients** — most accept the universal installer; the JSON snippet
above also works in most clients' MCP config. The full client list is at
[modelcontextprotocol.io/clients](https://modelcontextprotocol.io/clients).

```bash
npx add-mcp https://api.ledgerbee.com/api/v1/mcp/c/{appCompanyId}
```

</TabsContent>

</Tabs>

## Anonymous developer server

`/api/v1/mcp/developer` is an anonymous server that exposes a single tool,
`read_development_docs`, over the LedgerBee developer docs. Use it to verify
your client setup before connecting the tenant server:

```bash
claude mcp add --transport http ledgerbee-developer --scope user https://api.ledgerbee.com/api/v1/mcp/developer
```

The developer MCP endpoint in the [API Reference](/api) renders the same
install card with copy-paste setup for popular clients.

## Tools

{/* @codegen mcp-tools — generated by `pnpm docs:generate`; do not edit by hand */}

**Read tools** — available with the `mcp:read` scope on a tenant server; some also require the listed domain read scope:

| Tool | Additional scopes |
|---|---|
| `account_detail` | `accounts-read`, `journal-entries-read` |
| `accounts_overview` | `accounts-read` |
| `find_inbox_document_candidates` | — |
| `find_invoice_anchor_candidates` | — |
| `find_journal_entry_candidates` | — |
| `find_related_entries` | `journal-entries-read` |
| `get_bank_transaction` | — |
| `get_business_entity_details` | — |
| `get_counterparty` | `customers-read`, `vendors-read` |
| `get_dismissed_suggestions` | — |
| `get_document` | `journal-entries-read` |
| `get_journal_entry` | `journal-entries-read` |
| `get_overdue_invoices` | `customers-read`, `journal-entries-read` |
| `get_period` | `journal-entries-read` |
| `get_reconciliation_history` | — |
| `get_staged_write_detail` | — |
| `get_subscription` | `subscriptions-read` |
| `get_vat_breakdown` | `journal-entries-read`, `vat-codes-read` |
| `list_journal_entries` | — |
| `list_my_pending_writes` | — |
| `list_routes` | — |
| `list_vat_codes` | `vat-codes-read` |
| `lookup_bookkeeping_rule` | `company-read` |
| `lookup_cvr` | `company-read` |
| `read_development_docs` | — |
| `resolve_business_entity` | — |
| `search_bank_transactions` | `journal-entries-read` |
| `search_counterparty` | `customers-read`, `vendors-read` |
| `search_documents` | `journal-entries-read` |
| `search_journal_entries` | `journal-entries-read` |
| `search_subscriptions` | `subscriptions-read` |

**Write tools** — available with the `mcp:write` scope, or the listed domain write scope. Writes always require an OAuth grant:

| Tool | Additional scopes |
|---|---|
| `book_journal_entry` | `journal-entries-write` |
| `cancel_staged_write` | — |
| `create_draft_journal_entry` | `journal-entries-write` |
| `navigate` | — |
| `patch_draft_journal_entry` | `journal-entries-write` |
| `present_for_approval` | — |
| `record_bank_transaction_suggestion` | `mcp:bank-recon:write-suggestion` |
| `report_tool_gap` | — |
| `spotlight` | — |

Call `tools/list` on the server for the authoritative catalog with each tool’s parameters and description.

{/* @codegen-end mcp-tools */}

> MCP scopes are OAuth-only and cannot be assigned to API keys. Write tools
> always require an OAuth grant with the matching scope.

## Endpoints

| Endpoint | Auth | Purpose |
|---|---|---|
| `POST /api/v1/mcp` | OAuth 2.1 bearer or API key + MCP license (`mcp:read` baseline) | Tenant-scoped server |
| `POST /api/v1/mcp/c/{appCompanyId}` | same | Tenant-scoped server, company pinned in the URL |
| `POST /api/v1/mcp/developer` | Anonymous (any bearer) | Developer/docs server |

## Authorization (OAuth 2.1)

The tenant-scoped servers follow the MCP authorization spec. A compliant
client handles the whole flow on its own: it discovers the authorization
server via `.well-known`, registers itself, and opens the browser sign-in.
The metadata endpoints:

- `/.well-known/oauth-protected-resource` (and a per-company variant)
- `/.well-known/oauth-authorization-server`
- `/.well-known/openid-configuration`
- `/.well-known/jwks.json`

Clients that self-register use Dynamic Client Registration:

```
POST https://api.ledgerbee.com/api/v1/oauth/register
```

See [Authentication](/guides/authentication) for the full OAuth flow.
