calculate_estimate
Estimate token costs for any model by providing input and output token counts, with optional prompt caching discounts.
Instructions
Estimate the cost for a given number of input and output tokens on a specific model. Supports optional cached_tokens for prompt caching discounts.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| model_name | Yes | Model name (fuzzy matched) | |
| input_tokens | Yes | Number of input tokens | |
| output_tokens | Yes | Number of output tokens | |
| cached_tokens | No | Number of input tokens served from cache (prompt caching). Must be <= input_tokens. These tokens are billed at the cached rate instead of the standard input rate. |
Implementation Reference
- src/tools.ts:22-49 (registration)Tool registration entry for 'calculate_estimate' including name, description, and inputSchema definition.
{ name: "calculate_estimate", description: "Estimate the cost for a given number of input and output tokens on a specific model. Supports optional cached_tokens for prompt caching discounts.", inputSchema: { type: "object" as const, properties: { model_name: { type: "string", description: "Model name (fuzzy matched)", }, input_tokens: { type: "number", description: "Number of input tokens", }, output_tokens: { type: "number", description: "Number of output tokens", }, cached_tokens: { type: "number", description: "Number of input tokens served from cache (prompt caching). Must be <= input_tokens. These tokens are billed at the cached rate instead of the standard input rate.", }, }, required: ["model_name", "input_tokens", "output_tokens"], }, }, - src/tools.ts:91-96 (schema)Zod schema for validating calculate_estimate inputs: model_name, input_tokens, output_tokens, and optional cached_tokens.
const calculateEstimateSchema = z.object({ model_name: z.string().min(1), input_tokens: z.number().nonnegative(), output_tokens: z.number().nonnegative(), cached_tokens: z.number().nonnegative().optional(), }); - src/tools.ts:262-349 (handler)Handler logic for 'calculate_estimate' that parses inputs, looks up the model, calculates costs (with tiered pricing and prompt caching support), and returns a formatted cost estimate.
case "calculate_estimate": { const { model_name, input_tokens, output_tokens, cached_tokens } = calculateEstimateSchema.parse(args); const models = await getModels(); const { entry: model, isFineTuned } = fuzzyMatchWithMetadata(model_name, models); if (!model) { return { content: [ { type: "text", text: `No model found matching "${model_name}".`, }, ], }; } // Resolve cached token count: cap at input_tokens, ignore if model doesn't support caching const resolvedCachedTokens = cached_tokens != null && model.cache_read_input_token_cost != null && cached_tokens > 0 ? Math.min(cached_tokens, input_tokens) : 0; const uncachedInputTokens = input_tokens - resolvedCachedTokens; const result = calculateTieredCost(model, uncachedInputTokens, output_tokens); const cachedCost = resolvedCachedTokens > 0 ? resolvedCachedTokens * (model.cache_read_input_token_cost ?? 0) : 0; const totalCost = result.totalCost + cachedCost; const lines: string[] = [`Cost Estimate for ${model.key}`, ``]; if (isFineTuned) { lines.push( `⚠️ Note: This estimate is for the base model (${model.key}). Fine-tuned models use the same pricing as their base model.`, ); lines.push(``); } if (resolvedCachedTokens > 0) { lines.push( ` Cached input: ${formatTokenCount(resolvedCachedTokens)} tokens × ${formatCost(model.cache_read_input_token_cost_per_million ?? 0)}/1M = ${formatCost(cachedCost)}`, ); } if (result.tieredInput) { const baseTokens = TIERED_PRICING_THRESHOLD; const tieredTokens = uncachedInputTokens - baseTokens; lines.push( ` Input (base): ${formatTokenCount(baseTokens)} tokens × ${formatCost(model.input_cost_per_million)}/1M = ${formatCost(result.inputBaseCost)}`, ); lines.push( ` Input (>200K): ${formatTokenCount(tieredTokens)} tokens × ${formatCost(model.input_cost_per_million_above_200k ?? 0)}/1M = ${formatCost(result.inputTieredCost)}`, ); } else { lines.push( ` Input: ${formatTokenCount(uncachedInputTokens)} tokens × ${formatCost(model.input_cost_per_million)}/1M = ${formatCost(result.inputCost)}`, ); } if (result.tieredOutput) { const baseTokens = TIERED_PRICING_THRESHOLD; const tieredTokens = output_tokens - baseTokens; lines.push( ` Output (base): ${formatTokenCount(baseTokens)} tokens × ${formatCost(model.output_cost_per_million)}/1M = ${formatCost(result.outputBaseCost)}`, ); lines.push( ` Output (>200K): ${formatTokenCount(tieredTokens)} tokens × ${formatCost(model.output_cost_per_million_above_200k ?? 0)}/1M = ${formatCost(result.outputTieredCost)}`, ); } else { lines.push( ` Output: ${formatTokenCount(output_tokens)} tokens × ${formatCost(model.output_cost_per_million)}/1M = ${formatCost(result.outputCost)}`, ); } lines.push(` ─────────────────────────────`); lines.push(` Total: ${formatCost(totalCost)}`); return { content: [ { type: "text", text: lines.join("\n"), }, ], }; } - src/tools.ts:130-175 (helper)calculateTieredCost helper function that computes input/output costs with optional tiered pricing above the threshold (200K tokens).
export function calculateTieredCost( model: ModelEntry, inputTokens: number, outputTokens: number, ): TieredCostResult { const threshold = TIERED_PRICING_THRESHOLD; let inputBaseCost: number; let inputTieredCost = 0; let tieredInput = false; if (model.input_cost_per_token_above_200k != null && inputTokens > threshold) { tieredInput = true; inputBaseCost = threshold * model.input_cost_per_token; inputTieredCost = (inputTokens - threshold) * model.input_cost_per_token_above_200k; } else { inputBaseCost = inputTokens * model.input_cost_per_token; } let outputBaseCost: number; let outputTieredCost = 0; let tieredOutput = false; if (model.output_cost_per_token_above_200k != null && outputTokens > threshold) { tieredOutput = true; outputBaseCost = threshold * model.output_cost_per_token; outputTieredCost = (outputTokens - threshold) * model.output_cost_per_token_above_200k; } else { outputBaseCost = outputTokens * model.output_cost_per_token; } const inputCost = inputBaseCost + inputTieredCost; const outputCost = outputBaseCost + outputTieredCost; return { inputCost, outputCost, totalCost: inputCost + outputCost, tieredInput, tieredOutput, inputBaseCost, inputTieredCost, outputBaseCost, outputTieredCost, }; }