Skip to main content
Glama
tmzhuang

GnuCash Read-Only MCP Server

by tmzhuang

GnuCash Read-Only MCP Server

A Python-based Model Context Protocol (MCP) server that exposes a local GnuCash database (MariaDB) as read-only tools for LLMs.

The goal of this project is to allow local or cloud-based models (via an MCP client like Claude Desktop or a local llama.cpp agent) to query personal finance data using natural language, without risking data mutation.

License: AGPL-3.0 Python MCP

Architecture

  • Language: Python 3.10+

  • Database: MariaDB (Raw SQL, no ORM)

  • Protocol: Official MCP Python SDK (stdio transport)

  • LLM Testing: llama.cpp and promptfoo

The server exposes a subset of SQL queries as MCP tools. The LLM determines which tool to call and provides the arguments, and the Python server executes the query and returns a JSON envelope.

Related MCP server: spendglass

Security Model (Read-Only Enforcement)

Because this tool gives an LLM access to a personal database, it uses defense-in-depth to prevent writes:

  1. Database Level: The MariaDB user is restricted to GRANT SELECT on the specific schema.

  2. Session Level: The Python connection explicitly executes SET SESSION TRANSACTION READ ONLY and sets a max_statement_time before running any query.

  3. Application Level: guard.py parses the generated SQL, stripping comments and rejecting any statement that is not a SELECT or WITH ... SELECT. It also blocks file writes (INTO OUTFILE) and locking clauses (FOR UPDATE).

Available Tools

The server provides the following tools to the LLM:

Tool

Description

list_accounts

Returns the account tree with GUIDs, names, and types

get_account_balance

Calculates the balance of an account and its descendants as of a specific date

get_recent_transactions

Returns recent transactions for a given account

get_spending_by_category

Aggregates expenses over a date range

get_income_by_category

Aggregates income over a date range

search_transactions

Case-insensitive search across transaction descriptions and memos

get_net_worth

Calculates total assets minus total liabilities

Installation

Quick Start

# Clone the repository
git clone https://github.com/yourusername/gnucash-mcp.git
cd gnucash-mcp

# Create virtual environment
python -m venv .venv
source .venv/bin/activate  # On Windows: .venv\Scripts\activate

# Install dependencies
pip install -e ".[dev]"

# Create .env file (see .env.example)
cp .env.example .env
# Edit .env with your database credentials

Running the Server

# Start the MCP server
python server.py

The server will run on stdio and connect to your MCP client.

Using with an MCP Client

Claude Desktop

Add to your claude_desktop_config.json:

{
  "mcpServers": {
    "gnucash-mcp": {
      "command": "python",
      "args": ["path/to/gnucash-mcp/server.py"],
      "env": {
        "DB_HOST": "127.0.0.1",
        "DB_PORT": "3306",
        "DB_USER": "gnucash_ro",
        "DB_PASSWORD": "your_password",
        "DB_NAME": "gnucash",
        "QUERY_TIMEOUT_S": "10"
      }
    }
  }
}

llama.cpp / Ollama

Configure your local LLM client to use the stdio transport and point it to the server process.

Usage Examples

Query Account Balance

"How much money do I have in my EQ Bank account as of 2024-01-15?"

Get Recent Transactions

"Show me my last 10 transactions for the Savings account."

Analyze Spending

"How much did I spend on groceries in December 2023?"

Get Net Worth

"What is my current net worth?"

Search Transactions

"Find all transactions related to 'rent' in 2024."

Implementation Notes

Handling GnuCash Data Formats: GnuCash stores currency amounts as integer pairs (value_num / value_denom). The SQL queries divide these using CAST(value_num AS DECIMAL) / value_denom to avoid floating-point inaccuracies.

Dates in GnuCash are stored as DATETIME values. The Python helpers convert standard ISO dates (YYYY-MM-DD) into the appropriate query bounds.

Double-Entry Accounting & LLMs: GnuCash stores liabilities and income as negative numbers. Small local models often get confused by this when calculating net worth. To fix this, the server splits tools into two categories:

  • Inspection tools (like get_account_balance) return raw ledger values.

  • Reporting tools (like get_net_worth) use SQL ABS() and explicit JSON keys (e.g., total_liabilities_owed) to return human-readable positive values.

Local LLM Evaluation

To ensure the server works reliably with local models, I set up an evaluation suite using promptfoo and llama-swap. The tests cover tool routing, argument formatting, and loop prevention.

Models tested include Qwen3.5-9B, LocoOperator-4B, and Ling-3B. You can find the test configurations in the evals/ directory and the results summary in docs/evaluation-results.md.

Configuration

Create a .env file in the project root:

DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=gnucash_ro
DB_PASSWORD=your_secure_password
DB_NAME=gnucash
QUERY_TIMEOUT_S=10

Security Warning: Never commit your .env file! Use .env.example as a template and add your actual credentials separately.

Testing

Unit Tests

pytest tests/

Smoke Test

python smoke_test.py "EQ Bank"

Linting

ruff check .

Full Evaluation

promptfoo eval

Troubleshooting

Connection Refused

  • Ensure MariaDB is running and accessible

  • Verify the database user has SELECT permissions

  • Check that the database exists and is accessible

Query Timeout

  • Increase QUERY_TIMEOUT_S in .env

  • Check for slow queries in your GnuCash database

No Matching Account

  • Use the full account path (e.g., Assets:Current Assets:Angie:EQ Bank)

  • Use a substring search (e.g., EQ Bank) if the exact path is unknown

SQL Guard Rejection

  • The guard blocks non-SELECT queries for security

  • Ensure you're not asking for write operations

License

This project is licensed under the GNU Affero General Public License v3.0 (AGPL-3.0) - see the LICENSE file for details.

Contributing

See CONTRIBUTING.md for guidelines on how to contribute.

Security

This project handles sensitive financial data. See SECURITY.md for security policies and responsible disclosure procedures.

Architecture

For detailed architecture documentation, see docs/architecture.md.

Evaluation Results

See docs/evaluation-results.md for LLM performance benchmarks.

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    A
    maintenance
    Enables financial data access from connected bank accounts via MCP tools, allowing natural language queries about balances, transactions, subscriptions, investments, and more, with a focus on privacy and read-only access.
    MIT
  • A
    license
    Not graded
    quality
    A
    maintenance
    Read-only MCP server that lets local AI agents query bank transactions stored in a local SQLite database, with tools for accounts, transaction search, spending summaries, recurring charges, trends, themes, subscriptions, and store health.
    2
    MIT
  • A
    license
    Not graded
    quality
    B
    maintenance
    Enables natural language queries against Money Manager EX databases, providing exact, read-only financial analytics such as spending by category, account balances, and income vs expense.
    MIT
  • A
    license
    Not graded
    quality
    C
    maintenance
    Provides read-only access to self-hosted cash-flow forecasts, balances, transactions, and credit-card data, letting AI clients answer spending and upcoming-obligation questions without modifying financial settings.
    MIT