Skip to main content

scripts-kimi-token

#!/usr/bin/env python3 """Kimi OAuth token helper for claude-kimi alias (ADR-201).

Reads OAuth credentials from ~/.kimi/credentials/kimi-code.json, refreshes if expired or near expiry, and prints the access_token.

Usage: kimi-token # Print access token (refreshing if needed) kimi-token --check # Print token status without refreshing

Installation: ln -sf $(realpath kimi-token.py) ~/.local/bin/kimi-token chmod +x ~/.local/bin/kimi-token """ import json import sys import time import urllib.request from pathlib import Path

CREDENTIALS_FILE = Path.home() / ".kimi" / "credentials" / "kimi-code.json" CLIENT_ID = "17e5f671-d194-4dfb-9706-5516cb48c098" OAUTH_HOST = "https://auth.kimi.com" REFRESH_THRESHOLD = 300 # Refresh if <5 min remaining

def load_credentials(): if not CREDENTIALS_FILE.exists(): print("ERROR: No Kimi credentials found. Run 'kimi' CLI to login first.", file=sys.stderr) sys.exit(1) return json.loads(CREDENTIALS_FILE.read_text())

def save_credentials(creds): CREDENTIALS_FILE.write_text(json.dumps(creds, ensure_ascii=False))

def refresh_access_token(refresh_token_value): data = ( f"client_id={CLIENT_ID}" f"&grant_type=refresh_token" f"&refresh_token={refresh_token_value}" ).encode() req = urllib.request.Request( f"{OAUTH_HOST}/api/oauth/token", data=data, headers={"Content-Type": "application/x-www-form-urlencoded"}, method="POST", ) with urllib.request.urlopen(req, timeout=10) as resp: result = json.loads(resp.read()) return { "access_token": result["access_token"], "refresh_token": result["refresh_token"], "expires_at": time.time() + float(result["expires_in"]), "scope": result.get("scope", "kimi-code"), "token_type": result.get("token_type", "Bearer"), }

def main(): check_only = "--check" in sys.argv

creds = load_credentials()
expires_at = creds.get("expires_at", 0)
now = time.time()
remaining = expires_at - now

if check_only:
if remaining > 0:
print(f"Token valid for {remaining:.0f}s ({remaining/60:.1f}m)", file=sys.stderr)
else:
print(f"Token expired {-remaining:.0f}s ago", file=sys.stderr)
sys.exit(0)

# If token is still fresh enough, just print it
if remaining > REFRESH_THRESHOLD:
print(creds["access_token"])
return

# Need to refresh
refresh_tok = creds.get("refresh_token", "")
if not refresh_tok:
print("ERROR: No refresh token. Run 'kimi' CLI to login.", file=sys.stderr)
sys.exit(1)

try:
new_creds = refresh_access_token(refresh_tok)
save_credentials(new_creds)
print(new_creds["access_token"])
print(f"Token refreshed (valid for ~15m)", file=sys.stderr)
except Exception as e:
# If refresh fails but we have a token (even expired), try it
if creds.get("access_token"):
print(creds["access_token"])
print(f"WARNING: Token refresh failed ({e}), using existing token", file=sys.stderr)
else:
print(f"ERROR: Token refresh failed: {e}", file=sys.stderr)
sys.exit(1)

if name == "main": main()