内容
# mcp-token-saver
> 实时Claude.ai/Codex订阅感知,为AI编码助手提供服务。显示实时`会话 5小时`和`每周 7天`利用率,预测何时达到限制,在昂贵操作运行前进行限制,并衡量实际每任务成本 — 所有操作均无需离开您的机器。
[](https://www.npmjs.com/package/mcp-token-saver)
[](https://www.npmjs.com/package/mcp-token-saver)
[](LICENSE)
[](https://nodejs.org)
[](https://modelcontextprotocol.io)
[](https://www.typescriptlang.org)
---
## 为什么
Claude Code、Cursor、Codex等悄悄消耗您的订阅。IDE侧边栏显示`会话 5小时 75% / 每周 7天 45%`,但**模型本身看不到这些数字** — 因此它无法知道自己即将达到限制,执行某个大任务时。
`mcp-token-saver`公开了这些信息(并采取了行动):
1. **`usage_status`** — 从Claude Code使用的同一私有端点读取实时Claude.ai利用率(`/api/oauth/usage`)。
2. **`usage_forecast`** — 记录时间快照,计算燃烧率,告诉您是否会在下一次重置前达到100%。
3. **`should_proceed`** — 给定任务大小,根据当前使用情况决定`继续` / `降级` / `中止`。用防护栏取代猜测。
4. **`usage_delta`** — 标记任务前的基准,衡量任务实际消耗的百分比。真实成本,非估计值。
5. **`cache_stats`** — 读取Claude Code会话日志,计算实际缓存命中率。低命中率 = 浪费令牌。
无遥测,无API密钥(使用现有的OAuth令牌),无远程服务。
---
## 目录
- [功能](#功能)
- [工作原理](#工作原理)
- [快速入门](#快速入门)
- [工具API](#工具API)
- [自动将使用情况注入每个提示](#自动将使用情况注入每个提示)
- [激活协议](#激活协议)
- [架构](#架构)
- [开发](#开发)
- [FAQ](#FAQ)
- [许可证](#许可证)
---
## 功能
- **实时订阅数字。** 与Claude Code IDE栏相同的数据 — 利用率%,重置时间戳,额外积分余额。
- **燃烧率预测。** 记录每个快照,计算每小时百分比和达到100%的ETA。
- **飞行前门控。** `should_proceed`在利用率过高时阻止大操作。
- **真实每任务成本。** `usage_delta`衡量任务实际消耗的百分比。
- **缓存可观察性。** `cache_stats`解析Claude Code的会话JSONL,以显示真实缓存命中率。
- **自适应输出压缩。** 可选的钩子指令,告诉模型在利用率过高(>60%)时写更紧凑的响应,在临界时(>95%)更紧凑,在冷却时保持正常。无始终开启的原始人说话 — 仅在需要时压缩。
- **零配置。** 从`~/.claude/.credentials.json`读取OAuth令牌。如果您运行过`claude login`,则完成。
- **仅本地。** 无遥测。无外部服务。唯一网络调用是使用您自己的令牌到`api.anthropic.com`。
---
## 工作原理
```
┌──────────────────┐ "我应该执行这个大任务吗?" ┌──────────────────┐
│ Claude Code │ ────────────────────────────────▶ │ mcp-token-saver │
│ (或任何MCP │ │ (stdio服务器) │
│ 客户端) │ ◀─────────────────────────────── │ │
└──────────────────┘ { decision: "降级", └──────────────────┘
│ 原因: "5小时92%,切换到Haiku或缩短" }
│ │
│ ┌────┴──────────┐
│ │ /api/oauth/ │
│ │ 使用情况 │
│ │ (api.anthr…) │
│ └───────────────┘
▼
降级/继续 usage_history.jsonl
基于真实限制 ~/.mcp-token-saver/
```
OAuth令牌来自`~/.claude/.credentials.json`,由`claude login`写入。端点是Claude Code的IDE栏所使用的同一个端点(`anthropic-beta: oauth-2025-04-20`)。
---
## 快速入门
### 1. 添加到Claude Code
在您的项目的`.mcp.json`(或全局的`~/.claude/settings.json`)中:
```json
{
"mcpServers": {
"token-saver": {
"command": "npx",
"args": ["-y", "mcp-token-saver"]
}
}
}
```
### 2. 或克隆并在本地运行
```bash
git clone https://github.com/Talap-creator/mcp-token-saver.git
cd mcp-token-saver
npm install && npm run build
```
然后将`.mcp.json`指向`dist/index.js`:
```json
{"mcpServers":{"token-saver":{"command":"node","args":["C:/path/to/mcp-token-saver/dist/index.js"]}}}
```
### 3. 激活协议
将[`src/prompts/system.md`](src/prompts/system.md)复制到您的项目的`CLAUDE.md`中。没有此步骤,模型将看到工具但不会被告知使用它们。
### 4. 重启MCP客户端
重新加载窗口。在下一个提示中,模型可以看到您的实时订阅使用情况。
---
## 工具API
### `usage_status`
Claude.ai订阅使用情况的实时快照。自动记录到历史记录中。
**输入:** 无。
**输出**
```json
{
"subscription": "pro",
"rate_limit_tier": "default_claude_ai",
"five_hour": { "utilization_pct": 75, "resets_at": "2026-04-28T23:20:00Z" },
"seven_day": { "utilization_pct": 45, "resets_at": "2026-05-03T18:00:00Z" },
"seven_day_sonnet": null,
"extra_usage": { "enabled": false, "monthly_limit": null, "used_credits": null, "utilization_pct": null },
"fetched_at": "2026-04-28T19:26:28Z"
}
```
### `usage_forecast`
基于`usage_status`写入的历史记录的燃烧率预测。
**输入:** 无。
**输出**
```json
{
"five_hour": {
"current_pct": 75,
"resets_at": "2026-04-28T23:20:00Z",
"burn_rate_pct_per_hour": 18.4,
"eta_to_100_pct_iso": "2026-04-28T22:50:00Z",
"will_hit_limit_before_reset": true,
"samples_used": 12
},
"seven_day": { "current_pct": 45, "burn_rate_pct_per_hour": 0.8, "eta_to_100_pct_iso": null, "will_hit_limit_before_reset": false, "samples_used": 12 }
}
```
> 需要在当前桶中至少2个快照才能预测 — 定期调用`usage_status`(或使用下面的自动注入钩子)以建立历史记录。
### `should_proceed`
在大响应或大读取之前进行飞行前检查。
**输入**
| 字段 | 类型 | 描述 |
|---|---|---|
| `task_size` | `"small" \| "medium" \| "large" \| "huge"` | 粗略输出大小。small ~<500 tok, medium ~2k, large ~8k, huge >8k。 |
| `description` | `string` (可选) | 决策日志的自由文本标签。 |
**输出**
```json
{
"decision": "降级",
"reason": "使用情况热(5h 92%,7d 47%)。切换到Haiku或缩短响应。",
"current": { "five_hour_pct": 92, "seven_day_pct": 47 },
"projected": { "five_hour_pct": 98, "seven_day_pct": 53 },
"task_size": "large"
}
```
`decision`是`继续`、`降级`、`中止`之一。模型应将其视为硬门控。
### `usage_delta`
衡量任务的真实成本,占订阅百分比,而不是伪美元。
**输入**
| 字段 | 类型 | 描述 |
|---|---|---|
| `action` | `"mark" \| "measure"` | `mark`保存基准;`measure`返回基准以来的增量。 |
| `label` | `string` (可选) | 基准的标签。 |
**输出(action=measure)**
```json
{
"label": "refactor-auth",
"elapsed_seconds": 412,
"five_hour": { "before": 71, "after": 78.5, "delta_pct": 7.5 },
"seven_day": { "before": 44, "after": 45, "delta_pct": 1 }
}
```
### `cache_stats`
来自Claude Code会话日志的真实提示缓存命中率。
**输入**
| 字段 | 类型 | 描述 |
|---|---|---|
| `project_dir` | `string` (可选) | 项目工作目录。默认为最近修改的项目日志。 |
| `last_n` | `number` (可选,最大200) | 要分析的最近助手消息。默认为20。 |
**输出**
```json
{
"session_log": "/.../553db191-....jsonl",
"messages_analyzed": 20,
"cache_hit_rate_pct": 96.4,
"tokens": { "cache_read": 1564240, "cache_creation": 12810, "fresh_input": 38, "output": 6210 },
"warning": null
}
```
如果命中率<40%,会出现`warning`,通常意味着系统提示或工具列表在会话中间更改了。
---
## 自动将使用情况注入每个提示
要使模型**始终**看到您的当前使用情况而无需调用工具,请注册一个`UserPromptSubmit`钩子。将以下内容保存为`~/.claude/hooks/usage_status.js`:
```js
#!/usr/bin/env node
const fs = require("fs"), os = require("os"), path = require("path");
(async () => {
try {
const c = JSON.parse(fs.readFileSync(path.join(os.homedir(), ".claude/.credentials.json"), "utf8"));
const t = c?.claudeAiOauth?.accessToken;
if (!t || (c.claudeAiOauth.expiresAt && c.claudeAiOauth.expiresAt < Date.now())) return;
const ctrl = new AbortController(); setTimeout(() => ctrl.abort(), 4000);
const r = await fetch("https://api.anthropic.com/api/oauth/usage", {
headers: {
Authorization: `Bearer ${t}`,
"Content-Type": "application/json",
"anthropic-beta": "oauth-2025-04-20",
"x-app": "vscode",
},
signal: ctrl.signal,
});
if (!r.ok) return;
const u = await r.json();
const pct = b => b?.utilization != null ? `${b.utilization.toFixed(0)}%` : "—";
process.stdout.write(`[claude-usage] 会话(5h): ${pct(u.five_hour)} | 每周(7d): ${pct(u.seven_day)}\n`);
// 自适应输出压缩 — 会话热 = 更紧凑的响应。
const hot = Math.max(u.five_hour?.utilization ?? 0, u.seven_day?.utilization ?? 0);
let d = null;
if (hot >= 95) d = "仅限单行答案。代码或值,无冗余文本。";
else if (hot >= 80) d = "最小化令牌。代码优先于冗余文本。无前言,无摘要。";
else if (hot >= 60) d = "简洁回应。删除填充、犹豫和客套话。";
if (d) process.stdout.write(`[claude-usage-directive] ${d}\n`);
} catch {}
})();
```
`[claude-usage-directive]`行是一个**自适应输出压缩**提示 — 它告诉模型在会话热时写更紧凑的响应,在冷却时保持正常。在`CLAUDE.md`中添加此规则,使模型将其视为绑定:
> 当上下文中出现`[claude-usage]`行时,将其视为该回合的绑定样式覆盖 — 降低填充,缩短解释,优先使用代码而不是冗余文本,达到指定级别。
然后在`~/.claude/settings.json`中:
```json
{
"hooks": {
"UserPromptSubmit": [
{ "hooks": [{ "type": "command", "command": "node \"$HOME/.claude/hooks/usage_status.js\"", "timeout": 5 }] }
]
}
}
```
钩子在令牌丢失或端点关闭时静默失败 — 它永远不会阻止您的提示。输出作为附加上下文注入到下一个助手回合中。
---
## 激活协议
模型不会在没有指令的情况下调用可选工具。您有两个选项:
### 全局(推荐) — `~/.claude/CLAUDE.md`
将以下协议粘贴到`~/.claude/CLAUDE.md`(Claude Code的用户级内存文件)。然后它被自动加载到每个项目中 — 您只需编写一次,模型就会在所有仓库中使用这些工具。
### 按项目 — `<repo>/CLAUDE.md`
如果您只想在特定项目中使用该协议,请将其粘贴到项目的`CLAUDE.md`中。
### 协议
```markdown
您可以访问具有五个工具的`token-saver` MCP服务器:
`usage_status`, `usage_forecast`, `should_proceed`, `usage_delta`,
`cache_stats`. 它们公开了真实的Claude.ai订阅利用率。
您必须遵循此协议:
1. 在生成长响应或进行大文件/代码库读取之前,
调用`should_proceed`并附上诚实的`task_size`(“small” / “medium” /
“large” / “huge”)。如果`decision: "降级"`,请切换到较短的答案或建议Haiku。如果`decision: "中止"`,请拒绝并告诉用户等待重置(引用`resets_at`)。
2. 对于多步骤任务,在开始时调用`usage_delta`并附上`action: "mark"`,
在结束时调用`action: "measure"`。引用用户实际的增量(例如“此任务消耗了5小时会话的7.5%”)。
3. 当用户询问剩余多少、重置时间或“是否接近上限”时 — 调用`usage_status`(当前)或`usage_forecast`
(带有ETA)。
4. 每10-20回合调用`cache_stats`。如果`cache_hit_rate_pct < 40`或
设置了`warning`,请将其显示给用户 — 某些东西使提示缓存失效,他们正在为每个回合支付全额输入。
5. 如果工具返回“OAuth令牌已过期”,请告诉用户运行
`claude login`并继续而不进行使用门控以完成此回合。
6. 如果上下文中的`[claude-usage]`行显示`session(5h) >= 80%`,
请在开始任务前提及。不要在热会话中静默继续进行大任务。
将这些调用视为必填的基础设施,而不是可选的帮助程序。
```
---
## 架构
```
src/
├── index.ts # stdio入口点
├── server.ts # 工具注册(McpServer)
├── tools/
│ ├── usageStatus.ts # 实时/api/oauth/usage调用 + 历史记录追加
│ ├── usageForecast.ts # 基于历史记录的燃烧率 + ETA
│ ├── shouldProceed.ts # 门控决策:继续/降级/中止
│ ├── usageDelta.ts # 标记/测量基准差异
│ └── cacheStats.ts # 解析~/.claude/projects/*.jsonl的缓存命中率
└── utils/
├── anthropicUsage.ts # OAuth令牌读取器 + /api/oauth/usage获取
└── history.ts # 追加/读取~/.mcp-token-saver/usage_history.jsonl
```
**技术栈:** Node ≥18,TypeScript strict,ESM, `@modelcontextprotocol/sdk`,`zod`用于输入模式。
状态文件(均位于`~/.mcp-token-saver/`下,可覆盖环境变量):
- `usage_history.jsonl` — 追加式快照日志(`MCP_TOKEN_SAVER_HISTORY`)
- `delta_mark.json` — `usage_delta`的当前基准(`MCP_TOKEN_SAVER_DELTA_MARK`)
---
## 开发
```bash
npm run dev # tsc --watch
npm test # vitest 运行
npm run inspector # 在本地构建上启动MCP检查器
```
通过原始stdio进行烟雾测试:
```bash
printf '%s\n' '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0"}}}' \
'{"jsonrpc":"2.0","method":"notifications/initialized"}' \
'{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
| node dist/index.js
```
---
## FAQ
**`/api/oauth/usage` 是官方Anthropic API吗?**
不是。它是Claude Code的IDE侧边栏内部使用的同一个端点(`anthropic-beta: oauth-2025-04-20`)。不是公开的,可能会在未通知的情况下更改。
**它会发送我的代码吗?**
不会。唯一发出的调用是使用您自己的OAuth令牌到`api.anthropic.com/api/oauth/usage`。
**模型实际上可以在没有我提示的情况下使用这些工具吗?**
只有当您的`CLAUDE.md`(或系统提示)明确指示模型这样做 — 请参阅[激活协议](#激活协议)。可选帮助程序将被忽略。
**如果我的`claude login`令牌过期了怎么办?**
工具将返回`{ "error": "OAuth token expired — run 'claude login'." }`。重新运行`claude login`以刷新。
**v0.1 有`estimate_tokens` / `optimize_context` / `check_budget` — 它们去哪了?**
v0.2 放弃了它们。它们是估计值和伪本地美元计数器,与您的真实订阅不符。固定到`mcp-token-saver@0.1.x`如果您需要旧行为。
---
## 许可证
MIT © 2026
MCP 配置
以下是此 MCP Server 的配置信息,可直接复制到 Cursor 或其他 MCP 客户端中使用。
mcp.json
连接信息
猜你喜欢
暂无推荐服务器