Guide

Set up accounts

Build a chart of accounts for a household (assets, credit cards, income, expenses), change it, renumber it, move and delete accounts, and enter opening balances.

The chart of accounts is the skeleton of the book: every transaction moves value between its accounts. A household usually needs somewhere to keep money (assets), somewhere that records what is owed (liabilities), and categories for money coming in (income) and going out (expenses). This guide builds a small chart, adjusts it, and starts it off with the balances you have today.

Steps

  1. Plan the tree. Accounts nest: Assets:Current Assets:Checking. A parent that only groups its children is usually a placeholder, which cannot take transactions itself. account.types lists the types (BANK, CASH, CREDIT, ASSET, LIABILITY, INCOME, EXPENSE, EQUITY, STOCK, and so on); a child's type must suit its parent's.
  2. Create the parents, then the children with account.create. parent is the full name of the parent (the root by default) and commodity the currency; a child takes its parent's commodity if you leave it out.
  3. Edit with account.update: name, code, description, notes, colour, hidden, placeholder. You cannot change the commodity of an account that already has splits, or the type to one the parent does not allow.
  4. Number the accounts with account.renumber: give a subtree a prefix and an interval, and its accounts get codes 1-100, 1-200 and so on.
  5. Set one property down a whole subtree with account.cascade, for example a colour or hidden.
  6. Move an account to another parent with account.move, with its sub-accounts and transactions.
  7. Delete with account.delete. An account that has transactions is refused unless you say where they go: transactions: {"moveTo": "<account>"} moves its splits, or you can delete the transactions. Sub-accounts are moved up or deleted the same way.
  8. Enter opening balances. The money you already have when you start is recorded as a transaction against an Equity account called Opening Balances. account.openingBalanceAccount finds it. Create it with openingBalance: true if there is none, then post one transaction per opening balance with transaction.post: a positive value on the asset account and the same amount, negative, on Opening Balances. For a credit card or loan, reverse the signs.
  9. Keep a copy of the chart with export.accounts, which writes the accounts and their commodities to a file you can import into another book.

Example

A small household chart, with an opening balance.

Example: with a new, empty book open as book.gnucash, at 2024-07-01T12:00:00Z.

JSON-RPC

Request:

{"jsonrpc":"2.0","id":1,"method":"account.create","params":{"name":"Assets","type":"ASSET","commodity":"USD","placeholder":true}}

Response:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "fullName": "Assets",
    "placeholder": true,
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":2,"method":"account.create","params":{"name":"Checking","type":"BANK","parent":"Assets"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 2,
  "result": {
    "fullName": "Assets:Checking",
    "commodity": "CURRENCY::USD",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":3,"method":"account.create","params":{"name":"Wallet","type":"CASH","parent":"Assets"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 3,
  "result": {
    "fullName": "Assets:Wallet",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":4,"method":"account.create","params":{"name":"Expenses","type":"EXPENSE","commodity":"USD","placeholder":true}}

Response:

{
  "jsonrpc": "2.0",
  "id": 4,
  "result": {
    "fullName": "Expenses",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":5,"method":"account.create","params":{"name":"Food","type":"EXPENSE","parent":"Expenses"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 5,
  "result": {
    "fullName": "Expenses:Food",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":6,"method":"account.update","params":{"account":"Assets:Wallet","description":"Cash on hand"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 6,
  "result": {
    "fullName": "Assets:Wallet",
    "description": "Cash on hand",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":7,"method":"account.renumber","params":{"account":"Assets","prefix":"1","interval":100}}

Response:

{
  "jsonrpc": "2.0",
  "id": 7,
  "result": [
    {
      "account": "…",
      "fullName": "Assets:Wallet",
      "code": "1-100"
    },
    {
      "account": "…",
      "fullName": "Assets:Checking",
      "code": "1-200"
    }
  ]
}

Request:

{"jsonrpc":"2.0","id":8,"method":"account.openingBalanceAccount","params":{"currency":"USD"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 8,
  "result": {
    "account": null,
    "foundBy": null,
    "featureUsed": false
  }
}

Request:

{"jsonrpc":"2.0","id":9,"method":"account.create","params":{"name":"Opening Balances","type":"EQUITY","commodity":"USD","openingBalance":true}}

Response:

{
  "jsonrpc": "2.0",
  "id": 9,
  "result": {
    "fullName": "Opening Balances",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":10,"method":"transaction.post","params":{"datePosted":"2024-07-01","description":"Opening balance","splits":[{"account":"Assets:Checking","value":"1250.00"},{"account":"Opening Balances","value":"-1250.00"}]}}

Response:

{
  "jsonrpc": "2.0",
  "id": 10,
  "result": {
    "balanced": true,
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":11,"method":"account.move","params":{"account":"Assets:Wallet","parent":"Assets:Checking"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 11,
  "result": {
    "fullName": "Assets:Checking:Wallet",
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":12,"method":"account.delete","params":{"account":"Assets:Checking:Wallet"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 12,
  "result": {
    "deletedAccounts": [
      "…"
    ],
    "…": "…"
  }
}

Request:

{"jsonrpc":"2.0","id":13,"method":"account.balance","params":{"account":"Assets:Checking"}}

Response:

{
  "jsonrpc": "2.0",
  "id": 13,
  "result": {
    "balances": {
      "commodity": "CURRENCY::USD",
      "balance": {
        "num": "125000",
        "denom": "100"
      },
      "…": "…"
    },
    "…": "…"
  }
}

Command line

red-ale exec --book book.gnucash --script - <<'EOF'
account.create {"name":"Assets","type":"ASSET","commodity":"USD","placeholder":true}
account.create {"name":"Checking","type":"BANK","parent":"Assets"}
account.create {"name":"Wallet","type":"CASH","parent":"Assets"}
account.create {"name":"Expenses","type":"EXPENSE","commodity":"USD","placeholder":true}
account.create {"name":"Food","type":"EXPENSE","parent":"Expenses"}
account.update {"account":"Assets:Wallet","description":"Cash on hand"}
account.renumber {"account":"Assets","prefix":"1","interval":100}
account.openingBalanceAccount {"currency":"USD"}
account.create {"name":"Opening Balances","type":"EQUITY","commodity":"USD","openingBalance":true}
transaction.post {"datePosted":"2024-07-01","description":"Opening balance","splits":[{"account":"Assets:Checking","value":"1250.00"},{"account":"Opening Balances","value":"-1250.00"}]}
account.move {"account":"Assets:Wallet","parent":"Assets:Checking"}
account.delete {"account":"Assets:Checking:Wallet"}
account.balance {"account":"Assets:Checking"}
EOF

It prints:

[
  {
    "fullName": "Assets",
    "placeholder": true,
    "…": "…"
  },
  {
    "fullName": "Assets:Checking",
    "commodity": "CURRENCY::USD",
    "…": "…"
  },
  {
    "fullName": "Assets:Wallet",
    "…": "…"
  },
  {
    "fullName": "Expenses",
    "…": "…"
  },
  {
    "fullName": "Expenses:Food",
    "…": "…"
  },
  {
    "fullName": "Assets:Wallet",
    "description": "Cash on hand",
    "…": "…"
  },
  [
    {
      "account": "…",
      "fullName": "Assets:Wallet",
      "code": "1-100"
    },
    {
      "account": "…",
      "fullName": "Assets:Checking",
      "code": "1-200"
    }
  ],
  {
    "account": null,
    "foundBy": null,
    "featureUsed": false
  },
  {
    "fullName": "Opening Balances",
    "…": "…"
  },
  {
    "balanced": true,
    "…": "…"
  },
  {
    "fullName": "Assets:Checking:Wallet",
    "…": "…"
  },
  {
    "deletedAccounts": [
      "…"
    ],
    "…": "…"
  },
  {
    "balances": {
      "commodity": "CURRENCY::USD",
      "balance": {
        "num": "125000",
        "denom": "100"
      },
      "…": "…"
    },
    "…": "…"
  }
]

MCP tool call

Tool call:

{"name":"account.create","arguments":{"name":"Assets","type":"ASSET","commodity":"USD","placeholder":true}}

Result:

{
  "structuredContent": {
    "fullName": "Assets",
    "placeholder": true,
    "…": "…"
  }
}

Tool call:

{"name":"account.create","arguments":{"name":"Checking","type":"BANK","parent":"Assets"}}

Result:

{
  "structuredContent": {
    "fullName": "Assets:Checking",
    "commodity": "CURRENCY::USD",
    "…": "…"
  }
}

Tool call:

{"name":"account.create","arguments":{"name":"Wallet","type":"CASH","parent":"Assets"}}

Result:

{
  "structuredContent": {
    "fullName": "Assets:Wallet",
    "…": "…"
  }
}

Tool call:

{"name":"account.create","arguments":{"name":"Expenses","type":"EXPENSE","commodity":"USD","placeholder":true}}

Result:

{
  "structuredContent": {
    "fullName": "Expenses",
    "…": "…"
  }
}

Tool call:

{"name":"account.create","arguments":{"name":"Food","type":"EXPENSE","parent":"Expenses"}}

Result:

{
  "structuredContent": {
    "fullName": "Expenses:Food",
    "…": "…"
  }
}

Tool call:

{"name":"account.update","arguments":{"account":"Assets:Wallet","description":"Cash on hand"}}

Result:

{
  "structuredContent": {
    "fullName": "Assets:Wallet",
    "description": "Cash on hand",
    "…": "…"
  }
}

Tool call:

{"name":"account.renumber","arguments":{"account":"Assets","prefix":"1","interval":100}}

Result:

{
  "content": [
    {
      "type": "text",
      "text": "[{\"account\":\"…\",\"fullName\":\"Assets:Wallet\",\"code\":\"1-100\"},{\"account\":\"…\",\"fullName\":\"Assets:Checking\",\"code\":\"1-200\"}]"
    }
  ]
}

Tool call:

{"name":"account.openingBalanceAccount","arguments":{"currency":"USD"}}

Result:

{
  "structuredContent": {
    "account": null,
    "foundBy": null,
    "featureUsed": false
  }
}

Tool call:

{"name":"account.create","arguments":{"name":"Opening Balances","type":"EQUITY","commodity":"USD","openingBalance":true}}

Result:

{
  "structuredContent": {
    "fullName": "Opening Balances",
    "…": "…"
  }
}

Tool call:

{"name":"transaction.post","arguments":{"datePosted":"2024-07-01","description":"Opening balance","splits":[{"account":"Assets:Checking","value":"1250.00"},{"account":"Opening Balances","value":"-1250.00"}]}}

Result:

{
  "structuredContent": {
    "balanced": true,
    "…": "…"
  }
}

Tool call:

{"name":"account.move","arguments":{"account":"Assets:Wallet","parent":"Assets:Checking"}}

Result:

{
  "structuredContent": {
    "fullName": "Assets:Checking:Wallet",
    "…": "…"
  }
}

Tool call:

{"name":"account.delete","arguments":{"account":"Assets:Checking:Wallet"}}

Result:

{
  "structuredContent": {
    "deletedAccounts": [
      "…"
    ],
    "…": "…"
  }
}

Tool call:

{"name":"account.balance","arguments":{"account":"Assets:Checking"}}

Result:

{
  "structuredContent": {
    "balances": {
      "commodity": "CURRENCY::USD",
      "balance": {
        "num": "125000",
        "denom": "100"
      },
      "…": "…"
    },
    "…": "…"
  }
}