内容
# finance-mcp
本地、隐私优先的银行和信用卡交易访问,适用于Copilot,由[SimpleFIN](https://www.simplefin.org/)支持。它从您的金融机构拉取交易到一个规范化的磁盘缓存,并将它们暴露给Copilot作为MCP服务器。除了向SimpleFIN的单个HTTPS调用外,您的机器上不会留下任何数据 - 没有第三方SaaS看到您的数据,也不会显示任何虚假/样本数据。
## 为什么选择SimpleFIN
所有这些机构都得到SimpleFIN的支持(已针对其实时机构搜索进行验证):塔吉特信用卡、诺德斯特罗姆卡服务、亚马逊Chase卡(通过Chase Bank)、富达信用卡、富达NetBenefits(通过富达投资)、查尔斯施瓦布和塞浦路斯信用合作社。SimpleFIN的费用约为每年15美元,没有按账户计费,您拥有访问令牌。
## 安全模型
SimpleFIN **访问URL嵌入基本身份验证凭证**,可以读取您的交易。因此,它存储在 **此项目目录之外**(此存储库可能位于Dropbox等同步文件夹中):
- 访问URL + 交易缓存位于 `~/.finance-mcp/`(目录 `0700`,文件 `0600`)。
- 使用 `FINANCE_MCP_HOME` 覆盖位置。
- 访问URL也可以通过 `SIMPLEFIN_ACCESS_URL` 环境变量提供(优先于保存的文件),因此它永远不必接触磁盘。
## 设置
1. 获取SimpleFIN **设置令牌**:在 <https://bridge.simplefin.org/> 注册并生成一个(它是一个base64字符串)。
2. 声明它(一次性 - 令牌在成功声明后过期):
```bash
uv run finance-mcp claim # 提示输入令牌
# 或:uv run finance-mcp claim <SETUP_TOKEN>
```
生成的访问URL保存在 `~/.finance-mcp/access_url`(模式 0600)。
3. 将您的交易拉入缓存:
```bash
uv run finance-mcp sync --days 120
```
## 命令行界面
```bash
uv run finance-mcp accounts # 每个账户的余额
uv run finance-mcp transactions --search grocery # 搜索完整档案
uv run finance-mcp transactions --start 2026-01-01 --account <id> --json
uv run finance-mcp summary --group-by month # 流入/流出聚合
uv run finance-mcp summary # 默认按类别分组,不包括转账
uv run finance-mcp networth # 每个快照日期的净资产总额
uv run finance-mcp stats # 存档大小 + 日期覆盖
uv run finance-mcp categorize # 种子默认规则 + 显示覆盖率
uv run finance-mcp uncategorized # 顶部仍未分类的商家
uv run finance-mcp rules list # 显示分类规则
uv run finance-mcp rules add --pattern "trader joe" --category Groceries
uv run finance-mcp rules rm --rule-id <id> # 删除规则
uv run finance-mcp set-category <txn_id> Travel # 固定一个交易的类别
uv run finance-mcp sync --days 120 # 从SimpleFIN刷新
uv run finance-mcp subscriptions detect # 保存循环收费为跟踪列表
uv run finance-mcp subscriptions # 审计:跟踪账单是否已发布? + 新候选人
uv run finance-mcp subscriptions mark --name Sketch --lifecycle canceled --effective 2026-04-01
uv run finance-mcp web # 本地只读浏览器UI
```
`subscriptions detect` 扫描存档中的循环月度收费,并将它们保存到预算配置中,以便您的订阅成为一个持久的列表,而不是每次运行时重新推断的内容;它是幂等的,并跳过已跟踪的商家。`subscriptions`(审计)然后报告任何未按其周期发布的跟踪账单 - 可能的计费问题或取消 - 并将未跟踪的循环商家作为候选项显示。已保存的订阅不需要信封预算:`match` 关键字将其固定到商家。检测是一个启发式起点 - 查看保存的列表并删除任何误报。
`subscriptions mark` 是取消观察:您取消(或尝试取消)订阅后,将其标记为 `canceling`(尝试中,未确认)或 `canceled`(已确认),并具有生效日期。然后,审计停止将预期费用报告为缺失 - 您想要的缺失 - 而是如果在该日期之后发出费用,则警告您取消未生效 - 而不是悄悄计费。 `--lifecycle active` 重新激活账单。循环账单和订阅是同一个列表:预算日历中的任何内容都可以这样观察。
SimpleFIN限制请求为90天,并期望每天的请求数≤24,因此 `sync` 将长时间范围分成≤89天的窗口,您应该依赖存档进行日常查询,而不是不断重新同步。任何SimpleFIN警告或错误(`errors`/`errlist`)始终会显示。
## 网络UI(在浏览器中查看)
`finance-mcp web` 启动一个本地只读网络UI,用于查看存档和预算报告,而无需离开终端驱动的工作流:
```bash
uv run finance-mcp web # 提供 http://127.0.0.1:8765/
uv run finance-mcp web --port 9000 # 选择其他端口
```
它默认绑定到 `127.0.0.1`,因为它提供私人财务数据(仅当您了解暴露时才覆盖 `--host`)。请求主机头始终与允许列表进行检查,因此 `127.0.0.1` 绑定不会被DNS重新绑定破坏;要从另一个设备访问非回环或通配符绑定,请使用 `--allow-host` 指定设备面向的主机(其他主机均被拒绝)。每个页面都由MCP服务器公开的相同功能支持,因此浏览器视图和Copilot看到的数据相同,并且不会发生任何更改 - UI中没有同步或确认操作。选项卡涵盖账户、交易、支出、净资产、转账和烧钱/预测/分配/订阅报告;每个视图还公开它渲染的原始JSON。
## 本地存档(多年历史)
每次 `sync` 在本地执行两件事,均在 `~/.finance-mcp/`(模式 `0600`):
- 更新 `cache.json` - 最新规范化的快照,
- 将数据折叠到 `archive.db`,一个 **SQLite** 数据库,是持久的、可搜索的、多年的历史。
存档是 **追加-仅**:交易由其稳定的SimpleFIN ID(待处理费用稍后升级为已发布,无重复)更新,`first_seen` 被保留,并且永远不会删除任何内容 - 因此,即使交易超出了SimpleFIN的滚动窗口,交易也会保留在存档中。每次同步还会记录每个账户的 **余额快照**,这是 `networth` / `net_worth_history` 趋势随时间变化的依据。
所有读取命令和MCP工具均来自 `archive.db`(仅在该版本的第一次同步之前回退到 `cache.json`)。您也可以使用任何SQLite工具查询它:
```bash
sqlite3 ~/.finance-mcp/archive.db \
"SELECT posted, amount, description FROM transactions ORDER BY posted_ts DESC LIMIT 10;"
```
## MCP服务器(从Copilot使用)
服务器通过stdio运行,并公开这些工具:
| 工具 | 网络? | 目的 |
|------|----------|---------|
| `list_accounts` | 否 | 账户 + 余额 + 机构 |
| `account_balances` | 否 | 仅余额和截至日期 |
| `get_transactions` | 否 | 按日期/账户/搜索/金额过滤(包括类别) |
| `spending_summary` | 否 | 按类别、账户、组织或月份分组的流入/流出 |
| `categorization_status` | 否 | 类别覆盖率 + 按类别划分的支出明细 |
| `list_category_rules` | 否 | 活动子字符串 → 类别规则 |
| `add_category_rule` | 否 | 添加规则(可选标记匹配为转账) |
| `remove_category_rule` | 否 | 按ID删除规则 |
| `set_transaction_category` | 否 | 固定一个交易的类别(在同步后仍然存在) |
| `net_worth_history` | 否 | 每个快照日期的净资产总额(净资产趋势) |
| `archive_stats` | 否 | 存档大小 + 最早/最新的交易 |
| `sync_now` | **是** | 从SimpleFIN刷新缓存 + 存档 |
### 为他人安装(无需克隆)
安装 [uv](https://docs.astral.sh/uv/) 后,您可以直接从此存储库声明/同步并运行服务器 - `uvx` 按需获取并构建:
```bash
# 一次性声明 + 首次同步
uvx --from git+https://github.com/dfrysinger/finance-mcp finance-mcp claim
uvx --from git+https://github.com/dfrysinger/finance-mcp finance-mcp sync --days 120
```
然后通过将以下内容添加到 `~/.copilot/mcp-config.json` 下的 `mcpServers`(或在Copilot中运行 `/mcp` 进行管理):
```json
{
"mcpServers": {
"finance": {
"command": "uvx",
"args": [
"--from",
"git+https://github.com/dfrysinger/finance-mcp",
"finance-mcp-server"
],
"tools": ["*"]
}
}
}
```
### 本地checkout替代方案
如果您克隆了存储库并更喜欢从工作树运行:
```json
{
"mcpServers": {
"finance": {
"command": "uv",
"args": ["--directory", "<ABSOLUTE_PATH_TO>/finance-mcp", "run", "finance-mcp-server"],
"tools": ["*"]
}
}
}
```
`get_transactions` / `spending_summary` 提供持久存档(`archive.db`),`sync`(CLI)或 `sync_now` 将其保持最新。
## 注意 / 限制
- SimpleFIN不提供消费 **类别**,因此类别由本地规则引擎(描述/付款人上的不区分大小写的子字符串匹配)+每个交易的手动覆盖分配 - 从您的数据外部不会进行任何猜测。内部流动(转账、卡付款、P2P)被标记为诚实的消费总额不包括它们;传递 `--include-transfers` / `include_transfers=true` 以计算它们。
- 金额有符号:负数 = 资金流出。使用 `max_amount=0` 表示仅消费,`min_amount=0` 表示仅收入。
## 开发
```bash
uv run pytest -q
```
已针对SimpleFIN的公共演示数据集(声明 → 获取 → 规范化 → 缓存 → 查询,以及MCP标准输入/输出往返)进行了验证。