ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

CodeBurn MCP Server 实现指南:基于 stdio 的 `codeburn mcp` 用量与节省分析服务

CodeBurn MCP Server 实现指南:基于 stdio 的 `codeburn mcp` 用量与节省分析服务 CodeBurn MCP Server 实现指南基于 stdio 的codeburn mcp用量与节省分析服务【免费下载链接】codeburnFree, local tool to track AI coding token usage and cost across 37 tools and agents (Claude Code, Cursor, Codex, Gemini and more), by model, project, and task. npx codeburn项目地址: https://gitcode.com/gh_mirrors/co/codeburnCodeBurn 是一款在本机追踪 AI 编码 Token 用量与成本的工具覆盖 Claude Code、Cursor、Codex、Gemini 等 37 款工具与 Agent支持按模型、项目、任务维度统计。本文围绕仓库中的 CodeBurn MCP Server 设计规格 与 实现计划 两份核心文档完整讲解codeburn mcp这条 stdio MCP 命令的设计动机、架构决策、工具契约、隐私脱敏机制与性能优化手段并结合 src/mcp/server.ts、src/mcp/redact.ts、src/mcp/tables.ts 等真实实现代码逐层展开。读完本文你将理解如何把本机聚合的 AI 编码开销数据以 MCP 工具的形式暴露给 Claude Code、Cursor 等 AI Agent掌握get_usage/get_savings两个工具的完整参数契约、脱敏与并发合并原理以及从status --format menubar-json中抽取复用聚合逻辑的重构路径。一、背景与目标为什么需要 MCP ServerCodeBurn 已经在本地聚合了丰富的 AI 编码用量/成本数据按任务task、模型model、项目project、提供方provider归因同时包含 retry tax重试税、routing waste路由浪费、optimize findings优化建议、365 天历史曲线等。设计规格 codeburn-mcp.md 明确指出MCP 服务器的目标是在此基础上增加一条面向 AI Agent 的数据通道让 Agent 在对话过程中直接回答我的 Token 花在了哪里和我怎样才能花得更少这两类问题而不是由用户手动切换 CLI 查看。值得强调的是规格文档中的定位说明MCP 属于产品/差异化价值而非下载量手段——它真正的价值在于把竞品没有暴露的数据retry tax、routing waste、one-shot rate、任务归因以 Agent 可消费的形式开放出来。因此该功能被设计为统一用例同一套工具同时服务实时自我优化与历史数据分析两种场景统一输出契约每个工具既返回可直接展示的markdown 表格又返回同等的结构化 JSONstructuredContent内嵌而非独立包不新增第二个 npm 包而是作为现有 CLI 的codeburn mcp子命令复用既有的聚合管线。二、架构总览常驻进程 stdio 传输2.1 进程模型为什么必须是常驻进程计划文档中有一条被标记为BLOCKER的架构决策MCP 服务必须作为常驻的进程内in-process服务器运行通过StdioServerTransport与宿主通信绝不能采用每次调用都 exec 一个进程的模式。原因在于 CodeBurn 的解析器在进程内维护了一个 180 秒 TTL 的会话缓存见 src/parser.ts。实测表明若每次工具调用都启停进程--period all即使在热状态下也需要约17.6 秒——缓存完全无法跨调用复用。常驻进程则让一次解析结果在缓存 TTL 内被多次工具调用共享。2.2 模块划分实现计划把整个功能拆成四个新模块 一处既有模块改造模块职责现状src/usage-aggregator.ts从main.ts的status处理器中抽取聚合逻辑暴露buildPeriodData与buildMenubarPayloadForRange已实现src/mcp/redact.tspseudonym()redactProjectNames(payload, include)只做隐私脱敏已实现src/mcp/tables.tsmarkdown 渲染器renderSummaryTable/renderBreakdownTable/renderSavingsTable只做展示已实现src/mcp/server.tscreateServer(deps)工具注册与处理器、可注入聚合器与startStdioServer(version)加载定价 连接 stdio已实现src/main.ts引入聚合器、重构statusmenubar 分支、新增.command(mcp)已实现2.3 技术栈与依赖计划文档锁定的技术栈为TypeScriptESMtype: moduleNode ≥ 22.13、commander、modelcontextprotocol/sdk^1.29v1 线、zod、tsup、vitest。当前仓库的 package.json 与 tsup.config.ts 均已落地dependencies中新增modelcontextprotocol/sdk: ^1.29.0与zod: ^3.25.76tsup.config.ts新增external: [modelcontextprotocol/sdk, zod]。规格文档特别强调了两点约束实施时务必注意zod 必须显式声明为直接依赖它是 SDK 的 peer dependency当前 lockfile 里原本没有不能依赖传递引入SDK 大版本必须钉死在 v1存在一个 import 路径不同的、单独命名的 v2 包^1.29.0才能保证modelcontextprotocol/sdk/server/mcp.js与/server/stdio.js这些 v1 路径有效。external的作用是让 SDK 与 zod不进内联进dist/main.js。原配置splitting: false且无external会把所有依赖打进产物如果不 externalize动态 import 会把 SDK数 MB直接内联进dist/main.js。externalize 之后dist保持轻量且files: [dist]意味着被 external 的依赖必须出现在运行时dependencies中——这也是上文两条约束的最终原因。三、聚合器抽取为 MCP 复用status的聚合管线3.1 从main.ts搬到共享模块buildPeriodData原本是 src/main.ts 中的私有函数负责把ProjectSummary[]折叠成PeriodData成本、调用数、会话数、输入/输出 Token、缓存读写 Token、模型与任务分类明细等。实现计划的 Task 2 要求将其原样搬入新模块src/usage-aggregator.ts并导出同时补齐它引用的依赖如getShortModelName来自 src/models.ts直到npx tsc --noEmit通过。真实代码中该函数已位于 src/usage-aggregator.ts并扩展了大量与 durable cache、工作流洞察相关的字段。3.2buildMenubarPayloadForRange唯一的昂贵调用被隔离Task 3 更进一步把status --format menubar-json分支里main.ts:485–757的内联聚合块从const now new Date()到breakdownsIIFE整体搬进聚合器改为一个返回 payload 而非打印的函数export type PeriodInfo { range: DateRange; label: string } export type AggregateOpts { provider?: string project?: string[] exclude?: string[] daysSelection?: { range: DateRange; label: string; days: Setstring } | null optimize?: boolean claudeConfigSourceId?: string | null timeline?: boolean } export async function buildMenubarPayloadForRange( periodInfo: PeriodInfo, opts: AggregateOpts {}, ): PromiseMenubarPayload { /* ... */ }签名在真实实现中扩展了claudeConfigSourceId与timeline两个选项前者用于 Claude 配置选择器后者用于跳过桌面端不需要的buildGranularHistory时间线构建。关键点在于optimize布尔开关scanAndDetect来自 src/optimize.ts是整条管线中唯一昂贵的调用get_usage必须跳过它。这也是规格文档中第二个被标记为BLOCKER的决策——optimize约占整体成本的 70%若不拆分每个工具调用都要为它买单。前置条件约定该函数假设loadPricing()已经执行过status命令在main.ts调用MCP 服务在startStdioServer启动时调用函数内部不得再次调用loadPricing()。奇偶校验重构后status --format menubar-json输出必须与重构前逐字节一致由既有测试 tests/cli-status-menubar.test.ts 充当 parity guard另新增 tests/usage-aggregator.test.ts 直接单测聚合器例如optimize: false时返回零成本 payload 且不触发scanAndDetect。四、工具面get_usage与get_savings4.1 周期枚举映射MCP 面向 LLM 的周期名与 CodeBurn 内部周期名存在映射关系定义在 src/mcp/server.tsconst PERIOD { today: today, last_7_days: week, last_30_days: 30days, month_to_date: month, last_6_months: all, } as const const periodSchema z.enum([today, last_7_days, last_30_days, month_to_date, last_6_months])注意last_6_months → allCodeBurn 的all周期被有意限制为最近 6 个月见 src/cli-date.ts 中ALL_TIME_MONTHS 6的注释因此last_6_months就是 MCP 对外承诺的最大窗口。需要更长窗口的用户应使用 CLI 的lifetime周期或--from/--to但 MCP 工具面不暴露它们。4.2 工具公共契约两个工具均携带注解{ readOnlyHint: true, openWorldHint: false, idempotentHint: true, title }声明 zod 的inputSchema与outputSchema返回形如{ content: [{ type: text, text: markdown table }], structuredContent: 与 outputSchema 匹配的对象 }的CallToolResult。参数校验失败由 zod 自动转为 MCP 协议错误聚合异常则返回isError: true。4.3get_usage用量与成本参数类型默认值说明periodenumtoday周期见上文映射byproject \| model \| task \| provider无不传则输出头条摘要传则按该维度输出一张排序表limitnumberint1–10020breakdown 的行数上限include_project_namesbooleanfalse是否保留真实项目名行为逻辑src/mcp/server.ts不传by头条摘要——成本、调用数、会话数、输入/输出 Token、缓存命中率、one-shot 率外加 Top 5 模型与 Top 5 项目由renderSummaryTable生成传by输出该维度的排序表——project→topProjects、model→topModels、task→topActivities、provider→providers成本映射走buildMenubarPayloadForRange(..., { optimize: false })的廉价路径不做优化扫描空数据calls 0返回友好提示No usage recorded for label yet — run some coding sessions and try again.而非一张全零表格structuredContent携带period、empty、totalscostUSD / estimatedCostUSD / calls / sessions / cacheHitPercent / oneShotRate与可空的breakdown数组。4.4get_savings节省机会参数类型默认值说明periodenumlast_7_days刻意不默认到最慢的last_6_monthsinclude_project_namesbooleanfalse同get_usage行为逻辑src/mcp/server.ts走optimize: true路径运行scanAndDetect深度分析因此比get_usage慢规格文档中约 13s返回三类节省信息优化建议topFindings标题、影响级别、可节省金额重试税retryTax总额 按模型拆分路由浪费routingWaste总节省、基线模型、按模型拆分structuredContent携带optimize、retryTaxUSD、routingWasteUSD。4.5 服务器级instructions两个工具之外McpServer还声明了供 Agent 阅读的全局说明src/mcp/server.ts要点包括get_usage快、get_savings慢项目名默认假名化所有数据只在本机读取last_6_months是最大窗口数字反映最近一次扫描可能滞后当前会话几分钟。五、数据流从工具调用到返回规格文档给出了完整的数据流实现基本与之对应agent tool call → zod inputSchema 校验参数非法 → MCP 协议错误自动 → 按 {kind, period} 进行 in-flight 合并并发调用共享一次扫描 → buildMenubarPayloadForRange(periodInfo, { provider: all, optimize }) → parseAllSessions180s 进程内会话缓存复用 → daily-cache 聚合 / 模型效率 / 优化扫描 → redactProjectNames除非 include_project_names → 渲染 markdown 表格 构造 structuredContent → 返回 { content: [{type:text,text}], structuredContent }失败时 isError: true一个与规格文档的有意偏差需要说明规格要求对 provider 做allSettled级别的逐提供方隔离并输出degraded[]数组但计划文档明确将其推迟到 v1 之外——因为那需要改动所有命令共享的parseAllSessions循环parser.ts:2133风险过高。v1 选择在工具边界统一处理失败isError: true 错误消息并注明单个畸形 provider 中止扫描是与status/menubar 路径共享的既有行为并非本次引入。六、隐私与脱敏默认假名化绝不外泄路径6.1 设计动机MCP 是一个面向可能远程/云端 Agent 的出口面而 CodeBurn 的品牌承诺是数据永不离开你的机器。规格文档将默认哈希项目名标记为BLOCKER决策裸仓库名 带日期开销一旦出网就是泄露。因此默认把所有名称字段替换为稳定假名本地用户若确实需要真实名称可在单次调用中显式传入include_project_names: true。6.2 实现加盐 SHA-256 稳定假名src/mcp/redact.ts 的实现比计划更完善基础假名pseudonym(name) project-6hex但哈希前会拼接一个进程级随机盐randomBytes(32)盐持久化在~/.config/codeburn/.mcp-salt权限0o600。盐的存在让同一项目在不同机器上产生不同假名避免跨机反推领域分隔branch-分支名常含 ticket 号、客户名、功能代号、session-会话 ID 是行键需要保持同一会话跨行对齐、pr-PR 行的 URL 与owner/repo#123标签都含仓库名但数字保留——每种标识使用不同前缀 命名空间字符串避免项目 X 与分支 X 哈希相同覆盖范围src/mcp/redact.tstopProjects[].name、topProjects[].id、sessionDetails清空date、models假名化sessionId、topSessions[].project/projectKey/sessionId、byBranch[].branchnull分支保留为null、pullRequests[].url/label以及liveSessions整体剥离MCP 消费方永远不需要它、history.timeline中的sessionSeries与points[].sessions清空绝对路径永不出现payload 本身不含绝对路径脱敏层也不会为其补充。6.3 测试验证tests/mcp-redact.test.ts 覆盖假名稳定性与路径无关性、默认哈希且数字保留、includetrue保留真名、同一项目在topProjects与topSessions中假名一致、同一分支/PR 跨调用假名一致且彼此不同、脱敏后liveSessions不存在等十余个断言。七、表格渲染紧凑、可直接展示的 markdowntests/mcp-tables.test.ts 对应的 src/mcp/tables.ts 是纯展示层三个渲染器共用mdTable辅助函数空表输出_(no data)_占位行renderSummaryTable(p)头条行**Last 7 Days** — $12.50 · 100 calls · 4 sessions、缓存命中率 / one-shot 率 / 输入输出 TokenTop 5 模型与 Top 5 项目两张表。真实实现还增加了未定价模型提示unpricedModels警告行与unpricedModelHint()与估算成本标记markEstimated~ estimated cost图例renderBreakdownTable(p, by, limit)按project/model/task/provider四个维度分别渲染task 维度额外输出 Turns 与 One-shot 列provider 维度按成本降序renderSavingsTable(p)优化建议表Finding / Impact / Saves最多 10 条、重试税表按模型、路由浪费表Model / Overpaid / vs baseline。这些渲染器复用 src/format.ts 的formatCost/formatTokens以及 src/session-count-label.ts 的formatSessionCount与 CLI/TUI 其他界面共享格式化语义。八、性能设计三个层次的成本控制规格文档把性能要求拆为三层全部在真实实现中落地双路径拆分get_usage走廉价聚合跳过scanAndDetectget_savings才承担优化扫描——避免每个工具都付 13s 的税常驻进程 180s 缓存冷启动时startStdioServer会先await loadPricing()随后连接 stdio后续每次工具调用共享进程内解析缓存In-flight 合并coalescingsrc/mcp/server.ts 维护Mapstring, PromiseMenubarPayload键为use|sav 周期。并发调用同一{kind, period}时共享同一次扫描完成即从 Map 移除.finally。Agent 常常并行触发多个工具这正是为它设计的Token 纪律breakdown 以limit默认 20上限 100封顶历史永远只输出汇总 Top-N绝不返回完整 365 天数组。九、错误处理与空状态参数非法→ zod → MCP 协议错误自动无需手写空数据全新安装→isError: false 友好提示不返回零填充表格聚合异常 / payload 形状不匹配→isError: true 明确消息含err.message绝不挂起传输get_usage的 error 分支同时返回兜底的structuredContent全零 totals。十、codeburn mcp命令接线与 stdout 保护10.1 命令注册src/main.ts 注册了子命令program .command(mcp) .description(Run a Model Context Protocol server (stdio) exposing usage savings to AI agents) .action(async () { // stdout MUST carry only JSON-RPC; route stray logs to stderr. console.log ((...args: unknown[]) process.stderr.write(args.join( ) \n)) as typeof console.log const { startStdioServer } await import(./mcp/server.js) await startStdioServer(version) })两个细节值得注意stdout 保护stdout 上只能有 JSON-RPC 报文。聚合路径当前是 stdout 干净的写 stderr但全局preAction钩子与runOptimize中存在 stdoutconsole.log因此第一行就把console.log重定向到 stderr免疫现在或未来任何 stdout 写入。真实实现额外加了一条注释强调只保护console.log不碰process.stdout.write——因为StdioServerTransport正是靠它输出 JSON-RPC动态 import./mcp/server.js通过动态 import 引入使 tsup 将其纳入构建图SDK 与 zod 保持 external同时让 SDK 成为真正的懒加载。10.2 启动路径startStdioServer(version)src/mcp/server.ts的职责await loadPricing()→createServer({ version })→server.connect(new StdioServerTransport())。10.3 冒烟测试计划文档给出了一条不依赖任何 MCP 客户端、直接喂 JSON-RPC 的冒烟命令printf %s\n \ {jsonrpc:2.0,id:1,method:initialize,params:{protocolVersion:2025-06-18,capabilities:{},clientInfo:{name:smoke,version:1}}} \ {jsonrpc:2.0,id:2,method:tools/list} \ | node dist/cli.js mcp 2/dev/null | head -2期望 stdout 输出两行 JSON-RPC result第二行列出get_usage与get_savings且 stdout 无任何非 JSON 噪音。另可用node -e .../class McpServer/.test(...)断言 SDK 未被内联进dist/main.js。十一、测试策略注入聚合器 内存传输tests/mcp-server.test.ts 展示了这套系统的可测性设计——createServer接受可注入的聚合器deps.aggregate测试用InMemoryTransport.createLinkedPair()把 server 与一个真实 SDKClient连起来完全不需要启动子进程工具面listTools恰好返回get_usage/get_savings两个只读工具且get_usage带readOnlyHint: true默认脱敏get_usage { period: today, by: project }的序列化结果不包含real-repo且匹配project-[0-9a-f]{6}include_project_names: true时还原真名空状态calls 0的 payload 返回含no usage的文本失败传播聚合器抛出boom时get_savings返回isError: true且错误文本包含boom。这套模式意味着聚合器、脱敏、渲染、协议四层可以独立演进status输出靠 parity 测试守护MCP 行为靠内存传输测试守护无需真实数据即可回归。十二、实现计划落地路线Task 视角计划文档以任务驱动开发形式给出了 8 个落地步骤当前仓库已全部完成读者可对照源码逐项核对Task内容落地状态以真实源码为准Task 1添加modelcontextprotocol/sdk^1.29.0zod^3.25依赖并在 tsup 中 externalizepackage.jsondependencies、tsup.config.tsexternalTask 2把buildPeriodData从main.ts移入共享模块src/usage-aggregator.tsTask 3抽取buildMenubarPayloadForRangestatusmenubar 分支改调它parity 由 tests/cli-status-menubar.test.ts 守护src/usage-aggregator.ts tests/usage-aggregator.test.tsTask 4项目名默认哈希脱敏 可选揭示src/mcp/redact.ts、tests/mcp-redact.test.tsTask 5markdown 表格渲染器src/mcp/tables.ts、tests/mcp-tables.test.tsTask 6MCP 服务器工具、schema、handler、in-flight 合并src/mcp/server.ts、tests/mcp-server.test.tsTask 7接线codeburn mcp命令 stdout 保护src/main.tsTask 8全量验证npx tsc --noEmit npm test npm run build仓库 CI 约定计划文档同时给出了一条明确的验证基线Task 2/3 之后npx tsc --noEmit npx vitest run cli-status-menubar必须通过status --format menubar-json输出不变Task 6 之后npx vitest run mcp-server5 个测试全绿Task 7 之后构建产物中 SDK 保持 externalMcpServer source inlined? false。十三、明确推迟的内容v1 之外计划文档与规格文档共同划定的 v1 边界YAGNI包括逐提供方优雅降级degraded[]需改动共享的parseAllSessions循环v1 在工具边界用isError兜底——这是对已批准规格的唯一有意偏差HTTP/SSE 传输仅 stdiocompare_periods工具Agent 可以自己对比两次get_usage且其后端是全新代码、重叠语义不一致写/变更类工具、认证、多机/远程数据MCPprompts与resources原语v1 仅工具README 的 MCP 章节与 MCP 注册表收录lobehub/Smithery/mcp.so——属于后续任务而非代码。十四、自检清单供二次开发参考计划文档末尾的 Self-Review 可作为后续扩展或评审的核对表逐项对照真实实现进程内 stdio 服务 ✓廉价/优化路径通过optimize标志拆分scanAndDetect是唯一昂贵调用 ✓两个工具带注解 outputSchemaisError✓默认哈希脱敏 ✓in-flight 合并 启动预加载定价 ✓tsup external 钉死依赖版本 ✓stdout 保护 ✓周期枚举改名与last_6_months语义 ✓空状态消息 ✓limit封顶与汇总式历史不返回每日数组的 Token 纪律 ✓唯一偏差逐提供方degraded[]推迟已在文档中声明。整体看codeburn mcp是一套小工具面、深复用、强隐私的实现工具面只有两个只读工具背后复用status的完整聚合管线src/usage-aggregator.ts用optimize开关隔离唯一昂贵调用用加盐哈希把出口面默认脱敏用 in-flight 合并与常驻进程消化并发与缓存成本最终让任何支持 MCP 的 AgentClaude Code、Cursor、Claude Desktop 等在对话中直接查询本机 AI 编码开销并获取可执行的节省建议。【免费下载链接】codeburnFree, local tool to track AI coding token usage and cost across 37 tools and agents (Claude Code, Cursor, Codex, Gemini and more), by model, project, and task. npx codeburn项目地址: https://gitcode.com/gh_mirrors/co/codeburn创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表