预算管理协议服务器

YNAB MCP服务器是一个基于模型上下文协议(MCP)的服务器,用于通过AI助手(如Claude和Cursor)与You Need A Budget(YNAB)预算数据进行交互,支持查询预算信息、创建和更新交易、批量操作和支出分析等功能。

  • by smwitkowski
  • TypeScript
  • 本地部署
  • 1 星标
  • 更新于
在 GitHub 查看 smwitkowski/ynab-mcp

使用说明

YNAB MCP服务器

A. 模型上下文协议(MCP) 用于交互的服务器 你需要一个预算(YNAB) 通过Claude和Cursor等人工智能助手。

概述

YNAB MCP服务器使AI助手能够与您的YNAB预算数据进行交互,使您能够:

  • 查询预算信息、账户余额和交易记录
  • 通过自然语言创建和更新交易
  • 执行批量操作,如重新分类多个事务
  • 将交易拆分到多个类别
  • 分析支出模式和趋势

请参阅 概述文档 有关架构和用例的更多详细信息。

快速开始

  1. 安装依赖项:

    npm install
    
  2. 构建项目:

    npm run build
    
  3. 配置YNAB API密钥 (参见 YNAB身份验证指南):

    # Create .env file
    echo "YNAB_API_KEY=your_key_here" > .env
    
  4. 连接到您的MCP客户端 (参见 客户端配置):

    • 克劳德桌面:添加到 claude_desktop_config.json
    • 光标:在设置中配置或 mcp.json

请参阅 安装指南 了解详细的安装说明。

文档

特性

工具

  • get预算 -列出YNAB的所有预算
  • 获取预算详细信息 -获取特定预算的详细信息
  • getAccounts -列出预算中的所有账户
  • 获取类别 -列出所有有余额的类别
  • 获取类别平衡 -获取特定类别的详细信息
  • getTransactions -使用可选筛选器获取交易
  • 创建交易 -创建新交易
  • 左 -更新现有交易记录
  • batchUpdateTransactions -批量更新多个交易(例如,批量重新分类)
  • createSplit交易 -跨多个类别创建拆分交易
  • split交易 -将现有交易拆分为多个类别
  • 收款人 -列出收款人

资源

  • 预算摘要 -所有预算及账户余额概览
  • 账户余额 -预算中所有账户的当前余额

提示词

  • 预算概览 -预算状况快速概览
  • 支出分析 -分析特定类别的支出

响应格式

所有工具和资源都支持两种响应格式:

  • toon (默认):TOON(面向令牌的对象表示法)格式,用于减少令牌使用(减少30-60%)
  • json:标准JSON格式,人类可读且易于解析

您可以通过包含以下内容来指定格式 format: "toon" 或 format: "json" 在您的工具参数中。当省略时, toon 默认情况下用于最佳令牌效率。

TOON格式:TOON是一种专为LLM应用程序设计的紧凑数据格式。它保持了数据保真度,同时显著减少了令牌计数。对象数组表示为表(例如。, items[2]{id,name}:\n 1,Alice\n 2,Bob),使其成为事务列表等大型数据集的理想选择。

了解更多关于TOON的信息: toontools.app

金额和单位

了解如何处理货币金额对于正确使用此MCP服务器至关重要。

YNAB API格式(百万单位)

YNAB API将所有货币金额表示为 整数(单位:毫),在哪里 1000 毫单位等于 1.00 以预算货币计算。例如:

  • 1000 百万单位 = $1.00 美元
  • -50000 百万单位 = -$50.00 美元
  • 123456 百万单位 = $123.46 美元

这种格式避免了浮点精度问题,并确保了精确的货币计算。

此MCP服务器的格式(货币单位)

工具输入:全部 amount 工具参数中的字段(用于交易、拆分等)接受 以货币单位表示的数字 (例如。, -50.00 为了 -$50.00).服务器使用以下命令自动将这些转换为YNAB毫单位 toCurrencyAmount() 在发送到API之前。

工具输出:工具返回的所有金额和余额(例如。, amount, budgeted, balance, clearedBalance)返回为 以货币单位表示的数字 (不是原始毫单位),便于LLM和其他消费者使用。

符号规则

  • 负金额 (-50.00):流出(资金流出、支出、付款)
  • 正金额 (50.00):流入(资金流入、收入、存款)

转换和舍入

将货币单位输入转换为毫单位时,在转换之前,值将四舍五入到最接近的0.001货币单位(即最接近的毫单位)。例如:

  • 50.123 → 轮次至 50123 百万单位
  • 50.1234 → 轮次至 50123 百万单位
  • 50.1235 → 轮次至 50124 百万单位

备注:全部 amount 下面工具文档中的字段遵循这些相同的单位规则。

错误处理

当工具遇到错误时,它会返回一个结构化的错误负载,而不是抛出异常。这允许LLM检查错误详细信息并适当地处理它们。

错误响应格式

所有错误响应都遵循以下结构:

{
  "success": false,
  "errorType": "YNAB_API_ERROR" | "INTERNAL_ERROR",
  "message": "Human-readable error message",
  "toolName": "nameOfTheTool"
}

YNAB API错误

当发生YNAB API错误时(例如,重复的交易、无效的帐户ID),错误负载包括额外的字段:

{
  "success": false,
  "errorType": "YNAB_API_ERROR",
  "statusCode": 409,
  "errorId": "ynab.error.duplicate_import_id",
  "errorName": "Duplicate Import ID",
  "message": "a transaction with the same import_id already exists on the specified account",
  "toolName": "splitTransaction"
}

YNAB API常见错误:

  • 409 -重复的导入ID(具有相同交易的交易 import_id 已存在)
  • 400 -验证错误(参数无效,缺少必填字段)
  • 404 -未找到资源(预算、帐户、类别或交易不存在)

内部错误

对于非YNAB错误(例如网络问题、意外异常),错误有效载荷使用:

{
  "success": false,
  "errorType": "INTERNAL_ERROR",
  "message": "Description of what went wrong",
  "toolName": "createTransaction"
}

法学硕士最佳实践

  1. 始终检查 success:在处理工具结果之前,请验证 success: true (或检查 success: false).
  2. 检查错误详细信息:为 YNAB_API_ERROR,检查 statusCode, errorName,以及 message 了解出了什么问题。
  3. 优雅地处理:使用错误信息向用户提供有用的反馈,或使用更正的参数重试操作。

工具参考

本节记录了所有可用的工具、资源和提示及其输入参数和预期的输出结构。

备注:以下所有示例均显示JSON和TOON格式。默认情况下,工具返回TOON格式以减少令牌使用。指定 format: "json" 如果你需要JSON输出。

工具

get预算

列出用户可用的所有YNAB预算。

参数:

  • format (可选):响应格式- "toon" (默认)或 "json"

示例输出(JSON):

{
  "budgets": [
    {
      "id": "12345678-1234-1234-1234-123456789012",
      "name": "My Budget",
      "lastModified": "2024-01-15T10:30:00Z",
      "currency": "USD"
    }
  ],
  "defaultBudget": {
    "id": "12345678-1234-1234-1234-123456789012",
    "name": "My Budget"
  }
}

示例输出(TOON):

budgets[1]{id,name,lastModified,currency}:
  12345678-1234-1234-1234-123456789012,My Budget,2024-01-15T10:30:00Z,USD

defaultBudget{id,name}:
  12345678-1234-1234-1234-123456789012,My Budget

获取预算详细信息

获取有关特定预算的详细信息。

参数:

  • budgetId (必填):预算ID
  • format (可选):响应格式- "toon" (默认)或 "json"

输出示例:

{
  "id": "12345678-1234-1234-1234-123456789012",
  "name": "My Budget",
  "lastModified": "2024-01-15T10:30:00Z",
  "currency": "USD",
  "accounts": 5,
  "categories": 25,
  "payees": 50
}

getAccounts

获取预算的所有账户及其余额。

参数:

  • budgetId (必填):预算ID
  • format (可选):响应格式- "toon" (默认)或 "json"

示例输出(JSON):

{
  "accounts": [
    {
      "id": "87654321-4321-4321-4321-210987654321",
      "name": "Checking Account",
      "type": "checking",
      "onBudget": true,
      "closed": false,
      "balance": "$1,234.56",
      "clearedBalance": "$1,200.00",
      "unclearedBalance": "$34.56"
    }
  ],
  "totalBalance": "$5,678.90",
  "totalOnBudget": "$4,567.89"
}

示例输出(TOON):

accounts[1]{id,name,type,onBudget,closed,balance,clearedBalance,unclearedBalance}:
  87654321-4321-4321-4321-210987654321,Checking Account,checking,true,false,$1,234.56,$1,200.00,$34.56

totalBalance: $5,678.90
totalOnBudget: $4,567.89

获取类别

按类别组组织预算的所有类别。

参数:

  • budgetId (必填):预算ID
  • format (可选):响应格式- "toon" (默认)或 "json"

输出示例:

{
  "categoryGroups": [
    {
      "groupName": "Immediate Obligations",
      "groupId": "group-123",
      "hidden": false,
      "categories": [
        {
          "id": "cat-456",
          "name": "Rent",
          "budgeted": "$1,200.00",
          "activity": "-$1,200.00",
          "balance": "$0.00",
          "hidden": false,
          "goalType": "TB",
          "goalTarget": "$1,200.00"
        }
      ]
    }
  ],
  "totals": {
    "budgeted": "$3,000.00",
    "activity": "-$2,500.00",
    "balance": "$500.00"
  }
}

获取类别平衡

获取特定类别的平衡和详细信息。

参数:

  • budgetId (必填):预算ID
  • categoryId (必填):类别ID
  • format (可选):响应格式- "toon" (默认)或 "json"

输出示例:

{
  "id": "cat-456",
  "name": "Groceries",
  "budgeted": "$500.00",
  "activity": "-$450.00",
  "balance": "$50.00",
  "hidden": false,
  "categoryGroup": "Monthly Bills"
}

getTransactions

使用可选筛选器获取交易。最多返回50笔交易。

参数:

  • budgetId (必填):预算ID
  • accountId (可选):按帐户ID筛选
  • categoryId (可选):按类别ID筛选
  • payeeId (可选):按收款人ID筛选
  • sinceDate (可选):仅返回此日期或之后的交易(ISO格式)
  • type (可选):按交易类型筛选("uncategorized" 或 "unapproved")
  • format (可选):响应格式- "toon" (默认)或 "json"

示例输出(JSON):

{
  "count": 25,
  "transactions": [
    {
      "id": "trans-789",
      "date": "2024-01-15",
      "amount": "-$50.00",
      "payee": "Grocery Store",
      "category": "Groceries",
      "account": "Checking Account",
      "memo": "Weekly shopping",
      "cleared": "cleared",
      "approved": true
    }
  ],
  "totalAmount": "-$1,250.00"
}

示例输出(TOON):

count: 25

transactions[1]{id,date,amount,payee,category,account,memo,cleared,approved}:
  trans-789,2024-01-15,-$50.00,Grocery Store,Groceries,Checking Account,Weekly shopping,cleared,true

totalAmount: -$1,250.00

创建交易

在预算中创建新交易。

参数:

  • budgetId (必填):预算ID
  • accountId (必填):帐户ID
  • date (必填):交易日期(ISO格式,例如“2024-01-15”)
  • amount (必填):以货币单位表示的交易金额(例如。, -50.00 为了 -$50.00).服务器将其转换为YNAB毫单位。流出为负,流入为正。
  • payeeName (可选):收款人姓名
  • categoryId (可选):类别ID
  • memo (可选):交易备忘录
  • cleared (可选):已清除状态("cleared", "uncleared",或 "reconciled")
  • approved (可选):交易是否已批准(默认: true)
  • format (可选):响应格式- "toon" (默认)或 "json"

输出示例:

{
  "success": true,
  "transaction": {
    "id": "trans-789",
    "date": "2024-01-15",
    "amount": "-$50.00",
    "payee": "Grocery Store",
    "category": "Groceries",
    "account": "Checking Account",
    "memo": "Weekly shopping",
    "cleared": "uncleared",
    "approved": true
  }
}

左

更新现有交易。

参数:

  • budgetId (必填):预算ID
  • transactionId (必填):交易ID
  • accountId (可选):帐户ID
  • date (可选):交易日期(ISO格式)
  • amount (可选):以货币单位表示的交易金额(例如。, -50.00 为了 -$50.00).服务器将其转换为YNAB毫单位。流出为负,流入为正。
  • payeeName (可选):收款人姓名
  • categoryId (可选):类别ID
  • memo (可选):交易备忘录
  • cleared (可选):已清除状态("cleared", "uncleared",或 "reconciled")
  • approved (可选):交易是否批准
  • format (可选):响应格式- "toon" (默认)或 "json"

输出示例:

{
  "success": true,
  "transaction": {
    "id": "trans-789",
    "date": "2024-01-15",
    "amount": "-$55.00",
    "payee": "Grocery Store",
    "category": "Groceries",
    "account": "Checking Account",
    "memo": "Weekly shopping - updated",
    "cleared": "cleared",
    "approved": true
  }
}

batchUpdateTransactions

在一次呼叫中更新多个事务。非常适合批量操作,如一次重新分类多个事务。使用全有或全无语义:如果任何事务未通过验证,则整个批处理失败,并且不会更新任何事务。

参数:

  • budgetId (必填):预算ID
  • updates (必填):事务更新数组(至少1个)。每次更新必须恰好包含以下内容之一:
    • id (string):交易ID,或
    • importId (string):交易导入ID
  • 每次更新还可以包括以下任何可选字段 updateTransaction:
    • accountId, date, amount (货币单位,由服务器转换为YNAB毫单位), payeeId, payeeName, categoryId, memo, cleared, approved, flagColor
  • format (可选):响应格式- "toon" (默认)或 "json"

何时使用:

  • 使用 updateTransaction 用于更新单个事务
  • 使用 batchUpdateTransactions 更新30多个事务时(例如,批量重新分类、批量批准、批量标记)
  • 建议批量大小:每次呼叫最多100笔交易,以保持在YNAB费率限制范围内

示例使用流程:

  1. 呼叫 getTransactions 使用过滤器(例如。, type: 'uncategorized', sinceDate, payeeId)
  2. 识别需要更新的交易
  3. 呼叫 batchUpdateTransactions 一次性完成所有更新

输入示例:

{
  "budgetId": "12345678-1234-1234-1234-123456789012",
  "updates": [
    {
      "id": "trans-1",
      "categoryId": "cat-groceries"
    },
    {
      "id": "trans-2",
      "categoryId": "cat-groceries"
    },
    {
      "importId": "YNAB:-50000:2024-01-15:1",
      "categoryId": "cat-groceries",
      "approved": true
    }
  ]
}

输出示例:

{
  "success": true,
  "updatedCount": 3,
  "transactionIds": ["trans-1", "trans-2", "trans-3"],
  "serverKnowledge": 1234567890,
  "transactions": [
    {
      "id": "trans-1",
      "date": "2024-01-15",
      "amount": "-$50.00",
      "payee": "Grocery Store",
      "category": "Groceries",
      "account": "Checking Account",
      "memo": null,
      "cleared": "uncleared",
      "approved": true,
      "flagColor": null
    }
  ]
}

错误处理: 如果批中的任何事务未通过验证(例如,类别ID无效、缺少必填字段),则整个批失败并返回错误。LLM应修复有问题的事务并重试。

createSplit交易

跨多个类别创建新的拆分交易。拆分交易允许您将单个交易金额划分为多个类别(例如,将100美元的Target购买拆分为60美元的杂货和40美元的家居用品)。

参数:

  • budgetId (必填):预算ID
  • accountId (必填):帐户ID
  • date (必填):交易日期(ISO格式,例如2025-11-15)
  • splits (必填):分割线阵列(至少2条)。每个分割必须具有:
    • amount (必填):此拆分的货币单位金额(例如。, -60.00 为了 -$60.00).服务器将其转换为YNAB毫单位。流出为负,流入为正。
    • categoryId (可选):此拆分的类别ID
    • memo (可选):此分割线的备注
    • payeeId (可选):特定于此拆分的收款人ID
    • payeeName (可选):特定于此拆分的收款人姓名
  • payeeId (可选):父交易的收款人ID
  • payeeName (可选):父交易的收款人名称
  • memo (可选):应用于父交易的备忘录
  • cleared (可选):已清除状态("cleared", "uncleared",或 "reconciled").违约: "uncleared"
  • approved (可选):交易是否被批准。违约: true
  • amount (可选):以货币单位表示的总交易金额。如果提供,则必须与所有拆分的总和相匹配。如果省略,则使用拆分总和。服务器将其转换为YNAB毫单位。
  • format (可选):响应格式- "toon" (默认)或 "json"

例子:

{
  "budgetId": "budget-123",
  "accountId": "account-456",
  "date": "2024-01-15",
  "payeeName": "Target",
  "memo": "Weekly shopping",
  "splits": [
    {
      "amount": -60.00,
      "categoryId": "cat-groceries",
      "memo": "Food items"
    },
    {
      "amount": -40.00,
      "categoryId": "cat-household",
      "memo": "Cleaning supplies"
    }
  ]
}

输出示例:

{
  "success": true,
  "transaction": {
    "id": "trans-789",
    "date": "2024-01-15",
    "amount": "-$100.00",
    "payee": "Target",
    "category": null,
    "account": "Checking Account",
    "memo": "Weekly shopping",
    "cleared": "uncleared",
    "approved": true,
    "subtransactions": [
      {
        "id": "sub-1",
        "amount": "-$60.00",
        "category": "Groceries",
        "memo": "Food items",
        "payee": null
      },
      {
        "id": "sub-2",
        "amount": "-$40.00",
        "category": "Household Supplies",
        "memo": "Cleaning supplies",
        "payee": null
      }
    ]
  }
}

split交易

将现有交易拆分为多个类别。此工具处理YNAB API限制,该限制阻止直接更新 subtransactions 通过创建新的拆分事务并可选地管理原始事务,对现有事务进行处理。

参数:

  • budgetId (必填):预算ID
  • transactionId (必填):要拆分的现有交易的ID
  • splits (必填):分割线阵列(至少2条)。每个分割必须具有:
    • amount (必填):此拆分的货币单位金额(例如。, -75.00 为了 -$75.00).必须与原始交易的货币单位金额相加。服务器将其转换为YNAB毫单位。
    • categoryId (可选):此拆分的类别ID
    • memo (可选):此拆分的备忘录
    • payeeId (可选):此拆分的收款人ID
    • payeeName (可选):此拆分的收款人名称
  • mode (可选):操作模式:
    • "prepare_for_matching" (默认):创建新的拆分交易,并保留原始交易,将其标记为手动替换。安全无损。
    • "replace_original":创建拆分交易并删除原始交易。更高级,请谨慎使用。
  • format (可选):响应格式- "toon" (默认)或 "json"

限制:

  • 无法拆分已拆分的事务(有子事务)
  • 无法拆分已删除的交易
  • 无法拆分转账交易
  • 拆分金额必须与原始交易金额完全相等

示例(prepare_for_match模式):

{
  "budgetId": "budget-123",
  "transactionId": "trans-456",
  "mode": "prepare_for_matching",
  "splits": [
    {
      "amount": -75.00,
      "categoryId": "cat-groceries"
    },
    {
      "amount": -25.00,
      "categoryId": "cat-restaurants"
    }
  ]
}

输出示例:

{
  "success": true,
  "mode": "prepare_for_matching",
  "originalTransactionId": "trans-456",
  "originalUpdated": true,
  "newTransaction": {
    "id": "trans-789",
    "date": "2024-01-15",
    "amount": "-$100.00",
    "payee": "Amazon",
    "account": "Checking Account",
    "cleared": "uncleared",
    "approved": true,
    "subtransactions": [
      {
        "id": "sub-1",
        "amount": "-$75.00",
        "category": "Groceries",
        "memo": null,
        "payee": null
      },
      {
        "id": "sub-2",
        "amount": "-$25.00",
        "category": "Restaurants",
        "memo": null,
        "payee": null
      }
    ]
  }
}

准备工作流程:

  1. 工具使用指定的拆分创建新的拆分事务
  2. 工具用备忘录标记原始交易 "[replace with split]" 和设置 approved: false
  3. 用户在YNAB UI中手动将拆分交易与银行导入进行匹配
  4. 用户删除原始交易

替换工作流程_原始:

  1. 工具使用指定的拆分创建新的拆分事务
  2. 工具删除原始交易
  3. 用户在YNAB UI中手动将拆分交易与银行导入进行匹配(如果需要)

收款人

获取预算的所有收款人,包括转账收款人。

参数:

  • budgetId (必填):预算ID
  • format (可选):响应格式- "toon" (默认)或 "json"

输出示例:

{
  "totalPayees": 50,
  "regularPayees": 45,
  "transferPayees": 5,
  "payees": [
    {
      "id": "payee-123",
      "name": "Grocery Store"
    },
    {
      "id": "payee-456",
      "name": "Gas Station"
    }
  ],
  "transfers": [
    {
      "id": "transfer-789",
      "name": "Transfer : Checking to Savings",
      "transferAccountId": "account-savings"
    }
  ]
}

资源

预算摘要

所有预算和账户余额概述。

URI: ynab://budget-summary

输出示例:

{
  "budgets": [
    {
      "id": "12345678-1234-1234-1234-123456789012",
      "name": "My Budget",
      "currency": "USD",
      "lastModified": "2024-01-15T10:30:00Z",
      "accounts": {
        "onBudget": {
          "count": 3,
          "totalBalance": "$4,567.89"
        },
        "offBudget": {
          "count": 2,
          "totalBalance": "$10,000.00"
        }
      }
    }
  ],
  "defaultBudget": {
    "id": "12345678-1234-1234-1234-123456789012",
    "name": "My Budget"
  }
}

账户余额

按类型分组的预算中所有账户的当前余额。

URI: ynab://account-balances/{budgetId}

输出示例:

{
  "budgetId": "12345678-1234-1234-1234-123456789012",
  "accountsByType": {
    "Budget": [
      {
        "id": "account-123",
        "name": "Checking Account",
        "balance": "$1,234.56",
        "clearedBalance": "$1,200.00",
        "unclearedBalance": "$34.56"
      }
    ],
    "checking": [
      {
        "id": "account-456",
        "name": "Savings Account",
        "balance": "$10,000.00",
        "clearedBalance": "$10,000.00",
        "unclearedBalance": "$0.00"
      }
    ]
  },
  "totals": {
    "allAccounts": "$14,567.89",
    "budgetAccounts": "$4,567.89",
    "trackingAccounts": "$10,000.00"
  },
  "lastUpdated": "2024-01-15T10:30:00Z"
}

提示词

预算概览

快速了解您的预算状况。

论据:

  • budgetId (可选):预算ID(如果未提供,则使用默认值)

用途: 此提示会生成一条用户消息,要求概述预算,包括可用余额总额、超支类别和即将到来的账单。

支出分析

分析一段时间内特定类别的支出。

论据:

  • budgetId (必填):预算ID
  • categoryId (必填):类别ID
  • months (可选):要分析的月数(默认值:3)

用途: 此提示生成一条用户消息,要求分析指定类别的支出,包括平均支出、趋势和任何异常活动。

安装

请参阅 安装指南 了解详细的安装说明。

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

# Install dependencies
npm install
# or use Makefile
make install

# Build the project
npm run build
# or use Makefile
make build

配置

请参阅 YNAB身份验证指南 以获取详细的API密钥设置。

  1. 创建一个 .env 文件:
echo "YNAB_API_KEY=your_ynab_api_key_here" > .env
  1. 从以下位置获取YNAB API密钥:https://app.ynab.com/settings/developer

  2. (可选)设置默认预算ID:

echo "DEFAULT_BUDGET_ID=your_budget_id" >> .env

与MCP客户端一起使用

请参阅 客户端配置指南 有关Claude Desktop、Cursor和其他MCP客户端的详细设置说明。

克劳德桌面

  1. 构建项目: npm run build
  2. 添加到Claude Desktop配置(请参阅 客户端配置)
  3. 重新启动克劳德桌面

光标

  1. 构建项目: npm run build
  2. 在游标设置中配置(请参阅 客户端配置)
  3. 重新启动游标

发展

请参阅 安装指南 了解开发工作流程的详细信息。

# Run in development mode with hot reload
npm run dev
# or use Makefile
make dev

# Build for production
npm run build
# or use Makefile
make build

# Start production server
npm start
# or use Makefile
make start

使用Makefile

该项目包括 Makefile 常见的开发任务:

  • make install -安装依赖项
  • make build -构建TypeScript项目
  • make dev -以开发模式运行
  • make start -启动生产服务器
  • make clean -清理构建工件

示例用法

连接到Claude后,您可以:

  • “显示我所有的YNAB预算”
  • “我的支票账户余额是多少?”
  • “这个月我在杂货上花了多少钱?”
  • “在杂货店创建50美元的交易”
  • “显示上周的所有交易”

批量操作

服务器支持批处理操作,以实现高效的批量更新:

何时使用批更新与单次更新

  • 单次更新(updateTransaction):用于更新1-2个事务或需要细粒度控制时
  • 批量更新(batchUpdateTransactions):用于更新30+笔交易,尤其适用于:
    • 批量重新分类(例如,将所有“亚马逊”交易归类为“购物”)
    • 批量批准交易
    • 批量标记或清算交易
    • 将相同的更改应用于许多事务

推荐批量

  • 最优:每批30-100笔交易
  • 最大:保持在YNAB API速率限制范围内(通常每小时200个请求)
  • 太大了:超过100个事务的批处理可能会达到有效负载大小限制或超时

批量更新语义

这 batchUpdateTransactions 工具用途 全赢或全输的 语义:

  • 如果所有交易都有效,则它们都会成功更新
  • 如果任何交易未通过验证(ID无效、类别无效等),则整个批次失败
  • 不执行部分更新-全部成功或全部失败
  • 如果失败,请修复有问题的事务,然后重试该批处理

示例:批量重新分类工作流

// 1. Get uncategorized transactions
getTransactions({
  budgetId: "budget-123",
  type: "uncategorized",
  sinceDate: "2024-01-01"
})

// 2. Identify transactions to recategorize
// (LLM analyzes and decides category for each)

// 3. Batch update all at once
batchUpdateTransactions({
  budgetId: "budget-123",
  updates: [
    { id: "trans-1", categoryId: "cat-groceries" },
    { id: "trans-2", categoryId: "cat-groceries" },
    { id: "trans-3", categoryId: "cat-restaurants" },
    // ... up to 100 transactions
  ]
})

拆分交易

服务器支持创建和管理拆分事务,这允许将单个事务划分为多个类别。

YNAB API限制

YNAB API在拆分事务方面存在重要限制:

  • 无法更新 subtransactions 论现有的分割交易:一旦事务被拆分,就不能通过API修改其子事务
  • 无法直接将普通事务转换为拆分:您不能使用 PUT/PATCH 向现有事务添加拆分

何时使用拆分工具

  • createSplitTransaction:从头开始创建全新的拆分交易时使用(例如,解析Amazon/Target订单数据并创建拆分)
  • splitTransaction:当您需要拆分现有的导入交易时使用(例如,需要跨多个类别分类的银行导入)

拆分交易模式

这 splitTransaction 该工具提供两种模式:

  1. prepare_for_matching (默认,推荐):

    • 创建新的拆分交易
    • 保留原始交易
    • 标记原件以便手动更换
    • 安全无损
    • 用户在YNAB UI中手动将拆分与银行导入进行匹配
  2. replace_original (高级):

    • 创建新的拆分交易
    • 删除原始交易
    • 自动化程度更高,但需要信任拆分逻辑
    • 用户可能仍需要手动匹配银行导入

示例:亚马逊订单拆分工作流

// 1. Get imported Amazon transaction
getTransactions({
  budgetId: "budget-123",
  payeeId: "payee-amazon",
  sinceDate: "2024-01-01"
})

// 2. Parse order details (from CSV or order history)
// LLM identifies: $60 Groceries, $30 Electronics, $10 Household

// 3. Split the transaction
splitTransaction({
  budgetId: "budget-123",
  transactionId: "trans-amazon-123",
  mode: "prepare_for_matching",
  splits: [
    { amount: -60.00, categoryId: "cat-groceries" },
    { amount: -30.00, categoryId: "cat-electronics" },
    { amount: -10.00, categoryId: "cat-household" }
  ]
})

// 4. User manually matches split to bank import in YNAB UI
// 5. User deletes the original transaction

最佳实践

  • 从开始 prepare_for_matching:使用安全模式,直到你对你的拆分逻辑充满信心
  • 核实金额:始终确保拆分金额与原始交易金额完全一致
  • 优雅地处理错误:如果拆分失败,请检查交易是否尚未拆分、删除或转移
  • 使用 createSplitTransaction 对于新条目:从头开始创建交易(例如手动输入)时,请使用 createSplitTransaction 直接

API费率限制

YNAB API有费率限制。此服务器实现了最佳实践:

  • 在适当的情况下使用特定的端点而不是批量请求
  • 支持批处理操作,以实现高效的批量更新
  • 支持拆分事务以满足复杂的分类需求
  • 在适当的情况下缓存响应
  • 优雅地处理速率限制错误

贡献

欢迎投稿!请看 贡献.md 作为指导方针。

安全

请参阅 安全指南 安全最佳实践。

  • API密钥存储在环境变量中
  • 永不承诺 .env 文件
  • 尽可能使用只读访问
  • 查看YNAB API权限

要报告安全漏洞,请参阅 安全.md.

许可证

此项目根据MIT许可证获得许可-请参阅 许可证 文件以获取详细信息。

致谢