关于 Asset Notation
Asset Notation 是用于校验和转换 Asset Notation 文件的参考实现与命令行工具,也可将本地财富文档提供给 AI 助手,并在更新文件前校验写入内容。
主要功能
- 01依据内置结构校验文档
- 02在 CSV 与格式间转换
- 03记录持仓和估值
- 04按币种计算净资产
- 05通过 stdio 在本地处理数据
适用场景
- 01检查投资组合文件中的错误
- 02导入表格账户余额
- 03记录持仓估值变化
- 04让助手读取和维护本地财富文件
MCP 相关
`asset-notation mcp` 命令会为指定的本地文件启动 stdio MCP 服务,提供读取、列出、更新、导入和校验财富数据的工具,以及 asset-notation://document 资源。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
asset-notation
Asset Notation 的参考实现。这是一种开放格式,用于记录随时间变化的资产与负债。
它有三项用途:告诉你文档是否有效;在文档与现有电子表格之间导入和导出数字;并将文档提供给你本机上的 AI 助手。
npx asset-notation validate portfolio.json
npx asset-notation from-csv accounts.csv > portfolio.json
npx asset-notation to-csv portfolio.json > accounts.csv
npx asset-notation mcp wealth.json
import { validate, fromCsv, toCsv } from 'asset-notation';
const doc = fromCsv(readFileSync('accounts.csv', 'utf8'));
const { valid, errors, notes } = validate(doc);
为什么要支持 CSV
没人会为了尝试一项规范而重新输入自己的账户数据。如果一种格式无法导入你已有的数据,你就不会开始使用它。因此,转换器并非可有可无的便利功能,而是入门入口。
一行代表一项持有资产及其最近的估值,这正是大家已有的数据形态:每个账户一行,包含标签、余额和日期。
有两个细节决定了它能否在英语办公环境之外正常工作,而这两点都已妥善处理,而不是只写在文档里:
- 从法语、德语或西班牙语版 Excel 保存的电子表格会用分号分隔列,并用逗号表示小数。若按逗号分隔读取,
4210,55就会变成两列,所有余额都会出错。系统会根据表头检测分隔符,并据此读取金额。 - 金额始终以字符串形式保存。绝不会因浮点数计算而舍入余额。
系统会去掉千位分隔符,包括电子表格写入的不换行空格(1 234,56 和 1,234.56 都会转换为 1234.56)。日期也会以同样的方式读取:24/06/2026 和 24.06.2026 按日优先解析,06/24/2026 按月优先解析;若两种格式都能匹配,则由分隔符决定。
在 AI 助手中使用
asset-notation mcp <file.json> 是一个通过标准输入输出通信的 Model Context Protocol 服务。助手会读取并维护该文件;所有数据都留在本机,不会使用网络。文件不存在时,会在添加第一项持有资产时创建。
在助手桌面应用的配置文件中,或任何 MCP 客户端的配置文件中,将以下内容放在 mcpServers 下:
{
"mcpServers": {
"wealth": { "command": "npx", "args": ["-y", "asset-notation", "mcp", "/home/you/wealth.json"] }
}
}
通用 MCP 客户端也使用相同配置:命令为 npx,参数为 -y asset-notation mcp /home/you/wealth.json,传输方式为 stdio。路径必须是绝对路径:客户端会在不通过 shell 的情况下启动命令,因此 ~ 不会展开。
工具:read_document、net_worth、list_holdings、upsert_holding、add_valuation、validate、import_csv。资源:asset-notation://document。每次写入前都会验证整个文档;若文档无效,则会返回错误并拒绝写入。文件会以两个空格缩进的格式整体重写,金额仍以字符串形式保存。net_worth 会精确汇总每项持有资产的最新估值,按货币逐行列出,并告知所用估值中最早的日期。
如果你是受托管理他人财富的 AI
此软件包会读取和写入一个 Asset Notation 格式的 JSON 文件:其中包含一组 holdings(账户、房产、贷款,每项均为asset 或 liability)、一组 institutions,以及一组带日期的 valuations,其金额以十进制字符串表示。使用 npx -y asset-notation mcp <file.json> 启动,然后调用 list_holdings、通过 add_valuation 记录估值,并使用 net_worth 给出答复。所有内容都保留在本机;文件是唯一的状态存储,每次写入前都会根据随附的架构进行验证。
验证
根据文档声明的版本选择架构,按主版本号和次版本号匹配:文档声明自身的版本,并据此进行验证。架构随软件包一同发布,因此验证无需联网,也无需访问注册表——这正是该格式本身所要求的特性。
除架构外,还要检查 JSON Schema 无法表达的文档级规则:
| 情况 | 结论 |
|---|---|
| 同一集合中重复使用某个 id | 错误 |
parentId 链最终指回自身 | 错误 |
| 同一主体在同一资产上的两条所有权记录在时间上重叠 | 错误 |
| 引用指向不存在的对象 | 提示,仍然有效 |
| 同一资产的所有权份额总和大于 1 | 提示,仍然有效 |
未解析的引用是有意为之,也是其中最值得关注的一点。有效文档的任意子集本身也有效,因此,一份涵盖 12 个账户中的 3 个、并提及某家未作描述的银行的声明,是合法的部分披露,而不是损坏的文件。若将其报告为错误,就会禁止该格式旨在实现的分享方式。
validate() 遇到格式错误的文档时绝不会抛出异常:报告问题才是它的职责。
规范的符合性测试集(conformance/,每个版本一个文件,与架构文件完全一致)会在测试套件中运行:每个用例都明确给出验证器必须得出的结论,因此库的实现不会在不知不觉中偏离规范。
API
validate(doc: unknown): {
valid: boolean;
schemaVersion: string | null;
errors: string[]; // what makes it invalid
notes: string[]; // true, and not a fault
}
supportedVersions(): string[]
toCsv(doc, { delimiter? }): string
fromCsv(text, { delimiter?, generatedAt?, version?, baseCurrency? }): Document
netWorth(doc): {
byCurrency: { currency, assets, liabilities, net }[]; // decimal strings
oldestAsOf: string | null;
unvaluedHoldingIds: string[];
valuedHoldings: number;
}
fromCsv 接受 generatedAt,而不是读取时钟,因此相同的输入始终会生成相同的字节——这样转换后的文件才能进行差异比较或提交。
退出代码
0 表示有效,1 表示无效,2 表示命令有误。诊断信息输出到 stderr,结果输出到 stdout,因此可以通过管道传递转换结果,同时仍能清晰阅读警告。
许可证
Apache-2.0,与规范相同。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。