🚀 Jarvis — 個人財務MCP服務器 + 代理
Jarvis是一個用於個人財務跟蹤的模型上下文協議(MCP)服務器,由Notion數據庫提供支持。它包含一個由大語言模型(LLM)驅動的代理(Gemini),可將自然語言解析為結構化的工具調用。
⚠️ 重要提示
本項目與特定的Notion工作區緊密耦合:
Jarvis Notion站點
數據庫模式、關係和公式均在Notion中配置。要使用此項目,請複製Notion模板後繼續操作。
🚀 快速開始
1. 前提條件
- Node.js 18+
- 具備API集成功能的Notion賬戶
- Gemini API密鑰
2. Notion數據庫設置
在Notion中創建6個具有以下模式的數據庫:
| 數據庫 |
必需屬性 |
| 支出 |
標題、金額(數字)、日期(日期)、賬戶(關聯→賬戶)、類別(關聯→類別)、資金賬戶(關聯→賬戶)、已結清(複選框)、結清方(關聯→付款)、已支付金額(數字)、備註(富文本) |
| 收入 |
標題、金額(數字)、日期(日期)、賬戶(關聯→賬戶)、類別(關聯→類別)、預分解金額(數字)、預算(關聯→預算規則)、備註(富文本) |
| 付款 |
標題、金額(數字)、日期(日期)、轉出賬戶(關聯→賬戶)、轉入賬戶(關聯→賬戶)、已結清支出(關聯→支出)、備註(富文本) |
| 賬戶 |
標題、賬戶類型(選擇:信用卡/支票賬戶/儲蓄賬戶/投資賬戶)、初始餘額(數字)、分類賬餘額(公式)、信用卡預留金額(彙總)、可用支出金額(公式)、總收入(彙總)、總支出(彙總)、總入賬金額(彙總)、總出賬金額(彙總) |
| 類別 |
標題(類別名稱:食品雜貨、外出就餐、Lyft等) |
| 預算規則 |
標題(規則名稱)、賬戶(關聯→賬戶)、百分比(0 - 1之間的數字) |
3. 環境變量
將 env.example 複製到 .env 並填寫以下內容:
NOTION_API_KEY=secret_xxx
EXPENSES_DB_ID=xxx
INCOME_DB_ID=xxx
PAYMENTS_DB_ID=xxx
ACCOUNTS_DB_ID=xxx
CATEGORIES_DB_ID=xxx
BUDGET_RULES_DB_ID=xxx
GEMINI_API_KEY=xxx
PORT=3000
AGENT_PORT=4000
MCP_BASE_URL=http://localhost:3000
4. 安裝與運行
npm install
npm run mcp
npm run agent
✨ 主要特性
- 統一的
add_transaction:一個工具即可處理支出、收入和付款。
- 賬戶級餘額計算:信用卡欠款通過總支出減去總付款計算,而非單個支出的結清狀態。
- 自動結清付款:添加付款時,自動將匹配的未結清支出標記為已結清(更新資金賬戶預留金額)。
- 類別驗證:未知類別會被轉換為“其他”。
- 類別緩存:從Notion獲取類別,緩存時間為5分鐘。
- 與LLM無關的設計:代理層可以將Gemini替換為任何大語言模型。
- 批量操作:高效地批量更新交易和類別。
📦 安裝指南
1. 前提條件
- Node.js 18+
- 具備API集成功能的Notion賬戶
- Gemini API密鑰
2. Notion數據庫設置
在Notion中創建6個具有特定模式的數據庫,具體模式見上文“快速開始”部分。
3. 環境變量
複製 env.example 到 .env 並填寫相關信息,包括Notion API密鑰、數據庫ID、Gemini API密鑰等。
4. 安裝與運行
npm install
npm run mcp
npm run agent
💻 使用示例
基礎用法
MCP服務器 (localhost:3000)
POST /mcp
Content-Type: application/json
Accept: application/json, text/event-stream
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "add_transaction",
"arguments": {
"amount": 12.34,
"transaction_type": "expense",
"account": "sapphire",
"funding_account": "checkings",
"category": "groceries",
"date": "2026-01-10",
"note": "Trader Joes"
}
}
}
代理服務器 (localhost:4000)
POST /chat
Content-Type: application/json
{
"message": "spent $12.34 on groceries at Trader Joes yesterday"
}
響應:
{
"reply": "added expense of $12.34 to sapphire (category: groceries).",
"meta": {
"action": { "action": "add_transaction", "args": {...} },
"mcp": {...}
}
}
高級用法
可以根據實際需求調整請求參數,例如批量添加交易、更新交易類別等。以下是批量添加交易的示例:
POST /mcp
Content-Type: application/json
Accept: application/json, text/event-stream
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "add_transactions_batch",
"arguments": {
"transactions": [
{
"amount": 10.0,
"transaction_type": "expense",
"account": "sapphire",
"funding_account": "checkings",
"category": "groceries",
"date": "2026-01-10",
"note": "Trader Joes"
},
{
"amount": 20.0,
"transaction_type": "income",
"account": "checkings",
"category": "salary",
"date": "2026-01-11",
"note": "Monthly salary"
}
]
}
}
}
📚 詳細文檔
MCP工具參考
交易
| 工具 |
描述 |
關鍵參數 |
add_transaction |
添加支出、收入或付款 |
金額、交易類型、賬戶、類別、日期、備註、資金賬戶、轉出賬戶、轉入賬戶 |
add_transactions_batch |
批量添加多個交易 |
交易列表[] |
類別
| 工具 |
描述 |
關鍵參數 |
get_categories |
列出有效類別(緩存) |
— |
get_uncategorized_transactions |
獲取類別為“其他”的支出 |
— |
update_transaction_category |
更新一項支出的類別 |
支出ID、類別 |
update_transaction_categories_batch |
批量更新類別 |
更新列表[] |
預算
| 工具 |
描述 |
關鍵參數 |
set_budget_rule |
創建/更新預算分配 |
預算名稱、預算列表[](賬戶 + 百分比) |
split_paycheck |
按規則拆分總工資 |
總金額、預算名稱、日期 |
API端點
MCP服務器 (localhost:3000)
POST /mcp
Content-Type: application/json
Accept: application/json, text/event-stream
{
"jsonrpc": "2.0",
"id": "1",
"method": "tools/call",
"params": {
"name": "add_transaction",
"arguments": {
"amount": 12.34,
"transaction_type": "expense",
"account": "sapphire",
"funding_account": "checkings",
"category": "groceries",
"date": "2026-01-10",
"note": "Trader Joes"
}
}
}
代理服務器 (localhost:4000)
POST /chat
Content-Type: application/json
{
"message": "spent $12.34 on groceries at Trader Joes yesterday"
}
響應:
{
"reply": "added expense of $12.34 to sapphire (category: groceries).",
"meta": {
"action": { "action": "add_transaction", "args": {...} },
"mcp": {...}
}
}
有效賬戶
| 類型 |
值 |
| 所有賬戶 |
支票賬戶、短期儲蓄賬戶、賬單賬戶、自由無限信用卡、藍寶石信用卡、經紀賬戶、羅斯個人退休賬戶、Spaxx |
| 資金賬戶 |
支票賬戶、賬單賬戶、短期儲蓄賬戶 |
| 信用卡 |
藍寶石信用卡、自由無限信用卡 |
餘額模型
賬戶餘額通過Notion公式在賬戶級別進行計算,而非通過彙總單個支出狀態。
分類賬餘額 公式
if(account_type == "credit",
total_expenses - total_payments_in,
starting_balance + total_income - total_payments_out - total_expenses
)
- 信用卡:欠款 = 消費 - 已收到的付款。付款會立即全額減少餘額,無論單個支出是否結清。
- 借記卡/儲蓄賬戶:餘額 = 初始餘額 + 收入 - 支出 - 直接費用。
信用卡預留金額(彙總)
彙總 資金賬戶 為此賬戶的信用卡支出的 欠款金額。顯示資金賬戶(如支票賬戶)為未支付的信用卡支出預留了多少金額。
可用支出金額(公式)
ledger_balance - reserved_for_cc
支出結清(對賬)
通過API創建付款時,payments.ts 會自動結清匹配的支出(先結清最早的支出)。這會設置每個支出的 已支付金額,從而減少 欠款金額(公式:金額 - 已支付金額),進而減少資金賬戶的 信用卡預留金額。結清操作 對於資金賬戶的準確性至關重要,但 不影響信用卡的 分類賬餘額。
示例自然語言輸入(代理)
| 輸入 |
推斷操作 |
| "spent $12 on groceries" |
add_transaction(支出) |
| "hunt paid 2500" |
split_paycheck(預算:hunt) |
| "paid $300 to sapphire" |
add_transaction(付款) |
| "what categories can I use?" |
get_categories |
| "show me uncategorized" |
get_uncategorized_transactions |
🔧 技術細節
架構
┌───────────────────────────────────────────────────────────────────┐
│ 用戶輸入 │
│ "spent $12 on groceries at Trader Joes" │
└───────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────┐
│ 代理服務器 (端口 4000) │
│ POST /chat │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Gemini客戶端 (gemini_client.ts) 或LLM提供商 │ │
│ │ - 將自然語言解析為結構化操作 │ │
│ │ - 推斷:操作類型、金額、類別、賬戶等 │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ MCP客戶端 (mcp_client.ts) │ │
│ │ - 通過JSON-RPC調用MCP工具 │ │
│ └─────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────┐
│ MCP服務器 (端口 3000) │
│ POST /mcp │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 註冊工具 (server.ts) │ │
│ │ - add_transaction - get_categories │ │
│ │ - add_transactions_batch - get_uncategorized_transactions │ │
│ │ - set_budget_rule - update_transaction_category │ │
│ │ - split_paycheck - update_transaction_categories_batch │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ 服務層 │ │
│ │ - transactions.ts (add_transaction, batch) │ │
│ │ - payments.ts (create_payment, auto-clear expenses) │ │
│ │ - categories.ts (get/update uncategorized) │ │
│ │ - budgets.ts (set_budget_rule, split_paycheck) │ │
│ └─────────────────────────────────────────────────────────────┘ │
│ │ │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────────┐ │
│ │ Notion層 (notion/client.ts, notion/utils.ts) │ │
│ │ - API客戶端 + 數據庫ID │ │
│ │ - 類別緩存 + 驗證 │ │
│ │ - 賬戶/預算規則查找 │ │
│ └─────────────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────────┘
│
▼
┌───────────────────────────────────────────────────────────────────┐
│ Notion數據庫 │
│ - 支出數據庫 - 收入數據庫 - 付款數據庫 │
│ - 賬戶數據庫 - 類別數據庫 - 預算規則數據庫 │
└───────────────────────────────────────────────────────────────────┘
項目結構
jarvis/
├── src/
│ ├── mcp/ # MCP服務器 (端口 3000)
│ │ ├── server.ts # Express + MCP工具註冊
│ │ ├── constants.ts # 共享賬戶枚舉 + 驗證器
│ │ ├── notion/
│ │ │ ├── client.ts # Notion API客戶端 + 數據庫ID
│ │ │ ├── types.ts # 數據源API的類型包裝器
│ │ │ └── utils.ts # 輔助工具:類別緩存、查找
│ │ └── services/
│ │ ├── transactions.ts # add_transaction, batch
│ │ ├── payments.ts # create_payment, auto-clear
│ │ ├── categories.ts # uncategorized + updates
│ │ └── budgets.ts # 預算規則 + 工資拆分
│ │
│ └── agent/ # 代理服務器 (端口 4000)
│ ├── agent_server.ts # Express /chat端點
│ ├── mcp_client.ts # MCP的JSON-RPC客戶端
│ └── llm/
│ ├── gemini_client.ts # Gemini提示 + 操作解析器
│ └── claude_prompt.md # Claude系統提示參考
│
├── package.json
├── tsconfig.json
├── .env # 環境變量 (未提交)
└── README.md
開發
npm run typecheck
npm run mcp
npm run agent
📄 許可證
本項目採用MIT許可證。