"""Local secure launcher that loads routes and Keychain-backed MCP secrets.""" from __future__ import annotations import argparse import os import stat import subprocess from pathlib import Path from typing import Dict, Optional, Sequence from arr_mcp.run import main as run_mcp KEYCHAIN_ACCOUNT = "arr-web" KEYCHAIN_SERVICES = { "OSS_ACCESS_KEY_ID": "com.chillishark.arr.oss-access-key-id", "OSS_ACCESS_KEY_SECRET": "com.chillishark.arr.oss-access-key-secret", "ARR_MCP_BEARER_TOKEN": "com.chillishark.arr.mcp-bearer", } ROUTE_KEYS = frozenset( { "ARR_OSS_REGION", "ARR_OSS_ENDPOINT", "ARR_OSS_BUCKET", "ARR_OBJECT_PREFIX", } ) def _private_route_values(path: Path) -> Dict[str, str]: candidate = path.expanduser() if candidate.is_symlink(): raise ValueError("ARR MCP route configuration is invalid") resolved = candidate.resolve(strict=True) metadata = resolved.stat() if ( not stat.S_ISREG(metadata.st_mode) or metadata.st_uid != os.getuid() or stat.S_IMODE(metadata.st_mode) != 0o600 ): raise ValueError("ARR MCP route configuration is invalid") values: Dict[str, str] = {} for raw in resolved.read_text(encoding="utf-8").splitlines(): line = raw.strip() if not line or line.startswith("#") or "=" not in line: continue key, value = line.split("=", 1) key = key.strip() if key in ROUTE_KEYS: if key in values: raise ValueError("ARR MCP route configuration is invalid") values[key] = value.strip().strip('"').strip("'") if any(not values.get(key) for key in ("ARR_OSS_REGION", "ARR_OSS_BUCKET")): raise ValueError("ARR MCP route configuration is incomplete") return values def _keychain_secret(service: str) -> str: try: completed = subprocess.run( [ "security", "find-generic-password", "-s", service, "-a", KEYCHAIN_ACCOUNT, "-w", ], check=True, capture_output=True, text=True, timeout=10, ) except (OSError, subprocess.SubprocessError): raise ValueError("required ARR MCP Keychain item is unavailable") from None value = completed.stdout.strip() if not value: raise ValueError("required ARR MCP Keychain item is unavailable") return value def load_runtime_environment(route_config: Path) -> None: for key, value in _private_route_values(route_config).items(): os.environ[key] = value for environment_name, service in KEYCHAIN_SERVICES.items(): os.environ[environment_name] = _keychain_secret(service) def _parser() -> argparse.ArgumentParser: parser = argparse.ArgumentParser(add_help=False) parser.add_argument( "--route-config", type=Path, default=Path("~/.config/arr/agent-writeback.env"), ) return parser def main(argv: Optional[Sequence[str]] = None) -> int: args, remaining = _parser().parse_known_args(argv) load_runtime_environment(args.route_config) return run_mcp(remaining) if __name__ == "__main__": raise SystemExit(main())