mcpField
M
monarchmoney

monarchmoney

本地服务
github.com/hakimelek金融数据233 周前更新

关于 monarchmoney

monarchmoney 是用于访问 Monarch Money 财务数据的 Node.js/TypeScript 库和 MCP 服务,提供账户、交易、预算及现金流的类型化操作,涵盖读取和写入。

主要功能

  1. 01账户和交易的类型化 API 方法
  2. 02预算、现金流、持仓和余额数据
  3. 03电子邮件 OTP 与 MFA 认证流程
  4. 04保存并复用会话令牌
  5. 05自动分页及瞬时错误重试
  6. 06用于读取和修改数据的 30 个 MCP 工具

适用场景

  1. 01为应用获取财务数据
  2. 02通过 MCP 客户端查看交易、预算或现金流
  3. 03通过 AI Agent 修改交易和账户设置

MCP 相关

内置 MCP 服务提供 30 个用于读取和写入 Monarch Money 数据的工具。MCP 客户端可访问账户、交易、预算、现金流及受支持的修改操作。

配置

本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。

mcp.json · 通用配置
{
"mcpServers": {
"hakimelek-monarchmoney": {
"command": "npx",
"args": [
"-y",
"@hakimelek/monarchmoney"
],
"env": {
"MONARCH_TOKEN": "<MONARCH_TOKEN>"
}
}
}
}
启动命令npx -y @hakimelek/monarchmoney
需要配置的环境变量
MONARCH_TOKEN密钥Your Monarch Money auth token. Obtain by logging in with the library and saving mm.token.

本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。

安装包
npm@hakimelek/monarchmoney0.3.1

工具

30

收录的工具列表 · 更新于 2 周前

此工具无需参数。

详细介绍

Monarch Money (Node.js)

用于访问 Monarch Money 数据的 Node.js/TypeScript 库。

**免责声明:**此项目为非官方项目,与 Monarch Money 无关。

安装

npm install @hakimelek/monarchmoney

需要 Node.js 18+(使用原生 fetch 和 AbortSignal.timeout)。

快速开始

import {
  MonarchMoney,
  EmailOtpRequiredException,
  RequireMFAException,
} from "@hakimelek/monarchmoney";

const mm = new MonarchMoney();

try {
  await mm.login("[email protected]", "password");
} catch (e) {
  if (e instanceof EmailOtpRequiredException) {
    // Monarch sent a verification code to your email
    const code = await promptUser("Enter the code from your email:");
    await mm.submitEmailOtp("[email protected]", "password", code);
  } else if (e instanceof RequireMFAException) {
    // TOTP-based MFA is enabled on the account
    await mm.multiFactorAuthenticate("[email protected]", "password", "123456");
  }
}

// Fetch data — fully typed responses
const { accounts } = await mm.getAccounts();
console.log(accounts[0].displayName, accounts[0].currentBalance);

身份验证

Monarch 的 API 要求新设备/会话进行电子邮件验证(OTP),即使已禁用 MFA 也不例外。此库通过不同的异常类型处理此情况,以便你的应用做出相应响应。

使用电子邮件 OTP 处理登录
try {
  await mm.login(email, password);
} catch (e) {
  if (e instanceof EmailOtpRequiredException) {
    // A code was sent to the user's email — prompt them for it
    const code = await yourApp.promptForEmailCode();
    await mm.submitEmailOtp(email, password, code);
  }
}
使用 MFA 密钥(自动 TOTP)
await mm.login("email", "password", {
  mfaSecretKey: "YOUR_BASE32_SECRET",
});

MFA 密钥是 Monarch Money 中 Settings > Security > Enable MFA 下的“Two-factor text code”。

会话持久化与令牌复用

成功登录后(包括电子邮件 OTP 验证),你可以保存令牌,避免每次运行时都重新进行身份验证:

// Save token after login
mm.saveSession(); // writes to .mm/mm_session.json (mode 0o600)

// Next time, login() loads the saved session automatically
await mm.login(email, password); // uses saved token, no network call

// Or pass the token directly (skip login entirely)
const mm = new MonarchMoney({ token: "your-saved-token" });
mm.saveSession();          // save to disk
mm.loadSession();          // load from disk
mm.deleteSession();        // remove the file
mm.setToken("...");        // set token programmatically
交互式 CLI
await mm.interactiveLogin(); // prompts for email, password, email OTP or MFA code

API

所有方法都会返回类型化响应。在编辑器中将鼠标悬停在任意方法上,即可查看完整的 JSDoc 和类型信息。

读取方法
方法返回值说明
getAccounts()GetAccountsResponse所有已关联的账户
getAccountTypeOptions()GetAccountTypeOptionsResponse可用的账户类型/子类型
getRecentAccountBalances(startDate?)GetRecentAccountBalancesResponse每日余额(默认:过去 31 天)
getAccountSnapshotsByType(startDate, timeframe)GetSnapshotsByAccountTypeResponse按类型划分的快照("year" / "month")
getAggregateSnapshots(options?)GetAggregateSnapshotsResponse一段时间内的总净值
getAccountHoldings(accountId)GetAccountHoldingsResponse券商账户中的证券
getAccountHistory(accountId)AccountHistorySnapshot[]每日余额历史记录
getInstitutions()GetInstitutionsResponse已关联的金融机构
getBudgets(startDate?, endDate?)GetBudgetsResponse含实际数据的预算(默认:上个月至下个月)
getSubscriptionDetails()GetSubscriptionDetailsResponse套餐状态(试用、高级版等)
getTransactionsSummary()GetTransactionsSummaryResponse汇总摘要
getTransactions(options?)GetTransactionsResponse支持完整筛选的交易记录
getAllTransactions(options?)Transaction[]所有符合条件的交易记录(自动分页)
getTransactionPages(options?)AsyncGenerator<Transaction[]>逐页生成数据的异步生成器
getTransactionCategories()GetTransactionCategoriesResponse所有类别
getTransactionCategoryGroups()GetTransactionCategoryGroupsResponse类别组
getTransactionDetails(id)typed response单笔交易详情
getTransactionSplits(id)typed response交易的拆分项
getTransactionTags()GetTransactionTagsResponse所有标签
getCashflow(options?)GetCashflowResponse按类别、分组和商家划分的现金流
getCashflowSummary(options?)GetCashflowSummaryResponse收入、支出、储蓄和储蓄率
getRecurringTransactions(start?, end?)GetRecurringTransactionsResponse即将发生的定期交易
isAccountsRefreshComplete(ids?)boolean检查刷新状态
写入方法
方法返回值说明
createManualAccount(params)CreateManualAccountResponse创建手动账户
updateAccount(id, updates)UpdateAccountResponse更新账户设置/余额
deleteAccount(id)DeleteAccountResponse删除账户
requestAccountsRefresh(ids)boolean启动刷新(非阻塞)
requestAccountsRefreshAndWait(opts?)boolean刷新并轮询,直至完成
createTransaction(params)CreateTransactionResponse创建交易
updateTransaction(id, updates)UpdateTransactionResponse更新交易
deleteTransaction(id)boolean删除交易
updateTransactionSplits(id, splits)UpdateTransactionSplitResponse管理拆分项
createTransactionCategory(params)CreateCategoryResponse创建类别
deleteTransactionCategory(id, moveTo?)boolean删除类别
deleteTransactionCategories(ids)(boolean | Error)[]批量删除
createTransactionTag(name, color)CreateTransactionTagResponse创建标签
setTransactionTags(txId, tagIds)SetTransactionTagsResponse为交易设置标签
setBudgetAmount(params)SetBudgetAmountResponse设置/清除预算
uploadAccountBalanceHistory(id, csv)void上传余额历史记录 CSV

错误处理

import {
  MonarchMoneyError,          // base class for all errors
  EmailOtpRequiredException,  // email verification code needed — call submitEmailOtp()
  RequireMFAException,        // TOTP MFA required — call multiFactorAuthenticate()
  LoginFailedException,       // bad credentials or auth error (includes .statusCode)
  RequestFailedException,     // API/GraphQL failure (includes .statusCode, .graphQLErrors)
} from "@hakimelek/monarchmoney";

try {
  await mm.login(email, password);
} catch (e) {
  if (e instanceof EmailOtpRequiredException) {
    // e.code === "EMAIL_OTP_REQUIRED"
    // Prompt user for the code sent to their email
    const code = await getCodeFromUser();
    await mm.submitEmailOtp(email, password, code);
  } else if (e instanceof RequireMFAException) {
    // e.code === "MFA_REQUIRED"
    // Prompt for TOTP code or use mfaSecretKey
  } else if (e instanceof LoginFailedException) {
    // e.code === "LOGIN_FAILED", e.statusCode
    console.error("Login failed:", e.message);
  }
}

try {
  await mm.getAccounts();
} catch (e) {
  if (e instanceof RequestFailedException) {
    console.error(e.statusCode);     // HTTP status, if applicable
    console.error(e.graphQLErrors);  // GraphQL errors array, if applicable
    console.error(e.code);           // "HTTP_ERROR" | "REQUEST_FAILED"
  }
}

配置

const mm = new MonarchMoney({
  sessionFile: ".mm/mm_session.json", // session file path
  timeout: 10,                        // API timeout in seconds
  token: "pre-existing-token",        // skip login
  retry: {
    maxRetries: 3,                    // retry on 429/5xx (default: 3, set 0 to disable)
    baseDelayMs: 500,                 // base delay with exponential backoff + jitter
  },
  rateLimit: {
    requestsPerSecond: 10,            // token-bucket throttle (default: 0 = unlimited)
  },
});

mm.setTimeout(30); // change timeout later

重试机制会自动处理暂时性故障(429 Too Many Requests、500、502、503、504),采用指数退避并加入抖动。对于 429 响应,会遵循 Retry-After 标头。

自动分页

getTransactions() 返回单页数据。对于大型数据集,请使用自动分页辅助方法:

// Async generator — yields one page at a time (memory-efficient)
for await (const page of mm.getTransactionPages({ startDate: "2025-01-01", endDate: "2025-12-31" })) {
  for (const tx of page) {
    console.log(tx.merchant?.name, tx.amount);
  }
}

// Or collect everything into a flat array
const all = await mm.getAllTransactions({
  startDate: "2025-01-01",
  endDate: "2025-12-31",
  pageSize: 100, // transactions per page (default: 100)
});
console.log(`${all.length} total transactions`);

这两种方法都接受与 getTransactions() 相同的筛选选项(日期范围、类别、账户、标签等)。

刷新进度

使用 onProgress 回调跟踪账户刷新进度:

await mm.requestAccountsRefreshAndWait({
  timeout: 300,
  delay: 10,
  onProgress: ({ completed, total, elapsedMs }) => {
    console.log(`${completed}/${total} accounts refreshed (${(elapsedMs / 1000).toFixed(0)}s)`);
  },
});

MCP 服务(AI Agent 集成)

此软件包内置了一个 Model Context Protocol 服务,包含 30 个工具,可让 AI 助手通过 Claude Desktop、Cursor 和任何兼容 MCP 的客户端访问你的 Monarch Money 数据。

设置
  1. 使用此库登录,获取 Monarch Money 身份验证令牌(参见身份验证),并保存 mm.token。

  2. 将其添加到 MCP 客户端配置中(例如 Claude Desktop 的 claude_desktop_config.json):

{
  "mcpServers": {
    "monarch-money": {
      "command": "npx",
      "args": ["@hakimelek/monarchmoney"],
      "env": {
        "MONARCH_TOKEN": "your-token-here"
      }
    }
  }
}

或者直接运行:

MONARCH_TOKEN=your-token npx @hakimelek/monarchmoney
可用工具

读取(18 个工具): get_accounts、get_account_holdings、get_account_history、get_account_type_options、get_recent_account_balances、get_aggregate_snapshots、get_institutions、get_budgets、get_subscription_details、get_transactions、get_transactions_summary、get_transaction_details、get_transaction_categories、get_transaction_category_groups、get_transaction_tags、get_cashflow、get_cashflow_summary、get_recurring_transactions

写入(12 个工具): create_transaction、update_transaction、delete_transaction、create_manual_account、update_account、delete_account、refresh_accounts、is_refresh_complete、set_budget_amount、create_transaction_tag、set_transaction_tags、create_transaction_category

每个工具都提供带说明的类型化参数,因此 AI Agent 能准确了解应传入哪些参数。

项目结构

src/
  index.ts      — public exports
  client.ts     — MonarchMoney class with all API methods
  mcp.ts        — MCP server (30 tools for AI agents)
  errors.ts     — error classes (MonarchMoneyError hierarchy)
  endpoints.ts  — API URL constants
  queries.ts    — all GraphQL query/mutation strings
  types.ts      — TypeScript interfaces for all API responses

测试

npm test              # run tests once
npm run test:watch    # run tests in watch mode
npm run test:coverage # run with coverage report

测试使用 Vitest,无需真实的 API 凭据(必要时会对 fetch 进行模拟)。

测试 API 连接(连接到线上 api.monarch.com):

npm run build

# Login with email + password (will prompt for email OTP code if required)
[email protected] MONARCH_PASSWORD=yourpassword npm run test:connection

# Use a saved token (skips login)
MONARCH_TOKEN=your-token npm run test:connection -- --token

可将这些值设置在 .env 文件中,以方便使用(参见 .env.example)。

常见问题

如果我通过 Google 登录 Monarch,该如何使用?

在 Monarch 账户的 Settings > Security 中设置密码,然后在此库中使用该密码。

为什么 Monarch 每次登录时都会要求输入电子邮件验证码?

Monarch 要求对新设备或未识别的设备进行电子邮件验证。登录后,使用 mm.saveSession() 保存会话令牌,或存储 mm.token——后续运行将重用该令牌,无需重新验证。

此库的比较

目前有多种非官方的 Monarch Money 集成。以下是 @hakimelek/monarchmoney 的表现。

生态概览
@hakimelek/monarchmoneymonarch-money-api (pbassham)monarchmoney (keithah)monarchmoney (hammem)
平台Node.js / TypeScriptNode.js / JavaScriptNode.js / TypeScriptPython
npm 每周下载量—~440~130不适用(pip:~103K/月)
运行时依赖1(speakeasy)573
TypeScript 类型完整(每种响应)无有不适用
电子邮件 OTP 流程有无无无
MFA / TOTP有有有有
会话持久化有(0o600 权限)有有(AES-256)有
交互式 CLI 登录有有有有
HTTP 客户端原生 fetchnode-fetchnode-fetch + graphql-requestaiohttp
错误层级4 种类型化异常通用抛出通用抛出1 种异常
读取方法2015~20~16
写入方法149~12~10
速率限制有无有无
退避重试有无有无
自动分页有无无无
同时支持 CJS + ESM有无有无
刷新进度事件有无无无
内置 MCP 服务有(30 个工具)无无无
此库的优势

依赖精简。 运行时依赖只有 1 个,而 JS/TS 替代方案有 5–7 个。原生 fetch 意味着 Node 18+ 无需 HTTP polyfill。

支持电子邮件 OTP。 Monarch 现在要求对未识别的设备进行电子邮件验证,即使 MFA 已关闭也是如此。这是唯一一个能处理完整 EmailOtpRequiredException → submitEmailOtp() 流程的 Node.js 库。缺少此功能时,从新环境首次登录会导致自动化脚本中断。

全面类型化。 每种 API 响应都有专用的 TypeScript 接口——导出了 50 多种类型,涵盖账户、交易、持仓、现金流、预算、定期项目和变更。monarch-money-api 包完全没有类型。

结构化错误处理。 提供四种不同的异常类(LoginFailedException、RequireMFAException、EmailOtpRequiredException、RequestFailedException),并包含错误代码和状态代码。竞品会抛出通用错误或字符串。

更全面的写入功能。 包含 updateTransaction()、setBudgetAmount()、uploadAccountBalanceHistory()、getCashflow()、getCashflowSummary() 和 getRecurringTransactions()——这些功能在 monarch-money-api 中均不可用。

简洁、扁平的 API。 一个类,直接调用方法,无需学习子对象或冗长的层级。导入 MonarchMoney,调用方法,即可获得类型化结果。

参与贡献

欢迎贡献。请确保 TypeScript 编译无误(npm run build)且测试通过(npm test)。

许可证

MIT

评论

支持 Markdown

第一次接触 MCP?

从协议是什么,到在客户端里装上第一个服务,这几条回答覆盖了大多数入门问题。

一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。