我想给 MarginDeck 加一些 AI 功能。比如用一句话记下一笔成本,或者看完报表后,接着问一句:“这个月收入涨了,为什么利润反而少了?”

MarginDeck 是我做的一款 Mac 应用,用来记录多个产品的收入、成本和分摊,查看各个产品的经营情况。它已经有这些数字,也有计算规则。接下来要解决的是,用户怎样更方便地把记录填进去,又怎样继续追问这些数字。

这次做 1.6.0,我选择先接入 MCP,让用户在 Claude 或 Codex 里完成一部分操作。

不过,开始做的时候,我对 MCP 的机制并不太了解。我知道它能让 AI 调用工具,但本地应用怎么变成一个“Server”,客户端为什么还要安装,安装之后又为什么要批准连接,这些都是做的时候才慢慢分清的。

我想让用户接着用手上的 AI

最初列出来的需求很具体:记一笔收入、记一笔成本、新建产品、调整成本分摊、查某个月或某年的利润,最好还能导出一张经营概览图。

这些需求有两部分。把“服务器每月 20 美元”整理成记录,或者解释几个月的变化,适合在对话里完成;决定这笔成本计入哪个月、分给哪个产品、是否已经保存,则要沿用 MarginDeck 的规则。

如果在 App 里做聊天界面,我还需要处理模型接入、对话记录和调用费用。用户可能已经在用 Claude 或 Codex,也已经习惯在里面处理自己的事情。我想先试试把 MarginDeck 的能力接过去。

这样,用户可以在一段对话里连续做几件事:先记录成本,再查产品利润,最后让助手帮忙整理需要检查的项目。MarginDeck 负责账本和计算,AI 客户端负责这段对话。

这也是我选择 MCP 的理由。对这个版本来说,先把已有功能开放给外部助手,比从头做一套 App 内聊天体验更符合需求。

先把 MCP 里的几个角色分清

MCP 的全称是 Model Context Protocol。理解这次接入,只需要先看它提供工具的部分:一个程序告诉 AI 应用自己有哪些工具、每个工具需要什么参数,以及执行后会返回什么。

协议里有三个容易混在一起的名字:

名称 在这里指什么
Host,宿主 用户打开的 AI 应用,比如 Codex 或 Claude 桌面应用
Client,客户端组件 宿主内部负责连接某个 MCP 服务的部分
Server,服务程序 提供查询或操作工具的程序,这里是 MarginDeck 提供的 MCP 接口

平时说“在客户端里配置 MCP”,通常指的是整个 AI 应用;协议里的 Client 则是它内部的一部分。Server 可以运行在本机,也可以运行在远程机器上。MCP 官方架构说明对这些角色有更完整的解释。

Codex 和 Claude 分别包含模型交互与 MCP 客户端组件,各自连接同一套 MarginDeck 工具接口;工具结果返回各自的对话。

图 1:把两个宿主放在一起看,中间的工具发现、传参、执行和返回结果是相同的一套过程。每个客户端仍然单独建立连接、获得授权。

图里的“模型交互”是逻辑关系。模型可能由云端服务提供;本机运行 MCP 服务,不代表发送给 AI 的内容也都留在本机。

以“查询番茄钟 8 月利润”为例,助手需要先知道 MarginDeck 提供了哪些工具,再找到对应产品,带着年月等参数发出调用。MarginDeck 返回收入、成本和估算贡献利润后,助手再把结果整理成人能读懂的回答。客户端还可能先要求用户允许这次工具调用。

如果产品名不明确,或者只说了“帮我记一下服务器费用”,对话还需要继续。金额、币种、周期和归属都没说清楚时,不能因为句子听起来完整,就当成一条完整记录。

Codex 和 Claude 在这里有很多重复的工作:组织对话、使用模型、发现工具、发出调用、解释结果。MarginDeck 可以提供同一套工具,复用自己的业务逻辑。但两者的安装入口、配置文件和授权界面各有区别,不能只测试其中一个,就默认另一个也能用。

MarginDeck 里实际是怎样接起来的

MarginDeck 1.6.0 采用本机连接。客户端和 App 要在同一台 Mac 上,App 需要运行并开启“AI 连接”。

对客户端,主要入口是 stdio:客户端启动名为 MCPHeaders 的辅助程序,通过它的标准输入、标准输出交换协议消息。这个辅助程序再把请求转给 MarginDeck 的本机 HTTP 接口。stdio 和 HTTP 都是传递消息的方式;使用 HTTP,也不意味着服务一定在公网。这里引用的 MCP 2025-06-18 版传输说明分别描述了这两种方式。

MarginDeck 的本地调用路径:AI 客户端通过 stdio 辅助程序访问 App 的本机接口;凭据由签名校验的 XPC 通道取得;查询复用计算服务,写入先形成草稿,用户审核保存后才进入本地账本。

图 2:这是 MarginDeck 当前的实现。stdio、凭据与本机 HTTP 之间的连接由辅助程序处理,财务计算和正式保存仍在 App 中完成。图中省略了输入配对码的界面步骤。

图里的 MCPAgent 是另一个后台辅助程序。它通过 macOS 的进程间通信机制 XPC 核验连接身份、提供连接凭据,并与 App 的授权状态衔接。这条通道和传送财务工具请求的路径分开。普通用户不需要填这些凭据,安装时也不用复制一串长期有效的密钥。

这层适配保留了 App 里已有的计算和保存逻辑。我不希望 MCP 里算出的估算贡献利润,和打开 Dashboard 看到的结果用两套口径。这里的估算贡献利润,是已记录收入减去按扣费计划计入该期间的成本,用来观察产品经营情况,不是会计或税后净利润。

查询相对直接。批准“允许读取财务报告和产品名称”后,get_profit 可以查产品组合或单个产品的月度、年度结果,也可以查单个产品截至指定月份的累计结果。需要继续解释时,再获取相应明细。

准备记录还需要“允许提出待我确认的记录”。比如新增成本,工具先准备草稿;字段缺失时,返回还需要哪些信息。助手补齐之后,才能提交到 App 等待审核。用户在 MarginDeck 核对并保存,记录才正式入账。六位配对码和逐笔审核是 MarginDeck 的产品设计,不是 MCP 协议要求所有服务采用的步骤。

1.6.0 的工具名是 commit_draft,返回成功表示已提交审核。是否保存,要通过 get_operation 查询,不能看到调用结束就回答“已经记好了”。

下面按用途列出工具。表中的“读取”对应“允许读取财务报告和产品名称”,“提出记录”对应“允许提出待我确认的记录”;后者不允许助手直接保存正式记录。

工具 做什么 所需权限
get_status 检查连接状态,需要批准时返回配对码 配对前可调用,不返回财务记录
list_products、list_costs、get_cost 查找产品和成本,取得后续操作需要的编号与详情 读取
get_profit、get_report_details 查询估算贡献利润及报告明细 读取
export_financial_snapshot 把当前连接最近查询的报告生成 PNG 读取
prepare_product、prepare_revenue、prepare_cost、prepare_cost_allocation 准备产品、收入、成本或分摊变更草稿 提出记录
get_draft、update_draft、cancel_draft 查看、补全或取消草稿 提出记录
commit_draft 把完整草稿交给用户审核 提出记录
get_operation 查询审核后的保存结果,或确认丢失回复的操作 读取

完整走完“准备 → 审核 → 查询结果”的流程,需要同时开启两项权限。工具不会绕过 App 原有的 Free/Pro 限制。

接通之后,花时间的是这些地方

安装成功和批准访问,是两件事

测试时,我见过客户端显示 Connected,但 MarginDeck 里还在等待批准。也遇到过已经启用了 MCP,新的对话却说找不到工具。

从使用者的角度看,这很容易理解成“明明连上了,怎么还不能用”。实际上,中间至少有配置已保存、工具可发现、当前连接已批准这几个状态。

现在我把 get_status 放在第一次使用的步骤里。它可以告诉用户当前状态;需要配对时,返回六位码。财务读取仍然需要用户批准。

安装方式也重新分开了。Claude 桌面应用使用 .mcpb 扩展包;Claude Code 命令行使用安装命令;Codex 有自己的命令和配置。给 Claude Code 安装一次,不等于给 Claude 桌面应用也装好了。

.mcpb 解决的是打包和安装:把辅助程序及启动信息交给宿主。它不会替用户完成 MarginDeck 里的授权。MCPB 格式支持打包编译后的可执行程序,所以用户不用为了这个连接额外安装 Python 或 Node.js。

五分钟的授权,对日常使用太短了

早期版本里,批准的连接只有五分钟有效。测试时会碰到刚查完报表、换个问题,就得重新批准的情况。我后来把这项限制改为跟随 MarginDeck 的运行周期。

现在要分开看两个时间:六位配对码仍然两分钟有效;批准后的连接最长可以维持到 MarginDeck 完全退出。用户关闭 AI 连接或撤销授权,也会让它失效。只关 MarginDeck 窗口不算完全退出。

对于前面介绍的 stdio 入口,批准对应的是 MCPHeaders 辅助进程取得的连接凭据。凭据只保存在进程内存中;同一进程会复用已批准的连接,新启动的辅助进程需要重新配对。这不是对某次安装的永久授权。

例如,在同一个 Claude Code 进程里连续查询、准备记录,只要原连接仍有效,就不需要再次配对。退出后重新运行 claude,新进程启动的辅助程序需要重新批准。完全退出再启动 Claude 桌面应用、重新启动扩展进程时,也需要重新批准。仅在桌面客户端里新建聊天,要看它是否复用原来的辅助进程,不能只凭“新聊天”三个字判断。

安装配置会继续保留,所以重新配对通常不需要重新执行安装命令。

退出后为什么还提示已有连接

另一类问题出现在退出和再次启动时:界面提示已有后台连接,但活动监视器里只找到一个 MarginDeck。图 2 中的 MCPAgent 有单独的后台注册;macOS 中已注册的后台项目和正在运行的 App 进程,并不能简单画等号。

这部分后来补了退出清理和安全恢复。恢复时先检查旧连接的身份、安装位置和占用状态;核实不了时,再让用户明确选择替换。把“恢复”和“替换”分开,也比一律要求用户去找另一个进程更容易操作。

工具里的字段名,会影响助手怎样解释财务数据

有一次查询组合利润,助手把共享成本列成了“未归属成本”。金额未必算错,但说法让人以为还有一笔账没处理完。

MarginDeck 的共享成本,是刻意留在产品组合层面的开销。比如一项供整个业务使用的服务,你可以选择不分给某个产品。待分摊成本则是另一种情况,不能混成同一个概念。

因此,接口返回和工具说明里要明确区分它们,还要告诉助手:这些金额已经包含在组合总成本里,不要再扣一次。仅在界面上改一个标签,助手仍然可能读着旧字段得出原来的说法。

导出的图片也遇到过很直观的问题:金额显示出一长串小数,只有一个月的数据,却还画了一根柱子。后来我把金额统一显示到两位小数,加上千位分隔;查询范围只有一个月时,改成收入、预计成本和估算贡献利润的数字摘要,多个月才展示月度柱状图。显示时的舍入不改变底层计算结果。

想试一下,可以从一笔成本开始

下面对应 MarginDeck 1.6.0 的使用方式,需要 macOS 14 或更新版本。AI 连接不另收费,沿用 App 的 Free/Pro 限制;免费版支持一个未归档产品,跨产品分摊等 Pro 功能仍需购买。Claude 或 Codex 的账号和服务费用由对应服务商处理。

文中的产品和金额只是示例,请换成自己的记录。MarginDeck 支持从 RevenueCat、Stripe 只读同步收入,经审核应用后保存。已经保存的收入、成本,包括从这些来源导入的收入,都不要再通过 AI 重复录入。

1. 选择正在用的客户端

在 MarginDeck 左侧边栏选择“AI 连接”,点“开启”。

使用环境 在 MarginDeck 里做什么 随后在哪里使用
Claude 桌面应用 选择 Claude Desktop,保存 .mcpb 扩展包 在 Claude 桌面应用安装扩展后,新建对话
Claude Code 命令行 复制安装命令,在终端执行 在终端运行 claude,打开新会话
本机 Codex 复制安装命令,在终端执行 重启正在使用的 Codex 客户端,新建会话

Claude 桌面应用的手动安装入口是“设置 → 扩展 → 高级设置 → 安装扩展…”。官方安装说明有对应步骤。

命令方式需要先装好对应的命令行工具。如果选择 App 中的“手动配置”,Codex 的用户配置文件是 ~/.codex/config.toml,Claude Code 是 ~/.claude.json。它们都是电脑上的配置文件,不是要粘贴到聊天里的内容。可分别参考 Codex MCP 配置和 Claude Code MCP 配置。

这里使用的是同一台 Mac 上的本地连接。MarginDeck 1.6.0 没有提供供网页版或手机直接访问的公网 MCP 服务。

2. 获取配对码,批准当前连接

在助手里说:

调用 MarginDeck get_status,告诉我连接状态;如果需要批准,请显示六位配对码。

把返回的代码输入 MarginDeck,选择权限并批准,再回到对话里说“已批准,请继续”。只查报表,可以只开“允许读取财务报告和产品名称”;还想准备记录并查回保存结果,就同时开启“允许提出待我确认的记录”。

这一步也会提醒用户:账本存在本机,但授权助手读取的内容,可能交给 AI 服务商处理。

3. 准备一笔记录,回 App 核对

假设已经有一个叫“番茄钟”的产品,可以这样说:

给番茄钟新增一笔服务器成本,每月 20 美元,首次扣费日期为 2026 年 8 月 1 日,100% 归给番茄钟。缺少的信息先问我,准备好后提交审核。

助手可能继续确认分类或其他缺少的信息。提交后,在 MarginDeck 核对名称、金额、周期、日期和归属,再保存。

4. 查询并继续追问

查询番茄钟 2026 年 8 月的收入、计划成本和估算贡献利润。再看一下成本明细。

如果想解释变化,可以接着问具体哪项收入或成本变了;记录里没有的信息,例如用户流失原因,仍需要自己补充。

这条流程跑通后,再试着问整个产品组合,或者比较两个月。遇到缺少数据的地方,先把那笔记录查清楚,再让助手继续分析。

想试一下,可以从 MarginDeck 官网下载,安装 1.6.0 或更新版本,再按上面的步骤连接。