@tokenzero/mcp 0.2.6 → 0.2.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/bin/tokenzero-mcp.mjs +21 -5
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -15,6 +15,8 @@ claude mcp add tokenzero -- npx -y @tokenzero/mcp # Claude Code
|
|
|
15
15
|
| `audit_repo_token_waste` | locally | Static audit of a local directory (default: the working directory), a public GitHub repo, or a diff. Nothing from a local directory is uploaded. |
|
|
16
16
|
| `calculate_model_arbitrage` | locally | Prices a workload across models at list prices, with and without prompt caching. |
|
|
17
17
|
| `optimize_prompt_payload` | TokenZero service | Rewrites a request body so its static prefix is cacheable. Sends the body you pass to the TokenZero service (`https://tokenzero.sh` unless `TOKENZERO_URL` is set); do not include secrets. |
|
|
18
|
+
| `workspace_metrics` | TokenZero service | Reads a workspace's savings scorecard: hard savings and net ROI per window, each engine's contribution and one-click recommendations. Uses `TOKENZERO_KEY` unless a key is passed; `demo: true` returns a labelled sample. |
|
|
19
|
+
| `provision_workspace` | TokenZero service | Creates a free workspace and key with no form. The key is returned once. |
|
|
18
20
|
|
|
19
21
|
Optional environment: `TOKENZERO_URL` (another gateway for `optimize_prompt_payload`; default `https://tokenzero.sh`), `GITHUB_TOKEN` (raises GitHub rate limits for repo audits).
|
|
20
22
|
|
package/bin/tokenzero-mcp.mjs
CHANGED
|
@@ -9,17 +9,21 @@ import readline from "node:readline";
|
|
|
9
9
|
import crypto from "node:crypto";
|
|
10
10
|
|
|
11
11
|
// src/pricing.ts
|
|
12
|
-
var PRICING_VERSION = "2026-10-
|
|
12
|
+
var PRICING_VERSION = "2026-10-27";
|
|
13
13
|
var P = (provider, tier, input, output, cachedInput, cacheWrite, extra = {}) => ({ provider, tier, input, output, cachedInput, cacheWrite, ...extra });
|
|
14
14
|
var PRICES = {
|
|
15
15
|
// ---- OpenAI (standard tier, ≤272K; cache write = 30m TTL rate) ----
|
|
16
16
|
"gpt-6-astra": P("openai", "frontier", 10, 50, 1, 12.5, { ultrafast: true, longCtxAt: 272e3, longCtx: { input: 20, output: 75, cachedInput: 2, cacheWrite: 25 }, minCacheTokens: 1024 }),
|
|
17
17
|
"gpt-6.1-sol": P("openai", "mid", 2, 10, 0.1, 2.5, { ultrafast: true, longCtxAt: 272e3, longCtx: { input: 4, output: 15, cachedInput: 0.2, cacheWrite: 5 }, minCacheTokens: 1024 }),
|
|
18
|
+
"gpt-6.1-terra": P("openai", "mid", 1, 5, 0.05, 1.25, { longCtxAt: 272e3, longCtx: { input: 2, output: 7.5, cachedInput: 0.1, cacheWrite: 2.5 }, minCacheTokens: 1024 }),
|
|
18
19
|
"gpt-6-sol": P("openai", "mid", 2, 10, 0.2, 2.5, { longCtxAt: 272e3, longCtx: { input: 4, output: 15, cachedInput: 0.4, cacheWrite: 5 }, minCacheTokens: 1024 }),
|
|
19
20
|
"gpt-6-luna": P("openai", "fast", 0.1, 0.5, 0.01, 0.125, { longCtxAt: 272e3, longCtx: { input: 0.2, output: 0.75, cachedInput: 0.02, cacheWrite: 0.25 }, minCacheTokens: 1024 }),
|
|
20
21
|
"gpt-5.6-sol": P("openai", "frontier", 4, 20, 0.4, 5, { longCtxAt: 272e3, longCtx: { input: 8, output: 30, cachedInput: 0.8, cacheWrite: 10 }, minCacheTokens: 1024 }),
|
|
21
22
|
"gpt-5.6-terra": P("openai", "mid", 2, 12, 0.2, 2.5, { longCtxAt: 272e3, longCtx: { input: 4, output: 18, cachedInput: 0.4, cacheWrite: 5 }, minCacheTokens: 1024 }),
|
|
22
23
|
"gpt-5.6-luna": P("openai", "fast", 0.2, 1.2, 0.02, 0.25, { longCtxAt: 272e3, longCtx: { input: 0.4, output: 1.8, cachedInput: 0.04, cacheWrite: 0.5 }, minCacheTokens: 1024 }),
|
|
24
|
+
// Daybreak cyber model: access needs OpenAI approval; 400K window
|
|
25
|
+
"gpt-5.6-cyber": P("openai", "frontier", 12.5, 75, 1.25, 15.625, { longCtxAt: 272e3, longCtx: { input: 25, output: 112.5, cachedInput: 2.5, cacheWrite: 31.25 }, minCacheTokens: 1024 }),
|
|
26
|
+
"gpt-5.3-codex": P("openai", "mid", 1.75, 14, 0.175, void 0, { minCacheTokens: 1024 }),
|
|
23
27
|
"gpt-5.5": P("openai", "frontier", 5, 30, 0.5, void 0, { fastFactor: 2.5, longCtxAt: 272e3, longCtx: { input: 10, output: 45, cachedInput: 1 }, minCacheTokens: 1024 }),
|
|
24
28
|
"gpt-5.5-pro": P("openai", "frontier", 30, 180),
|
|
25
29
|
"gpt-5.4": P("openai", "frontier", 2.5, 15, 0.25, void 0, { longCtxAt: 272e3, longCtx: { input: 5, output: 22.5, cachedInput: 0.5 }, minCacheTokens: 1024 }),
|
|
@@ -84,7 +88,8 @@ var PRICES = {
|
|
|
84
88
|
var MODEL_ALIASES = { "deepseek-v4-flash": "deepseek-flash", "deepseek-v4-flash-vision-exp": "deepseek-flash" };
|
|
85
89
|
var CASCADE_TARGET = {
|
|
86
90
|
"gpt-6-astra": "gpt-6.1-sol",
|
|
87
|
-
"gpt-6.1-sol": "gpt-6-
|
|
91
|
+
"gpt-6.1-sol": "gpt-6.1-terra",
|
|
92
|
+
"gpt-6.1-terra": "gpt-6-luna",
|
|
88
93
|
"gpt-6-sol": "gpt-6-luna",
|
|
89
94
|
"gpt-5.6-sol": "gpt-5.6-terra",
|
|
90
95
|
"gpt-5.6-terra": "gpt-5.6-luna",
|
|
@@ -157,6 +162,7 @@ var MODEL_SUNSET = {
|
|
|
157
162
|
"gpt-5-nano": { retires: "2026-12-11", replacement: "gpt-5.6-luna", announced: "2026-06-11" },
|
|
158
163
|
"gpt-5-pro": { retires: "2026-12-11", replacement: "gpt-5.6-sol", announced: "2026-06-11" },
|
|
159
164
|
"gpt-5.1": { retires: "2027-04-01", replacement: "gpt-6-sol", announced: "2026-10-01" },
|
|
165
|
+
"gpt-5.3-codex": { retires: "2027-04-01", replacement: "gpt-6-sol", announced: "2026-10-01" },
|
|
160
166
|
"gpt-5.4-nano": { retires: "2027-04-01", replacement: "gpt-6-luna", announced: "2026-10-01" },
|
|
161
167
|
"o1": { retires: "2026-10-23", replacement: "gpt-5.6-sol", announced: "2026-04-22" },
|
|
162
168
|
"o3": { retires: "2026-12-11", replacement: "gpt-5.6-sol", announced: "2026-06-11" },
|
|
@@ -637,7 +643,7 @@ async function fetchRepoFiles(repo, opts = {}) {
|
|
|
637
643
|
const meta = await fetch(`${GH}/repos/${repo}`, { headers: ghHeaders(opts.token) });
|
|
638
644
|
if (meta.status === 404) throw new Error("repository not found (private repos are not supported)");
|
|
639
645
|
if (!meta.ok) throw new Error(`GitHub API ${meta.status}: ${(await meta.text()).slice(0, 200)}`);
|
|
640
|
-
const
|
|
646
|
+
const metaJson = await meta.json(), branch = metaJson.default_branch, fullName = typeof metaJson.full_name === "string" ? metaJson.full_name : repo;
|
|
641
647
|
const tree = await fetch(`${GH}/repos/${repo}/git/trees/${encodeURIComponent(branch)}?recursive=1`, { headers: ghHeaders(opts.token) });
|
|
642
648
|
if (!tree.ok) throw new Error(`GitHub tree ${tree.status}`);
|
|
643
649
|
const treeAll = (await tree.json()).tree;
|
|
@@ -661,7 +667,7 @@ async function fetchRepoFiles(repo, opts = {}) {
|
|
|
661
667
|
const r = await fetch(`https://raw.githubusercontent.com/${repo}/${branch}/${n}`, { headers: { "user-agent": UA } });
|
|
662
668
|
return r.ok ? { path: n, content: await r.text() } : null;
|
|
663
669
|
}))).filter((m) => !!m);
|
|
664
|
-
return { files, manifests: manifests2, branch, total_candidates: entries.length };
|
|
670
|
+
return { files, manifests: manifests2, branch, total_candidates: entries.length, full_name: fullName };
|
|
665
671
|
}
|
|
666
672
|
|
|
667
673
|
// src/arbitrage.ts
|
|
@@ -754,7 +760,7 @@ function manifests(root) {
|
|
|
754
760
|
}
|
|
755
761
|
|
|
756
762
|
// mcp/src/main.ts
|
|
757
|
-
var VERSION = "0.2.
|
|
763
|
+
var VERSION = "0.2.8";
|
|
758
764
|
var BAKED_URL = true ? "https://tokenzero.sh" : "__TOKENZERO_DEFAULT_URL__";
|
|
759
765
|
var SUPPORTED = [...MCP_LEGACY_VERSIONS];
|
|
760
766
|
var SERVER = { name: "tokenzero", version: VERSION };
|
|
@@ -764,26 +770,36 @@ var serviceUrl = () => (process.env.TOKENZERO_URL || (BAKED_URL.startsWith("http
|
|
|
764
770
|
var TOOLS = [
|
|
765
771
|
{
|
|
766
772
|
name: "audit_repo_token_waste",
|
|
773
|
+
title: "Audit a repo or directory for LLM token waste",
|
|
774
|
+
annotations: { title: "Audit a repo or directory for LLM token waste", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: true },
|
|
767
775
|
description: "Static audit for LLM token waste: uncached static prompts and prompt templates, frontier models on extraction/classification prompts, calls in loops, unpriced models. Give `path` for a local directory (scanned on this machine, nothing uploaded; defaults to the working directory), `repo` (owner/name) for a public GitHub repo, or `diff` for a unified diff. Results are static heuristics, not measurements.",
|
|
768
776
|
inputSchema: { type: "object", properties: { path: { type: "string", description: "local directory; defaults to the current working directory" }, repo: { type: "string", description: "public GitHub owner/name" }, diff: { type: "string", description: "unified diff text, e.g. from git diff" } }, additionalProperties: false }
|
|
769
777
|
},
|
|
770
778
|
{
|
|
771
779
|
name: "calculate_model_arbitrage",
|
|
780
|
+
title: "Price a workload across models",
|
|
781
|
+
annotations: { title: "Price a workload across models", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
772
782
|
description: `Price a workload at list prices (table ${PRICING_VERSION}) for the requested model, its cheaper sibling and any extra models, with and without prompt caching. Runs locally.`,
|
|
773
783
|
inputSchema: { type: "object", properties: { model: { type: "string" }, input_tokens: { type: "number" }, output_tokens: { type: "number" }, requests_per_month: { type: "number" }, static_tokens: { type: "number", description: "portion of input_tokens that is a fixed prefix (system + tools)" }, compare_to: { type: "array", items: { type: "string" } } }, required: ["model", "input_tokens", "output_tokens"], additionalProperties: false }
|
|
774
784
|
},
|
|
775
785
|
{
|
|
776
786
|
name: "optimize_prompt_payload",
|
|
787
|
+
title: "Make a request body cache-friendly",
|
|
788
|
+
annotations: { title: "Make a request body cache-friendly", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
777
789
|
description: "Rewrite an OpenAI Chat/Responses or Anthropic Messages request body so its static prefix is provider-cacheable, and project the saving. Sends the body you pass to the TokenZero service (set TOKENZERO_URL); do not pass secrets in it.",
|
|
778
790
|
inputSchema: { type: "object", properties: { body: { type: "object" }, endpoint: { type: "string", enum: ["/v1/chat/completions", "/v1/responses", "/v1/messages"] }, strategy: { type: "string", enum: ["static", "conversation"] } }, required: ["body"], additionalProperties: false }
|
|
779
791
|
},
|
|
780
792
|
{
|
|
781
793
|
name: "workspace_metrics",
|
|
794
|
+
title: "Read a workspace savings scorecard",
|
|
795
|
+
annotations: { title: "Read a workspace savings scorecard", readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
782
796
|
description: "Live value scorecard for a TokenZero workspace (GET /v1/workspaces/me/metrics): hard savings and net ROI per window, per-engine contribution, speed, parity, availability, privacy posture, per-model breakdown and one-click recommendations. Uses TOKENZERO_KEY unless a key is given; demo: true returns a labelled sample.",
|
|
783
797
|
inputSchema: { type: "object", properties: { key: { type: "string", description: "workspace key (tz_live_\u2026); defaults to TOKENZERO_KEY" }, window: { type: "string", enum: ["24h", "7d", "30d", "all"] }, demo: { type: "boolean" } } }
|
|
784
798
|
},
|
|
785
799
|
{
|
|
786
800
|
name: "provision_workspace",
|
|
801
|
+
title: "Create a free TokenZero workspace",
|
|
802
|
+
annotations: { title: "Create a free TokenZero workspace", readOnlyHint: false, destructiveHint: false, idempotentHint: false, openWorldHint: false },
|
|
787
803
|
description: "Create a TokenZero workspace and key with no form (POST /v1/workspaces on the TokenZero service). Returns the key once, the base URLs that route through it, the one-click dashboard link (key in the URL fragment, never sent to the server) and the badge URL. Free up to the monthly free tier; nothing is billed.",
|
|
788
804
|
inputSchema: { type: "object", properties: { name: { type: "string", description: 'workspace name (defaults to "mcp-agent")' } }, additionalProperties: false }
|
|
789
805
|
}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tokenzero/mcp",
|
|
3
3
|
"mcpName": "sh.tokenzero/mcp",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.8",
|
|
5
5
|
"description": "TokenZero MCP server (stdio): audit LLM token waste in your project locally, price model alternatives, and make prompts cache-friendly from Claude Code, Cursor, Windsurf or Cline.",
|
|
6
6
|
"type": "module",
|
|
7
7
|
"license": "Apache-2.0",
|