LedgerBee Developer
  • Getting started
  • Conventions
  • Products
  • Configuration
  • API Reference
SSO
MCP (AI agents)
Configuration

MCP (AI agents)

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:

URLUse
https://api.ledgerbee.com/api/v1/mcpSingle 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

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

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

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

  1. Open 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:

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

Cursor — Add to Cursor, or paste this into your mcp.json:

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

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

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

Codex:

TerminalCode
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.

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

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.

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

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

  1. Open 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:

TerminalCode
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:

Code
{ "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):

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

Codex:

TerminalCode
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.

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

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:

TerminalCode
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 renders the same install card with copy-paste setup for popular clients.

Tools

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

ToolsetResourceToolOperationAdditional scopesAlso requires
every connectiondevelopment_docread_development_docsaction——
every connectionmcp_grantrequest_permissionsaction—user token
every connectionmcp_toollist_mcp_toolslist——
every connectionmcp_toolcall_mcp_toolaction——
contextaccounting_periodget_accounting_periodgetjournal-entries-read—
contextbookkeeping_rulelookup_bookkeeping_ruleactioncompany-read—
contextjournal_categorylist_journal_categorieslistjournal-categories-read—
contextledger_accountlist_ledger_accountslistaccounts-read—
contextledger_accountget_ledger_accountgetaccounts-read, journal-entries-read—
contextvat_codelist_vat_codeslistvat-codes-read—
ledgerjournal_entrylist_journal_entrieslist—user token
ledgerjournal_entryget_journal_entrygetjournal-entries-read—
ledgerjournal_entrysearch_journal_entriesactionjournal-entries-read—
ledgervat_reportget_vat_breakdownactionjournal-entries-read, vat-codes-read—
ledger_analysisjournal_entryfind_counterparty_mispostingsactioncustomers-read, journal-entries-read, suppliers-read—
ledger_analysisjournal_entryfind_related_entriesactionjournal-entries-read—
counterpartiescounterpartylist_counterpartieslistcustomers-read or suppliers-read—
counterpartiescounterpartyget_counterpartygetcustomers-read or suppliers-read—
counterpartiescounterparty_grouplist_counterparty_groupslistcustomers-read or suppliers-read—
counterpartiescvr_registrationlookup_cvractioncompany-read—
documentsdocumentlist_documentslistjournal-entries-read—
documentsdocumentget_documentgetjournal-entries-read—
bookkeepingdraft_journal_entryget_draft_journal_entrygetjournal-entries-read—
stagingstaged_writelist_staged_writeslist—user token
stagingstaged_writeget_staged_writeget—user token
apipublic_apiapi_detailsaction——
apipublic_apiapi_readaction——
apipublic_apiapi_searchaction——
reportsfinancial_reportget_financial_reportgetaccounts-read—
reportsinvoiceget_overdue_invoicesactionjournal-entries-read, customers-read or suppliers-read—
bankingbank_accountlist_bank_accountslist——
bankingbank_reconciliationlist_bank_reconciliationslist——
bankingbank_transactionlist_bank_transactionslistjournal-entries-read—
bankingbank_transactionget_bank_transactionget——
bank_matchingbank_reconciliationget_dismissed_suggestionsaction——
bank_matchingbank_transactionfind_inbox_document_candidatesaction——
bank_matchingbank_transactionfind_invoice_anchor_candidatesaction——
bank_matchingbank_transactionfind_journal_entry_candidatesaction——
bank_matchingbusiness_entityget_business_entityget——
bank_matchingbusiness_entityresolve_business_entityaction——
subscriptionssubscriptionlist_subscriptionslistsubscriptions-readSubscription licence
subscriptionssubscriptionget_subscriptiongetsubscriptions-readSubscription licence
payrollpayroll_runlist_payroll_runslist—PayRoll licence, user token, payroll.read permission
uipageinspect_pageaction—user token
uiroutelist_routeslist——
dashboardsdashboardlist_dashboardslist—user token
dashboardsdashboardget_dashboardget—user token

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

ToolsetResourceToolOperationAdditional scopesAlso requires
every connectiontool_gapreport_tool_gapaction—user token
counterpartiescounterpartycreate_counterpartycreatecustomers-write or suppliers-writeuser token
counterpartiescounterpartyupdate_counterpartyupdatecustomers-write or suppliers-writeuser token
bookkeepingdraft_journal_entrycreate_draft_journal_entrycreatejournal-entries-writeuser token
bookkeepingdraft_journal_entryupdate_draft_journal_entryupdatejournal-entries-writeuser token
bookkeepingdraft_journal_entrydelete_draft_journal_entrydeletejournal-entries-writeuser token
bookkeepingdraft_journal_entrybook_journal_entryactionjournal-entries-writeuser token
stagingstaged_writeapprove_staged_writeaction—user token
stagingstaged_writecancel_staged_writeaction—user token
stagingstaged_writepresent_for_approvalaction—user token
apipublic_apiapi_writeaction—user token
bank_matchingbank_reconciliationapprove_bank_matchactionjournal-entries-writeuser token
uipagefire_actionaction—user token
uipagehighlight_rowsaction—user token
uipagespotlightaction—user token
uiroutenavigateaction—user token
dashboardsdashboardcreate_dashboardcreate—user token
dashboardsdashboardedit_dashboard_global_configaction—user token
dashboardsdashboardedit_dashboard_layoutaction—user token
dashboardsdashboardedit_dashboard_metadataaction—user token
dashboardsdashboard_widgetcreate_dashboard_widgetcreate—user token
dashboardsdashboard_widgetupdate_dashboard_widgetupdate—user token
dashboardsdashboard_widgetdelete_dashboard_widgetdelete—user token

Every tool names the toolset it belongs to, the resource it acts on and its operation. A toolset is the job a tool serves; the tools marked every connection belong to none and are always advertised. list, get, create, update and delete tools are named <operation>_<resource>; an action is a lifecycle step or lookup with no CRUD shape, such as booking a draft. A renamed tool stops answering to its old name in the same release.

This table is the full catalog. Call tools/list on the server for the tools your connection advertises, with each tool’s parameters and description.

A connection advertises the tools of its enabled toolsets plus the tools that belong to none. The toolsets are picked on the consent screen, which offers the ones the requested permissions can serve and ticks the recommended set — or, when a client re-authorizes a connection you already have, that connection's own set. An admin changes it afterwards under Settings → Integrations → OAuth clients → Connected apps, where each connection has a toolset checkbox per toolset; the change reaches the client the next time it reconnects. A toolset decides what the connection is shown, not what it may do: a read outside the enabled set stays reachable through call_mcp_tool, and what bounds a write is its scopes and the company's write policy. The page-control and dashboard-editing tools are off unless a connection enables ui or dashboards; their reads stay reachable through call_mcp_tool, and their writes need the toolset ticked on a hosted client. An agent asks for a toolset with request_permissions, the same call it uses for a missing scope.

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

Discovery

Two tools search the catalog and reach a tool by name, so an agent never has to guess whether a capability exists. Both are advertised to every connection.

  • list_mcp_tools searches the full catalog by keyword, toolset or kind. Each row carries the tool's name, toolset, resource, operation and description, and invokeVia: direct when the tool is in this connection's tools/list, call_mcp_tool when it is a read outside it, or enable_toolset when it is a write outside it, in which case enableToolset names the toolset to ask for. blockedReason carries the message tools/list puts on a tool the caller cannot invoke yet, or null when no gate is visible at list time. Called with no arguments it returns the toolset index; a query that matches nothing returns the index and the closest names rather than an empty list. response_format: "detailed" adds each tool's input schema and annotations.
  • call_mcp_tool runs one read tool by name, with the target's own arguments under arguments, and returns that tool's own result. The target is checked exactly as a direct call: its scopes, licence, rate limit and AI budget apply, and a refusal carries the same message. A write tool is refused with its toolset named. Neither discovery tool can be run through it.

A wrapped call is recorded in the MCP audit log as call_mcp_tool:<tool>, with the target's route in targetOperation when the target is a facade tool. The usage statistics report the target under its own name and count the wrapped calls separately.

Direct mode

The curated tools above cover the common accounting tasks. For everything else, the four tools on the public_api resource call the public REST API directly, as the connection's own access token. Any route the grant can already call over HTTP is reachable through them, and no other route is: the facade grants nothing on its own.

  • Search finds routes by keyword. Each result carries the method, the path template, the required scopes, whether this connection can call it (callable), and curatedTool when a dedicated tool already covers the route.
  • Details describes one route: path and query parameters, the request body schema, the success response shape, required scopes, and deprecation.
  • Read performs a GET and returns the status and JSON body. A body longer than maxBytes (default 64 KB) is cut, and the result names the route's paging parameters.
  • Write performs a POST, PATCH, PUT or DELETE. It takes a one-line summary of the change, shown on the approval card and kept in the audit log.

The agent searches first and uses the curated tool whenever one is named: the curated tools validate input, stage the change for review in LedgerBee, and can be reversed. The facade does none of that.

Enabling writes

Direct writes are off by default. Turn them on under Inbox → Hivey → Permissions, where the Direct API writes row takes one of three values.

ValueEffect on the write tool
Deny (default)The call is refused. The tool is advertised with an "unavailable" marker that names this setting.
ApprovalThe request is stored and appears in the approval queue. It runs when you approve it, as the same grant that staged it. The tool returns executed: false and a chainId.
AutoThe request runs immediately and the tool returns executed: true with the route's status and body. No approval card is shown.

The three read-side tools have no setting: a read the grant can perform over HTTP is not more dangerous when performed through MCP.

Scopes

Search, details and read require mcp:read; write requires mcp:write and a user-consented grant. Every route also enforces its own scopes, exactly as it does for an HTTP client: a read of /v1/customers needs customers-read, and a write of POST /v1/customers needs customers-write. A call whose grant lacks the route's scope is refused before any request is made, with the missing scope named. Search reports the same check as callable, so the agent can see which routes it can reach.

Idempotency

Every write call carries an idempotency key. When the agent passes idempotencyKey, that key is sent; otherwise the server derives one from the grant, the method, the route template and the request body. The result echoes the key as idempotencyKey and sets replayed: true when the API served the stored outcome of an earlier identical request instead of writing again. A retry after a timeout therefore creates no duplicate.

Excluded routes

Routes that manage authentication, single sign-on, API keys and the MCP endpoint itself (/v1/auth, /v1/oauth, /v1/api-key, /v1/scim, /v1/portal-sso, /v1/mcp) are never reachable through the facade, whatever scopes the grant holds, and neither is any write to /v1/webhook-endpoints: a webhook endpoint created under prompt injection would be an exfiltration channel. A request to one of them is refused with a message saying so.

Errors

A route that answers 400 or above does not fail the tool call. The result carries error: true, the status, and the route's own error body, so the agent can read a validation message and correct the request. The facade's own refusals raise a tool error: an unknown path, an excluded route, a missing scope, or direct writes set to Deny.

Audit

Every facade call is recorded in the MCP audit log with the tool name, the grant, the outcome, and targetOperation, the route it hit, as "POST /v1/customers". The loopback request carries the same request id as the MCP call, so the API request log and the MCP audit row share one id.

Endpoints

EndpointAuthPurpose
POST /api/v1/mcpOAuth 2.1 bearer, Dynamic Client Registration grant (mcp:read scope)Tenant-scoped server
POST /api/v1/mcp/c/{appCompanyId}sameTenant-scoped server, company pinned in the URL
POST /api/v1/mcp/developerAnonymous (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. An MCP client is a DCR-registered connected app — the same record backs both terms:

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

A partner app that LedgerBee registers for you (rather than self-registering via DCR) runs the same authorization flow. See Connected Apps.

See Authentication for the full OAuth flow.

Last modified on September 13, 2026
SCIM provisioning
On this page
  • One server per company
  • Connect a client
  • Anonymous developer server
  • Tools
  • Discovery
  • Direct mode
    • Enabling writes
    • Scopes
    • Idempotency
    • Excluded routes
    • Errors
    • Audit
  • Endpoints
  • Authorization (OAuth 2.1)
JSON
JSON