#!/usr/bin/env python3 """ Fetch Claude.ai usage limits by connecting to existing Chrome session. Requires: pip install playwright Usage: python3 claude-usage.py [--json] """ import asyncio import json import re import sys from playwright.async_api import async_playwright CDP_URL = "http://127.0.0.1:9222" # Chrome DevTools Protocol async def get_usage(): async with async_playwright() as p: try: # Connect to existing Chrome instance browser = await p.chromium.connect_over_cdp(CDP_URL) except Exception as e: print(f"Error: Can't connect to Chrome at {CDP_URL}", file=sys.stderr) print("Make sure Chrome is running with: --remote-debugging-port=9222", file=sys.stderr) sys.exit(1) # Get the default context (existing session with cookies) context = browser.contexts[0] if browser.contexts else await browser.new_context() page = await context.new_page() try: await page.goto("https://claude.ai/settings/usage", wait_until="networkidle", timeout=30000) await page.wait_for_selector("text=Plan usage limits", timeout=10000) content = await page.content() # Parse usage data usage = {} # Current session session_match = re.search(r'Current session.*?(\d+)%\s*used', content, re.DOTALL) if session_match: usage['session_percent'] = int(session_match.group(1)) reset_match = re.search(r'Resets in\s*(\d+)\s*hr\s*(\d+)\s*min', content) if reset_match: usage['session_resets_hr'] = int(reset_match.group(1)) usage['session_resets_min'] = int(reset_match.group(2)) # Weekly limits - All models weekly_match = re.search(r'All models.*?(\d+)%\s*used', content, re.DOTALL) if weekly_match: usage['weekly_percent'] = int(weekly_match.group(1)) weekly_reset_match = re.search(r'Resets\s*(Sun|Mon|Tue|Wed|Thu|Fri|Sat)\s*(\d+:\d+\s*[AP]M)', content) if weekly_reset_match: usage['weekly_resets'] = f"{weekly_reset_match.group(1)} {weekly_reset_match.group(2)}" # Sonnet only sonnet_match = re.search(r'Sonnet only.*?(\d+)%\s*used', content, re.DOTALL) if sonnet_match: usage['sonnet_percent'] = int(sonnet_match.group(1)) return usage except Exception as e: print(f"Error fetching usage: {e}", file=sys.stderr) sys.exit(1) finally: await page.close() def main(): usage = asyncio.run(get_usage()) if "--json" in sys.argv: print(json.dumps(usage)) else: print(f"📊 Claude.ai Usage") print(f" Session: {usage.get('session_percent', '?')}% (resets in {usage.get('session_resets_hr', '?')}h {usage.get('session_resets_min', '?')}m)") print(f" Weekly: {usage.get('weekly_percent', '?')}% (resets {usage.get('weekly_resets', '?')})") print(f" Sonnet: {usage.get('sonnet_percent', '?')}%") if __name__ == "__main__": main()