Skip to main content
Glama
cesarzea

caton mcp

by cesarzea

Catón AI

CI CodeQL OpenSSF Scorecard License: MIT

A local-first, plugin-based financial watchdog for individuals and small businesses.

Catón AI connects to where your money actually goes — bank accounts, cards and the usage APIs of the services you pay for — keeps everything on your own machine, and lets plugins and AI agents watch it for you: budgets, goals, cash-flow forecasts, and alerts such as "tell me when my Anthropic spend goes over $20".

Status: pre-alpha. A first command-line version syncs European bank accounts through Enable Banking into a local ledger, reports monthly outflows and serves the ledger read-only to AI assistants over MCP. Plugins, agents, alerts and the web UI are not built yet.

Why the name

Cato the Elder was the Roman censor famous for his austerity and for reprimanding waste. Catón AI plays the same role for your finances: it keeps watch, and it tells you when something is off.

Related MCP server: Beanquery MCP Server

Principles

  • Local-first and private. Data and credentials stay on your machine. No telemetry.

  • Minimal core, everything else is a plugin. Data sources, budgets, goals and watchdog agents are plugins, including the official ones.

  • Permissions, not trust. Plugins declare what they can read, write and whether they may use the network; nothing gets network access by default.

  • Reviewed before activation. Plugins are checked automatically — including an AI-assisted security and functionality review — before they touch your data.

Documentation

Engineering standards

Enforced standards run through npm run check locally and in CI on every pull request; main cannot change unless they all pass. Each gate was verified to fail on a deliberate violation when it was introduced.

Architecture and code

Standard

Status

Architecture documented with arc42 and C4; decisions recorded as MADR architecture decision records

Adopted

Module boundaries checked by dependency-cruiser: public entry points only, no cycles, no undeclared or development dependencies in production code

Enforced

TypeScript @tsconfig/strictest; any forbidden

Enforced

typescript-eslint strict-type-checked + stylistic-type-checked, SonarJS cognitive complexity

Enforced

Tests with Vitest and ≥ 90 % coverage

Enforced

Small units: files ≤ 150 lines, functions ≤ 30 lines, cyclomatic complexity ≤ 8

Enforced

Dead-code detection with knip: no unused files, exports or dependencies

Enforced

Google TypeScript Style Guide conventions (named exports only); Prettier formatting

Enforced

Security and supply chain

Standard

Status

OpenSSF Scorecard published on every change to main

Enforced

CodeQL security-and-quality analysis on every pull request

Enforced

GitHub Actions pinned by commit SHA, least-privilege workflow tokens

Enforced

Secret scanning with push protection; private vulnerability reporting

Enforced

Automated dependency updates with Dependabot

Enforced

Process

Standard

Status

Protected main: pull requests only, required checks (Node.js 24 and 26, CodeQL, PR title), linear history, squash merges

Enforced

Code review following Google's engineering practices, with a definition of done in CONTRIBUTING

Adopted

Conventional Commits for every commit on main

Enforced

Planned

Standard

Status

OWASP Top 10 for LLM Applications 2025 mapping and threat model

Planned

OpenSSF Best Practices badge

Planned

Signed releases with SLSA provenance and SBOM

Planned

OWASP ASVS 5.0 level 2, before offering the product to businesses

Planned

Mutation testing of the accounting domain

Planned

Getting started

Requires Node.js 24 LTS or newer and an Enable Banking application in restricted mode with your own accounts linked and authorised (one session per bank).

Create ~/.config/caton-ai/config.json, readable only by you (chmod 600). Each entry is an instance of a plugin; its secret variables are never written here:

{
  "instances": [
    {
      "id": "mybank",
      "title": "My bank",
      "plugin": "enable-banking",
      "settings": {"app-id": "<application id>", "session-id": "<authorised session id>"}
    }
  ]
}

Secrets go in an encrypted store (ADR 0017) as plugin:instance:variable, here enable-banking:mybank:private-key. One secret can serve several instances: save it under a name of your choice and enter ${that-name} as their value (ADR 0019). The web interface lists every secret an instance needs, with what it is and where to get it:

npm run build           # builds the web interface once
npm start -- serve      # prints a one-time link to http://127.0.0.1:7170

See ADR 0018 for how it is protected. A configuration in the first format (plugins and connections) is converted with npm start -- config migrate.

npm ci --ignore-scripts
npm start -- sync       # fetch accounts, movements and balances into the local ledger
npm start -- accounts   # accounts and latest balances
npm start -- spend 3    # money leaving your accounts per month, last 3 months (cash basis)
npm start -- status     # last sync of every connection

Outflows still include transfers between your own accounts; transfer detection and categorisation are next. Unattended PSD2 access allows only a few requests per account per day (the exact quota is still to be verified), so sync at most once or twice a day. Current limitations are tracked in ADR 0012.

Ask your AI assistant (MCP)

caton mcp serves the ledger read-only over the Model Context Protocol (specification 2026-07-28; hosts still on 2025-era versions are served too). It never contacts a bank, amounts are exact decimals, and every answer says whether the figures are complete. See ADR 0013.

Tool

What it answers

sync_status

When each bank connection last synced, and why it failed

list_accounts

Accounts and their latest balances

list_transactions

Movements by date, account, direction or text, one page at a time

monthly_outflows

Money that left the accounts per month (includes own-account transfers)

top_counterparties

Who received the most money

Register it in your MCP host with absolute paths; the host must start Node.js 24 or newer, which may not be the node on its PATH. For Claude Code:

claude mcp add caton-ai -- /path/to/node24/bin/node /path/to/caton-ai/packages/cli/src/main.ts mcp

For hosts configured with JSON, such as Claude Desktop:

{
  "mcpServers": {
    "caton-ai": {
      "command": "/path/to/node24/bin/node",
      "args": ["/path/to/caton-ai/packages/cli/src/main.ts", "mcp"]
    }
  }
}

Account names, descriptions and counterparties come from banks and third parties; the server tells the assistant to treat them as data, never as instructions. With a hosted model, what the tools return is sent to its provider.

Development

Requires Node.js 24 LTS or newer.

npm ci --ignore-scripts
npm run check   # types, lint, format, architecture rules, dead code, web build, tests + coverage

See CONTRIBUTING.md for the quality gates and conventions.

Security

Please report vulnerabilities privately as described in SECURITY.md.

License

MIT © César Zea

Related MCP Connectors

Related MCP Servers

  • A
    license
    C
    quality
    D
    maintenance
    A Model Context Protocol server that allows AI assistants to query and analyze financial data through Ledger CLI, enabling tasks like financial reporting, budget analysis, and accounting.
    9
    51
    MIT
  • A
    license
    Not graded
    quality
    D
    maintenance
    An experimental server implementing the Model Context Protocol to allow AI assistants to query and analyze financial data stored in Beancount ledger files using the Beancount Query Language.
    53
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    A Model Context Protocol server that provides AI assistants like Claude with secure, read-only access to MoneyWiz financial data for natural language queries and financial analytics.
    13
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    A Model Context Protocol (MCP) server that keeps the books for your personal and business finances using double-entry accounting — driven entirely from an LLM.
    220 npm
    MIT