Skip to content

Instantly share code, notes, and snippets.

@subframe7536
Last active August 30, 2025 18:21
Show Gist options
  • Select an option

  • Save subframe7536/c708236c7e5c01fbc7f34dcf7c5ab937 to your computer and use it in GitHub Desktop.

Select an option

Save subframe7536/c708236c7e5c01fbc7f34dcf7c5ab937 to your computer and use it in GitHub Desktop.
Claude Code Env Manager
#!/usr/bin/env python3
"""
Claude Configuration Manager - Simplified and Optimized
Manages API configurations for Claude with multiple presets support.
"""
import argparse
import json
import os
import sys
from pathlib import Path
from typing import Dict, Optional, Tuple
class ConfigManager:
"""Handles all configuration operations for Claude API settings."""
def __init__(self):
self.config_path = self._get_config_path()
self.default_base_url = "https://api.anthropic.com"
def _get_config_path(self) -> Path:
"""Get configuration file path from environment or default location."""
if "CC_CONFIG" in os.environ:
return Path(os.environ["CC_CONFIG"])
return Path.home() / ".config" / "cc.config.json"
def load_config(self) -> Dict:
"""Load configuration from file, return empty config if file doesn't exist."""
if not self.config_path.exists():
return {"presets": {}, "active": ""}
try:
with open(self.config_path, "r") as f:
return json.load(f)
except (json.JSONDecodeError, IOError) as e:
print(f"Error reading config file: {e}")
return {"presets": {}, "active": ""}
def save_config(self, config: Dict) -> bool:
"""Save configuration to file."""
try:
self.config_path.parent.mkdir(parents=True, exist_ok=True)
with open(self.config_path, "w") as f:
json.dump(config, f, indent=2)
return True
except IOError as e:
print(f"Error saving config: {e}")
return False
def get_presets(self) -> Dict:
"""Get all presets from configuration."""
return self.load_config().get("presets", {})
def get_active_name(self) -> str:
"""Get the name of the active preset."""
return self.load_config().get("active", "")
def get_active_preset(self) -> Optional[Dict]:
"""Get the currently active preset configuration."""
config = self.load_config()
presets = self.get_presets()
active_name = self.get_active_name()
if not active_name or active_name not in presets:
# Auto-select first available preset
if presets:
active_name = next(iter(presets.keys()))
config["active"] = active_name
self.save_config(config)
print(f"Auto-selected preset: {active_name}")
return presets.get(active_name) if active_name else None
def set_preset(self, name: str, base_url: str, api_key: str) -> bool:
"""Create or update a preset."""
config = self.load_config()
# Use defaults if not provided
if not base_url:
base_url = self.default_base_url
if not api_key:
print("Error: API Key is required")
return False
config.setdefault("presets", {})[name] = {
"base_url": base_url,
"api_key": api_key,
}
config["active"] = name
return self.save_config(config)
def switch_preset(self, name: str) -> bool:
"""Switch to a different preset."""
config = self.load_config()
presets = self.get_presets()
if name not in presets:
print(f"Preset '{name}' not found")
return False
config["active"] = name
return self.save_config(config)
def delete_preset(self, name: str) -> bool:
"""Delete a preset."""
config = self.load_config()
presets = self.get_presets()
if name not in presets:
print(f"Preset '{name}' not found")
return False
del presets[name]
# If we deleted the active preset, switch to another one
if self.get_active_name() == name:
config["active"] = next(iter(presets.keys())) if presets else ""
return self.save_config(config)
def apply_to_environment(self) -> bool:
"""Apply the active preset to environment variables."""
preset = self.get_active_preset()
if not preset:
print("No active preset available")
return False
os.environ["ANTHROPIC_BASE_URL"] = preset["base_url"]
os.environ["ANTHROPIC_AUTH_TOKEN"] = preset["api_key"]
return True
def parse_env(self) -> Tuple[str | None, str | None, bool]:
"""Check if environment variables match the active preset."""
env_base_url = os.environ.get("ANTHROPIC_BASE_URL")
env_api_key = os.environ.get("ANTHROPIC_AUTH_TOKEN")
preset = self.get_active_preset()
is_applied = False
if preset:
is_applied = (
env_base_url == preset["base_url"]
and env_api_key == preset["api_key"]
)
return (env_base_url, env_api_key, is_applied)
def mask_api_key(api_key: str) -> str:
"""Mask API key for display purposes."""
if not api_key or len(api_key) < 8:
return "<INVALID>"
return f"{api_key[:4]}...{api_key[-4:]}"
def show_status(config_manager: ConfigManager, verbose: bool = False):
"""Display current configuration status."""
presets = config_manager.get_presets()
active_name = config_manager.get_active_name()
# Show environment variables
env_base_url, env_api_key, is_synced = config_manager.parse_env()
env_base_url_display = env_base_url or "<EMPTY>"
env_api_key_display = (
mask_api_key(env_api_key) if env_api_key else "<EMPTY>"
)
print("Current Environment:")
print(f" ANTHROPIC_BASE_URL: {env_base_url_display}")
print(f" ANTHROPIC_AUTH_TOKEN: {env_api_key_display}")
print()
if not presets:
print("No presets configured.")
return
# Check if environment is synced with active preset
sync_status = " ✓" if is_synced else " ✗"
print(
f"Active Preset: {active_name or '<NONE>'}{sync_status if active_name else ''}"
)
if verbose:
print(f"Configuration file: {config_manager.config_path}")
for name, preset in presets.items():
status = "*" if name == active_name else " "
print(f"{status} {name}")
def interactive_setup(config_manager: ConfigManager):
"""Interactive configuration setup."""
presets = config_manager.get_presets()
print("=== Claude Configuration Setup ===")
if presets:
show_status(config_manager, verbose=True)
print()
# Get preset name
while True:
preset_name = input("Preset name: ").strip()
if preset_name:
break
print("Preset name cannot be empty!")
# Check if editing existing preset
existing = presets.get(preset_name)
if existing:
print(f"\nEditing existing preset '{preset_name}'")
print("Press Enter to keep current values:")
print(f"Current Base URL: {existing['base_url']}")
print(f"Current API Key: {mask_api_key(existing['api_key'])}")
base_url = input(f"Base URL [{existing['base_url']}]: ").strip()
api_key = input("API Key [unchanged]: ").strip()
base_url = base_url or existing["base_url"]
api_key = api_key or existing["api_key"]
else:
print(f"\nCreating new preset '{preset_name}'")
base_url = (
input(f"Base URL [{config_manager.default_base_url}]: ").strip()
or config_manager.default_base_url
)
api_key = input("API Key: ").strip()
if not api_key:
print("Error: API Key is required for new presets")
return False
# Save configuration
if config_manager.set_preset(preset_name, base_url, api_key):
print(f"\n✓ Preset '{preset_name}' saved and activated")
return True
else:
print("✗ Failed to save configuration")
return False
def print_shell(config_manager: ConfigManager, shell_type: str):
"""Export environment variables for shell evaluation."""
preset = config_manager.get_active_preset()
if not preset:
print("# No active preset available", file=sys.stderr)
return
base_url = preset["base_url"]
api_key = preset["api_key"]
if shell_type in ["bash", "zsh"]:
print(f'export ANTHROPIC_BASE_URL="{base_url}"')
print(f'export ANTHROPIC_AUTH_TOKEN="{api_key}"')
elif shell_type in ["powershell", "pwsh"]:
print(f'$env:ANTHROPIC_BASE_URL="{base_url}"')
print(f'$env:ANTHROPIC_AUTH_TOKEN="{api_key}"')
else:
print(f"Unsupported shell: {shell_type}", file=sys.stderr)
sys.exit(1)
def create_parser():
"""Create and configure the argument parser."""
parser = argparse.ArgumentParser(
prog="cc_manage",
description="Claude Configuration Manager - Manage API configurations with multiple presets",
formatter_class=argparse.RawDescriptionHelpFormatter,
)
subparsers = parser.add_subparsers(
dest="command", help="Available commands", metavar="COMMAND"
)
# Setup command
config_parser = subparsers.add_parser(
"config",
aliases=["set", "setup"],
help="Interactive configuration setup",
)
# Show command
show_parser = subparsers.add_parser(
"show",
aliases=["status", "list"],
help="Show detailed configuration status",
)
# Switch command
switch_parser = subparsers.add_parser(
"switch", aliases=["use"], help="Switch to a different preset"
)
switch_parser.add_argument(
"preset_name", help="Name of the preset to switch to"
)
# Delete command
remove_parser = subparsers.add_parser(
"remove", aliases=["rm"], help="Delete a preset"
)
remove_parser.add_argument(
"preset_name", help="Name of the preset to delete"
)
# Export command
active_parser = subparsers.add_parser(
"active", help="Export environment variables for shell evaluation"
)
active_parser.add_argument(
"shell",
choices=["bash", "zsh", "powershell", "pwsh"],
help="Shell type for export format",
)
# Path command
path_parser = subparsers.add_parser(
"path", help="Show configuration file path"
)
# JSON command
json_parser = subparsers.add_parser(
"json", help="Output configuration as JSON"
)
return parser
def main():
"""Main CLI entry point."""
config_manager = ConfigManager()
parser = create_parser()
# Handle the case where no arguments are provided - show status
if len(sys.argv) < 2:
print(f"Run `{sys.argv[0]} -h` to get usage\n")
show_status(config_manager)
return
try:
args = parser.parse_args()
if args.command in ["setup", "set", "config"]:
interactive_setup(config_manager)
elif args.command in ["show", "status", "list"]:
show_status(config_manager, verbose=True)
elif args.command in ["switch", "use"]:
if config_manager.switch_preset(args.preset_name):
print(f"✓ Switched to preset '{args.preset_name}'")
else:
sys.exit(1)
if config_manager.apply_to_environment():
print("✓ Configuration loaded to environment")
show_status(config_manager)
else:
sys.exit(1)
elif args.command in ["remove", "rm"]:
if config_manager.delete_preset(args.preset_name):
print(f"✓ Deleted preset '{args.preset_name}'")
else:
sys.exit(1)
elif args.command == "active":
print_shell(config_manager, args.shell)
elif args.command == "path":
print(config_manager.config_path)
elif args.command == "json":
config = config_manager.load_config()
print(json.dumps(config, indent=2))
except KeyboardInterrupt:
print("\n\nOperation cancelled.")
sys.exit(1)
except Exception as e:
print(f"Error: {e}")
sys.exit(1)
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment