Skip to main content
Glama
measure_token_savings.py14.6 kB
#!/usr/bin/env python3 """Script to measure token savings from context engineering optimizations. Compares old vs new response formats and estimates token savings. Uses tiktoken for accurate token counting (cl100k_base encoding used by Claude). """ import json import sys try: import tiktoken except ImportError: print("Installing tiktoken...") import subprocess subprocess.check_call([sys.executable, "-m", "pip", "install", "tiktoken", "-q"]) import tiktoken def count_tokens(text: str) -> int: """Count tokens using cl100k_base encoding (Claude-compatible).""" enc = tiktoken.get_encoding("cl100k_base") return len(enc.encode(text)) def compare_responses(name: str, old: dict, new: dict) -> dict: """Compare old and new response formats.""" old_json = json.dumps(old, indent=2) new_json = json.dumps(new, indent=2) old_tokens = count_tokens(old_json) new_tokens = count_tokens(new_json) saved = old_tokens - new_tokens pct = (saved / old_tokens * 100) if old_tokens > 0 else 0 return { "name": name, "old_tokens": old_tokens, "new_tokens": new_tokens, "saved": saved, "pct": pct, } # ==================== TEST CASES ==================== test_cases = [] # 1. list_repositories (2 repos) test_cases.append(("list_repositories", { "count": 2, "search": "api", "query": 'name ~ "api"', "repositories": [ {"name": "api-gateway", "full_name": "ws/api-gateway", "description": "API Gateway service", "is_private": True, "project": "BACKEND"}, {"name": "api-docs", "full_name": "ws/api-docs", "description": "API Documentation", "is_private": False, "project": "DOCS"}, ] }, { "repositories": [ {"name": "api-gateway", "full_name": "ws/api-gateway", "description": "API Gateway service", "private": True, "project": "BACKEND"}, {"name": "api-docs", "full_name": "ws/api-docs", "description": "API Documentation", "private": False, "project": "DOCS"}, ] })) # 2. create_repository test_cases.append(("create_repository", { "success": True, "name": "my-new-repo", "full_name": "workspace/my-new-repo", "clone_urls": { "https": "https://bitbucket.org/workspace/my-new-repo.git", "ssh": "git@bitbucket.org:workspace/my-new-repo.git", "html": "https://bitbucket.org/workspace/my-new-repo" }, "html_url": "https://bitbucket.org/workspace/my-new-repo" }, { "name": "my-new-repo", "full_name": "workspace/my-new-repo", "clone_urls": { "https": "https://bitbucket.org/workspace/my-new-repo.git", "ssh": "git@bitbucket.org:workspace/my-new-repo.git", "html": "https://bitbucket.org/workspace/my-new-repo" }, })) # 3. delete_repository test_cases.append(("delete_repository", { "success": True, "message": "Repository 'my-repo' deleted" }, {})) # 4. create_pull_request test_cases.append(("create_pull_request", { "success": True, "id": 123, "title": "Add new feature", "state": "OPEN", "url": "https://bitbucket.org/ws/repo/pull-requests/123", "source_branch": "feature/new-feature", "destination_branch": "main", }, { "id": 123, "title": "Add new feature", "state": "OPEN", "url": "https://bitbucket.org/ws/repo/pull-requests/123", })) # 5. list_pull_requests (3 PRs) test_cases.append(("list_pull_requests", { "count": 3, "state_filter": "OPEN", "pull_requests": [ {"id": 1, "title": "PR 1", "state": "OPEN", "author": "John", "source_branch": "feat-1", "destination_branch": "main", "url": "https://bb.org/pr/1"}, {"id": 2, "title": "PR 2", "state": "OPEN", "author": "Jane", "source_branch": "feat-2", "destination_branch": "main", "url": "https://bb.org/pr/2"}, {"id": 3, "title": "PR 3", "state": "OPEN", "author": "Bob", "source_branch": "feat-3", "destination_branch": "main", "url": "https://bb.org/pr/3"}, ] }, { "pull_requests": [ {"id": 1, "title": "PR 1", "state": "OPEN", "author": "John", "source_branch": "feat-1", "destination_branch": "main", "url": "https://bb.org/pr/1"}, {"id": 2, "title": "PR 2", "state": "OPEN", "author": "Jane", "source_branch": "feat-2", "destination_branch": "main", "url": "https://bb.org/pr/2"}, {"id": 3, "title": "PR 3", "state": "OPEN", "author": "Bob", "source_branch": "feat-3", "destination_branch": "main", "url": "https://bb.org/pr/3"}, ] })) # 6. trigger_pipeline test_cases.append(("trigger_pipeline", { "success": True, "uuid": "{abc-123-def-456}", "build_number": 42, "state": "PENDING", "branch": "main", "created_on": "2025-01-15T14:30:45.123456Z", }, { "uuid": "{abc-123-def-456}", "build_number": 42, "state": "PENDING", })) # 7. list_commits (5 commits) test_cases.append(("list_commits", { "count": 5, "branch": "main", "path": None, "commits": [ {"hash": "abc123def456", "full_hash": "abc123def456789012345678901234567890", "message": "First commit", "author": "John <john@example.com>", "date": "2025-01-15T14:30:45.123456Z"}, {"hash": "def456ghi789", "full_hash": "def456ghi789012345678901234567890abcd", "message": "Second commit", "author": "Jane <jane@example.com>", "date": "2025-01-14T10:20:30.456789Z"}, {"hash": "ghi789jkl012", "full_hash": "ghi789jkl012345678901234567890efgh", "message": "Third commit", "author": "Bob <bob@example.com>", "date": "2025-01-13T08:15:22.789012Z"}, {"hash": "jkl012mno345", "full_hash": "jkl012mno345678901234567890ijkl", "message": "Fourth commit", "author": "Alice <alice@example.com>", "date": "2025-01-12T16:45:55.012345Z"}, {"hash": "mno345pqr678", "full_hash": "mno345pqr678901234567890mnop", "message": "Fifth commit", "author": "Charlie <charlie@example.com>", "date": "2025-01-11T12:00:00.345678Z"}, ] }, { "commits": [ {"hash": "abc123def456", "message": "First commit", "author": "John <john@example.com>", "date": "2025-01-15T14:30"}, {"hash": "def456ghi789", "message": "Second commit", "author": "Jane <jane@example.com>", "date": "2025-01-14T10:20"}, {"hash": "ghi789jkl012", "message": "Third commit", "author": "Bob <bob@example.com>", "date": "2025-01-13T08:15"}, {"hash": "jkl012mno345", "message": "Fourth commit", "author": "Alice <alice@example.com>", "date": "2025-01-12T16:45"}, {"hash": "mno345pqr678", "message": "Fifth commit", "author": "Charlie <charlie@example.com>", "date": "2025-01-11T12:00"}, ] })) # 8. compare_commits (10 files) test_cases.append(("compare_commits", { "base": "main", "head": "feature-branch", "files_changed": 10, "files": [ {"path": "src/main.py", "status": "modified", "lines_added": 50, "lines_removed": 20}, {"path": "src/utils.py", "status": "modified", "lines_added": 15, "lines_removed": 5}, {"path": "src/new_module.py", "status": "added", "lines_added": 100, "lines_removed": 0}, {"path": "tests/test_main.py", "status": "modified", "lines_added": 30, "lines_removed": 10}, {"path": "tests/test_utils.py", "status": "modified", "lines_added": 20, "lines_removed": 8}, {"path": "docs/README.md", "status": "modified", "lines_added": 25, "lines_removed": 5}, {"path": "config/settings.py", "status": "modified", "lines_added": 10, "lines_removed": 3}, {"path": "old_file.py", "status": "removed", "lines_added": 0, "lines_removed": 150}, {"path": "scripts/deploy.sh", "status": "added", "lines_added": 45, "lines_removed": 0}, {"path": "requirements.txt", "status": "modified", "lines_added": 5, "lines_removed": 2}, ] }, { "files": [ {"path": "src/main.py", "status": "modified", "+": 50, "-": 20}, {"path": "src/utils.py", "status": "modified", "+": 15, "-": 5}, {"path": "src/new_module.py", "status": "added", "+": 100, "-": 0}, {"path": "tests/test_main.py", "status": "modified", "+": 30, "-": 10}, {"path": "tests/test_utils.py", "status": "modified", "+": 20, "-": 8}, {"path": "docs/README.md", "status": "modified", "+": 25, "-": 5}, {"path": "config/settings.py", "status": "modified", "+": 10, "-": 3}, {"path": "old_file.py", "status": "removed", "+": 0, "-": 150}, {"path": "scripts/deploy.sh", "status": "added", "+": 45, "-": 0}, {"path": "requirements.txt", "status": "modified", "+": 5, "-": 2}, ] })) # 9. get_repository (detailed) test_cases.append(("get_repository", { "name": "my-repo", "full_name": "ws/my-repo", "description": "A sample repository for testing purposes", "is_private": True, "created_on": "2025-01-01T14:30:45.123456+00:00", "updated_on": "2025-01-15T09:15:32.789012+00:00", "mainbranch": "main", "clone_urls": {"https": "https://bitbucket.org/ws/my-repo.git", "ssh": "git@bitbucket.org:ws/my-repo.git"}, "project": "DS" }, { "name": "my-repo", "full_name": "ws/my-repo", "description": "A sample repository for testing purposes", "private": True, "created": "2025-01-01T14:30", "updated": "2025-01-15T09:15", "mainbranch": "main", "clone_urls": {"https": "https://bitbucket.org/ws/my-repo.git", "ssh": "git@bitbucket.org:ws/my-repo.git"}, "project": "DS" })) # 10. list_branches (5 branches) test_cases.append(("list_branches", { "count": 5, "branches": [ {"name": "main", "target_hash": "abc123def456", "target_message": "Merge PR #42", "target_date": "2025-01-15T14:30:45.123456Z"}, {"name": "develop", "target_hash": "def456ghi789", "target_message": "WIP: new feature", "target_date": "2025-01-14T10:20:30.456789Z"}, {"name": "feature/auth", "target_hash": "ghi789jkl012", "target_message": "Add authentication", "target_date": "2025-01-13T08:15:22.789012Z"}, {"name": "feature/api", "target_hash": "jkl012mno345", "target_message": "API endpoints", "target_date": "2025-01-12T16:45:55.012345Z"}, {"name": "hotfix/bug", "target_hash": "mno345pqr678", "target_message": "Fix critical bug", "target_date": "2025-01-11T12:00:00.345678Z"}, ] }, { "branches": [ {"name": "main", "commit": "abc123def456", "message": "Merge PR #42", "date": "2025-01-15T14:30"}, {"name": "develop", "commit": "def456ghi789", "message": "WIP: new feature", "date": "2025-01-14T10:20"}, {"name": "feature/auth", "commit": "ghi789jkl012", "message": "Add authentication", "date": "2025-01-13T08:15"}, {"name": "feature/api", "commit": "jkl012mno345", "message": "API endpoints", "date": "2025-01-12T16:45"}, {"name": "hotfix/bug", "commit": "mno345pqr678", "message": "Fix critical bug", "date": "2025-01-11T12:00"}, ] })) # 11. approve_pr test_cases.append(("approve_pr", { "success": True, "pr_id": 123, "approved_by": "John Doe", "approved_on": "2025-01-15T14:30:45.123456Z", }, { "pr_id": 123, "approved_by": "John Doe", })) # 12. list_pipelines (3 pipelines) test_cases.append(("list_pipelines", { "count": 3, "pipelines": [ {"uuid": "{pipe-1}", "build_number": 100, "state": "COMPLETED", "result": "SUCCESSFUL", "branch": "main", "created_on": "2025-01-15T14:30:45.123456Z"}, {"uuid": "{pipe-2}", "build_number": 99, "state": "COMPLETED", "result": "FAILED", "branch": "develop", "created_on": "2025-01-14T10:20:30.456789Z"}, {"uuid": "{pipe-3}", "build_number": 98, "state": "IN_PROGRESS", "result": None, "branch": "feature/x", "created_on": "2025-01-13T08:15:22.789012Z"}, ] }, { "pipelines": [ {"uuid": "{pipe-1}", "build_number": 100, "state": "COMPLETED", "result": "SUCCESSFUL", "branch": "main", "created": "2025-01-15T14:30"}, {"uuid": "{pipe-2}", "build_number": 99, "state": "COMPLETED", "result": "FAILED", "branch": "develop", "created": "2025-01-14T10:20"}, {"uuid": "{pipe-3}", "build_number": 98, "state": "IN_PROGRESS", "result": None, "branch": "feature/x", "created": "2025-01-13T08:15"}, ] })) def main(): print("=" * 70) print("TOKEN SAVINGS ANALYSIS - Context Engineering v0.6.0") print("=" * 70) print() results = [] total_old = 0 total_new = 0 for name, old, new in test_cases: result = compare_responses(name, old, new) results.append(result) total_old += result["old_tokens"] total_new += result["new_tokens"] # Print individual results print(f"{'Tool':<25} {'Old':>8} {'New':>8} {'Saved':>8} {'%':>8}") print("-" * 70) for r in results: print(f"{r['name']:<25} {r['old_tokens']:>8} {r['new_tokens']:>8} {r['saved']:>8} {r['pct']:>7.1f}%") print("-" * 70) # Summary total_saved = total_old - total_new total_pct = (total_saved / total_old * 100) if total_old > 0 else 0 print(f"{'TOTAL':<25} {total_old:>8} {total_new:>8} {total_saved:>8} {total_pct:>7.1f}%") print() # Categorized summary print("=" * 70) print("SAVINGS BY CATEGORY") print("=" * 70) categories = { "Writes (create/delete/update)": ["create_repository", "delete_repository", "create_pull_request", "trigger_pipeline", "approve_pr"], "Lists": ["list_repositories", "list_pull_requests", "list_commits", "list_branches", "list_pipelines"], "Detailed responses": ["get_repository", "compare_commits"], } for cat_name, tools in categories.items(): cat_results = [r for r in results if r["name"] in tools] if cat_results: cat_old = sum(r["old_tokens"] for r in cat_results) cat_new = sum(r["new_tokens"] for r in cat_results) cat_saved = cat_old - cat_new cat_pct = (cat_saved / cat_old * 100) if cat_old > 0 else 0 print(f"{cat_name}: {cat_saved} tokens saved ({cat_pct:.1f}%)") print() print("=" * 70) print(f"OVERALL: {total_saved} tokens saved ({total_pct:.1f}% reduction)") print("=" * 70) # Cost estimation (rough, based on Claude pricing) # Claude Sonnet: ~$3/M input, $15/M output input_cost_per_m = 3.0 output_cost_per_m = 15.0 # Assume tool responses are primarily input tokens for the model cost_saved_per_1000_calls = (total_saved / len(test_cases)) * 1000 / 1_000_000 * input_cost_per_m print() print(f"Estimated cost savings: ${cost_saved_per_1000_calls:.4f} per 1000 tool calls") print(f"(Based on average of {total_saved // len(test_cases)} tokens saved per call)") if __name__ == "__main__": main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/JaviMaligno/mcp-server-bitbucket'

If you have feedback or need assistance with the MCP directory API, please join our Discord server