import os
from pathlib import Path
from dotenv import load_dotenv
from garminconnect import Garmin, GarminConnectAuthenticationError
from garth.exc import GarthException
# Load environment variables
env_path = Path(__file__).parent / ".env"
load_dotenv(dotenv_path=env_path)
def get_mfa_from_input() -> str:
"""Prompt user for MFA code."""
print("\nš Garmin Connect MFA required.")
print("š§ Please check your email for the verification code.")
return input("Enter MFA code: ")
def authenticate():
"""Performs a one-time interactive authentication to generate tokens."""
email = os.environ.get("GARMIN_EMAIL")
password = os.environ.get("GARMIN_PASSWORD")
tokenstore = os.path.expanduser(os.getenv("GARMINTOKENS", "~/.garminconnect"))
backup_store = tokenstore + "_backup"
if not email or not password:
print("ā GARMIN_EMAIL and GARMIN_PASSWORD must be set in .env")
return False
print("š Starting one-time interactive authentication...")
# Temporarily move existing tokens aside to force fresh login
if os.path.exists(tokenstore):
print(f"š Moving existing tokens to {backup_store} for fresh login...")
if os.path.exists(backup_store):
import shutil
shutil.rmtree(backup_store)
os.rename(tokenstore, backup_store)
try:
# Initialize with credentials and MFA prompt
api = Garmin(email, password, prompt_mfa=get_mfa_from_input)
# This will trigger the login and MFA prompt if needed
api.login()
# Manually save the tokens to ensure they are written
api.garth.dump(tokenstore)
print("\nā
Authentication successful!")
print(f"š¾ Tokens have been saved to: {tokenstore}")
# Clean up backup
if os.path.exists(backup_store):
import shutil
shutil.rmtree(backup_store)
print("šļø Cleaned up backup tokens")
print("You can now run the main server script: python garmin_mcp_server_fixed.py")
return True
except (GarthException, GarminConnectAuthenticationError) as e:
print(f"ā Authentication failed: {e}")
# Restore backup if authentication failed
if os.path.exists(backup_store):
if os.path.exists(tokenstore):
import shutil
shutil.rmtree(tokenstore)
os.rename(backup_store, tokenstore)
print("š Restored original tokens")
return False
except Exception as e:
print(f"ā An unexpected error occurred: {e}")
# Restore backup if authentication failed
if os.path.exists(backup_store):
if os.path.exists(tokenstore):
import shutil
shutil.rmtree(tokenstore)
os.rename(backup_store, tokenstore)
print("š Restored original tokens")
return False
if __name__ == "__main__":
print("šāāļø Garmin Connect One-Time Setup")
print("========================================")
print("This script will perform the initial authentication to generate your tokens.")
authenticate()