个人财务账本访问服务

一个为AI代理提供结构化访问Beancount个人财务账本的只读MCP服务器。

  • by mekanics
  • Python
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 mekanics/mcp-beancount

使用说明

mcp帐户

只读MCP服务器,为AI代理提供结构化访问权限 Beancount 个人财务分类账。


先决条件


安装

uv sync

配置

变量 必填 默认 描述
BEANCOUNT_FILE ✅ — 通往你的绝对之路 .beancount 分类帐档案
ACCOUNT_ALLOWLIST ❌ (无) 逗号分隔的帐户前缀白名单(例如。 Assets:Bank,Expenses:)
BEANCOUNT_RELOAD ❌ false 在每次工具调用时重新加载分类账(开发模式)
BASE_CURRENCY ❌ operating_currency 从分类账 覆盖基础货币 net_worth_converted (例如。 CHF)

复制 .env.example 到 .env 并填写您的值:

cp .env.example .env

跑步

BEANCOUNT_FILE=/path/to/ledger.beancount uv run mcp-beancount

或者用a .env 文件(需要 dotenv 或同等):

export BEANCOUNT_FILE=/path/to/ledger.beancount
uv run mcp-beancount

MCP客户端配置

克劳德桌面

添加 ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "beancount": {
      "command": "uv",
      "args": ["run", "--project", "/path/to/mcp-beancount", "mcp-beancount"],
      "env": {
        "BEANCOUNT_FILE": "/absolute/path/to/ledger.beancount",
        "ACCOUNT_ALLOWLIST": ""
      }
    }
  }
}

开爪

添加到您的OpenClaw MCP配置中:

{
  "mcpServers": {
    "beancount": {
      "command": "uv",
      "args": ["run", "--project", "/path/to/mcp-beancount", "mcp-beancount"],
      "env": {
        "BEANCOUNT_FILE": "/absolute/path/to/ledger.beancount"
      }
    }
  }
}

工具参考

工具 签名 描述
get_net_worth (date?: str) 截至日期的净值(资产-负债),多币种,价格转换
get_balances (account_pattern: str) 与账户前缀/glob匹配的非零余额
get_income_statement (year: int, month?: int) 一段时间的收入与支出
get_transactions (account?: str, since?: str, limit?: int) 最近的交易,可过滤
query (bql: str) 原始BQL查询(只读)

例子

# Net worth today (multi-currency, per-currency breakdown + converted total)
get_net_worth()
# Returns:
# {
#   "as_of": "2026-03-28",
#   "base_currency": "CHF",
#   "assets": {
#     "Assets:Bank:UBS":    {"CHF": 50000.0},
#     "Assets:Broker:IBKR": {"USD": 30000.0}
#   },
#   "liabilities": {
#     "Liabilities:CreditCard": {"CHF": -2000.0}
#   },
#   "total_assets":       {"CHF": 50000.0, "USD": 30000.0},
#   "total_liabilities":  {"CHF": -2000.0},
#   "net_worth":          {"CHF": 48000.0, "USD": 30000.0},
#   "net_worth_converted": 74700.0,   # CHF 48000 + USD 30000 * 0.89
#   "skipped_positions":  []          # currencies with no price directive
# }

# Net worth as of 2025-12-31
get_net_worth(date="2025-12-31")

# All bank account balances
get_balances(account_pattern="Assets:Bank:")

# 2026 income statement
get_income_statement(year=2026)

# Q1 2026 income statement
get_income_statement(year=2026, month=1)

# Last 20 food expenses
get_transactions(account="Expenses:Food", limit=20)

# Transactions since 2026-01-01
get_transactions(since="2026-01-01")

# Raw BQL query
query("SELECT account, sum(position) WHERE account ~ 'Assets' GROUP BY account")

运行测试

BEANCOUNT_FILE=/path/to/any.beancount uv run pytest

或使用包含的 sample.beancount (测试通过夹具自动使用此功能):

uv run pytest

安全

  • 没有写:beancount库本质上是只读的
  • 没有shell调用:所有计算都是通过beancount Python API进行的
  • 路径隔离: BEANCOUNT_FILE 在启动时设置;从未通过工具论证暴露
  • 允许名单:可选 ACCOUNT_ALLOWLIST 将所有工具限制为特定的帐户前缀