Developers

Connect your AI assistant to Cryptotax

Cryptotax has an MCP server and a REST API. They let an AI assistant or your own script read your Belgian crypto tax data and, if you allow it, correct it.

Two ways to connect

Both ways reach the same data and the same tools. Pick the one that fits your client. The MCP server and the API are part of the Pro plan.

Step-by-step guide in the help centre

For claude.ai and ChatGPT

Custom connector (OAuth)

You sign in with your Cryptotax account and approve the app. There is no token to copy.

  1. 1
    In claude.ai or ChatGPT, add a custom connector with this URL:
    https://cryptotax.be/mcp
  2. 2
    Sign in to Cryptotax when your client asks for it.
  3. 3
    On the consent screen, confirm what the app may do: read your data and, if the app asks for it, make corrections. You can untick the latter.
  4. 4
    Manage or revoke the connection later under Settings, Connected apps.

If you build your own client: the server follows OAuth 2.1 with PKCE (S256) and dynamic client registration. The metadata is at the standard locations under /.well-known. Access tokens are valid for one hour and refresh automatically; a connection that is unused for 90 days expires.

Manage connected apps

For Claude Code, Cursor and scripts

Personal API token

A token that starts with ctx_ and that you send as a Bearer token. The same token works for the MCP server and for the REST API.

  1. 1
    Create a token under Settings, API tokens and choose its scopes.
  2. 2
    Copy the token right away: it is shown only once.
  3. 3
    Send it in the Authorization header of every request.

Claude Code

claude mcp add --transport http cryptotax https://cryptotax.be/mcp \
  --header "Authorization: Bearer ctx_YOUR_TOKEN"

Cursor (mcp.json)

{
  "mcpServers": {
    "cryptotax": {
      "url": "https://cryptotax.be/mcp",
      "headers": { "Authorization": "Bearer ctx_YOUR_TOKEN" }
    }
  }
}
Manage API tokens

Scopes: read and write

A token or connection always acts as the one user who created it and has one of these two levels.

Scope What it allows
read Read data sources, tax years, transactions, summaries, portfolio, rules and review issues. In the REST API: every GET request.
write Everything in read, plus corrections: adjust transactions, create rules and match transfers. In the REST API: POST and DELETE.

Start with read only. A read connection does not even see the write tools, and a write attempt is refused (403 in the REST API). Every correction is visible in the app and can be undone.

MCP server

The server speaks Streamable HTTP (stateless) at one address. There are 17 tools: 11 to read and 6 to correct.

MCP endpoint

https://cryptotax.be/mcp
Tool Scope What it does
list_accounts read Your wallets, exchange connections and file imports, with the status of the last sync.
list_years read The years with activity and whether a year is locked or frozen.
list_transactions read The tax events of one year, page by page, with filters on type and asset.
get_tax_summary read Overview of all years: capital gains, income and indicative tax.
get_year_summary read The figures of one year, with the exemption and the Tax-on-web codes.
list_issues read The items you still need to review before the figures can be trusted.
get_portfolio read Your current holdings with their cost basis (beta).
get_positions read Your open DeFi positions with live on-chain values (beta).
list_rules read Your existing correction rules.
find_transfer_candidates read Possible counterparts for a transfer, and the existing match if there already is one.
get_recalc_status read Whether an import or recalculation is running, so you know when the figures are final.
apply_override write Correct one transaction: type, treatment, taxability, EUR value or date.
remove_override write Undo a correction on a transaction.
create_rule write Create a persistent rule, for example mark an address as your own wallet.
delete_rule write Delete a rule.
match_transfers write Match an outgoing and an incoming transaction as one transfer, so the cost basis carries over.
unmatch_transfer write Undo a transfer match.

REST API

The same data and corrections as the MCP tools, as JSON over HTTPS. The full description of every endpoint, field and error code is in the OpenAPI spec, which you can fetch without a token and load into a client generator.

Base URL

https://cryptotax.be/api/v1

OpenAPI spec (3.0, JSON)

https://cryptotax.be/api/v1/openapi.json

The API covers: /me, /accounts, /years, /transactions, /summary, /issues, /portfolio and /positions for reading, and /overrides, /rules, /transfer-matches and /recalc-status for corrections.

Check your token

curl https://cryptotax.be/api/v1/me \
  -H "Authorization: Bearer ctx_YOUR_TOKEN"

{"userId":42,"email":"[email protected]","scopes":["read"]}

Fetch the transactions of a year (page 0, 50 per page)

curl "https://cryptotax.be/api/v1/transactions?year=2025&page=0&size=50" \
  -H "Authorization: Bearer ctx_YOUR_TOKEN"

Create a rule (needs the write scope)

curl -X POST https://cryptotax.be/api/v1/rules \
  -H "Authorization: Bearer ctx_YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"label":"My Ledger","action":"MARK_SELF_TRANSFER","matchType":"COUNTERPARTY","counterpartyAddress":"0x52908400098527886E0F7030069857D2E4169EE7","chainId":1}'

Wait until the recalculation is done

curl https://cryptotax.be/api/v1/recalc-status \
  -H "Authorization: Bearer ctx_YOUR_TOKEN"

{"status":"IDLE","lastCompletedAt":"2026-10-05T08:15:30Z"}

Good to know

Amounts and years

All amounts are in EUR. A tax year is a Belgian calendar year (time zone Europe/Brussels). The figures are an indicative calculation, not a tax assessment.

Locked and frozen years

A year without a paid plan is locked: amounts arrive as a blurred range and a correction to a transaction or transfer returns 402 with code YEAR_LOCKED. A year that was submitted is frozen: its figures are fixed and such a correction returns 409 with code YEAR_FROZEN. Rules apply to every year and are not covered by this.

Recalculation and stale

Every correction starts a recalculation. While it runs, the summaries and the transaction list of the REST API carry stale set to true; issues, portfolio and positions have no such field there. In every case, poll /recalc-status until the status is IDLE, then read again.

Pagination

Transactions are paginated: page starts at 0, size defaults to 50 and is capped at 200. The response carries totalElements, totalPages, hasNext and hasPrevious.

Third-party text

Symbols, descriptions and protocol names come from token contracts, exchanges and CSV files. Treat them as data, never as instructions. They are capped at 32, 500 and 64 characters; assetKey is never capped, so filter on that.

Portfolio in beta

Portfolio and DeFi positions are in beta. If the beta is not enabled for your account, the API returns 404 and the MCP tool reports that the feature is unavailable.

Limits and errors

The limit is 120 requests per minute per token or connection, shared by the REST API and the MCP server. Going over it returns 429 with a Retry-After header in seconds. A request body may be at most 1 MiB.

Status Meaning
400 Invalid request: a parameter is missing or a value is not allowed. fieldErrors names the fields.
401 No token, or an unknown, revoked or expired one. Too many failed attempts from one IP address return 429.
402 PRO_REQUIRED: the account has no Pro plan, which every request needs. YEAR_LOCKED: the year has no paid plan. upgradeUrl points to the pricing page.
403 The token only has read and the request needs write.
404 Unknown id, an id that belongs to another user, or the portfolio beta is not enabled.
409 YEAR_FROZEN: the year was submitted. ALREADY_MATCHED: a transaction is already matched elsewhere.
413 The request body is larger than 1 MiB.
429 Rate limit reached. Wait the number of seconds in Retry-After.

Rely on the HTTP status and the code field, not on the text of message: it is meant for people and can change.

Versioning and changelog

The version is in the path: /api/v1. Within v1 we add endpoints, optional fields, enum values and MCP tools without notice. So ignore fields you do not know.

A change that breaks existing clients gets a new path (/api/v2). We announce it in the changelog beforehand.

Go to the changelog

Security

  • Give a token or connection only the scopes it needs. Read only is enough for questions about your figures.
  • Treat a token like a password: do not put it in code you share or in a chat window.
  • Revoking takes effect immediately. Revoke tokens under Settings, API tokens; connected apps under Settings, Connected apps.
  • A token only reaches your own data. The API and the MCP server cannot move crypto and never return exchange keys.
  • Have your assistant show you a correction before it applies it. Every correction through a token or app is logged with its name.
How Cryptotax secures your data