Personal Expense Tracker MCP
Personal Expense Tracker MCP
项目简介
Personal Expense Tracker MCP 是一个用于追踪个人支出的简单本地 MCP 服务器。
它把支出数据存储在本地的 CSV 文件中。
该服务器为 MCP 客户端提供五个功能明确的工具:
添加一项新支出
列出已保存的支出
生成支出汇总
更新已有支出
删除已有支出
本项目设计得简单且易于在本地运行。
不需要银行账户或外部 API。
Related MCP server: Expense Tracker MCP
环境要求
开始之前,请确保你已安装以下环境:
Node.js 20 或更新版本
npm
Git
检查 Node.js
node --version检查 npm
npm --version检查 Git
git --version安装
1 克隆仓库
git clone https://github.com/MohammadYousef-001/Personal-Expenses-Tracker.git2 进入项目目录
cd Personal-Expenses-Tracker3 安装依赖包
npm install等待 npm 完成依赖包的安装。
数据文件
支出数据存储在本地文件中:
data/expenses.csvCSV 文件使用以下列:
id,amount,category,date,description不要更改这些列的名称。
运行 MCP 服务器
运行以下命令启动服务器:
npm run dev服务器的 MCP 通信使用标准输入和标准输出。
它是一个本地服务器,不需要 Web 端口。
运行 MCP Inspector
MCP Inspector 是手动测试这些工具的最简单方式。
运行:
npm run inspect浏览器窗口会打开 MCP Inspector。
如果没有自动打开,请使用终端中显示的 URL。
在 Inspector 中:
连接到本地服务器
打开 Tools 部分
选择一个工具
输入输入内容
点击 Execute Tool
检查结果
可用工具
工具 | 作用说明 | 主要输入 |
| 向 CSV 文件添加一条新支出 | amount category date description |
| 列出已保存的支出,并可按条件筛选 | month category |
| 计算某个月的支出总和 | month |
| 更新一条已有支出 | id 以及至少一个支出字段 |
| 删除一条已有支出 | id |
工具 1 add_expense
使用 add_expense 保存一条新支出
输入参数
amount
支出的金额
必须是一个正数
category
支出类别
例如
groceries
transport
bills
shopping类别会小写保存,这样类别名称就能保持一致
date
支出的日期
必须使用
YYYY-MM-DD例如
2026-08-12日期还必须是真实存在的日历日期
下面的示例是无效的
2026-99-99description
可选填的支出说明
示例
{
"amount": 25,
"category": "groceries",
"date": "2026-08-12",
"description": "milk and bread"
}一个成功的请求会把支出添加到
data/expenses.csv工具 2 list_expenses
使用 list_expenses 查看已保存的支出
不添加过滤条件时
{}按类别过滤
{
"category": "groceries"
}按月份过滤
{
"month": "2026-08"
}同时使用两个过滤条件
{
"month": "2026-08",
"category": "groceries"
}月份必须使用
YYYY-MM月份必须在 01 和 12 之间
以下写法是无效的
2026-99工具 3 get_spending_summary
使用 get_spending_summary 查看支出的汇总信息
示例
{
"month": "2026-08"
}结果可以包括
所选月份
支出总金额
支出笔数
每个类别的支出合计
结果示例
month: 2026-08
total amount: 150
expense count: 4
category totals:
groceries: 80
transport: 30
bills: 40实际的值取决于 data/expenses.csv 中的数据
常见用途示例
添加一笔支出
I spent 25 on groceries today以下提示词可以用来创建这种请求:
add_expense查找支出
show my grocery expenses for this month以下提示词可以用来创建这种请求:
list_expenses检查支出情况
how much did I spend this month以下提示词可以用来创建这种请求:
get_spending_summary输入校验
本项目会在使用工具之前对工具输入进行校验
无效输入示例:
负数金额
金额为零
日期格式错误
日期不存在
无效月份
类别过长
描述过长
无效输入会在保存之前被拒绝
测试 Schema
运行
npm run check:schema如果一切正常,应该会显示
All expense schemas are valid.故障排查
问题 1 packages 缺失
如果出现提示找不到某个包或模块的错误信息,运行
npm install然后再去操作
npm run dev问题 2 MCP Inspector 无法启动
先确认依赖包已经安装
npm install再运行
npm run inspect如果旧 Inspector 进程仍在运行,请按 Ctrl+C(macOS / Linux)或 Ctrl+C(Windows)
Ctrl + C停掉旧进程后再操作 Inspector
问题 3 TypeScript 或 schema 错误
运行
npm run check:schema如果一切正确,你应该可以看到
All expense schemas are valid.如果出现错误,请一次性终端中显示的文件名和行号
修复错误后再启动 Inspector
问题 4 无效日期
日期必须符合
YYYY-MM-DD有效示例
2026-08-12无效示例
2026-99-99问题 5 没有返回任何支出
检查文件
data/expenses.csv确保在 CSV 表头下面有数据行
如果文件中只有表头,那么返回空结果是正常的
项目结构
需要注意的是
Personal-Expenses-Tracker/
│
├── data/
│ └── expenses.csv
│
├── docs/
│ ├── design.md
│ └── threat-model.md
│
├── examples/
│
├── src/
│ ├── index.ts
│ ├── schemas/
│ ├── tools/
│ └── lib/
│
├── SECURITY.md
├── package.json
└── README.md安全
工具输入被视为不可信输入
该项目在重要操作之前会对输入进行校验
支出文件的只由本应用掌控
返回给 MCP 客户端的错误保持简短以免泄露,没有必要
更详细的错误信息会保留在本地终端方便调试
这些支出工具不需要 NTP网络请求MPTCP
更多安全主题的信息见
SECURITY.md项目范围
这是个小型的本地个人支出追踪项目
它不包含:
银行账户连接
自动银行数据导入
用户登录
云数据库
图形界面应用
财务预测
核心目标是为本地支出记账提供一组简单 MCP
使用许可证
本项目使用 MIT 许可证
许可协议见 LICENSE
Available Tools
5 toolsadd_expenseC
add a new expense
| Name | Required | Description | Default |
|---|---|---|---|
| date | Yes | The expense date in YYYY-MM-DD format | |
| amount | Yes | The expense amount, up to 1000000 | |
| category | Yes | The normalized expense category | |
| description | No | A short optional description of the expense |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false, so the description does not need to restate that this is a write operation. However, it adds no behavioral context beyond what the name implies—it simply restates 'add a new expense', which is effectively a tautology. There is no mention of side effects, idempotency, validation rules, or what happens on conflict, making it entirely uninformative for behavioral expectations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely short (five words), which could be seen as concise, but it is under-specified rather than efficiently structured. It lacks any front-loaded information beyond a bare verb phrase. There is no hierarchy of information; it is merely a label, failing to earn its place by providing any useful detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With four parameters, three of which are required, and no output schema, the description is completely inadequate. It does not mention required fields, expected input format (though schema covers this), possible side effects, or return behavior. An agent has no way to anticipate the tool's behavior or success criteria beyond the raw schema, making the description insufficient for correct invocation in a meaningful context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema provides 100% coverage of all four parameters, including descriptions for amount, category, date, and optional description. The description adds no parameter-specific meaning, so the baseline score of 3 applies. While the description doesn't harm parameter understanding, it also doesn't supplement the schema or clarify relationships between parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'add a new expense' conveys a clear verb (add) and resource (expense). It is distinct from sibling tools like update_expense and delete_expense simply by the verb 'add', so an agent can infer its core purpose. However, it does not explicitly distinguish itself from potential overlap or specify any scope (e.g., personal vs. shared), so it stops short of full differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides no guidance on when to use this tool versus alternatives. It does not mention prerequisites, context, or when 'add' is preferred over 'update' or other siblings. An agent is left to infer usage purely from the tool name and schema, which is insufficient for a choice among several expense-related tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
delete_expenseADestructive
delete an existing expense by ID
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The ID of the expense |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare destructiveHint=true and readOnlyHint=false, indicating a destructive write operation. The description adds no further behavioral context beyond restating the action; it does not mention side effects, irreversibility, or the nature of the response. It does not contradict the annotations, so it meets the baseline but adds little value.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, concise sentence that clearly communicates the action and target. It is front-loaded and contains no extraneous words, achieving appropriate brevity for a simple operation.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter delete operation with no output schema, the description covers the essential purpose and key parameter. It does not describe return values or error conditions, but these are often standard for delete operations and are not critical given the tool's simplicity. The description is complete enough for an agent to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema fully covers the single parameter 'id' with a description, and the tool description also mentions 'by ID', but adds no additional semantic detail beyond what the schema provides. With 100% schema description coverage, the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description 'delete an existing expense by ID' clearly states the action (delete) and the resource (expense), and specifies the identifier used. It is unambiguous and easily distinguishes from siblings like add_expense, update_expense, and list_expenses through the verb and resource.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implicitly conveys usage by the verb 'delete', but it does not explicitly state when to use it versus the alternatives, nor does it mention any constraints such as required existence or irreversibility. The context is clear enough for an agent to infer usage, but no explicit guidance or exclusions are provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_spending_summaryCRead-only
get a spending summary
| Name | Required | Description | Default |
|---|---|---|---|
| month | No | A calendar month in YYYY-MM format |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is fully covered and the bar is lower. The description adds only the marginal notion that this returns an aggregated summary, but does not disclose what gets aggregated or scoped. It does not contradict the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The phrase is four words with zero waste and a front-loaded verb, which is efficient. However, the brevity stems more from under-specification than from disciplined trimming, so it does not reach the level of a well-packaged, substance-complete definition.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with one optional parameter and annotations covering safety, this is a simple tool, but the description omits what the summary contains and what happens when month is omitted. With no output schema and no descriptive context, an agent still cannot predict the return shape or default time scope.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% — the single month parameter is fully documented with the description 'A calendar month in YYYY-MM format' and a regex pattern. Per the rubric, the baseline is 3 when the schema does the heavy lifting, and the description adds nothing beyond it.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a verb ('get') and a resource ('spending summary'), and it distinguishes itself from the CRUD siblings (add/update/delete/list_expenses) as the aggregation view. However, it essentially restates the tool name ('get_spending_summary' → 'get a spending summary') and adds no new information about what the summary contains, so it sits at minimum viable rather than distinctly helpful.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to choose this tool vs its siblings. There is no mention of how a summary differs from list_expenses, when the optional month should be supplied, or what default scope applies if month is omitted. With four sibling tools, this leaves the decision entirely to the agent's inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_expensesBRead-only
list expenses with optional filters
| Name | Required | Description | Default |
|---|---|---|---|
| month | No | A calendar month in YYYY-MM format | |
| category | No | The normalized expense category |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, so the tool is known to be safe. The description adds no behavioral context beyond 'list expenses'—nothing about pagination, sorting, default behavior (e.g., what happens if no filters are provided), or response format. Given annotations cover safety, the description fails to enrich the agent's understanding of how the tool behaves.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, short sentence with no redundant words or filler. It is efficiently front-loaded with the core action ('list expenses') and the key feature ('optional filters'). Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's low complexity (2 optional params, no nested objects, no output schema) and strong annotations, the description is minimally adequate. However, it does not explain whether the filters can be combined, what the response looks like, or if there are limits. An agent would have to infer these from the schema and typical conventions. It is complete enough for a basic call but leaves room for ambiguity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both month and category are fully described in the schema. The description's phrase 'optional filters' adds no extra meaning about semantics like combined filtering or format. The baseline is 3 because the schema carries the full load; the description offers no additional insight.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists expenses and mentions optional filters, which maps to the parameters. It is distinct from the siblings (add/update/delete/spending summary) since 'list' is unambiguous. However, it does not explicitly name the filter dimensions (month, category) or contrast with the summary tool, so it's specific but not maximally differentiated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is no guidance on when to use this tool versus alternatives. The description does not mention that get_spending_summary is for aggregated data, nor does it indicate that list_expenses is for raw expense details. The usage context is only implied by the verb 'list' and not explicitly stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_expenseB
update an existing expense by ID
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes | The ID of the expense | |
| date | No | The expense date in YYYY-MM-DD format | |
| amount | No | The expense amount, up to 1000000 | |
| category | No | The normalized expense category | |
| description | No | A short optional description of the expense |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already indicate readOnlyHint=false and destructiveHint=false, so the mutation nature is expected. The description adds that it updates an existing expense by ID, implying the target must exist. However, it does not disclose whether it performs a partial update (only provided fields) or a full replacement, nor what happens if the ID is not found. Given the annotations, the additional information is minimal but not contradictory.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, compact sentence that front-loads the core action. There is no filler or redundant information. It earns its place with zero waste, making it exemplarily concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a mutation tool with 5 parameters, no output schema, and only basic annotations, the description is insufficiently complete. It does not explain the update semantics (partial vs. full), error behavior for missing ID, or what the tool returns. While parameters are covered by the schema, key operational context is absent, leaving an agent to guess.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% since every parameter (id, date, amount, category, description) has its own description in the schema. The tool description adds no parameter-specific details beyond what the schema already provides. The baseline of 3 is appropriate given the high schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb 'update' and identifies the resource 'expense' and the key 'by ID'. It clearly distinguishes from sibling tools (add, delete, list, summary) by indicating this modifies an existing record. The purpose is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No guidance is given on when to use this tool versus alternatives, such as using add_expense for new expenses or delete_expense for removal. The description relies on the tool name and context, but does not explicitly state conditions or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
5 tool updates
v0.1.0- First observed
add_expense - First observed
delete_expense - First observed
get_spending_summary - First observed
list_expenses - First observed
update_expense
TDQS
Scored across 5 tools
Each tool has a clearly distinct purpose: add, update, delete, list, and summarize expenses. There is zero overlap, making it easy for an agent to select the right tool for the task.
All tools follow the consistent verb_noun pattern (add_expense, update_expense, delete_expense, list_expenses, get_spending_summary). This creates a predictable and uniform naming convention.
With only 5 tools, the server is tightly scoped for a personal expense tracker. Each tool serves a necessary function without unnecessary bloat, and the count is well within the ideal range.
The toolset covers full CRUD for expenses (add, update, delete, list) plus a summary function. A minor gap is the lack of a direct 'get_expense' by ID, but the list tool with filters can likely retrieve individual expenses, so it's a workable limitation.
Maintenance
Related MCP Connectors
- ManiloOAuthapp.manilo
Log, query, and edit expenses, budgets, and accounts in Manilo from any MCP-compatible AI assistant.
- ManiloOAuthapp.ledgy.api
Log, query, and edit expenses, budgets, and accounts in Manilo (formerly Ledgy) from any MCP-compatible AI assistant.
Track expenses from your AI chat: log, categorize, monthly CSV reports. All data is local.
Log, query, and edit expenses, budgets, and accounts in Ledgy from any MCP-compatible AI assistant.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceEnables users to track personal expenses through natural language interactions with comprehensive category support and financial summaries. Provides both local and remote MCP server options with SQLite storage for fast expense management operations.-
- FlicenseNot gradedqualityDmaintenanceMCP server for tracking expenses with local SQLite storage. Provides tools to add, list, and summarize expenses by category.-
- FlicenseAqualityCmaintenanceMCP server for managing personal expenses, enabling users to add, list, and summarize expenses by category, with data stored in a local SQLite database.3-
- FlicenseNot gradedqualityBmaintenanceEnables managing and analyzing personal expenses through MCP tools, including adding expense records, listing expenses within date ranges, and summarizing spending by category, with expense categories exposed as an MCP resource.-