{"id":51104812,"url":"https://github.com/pozii/tokensaver","last_synced_at":"2026-06-24T13:30:59.304Z","repository":{"id":366369532,"uuid":"1276034423","full_name":"pozii/tokensaver","owner":"pozii","description":"MCP server that cuts AI agent token costs by up to 97% — compression, caching, pruning, web extraction","archived":false,"fork":false,"pushed_at":"2026-06-21T13:19:20.000Z","size":33,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-21T15:12:55.920Z","etag":null,"topics":["ai","claude","context-compression","cost-reduction","fastmcp","llm","mcp","mcp-server","openai","python","token-optimization"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pozii.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-06-21T13:09:25.000Z","updated_at":"2026-06-21T13:21:53.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/pozii/tokensaver","commit_stats":null,"previous_names":["pozii/tokensaver"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/pozii/tokensaver","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pozii%2Ftokensaver","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pozii%2Ftokensaver/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pozii%2Ftokensaver/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pozii%2Ftokensaver/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pozii","download_url":"https://codeload.github.com/pozii/tokensaver/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pozii%2Ftokensaver/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34735263,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-24T02:00:07.484Z","response_time":106,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai","claude","context-compression","cost-reduction","fastmcp","llm","mcp","mcp-server","openai","python","token-optimization"],"created_at":"2026-06-24T13:30:59.237Z","updated_at":"2026-06-24T13:30:59.299Z","avatar_url":"https://github.com/pozii.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n# TokenSaver MCP\n\n**Cut your AI API costs by up to 97% — without changing a single prompt.**\n\n[![License](https://img.shields.io/badge/license-Apache%202.0-blue.svg)](LICENSE)\n[![Python](https://img.shields.io/badge/python-3.11%2B-blue)](https://www.python.org)\n[![MCP](https://img.shields.io/badge/MCP-compatible-green)](https://modelcontextprotocol.io)\n[![Tests](https://img.shields.io/badge/tests-38%20passing-brightgreen)](#running-tests)\n\nAn [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server that gives AI agents ten tools to measure, compress, cache, and prune token usage — so developers on limited plans can do more with less.\n\n\u003c/div\u003e\n\n---\n\n## Why TokenSaver?\n\nEvery API call sends more tokens than necessary. Conversation history accumulates. Web pages arrive as raw HTML. Tool results get re-fetched on every turn. System prompts bloat over iterations.\n\nTokenSaver intercepts each of these patterns and fixes them at the agent level — no model changes, no prompt engineering, no plan upgrades.\n\n| Scenario | Before | After | Saved |\n|---|---:|---:|---:|\n| 10-turn conversation history | 40,000 tokens | 8,000 tokens | **80%** |\n| Webpage fetch (raw HTML) | 22,000 tokens | 1,200 tokens | **94%** |\n| Bloated system prompt | 600 tokens | 220 tokens | **63%** |\n| Repeated tool call (cached) | 1,500 tokens | 50 tokens | **97%** |\n\n---\n\n## Tools\n\n| Tool | What it does |\n|---|---|\n| `count_tokens` | Measure token cost before sending — decide whether to compress first |\n| `compress_context` | Shrink long text or conversation history with offline LSA summarization |\n| `cache_store` / `cache_get` / `cache_invalidate` | Persist tool results to disk with TTL — never run the same lookup twice |\n| `extract_webpage` | Fetch a URL and return only the readable content, not raw HTML |\n| `summarize_file` | Get a structural + content summary of any file or directory |\n| `prune_conversation` | Remove filler turns and compress old messages in conversation history |\n| `optimize_prompt` | Shorten verbose system prompts while preserving constraints |\n| `advise_context_window` | Diagnose token bloat and get targeted recommendations |\n\nAll tools work **fully offline** — no API key required for core features.\n\n---\n\n## Installation\n\n```bash\ngit clone https://github.com/pozii/tokensaver.git\ncd tokensaver\npip install -e .\n```\n\n\u003e **Python 3.11+ required.** On first use, `compress_context` will auto-download the NLTK `punkt_tab` tokenizer (~2 MB) if not already present.\n\n---\n\n## How it connects to your AI client\n\nTokenSaver has no URL and runs no background server by default. It uses **stdio transport**: the AI client reads your config, spawns `python -m tokensaver` as a child process, and talks to it through stdin/stdout. You never open a port or start anything manually — the client does it for you when it launches.\n\n```\nYour AI client  ──spawn──▶  python -m tokensaver  ──stdio──▶  tools available\n```\n\nThe alternative is **SSE transport**, where you start the server yourself on a local port and the client connects over HTTP. This is useful for multi-agent setups or when multiple clients share the same server instance.\n\n---\n\n## Setup\n\n### Claude Desktop\n\nConfig file location:\n- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`\n- **Windows:** `%APPDATA%\\Claude\\claude_desktop_config.json`\n\n```json\n{\n  \"mcpServers\": {\n    \"tokensaver\": {\n      \"command\": \"python\",\n      \"args\": [\"-m\", \"tokensaver\"]\n    }\n  }\n}\n```\n\nSave the file and restart Claude Desktop. The tokensaver tools will appear in the tool list.\n\n### Claude Code\n\n```bash\nclaude mcp add tokensaver -- python -m tokensaver\n```\n\nOr add manually to `~/.claude/settings.json`:\n\n```json\n{\n  \"mcpServers\": {\n    \"tokensaver\": {\n      \"command\": \"python\",\n      \"args\": [\"-m\", \"tokensaver\"]\n    }\n  }\n}\n```\n\n### OpenCode\n\nConfig file: `~/.config/opencode/config.json`\n\n```json\n{\n  \"mcp\": {\n    \"servers\": {\n      \"tokensaver\": {\n        \"type\": \"local\",\n        \"command\": [\"python\", \"-m\", \"tokensaver\"]\n      }\n    }\n  }\n}\n```\n\n### Any MCP-compatible client (SSE mode)\n\nStart the server once:\n\n```bash\npython -m tokensaver --transport sse --port 8765\n```\n\nThen point your client at:\n\n```\nhttp://localhost:8765/sse\n```\n\n### Fixing Python path issues\n\nIf your system has multiple Python versions and `python` resolves to the wrong one, use the full path:\n\n```bash\n# Find the right Python\nwhich python3        # macOS / Linux\nwhere python         # Windows\n```\n\nThen use the full path in your config:\n\n```json\n{\n  \"mcpServers\": {\n    \"tokensaver\": {\n      \"command\": \"/usr/local/bin/python3\",\n      \"args\": [\"-m\", \"tokensaver\"]\n    }\n  }\n}\n```\n\n```json\n{\n  \"mcpServers\": {\n    \"tokensaver\": {\n      \"command\": \"C:\\\\Python314\\\\python.exe\",\n      \"args\": [\"-m\", \"tokensaver\"]\n    }\n  }\n}\n```\n\n---\n\n## Usage\n\n### Recommended workflow\n\n```\nEach turn:\n  1. count_tokens          → How large is my current context?\n  2. advise_context_window → Am I approaching the model's limit?\n\nBefore expensive tool calls:\n  3. cache_get             → Did I already run this?\n\nWhen fetching web content:\n  4. extract_webpage       → Clean text, not raw HTML\n\nWhen history grows long:\n  5. prune_conversation    → Drop filler turns, compress old ones\n  6. compress_context      → Shrink large injected context blocks\n\nWhen writing system prompts:\n  7. optimize_prompt       → Remove redundant phrasing\n```\n\n### Tool reference\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003ecount_tokens\u003c/strong\u003e — measure before you send\u003c/summary\u003e\n\n```json\n{\n  \"content\": \"Some long text or list of messages...\",\n  \"model\": \"claude-sonnet-4\",\n  \"include_message_overhead\": true\n}\n```\n\nReturns `token_count`, `encoding_used`, `model`. Accepts a plain string or an OpenAI-format message list.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003ecompress_context\u003c/strong\u003e — shrink long text\u003c/summary\u003e\n\n```json\n{\n  \"text\": \"3,000-token context block...\",\n  \"target_tokens\": 600,\n  \"mode\": \"extractive\"\n}\n```\n\n`extractive` (default) uses LSA sentence ranking — free, offline, no API call.  \n`abstractive` uses `claude-haiku` for higher quality — requires `ANTHROPIC_API_KEY`.\n\nReturns `compressed`, `original_tokens`, `compressed_tokens`, `reduction_pct`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003ecache_store / cache_get / cache_invalidate\u003c/strong\u003e — skip repeated work\u003c/summary\u003e\n\n```python\n# Standard pattern: check before running\nkey = cache_key(\"extract_webpage\", {\"url\": \"https://example.com\"})\nhit = cache_get(key=key)\n\nif not hit[\"hit\"]:\n    result = extract_webpage(url=\"https://example.com\")\n    cache_store(key=key, value=str(result), ttl_seconds=3600)\n```\n\nCache is stored on disk at `~/.tokensaver/cache/` and survives server restarts.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eextract_webpage\u003c/strong\u003e — content, not markup\u003c/summary\u003e\n\n```json\n{\n  \"url\": \"https://example.com/article\",\n  \"max_tokens\": 2000,\n  \"include_links\": false,\n  \"include_metadata\": true\n}\n```\n\nUses [trafilatura](https://github.com/adbar/trafilatura) with BeautifulSoup as fallback. Returns `content`, `title`, `token_count`, `truncated`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003esummarize_file\u003c/strong\u003e — understand code without reading it all\u003c/summary\u003e\n\n```json\n{\n  \"path\": \"/home/user/myproject\",\n  \"mode\": \"both\",\n  \"max_tokens\": 500,\n  \"file_extensions\": [\".py\", \".md\"],\n  \"max_depth\": 3\n}\n```\n\n`mode` options: `\"structure\"` (tree only), `\"content\"` (summarized text), `\"both\"`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eprune_conversation\u003c/strong\u003e — clean up history\u003c/summary\u003e\n\n```json\n{\n  \"messages\": [...],\n  \"max_output_tokens\": 2000,\n  \"keep_last_n\": 4,\n  \"prune_strategy\": \"hybrid\"\n}\n```\n\n`\"remove\"` drops filler turns (\"Sure!\", \"Got it.\").  \n`\"compress\"` summarizes older turns in place.  \n`\"hybrid\"` does both — recommended for most cases.\n\nReturns the pruned `messages` list, `original_tokens`, `pruned_tokens`, counts of removed/compressed turns.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eoptimize_prompt\u003c/strong\u003e — shorter system prompts\u003c/summary\u003e\n\n```json\n{\n  \"prompt\": \"Please make sure to always answer questions...\",\n  \"optimization_level\": \"medium\",\n  \"preserve_constraints\": true,\n  \"output_format\": \"prose\"\n}\n```\n\n`\"light\"` removes filler phrases. `\"medium\"` deduplicates sentences. `\"aggressive\"` restructures.  \n`preserve_constraints: true` always keeps sentences containing `never`, `must`, `always`, `do not`.\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eadvise_context_window\u003c/strong\u003e — know what to fix\u003c/summary\u003e\n\n```json\n{\n  \"model\": \"gpt-4o\",\n  \"current_tokens\": 110000,\n  \"messages\": [...],\n  \"target_utilization\": 0.75\n}\n```\n\nReturns `status` (`\"ok\"` / `\"warning\"` / `\"critical\"`), `headroom_tokens`, prioritized `recommendations`, and a per-turn breakdown sorted by token cost.\n\nSupports: GPT-4o, GPT-4o-mini, Claude 3–4 series, Gemini 1.5/2.0/2.5, O1/O3, Llama 3, Mistral.\n\n\u003c/details\u003e\n\n---\n\n## Optional: LLM-backed summarization\n\nFor higher-quality abstractive compression on very large texts (\u003e5,000 tokens):\n\n```bash\npip install \"tokensaver-mcp[llm]\"\n```\n\nSet `ANTHROPIC_API_KEY` in your environment or a `.env` file, then use `mode: \"abstractive\"` in `compress_context`.\n\n---\n\n## Running Tests\n\n```bash\npip install -e \".[dev]\"\npython -m pytest tests/ -v\n```\n\n38 tests — all offline, no API key or network required.\n\n---\n\n## Project Structure\n\n```\nsrc/tokensaver/\n  server.py          # FastMCP app, tool registration\n  models.py          # Context window table, shared types\n  tools/\n    counter.py       # count_tokens\n    compress.py      # compress_context\n    cache.py         # cache_store / cache_get / cache_invalidate\n    extractor.py     # extract_webpage\n    summarizer.py    # summarize_file\n    pruner.py        # prune_conversation\n    optimizer.py     # optimize_prompt\n    advisor.py       # advise_context_window\n  utils/\n    token_utils.py   # tiktoken wrapper\n    text_utils.py    # sentence splitting, deduplication\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpozii%2Ftokensaver","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpozii%2Ftokensaver","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpozii%2Ftokensaver/lists"}