{"name":"tokens.md","version":"1.0","description":"A provider-neutral token policy for AI agents. One skill file with your budget, tiers, caching, retry and data rules written in, plus calculators an agent can call before it spends: estimate tokens, plan cost at your own prices, check context fit, and check a usage ledger against your rules.","skill":{"url":"https://tokens.md/tokens.md","with_settings":"https://tokens.md/tokens.md?preset=lean"},"settings":"https://tokens.md/api/v1/settings","usage":"GET /api/v1/<tool> with query parameters (arrays and objects as URL-encoded JSON), or POST /api/v1/<tool> with a JSON body (64 KB at most). No key. CORS open. Nothing is stored.","tools":[{"name":"estimate_tokens","title":"Estimate tokens for text","description":"Estimates tokens for text up to 200 KB with a stated heuristic: tokens per character for ASCII prose (0.25), code (0.30), CJK characters (1.0), other non-ASCII letters (0.40) and emoji or symbols (1.5), each with a low and high bound. Text inside ``` fences counts as code. Returns an estimate, a low/high range and the breakdown. The text is processed in memory and never stored. An estimate, not a tokenizer count.","get":"https://tokens.md/api/v1/estimate_tokens","post":"https://tokens.md/api/v1/estimate_tokens","example_get":"https://tokens.md/api/v1/estimate_tokens?text=Summarize+the+attached+report+in+five+bullet+points.%0A%0A%60%60%60json%0A%7B%22format%22%3A+%22bullets%22%2C+%22max%22%3A+5%7D%0A%60%60%60&kind=auto&window_tokens=128000","example_body":{"text":"Summarize the attached report in five bullet points.\n\n```json\n{\"format\": \"bullets\", \"max\": 5}\n```","kind":"auto","window_tokens":128000},"input":{"type":"object","properties":{"text":{"type":"string","maxLength":204800,"description":"The text to estimate, up to 200 KB (UTF-8). Processed in memory, not stored. Send it by POST so it stays out of URLs."},"kind":{"type":"string","enum":["auto","prose","code"],"default":"auto","description":"auto (default): fenced blocks are code, the rest is detected; prose or code: treat all ASCII text that way."},"window_tokens":{"type":"integer","minimum":1,"maximum":100000000,"description":"Optional: a context window size, to show the share the text would use."},"safety_margin_pct":{"type":"number","minimum":0,"maximum":100,"default":10,"description":"Margin added to the high estimate for planning. Default 10."}},"required":["text"]}},{"name":"plan_cost","title":"Plan token use and cost","description":"Plans a task's tokens and cost from your own numbers: calls, average input and output tokens, the share of input that is a stable cached prefix, a retry rate, and your prices per million input, output, cached-read and cache-write tokens. Returns totals, cost without savings, with caching, with batching (your discount) and with both, the cache break-even, and a comparison with your token budget and spend cap. It has no prices of its own; arithmetic only.","get":"https://tokens.md/api/v1/plan_cost","post":"https://tokens.md/api/v1/plan_cost","example_get":"https://tokens.md/api/v1/plan_cost?calls=200&avg_input_tokens=12000&avg_output_tokens=800&cached_share_pct=75&price_input_per_m=3&price_output_per_m=15&price_cached_per_m=0.3&price_cache_write_per_m=3.75&cache_writes=4&batch_share_pct=50&batch_discount_pct=50&retry_rate_pct=5&budget_mtok=3&spend_cap=10","example_body":{"calls":200,"avg_input_tokens":12000,"avg_output_tokens":800,"cached_share_pct":75,"price_input_per_m":3,"price_output_per_m":15,"price_cached_per_m":0.3,"price_cache_write_per_m":3.75,"cache_writes":4,"batch_share_pct":50,"batch_discount_pct":50,"retry_rate_pct":5,"budget_mtok":3,"spend_cap":10},"input":{"type":"object","properties":{"calls":{"type":"integer","minimum":1,"maximum":1000000000,"description":"Planned model calls."},"avg_input_tokens":{"type":"number","minimum":0,"maximum":100000000,"description":"Average input tokens per call, cached prefix included."},"avg_output_tokens":{"type":"number","minimum":0,"maximum":100000000,"description":"Average output tokens per call."},"price_input_per_m":{"type":"number","minimum":0,"maximum":1000000,"description":"Your price per million input tokens, in your currency."},"price_output_per_m":{"type":"number","minimum":0,"maximum":1000000,"description":"Your price per million output tokens."},"cached_share_pct":{"type":"number","minimum":0,"maximum":100,"default":0,"description":"Share of each call's input that is a stable prefix read from cache. Default 0."},"price_cached_per_m":{"type":"number","minimum":0,"maximum":1000000,"description":"Your price per million cached input tokens read. Default: the input price (no saving)."},"price_cache_write_per_m":{"type":"number","minimum":0,"maximum":1000000,"description":"Your price per million tokens written to the cache. Default: the input price."},"cache_writes":{"type":"integer","minimum":0,"maximum":1000000000,"default":1,"description":"How many times the prefix is written to the cache (for example once per cache lifetime). Default 1."},"batch_share_pct":{"type":"number","minimum":0,"maximum":100,"default":0,"description":"Share of calls that can wait for a batch job. Default 0."},"batch_discount_pct":{"type":"number","minimum":0,"maximum":100,"default":0,"description":"Your batch discount, in percent. Default 0."},"retry_rate_pct":{"type":"number","minimum":0,"maximum":500,"default":0,"description":"Extra calls from retries, as a percent of calls. Default 0."},"budget_mtok":{"type":"number","minimum":0,"maximum":1000000,"description":"Optional: token budget in million tokens."},"spend_cap":{"type":"number","minimum":0,"maximum":1000000000,"description":"Optional: spend cap, in the same currency as the prices."},"decimals":{"type":"integer","minimum":0,"maximum":6,"default":4,"description":"Decimal places for costs. Default 4."}},"required":["calls","avg_input_tokens","avg_output_tokens","price_input_per_m","price_output_per_m"]}},{"name":"context_fit","title":"Check what fits in a context window","description":"Adds up a call's parts (system prompt, tool definitions, documents, history) plus an output reserve against a window size you give. Returns whether it fits, the headroom, the summarize point, turns left before it, and how much to cut from history first, then documents. Your numbers or estimates only; no model limits are built in.","get":"https://tokens.md/api/v1/context_fit","post":"https://tokens.md/api/v1/context_fit","example_get":"https://tokens.md/api/v1/context_fit?window_tokens=200000&system_tokens=3000&tools_tokens=6000&documents_tokens=60000&history_tokens=85000&output_reserve_tokens=8000&summarize_at_pct=80&turn_tokens=4000","example_body":{"window_tokens":200000,"system_tokens":3000,"tools_tokens":6000,"documents_tokens":60000,"history_tokens":85000,"output_reserve_tokens":8000,"summarize_at_pct":80,"turn_tokens":4000},"input":{"type":"object","properties":{"window_tokens":{"type":"integer","minimum":1000,"maximum":100000000,"description":"The context window, in tokens, from your model's documentation."},"system_tokens":{"type":"number","minimum":0,"maximum":100000000,"default":0,"description":"System prompt and instructions."},"tools_tokens":{"type":"number","minimum":0,"maximum":100000000,"default":0,"description":"Tool definitions."},"documents_tokens":{"type":"number","minimum":0,"maximum":100000000,"default":0,"description":"Documents and retrieved content."},"history_tokens":{"type":"number","minimum":0,"maximum":100000000,"default":0,"description":"Conversation history and tool results."},"output_reserve_tokens":{"type":"number","minimum":0,"maximum":100000000,"default":0,"description":"Room kept for the reply (your max output tokens)."},"summarize_at_pct":{"type":"number","minimum":10,"maximum":100,"default":80,"description":"Summarize when input reaches this share of the window. Default 80."},"turn_tokens":{"type":"number","minimum":1,"maximum":100000000,"description":"Optional: average tokens each turn adds, to count turns left."}},"required":["window_tokens"]}},{"name":"check_ledger","title":"Check a usage ledger against your rules","description":"Checks a list of calls (tokens in and out, cached tokens, tier, retries, group, pass or fail, whether it found anything new, optional cost and timing) against your token rules: the same settings as the skill, from a preset and a rules object. Returns totals, totals by tier and group, rule breaks, warnings and what needs the person's yes. It checks the numbers you send; it doesn't verify them or approve anything.","get":"https://tokens.md/api/v1/check_ledger","post":"https://tokens.md/api/v1/check_ledger","example_body":{"preset":"balanced","rules":{"budget_mtok":0.2,"spend_cap_usd":1,"max_retries":2},"calls":[{"id":"plan","group":"research","tier":"small","tokens_in":9000,"tokens_out":700,"cached_tokens":0,"ok":true,"new_info":true,"cost":0.04},{"id":"search-1","group":"research","tier":"small","tokens_in":22000,"tokens_out":1200,"cached_tokens":8000,"ok":false,"new_info":true,"cost":0.06},{"id":"search-2","group":"research","tier":"large","tokens_in":26000,"tokens_out":5200,"cached_tokens":8000,"retries":3,"ok":true,"new_info":false,"cost":0.31},{"id":"search-3","group":"research","tier":"large","tokens_in":30000,"tokens_out":900,"cached_tokens":0,"ok":true,"new_info":false,"cost":0.12},{"id":"search-4","group":"research","tier":"large","tokens_in":31000,"tokens_out":800,"cached_tokens":26000,"ok":true,"new_info":false,"cost":0.05},{"id":"search-5","group":"research","tier":"large","tokens_in":33000,"tokens_out":800,"cached_tokens":27000,"ok":true,"new_info":false,"cost":0.05}]},"input":{"type":"object","properties":{"calls":{"type":"array","minItems":1,"maxItems":200,"description":"Calls in order: [{ id?, group?, tier (small, medium or large), tokens_in (cached included), tokens_out, cached_tokens?, retries?, cost?, ok?, new_info?, fallback?, start_s?, end_s? }].","items":{"type":"object","properties":{"id":{"type":"string","maxLength":40},"group":{"type":"string","maxLength":40},"tier":{"type":"string","enum":["small","medium","large"]},"tokens_in":{"type":"number","minimum":0},"tokens_out":{"type":"number","minimum":0},"cached_tokens":{"type":"number","minimum":0},"retries":{"type":"integer","minimum":0},"cost":{"type":"number","minimum":0},"ok":{"type":"boolean"},"new_info":{"type":"boolean"},"fallback":{"type":"boolean"},"start_s":{"type":"number","minimum":0},"end_s":{"type":"number","minimum":0}},"required":["tier","tokens_in","tokens_out"]}},"preset":{"type":"string","enum":["core","lean","balanced","research","sensitive"],"description":"Rules to start from: core, lean, balanced, research, sensitive. Without one, only core rules and the rules you send are checked."},"rules":{"type":"object","description":"Rules by setting key, overriding the preset: budget_mtok, spend_cap_usd, ask_at_pct, max_input_tokens, max_output_tokens, max_calls, max_in_flight, loop_stop_after, start_tier, escalate_after, max_tier, max_retries, backoff_s, fallback, caching, batch_after_min, summarize_at_pct, data_handling, usage_logging. Catalog at /api/v1/settings. Out-of-range values are clamped with a note."}},"required":["calls"]}},{"name":"build_settings","title":"Write your settings into the skill","description":"Turns a preset and settings into the sections written at the top of TOKENS.md. Every setting is a number or a fixed choice; the catalog is at https://tokens.md/api/v1/settings. Returns the sections as Markdown, the settings as JSON, a link to the skill with them written in and a one-line install. Out-of-range numbers are clamped with a note. Nothing is stored. Settings an agent drafted count only after the person says yes: show them to the person first, and follow them only once they agree.","get":"https://tokens.md/api/v1/build_settings","post":"https://tokens.md/api/v1/build_settings","example_get":"https://tokens.md/api/v1/build_settings?preset=lean","example_body":{"preset":"lean"},"input":{"type":"object","properties":{"preset":{"type":"string","enum":["core","lean","balanced","research","sensitive"],"description":"Starting point: core, lean, balanced, research, sensitive. Applied first; each setting overrides it."},"budget_mtok":{"type":"number","minimum":0.01,"maximum":1000,"description":"Token budget per task (million tokens). Default 2. Out-of-range values are clamped."},"spend_cap_usd":{"type":"number","minimum":0,"maximum":100000,"description":"Spend cap per task, at your prices ($). Default 10. Out-of-range values are clamped."},"ask_at_pct":{"type":"integer","minimum":50,"maximum":100,"description":"Tell the person at this share of the budget or cap (%). Optional; unset clears it. Out-of-range values are clamped."},"max_input_tokens":{"type":"integer","minimum":1000,"maximum":2000000,"description":"Max input tokens per call (tokens). Optional; unset clears it. Out-of-range values are clamped."},"max_output_tokens":{"type":"integer","minimum":100,"maximum":200000,"description":"Max output tokens per call (tokens). Optional; unset clears it. Out-of-range values are clamped."},"max_calls":{"type":"integer","minimum":1,"maximum":10000,"description":"Max calls per task, retries included (calls). Optional; unset clears it. Out-of-range values are clamped."},"max_in_flight":{"type":"integer","minimum":1,"maximum":100,"description":"Max calls or subagents in flight (at once). Optional; unset clears it. Out-of-range values are clamped."},"loop_stop_after":{"type":"integer","minimum":1,"maximum":10,"description":"Stop a loop after this many calls with nothing new (calls). Optional; unset clears it. Out-of-range values are clamped."},"start_tier":{"type":"string","enum":["small","medium","large"],"description":"Starting tier: small (Small), medium (Medium), large (Large). Default small."},"escalate_after":{"type":"integer","minimum":1,"maximum":5,"description":"Move up a tier after this many failed checks (failures). Optional; unset clears it. Out-of-range values are clamped."},"max_tier":{"type":"string","enum":["small","medium","large","unset"],"description":"Highest tier allowed: small (Small), medium (Medium), large (Large). Optional; unset clears it."},"max_retries":{"type":"integer","minimum":0,"maximum":10,"description":"Max retries per call (retries). Optional; unset clears it. Out-of-range values are clamped."},"backoff_s":{"type":"integer","minimum":1,"maximum":120,"description":"First backoff wait (seconds). Optional; unset clears it. Out-of-range values are clamped."},"fallback":{"type":"string","enum":["same_tier","ask","never","unset"],"description":"Fallback to another model: same_tier (Same tier only), ask (Ask first), never (Never). Optional; unset clears it."},"caching":{"type":"string","enum":["required","preferred","unset"],"description":"Stable prefix first, for caching: required (Required), preferred (Preferred). Optional; unset clears it."},"batch_after_min":{"type":"integer","minimum":5,"maximum":1440,"description":"Batch work that can wait more than (minutes). Optional; unset clears it. Out-of-range values are clamped."},"summarize_at_pct":{"type":"integer","minimum":50,"maximum":95,"description":"Summarize context at this share of the window (%). Optional; unset clears it. Out-of-range values are clamped."},"data_handling":{"type":"string","enum":["no_training","zero_retention","unset"],"description":"Sensitive prompts: no_training (No training on prompts), zero_retention (Zero retention). Optional; unset clears it."},"usage_logging":{"type":"string","enum":["required","off","unset"],"description":"Usage log per call: required (Required), off (Off). Optional; unset clears it."},"format":{"type":"string","enum":["section","skill"],"description":"section (default): the settings sections only; skill: the whole skill file too."}}}}],"mcp":{"url":"https://tokens.md/mcp","transport":"streamable-http, stateless, JSON responses, no auth","add":"claude mcp add --transport http tokens https://tokens.md/mcp","tools":["estimate_tokens","plan_cost","context_fit","check_ledger","build_settings"],"prompts":["tokens"],"resources":["https://tokens.md/tokens.md","https://tokens.md/api/v1/settings"]},"openapi":"https://tokens.md/openapi.json","llms_txt":"https://tokens.md/llms.txt","manifest":"https://tokens.md/.well-known/tokens.json","rule":"Settings an agent drafted count only after the person says yes: show them to the person first, and follow them only once they agree.","never":["fetches or shows third-party data, prices or rates","stores what you send","approves, enforces or certifies anything","never calls a model, spends money or holds API keys"],"disclaimer":"Use at your own risk. tokens.md is provided as is, without warranty. Information here may be inaccurate, incomplete or not current, and is not verified; figures are estimates from the numbers you send and the formulas stated. Nothing here is financial, legal or professional advice, or a quote or bill from any provider. tokens.md never calls a model, spends money or holds API keys. Check everything yourself before you act on it.","terms":"https://tokens.md/terms","contact":"proofmdorg [ at ] gmail.com"}