Files
monarch-mcp-custom/login_setup.py
Ben 6fc09d956f
All checks were successful
Build and Push Monarch MCP Docker Image / build (push) Successful in 8s
feat: add automatic re-authentication with MFA support
Implement automatic token refresh using stored credentials and TOTP MFA secret. When an API call fails with a 401/unauthorized error, the system now transparently re-authenticates using MONARCH_EMAIL, MONARCH_PASSWORD, and MONARCH_MFA_SECRET, then retries the original request.

Changes:
- Add refresh_authentication() function in auth.py for credential-based login
- Create @retry_on_auth_error decorator to handle and retry failed auth calls
- Apply decorator to all MCP tools (get_accounts, get_transactions, etc.)
- Add MONARCH_MFA_SECRET to .env.example with documentation
- Update login_setup.py to instruct users about required env vars
- Replace PROBLEM.md with PLAN.md documenting the implementation
2025-12-24 15:45:43 +00:00

79 lines
2.6 KiB
Python

#!/usr/bin/env python3
"""
Interactive Monarch Money login with MFA support.
Saves session securely and provides the token for Docker environment.
"""
import asyncio
import getpass
import sys
from pathlib import Path
# Add src to sys.path
sys.path.insert(0, str(Path(__file__).parent / "src"))
from monarchmoney import MonarchMoney, RequireMFAException
from dotenv import load_dotenv
from monarch_mcp_custom.auth import save_token
async def main():
load_dotenv()
print("\n🏦 Monarch Money - Custom MCP Setup")
print("=" * 45)
print("This script will help you obtain an authentication token")
print("for use in your Docker .env file.\n")
mm = MonarchMoney()
try:
email = input("Email: ")
password = getpass.getpass("Password: ")
try:
await mm.login(email, password, use_saved_session=False, save_session=True)
print("✅ Login successful!")
except RequireMFAException:
print("🔐 MFA code required")
mfa_code = input("Two Factor Code: ")
await mm.multi_factor_authenticate(email, password, mfa_code)
print("✅ MFA authentication successful")
token = mm.token
if token:
print("\n" + "!" * 50)
print("🔑 YOUR MONARCH_TOKEN:")
print(f"\n{token}\n")
print("!" * 50)
print("\nCopy the token above into your .env file as:")
print(f"MONARCH_TOKEN={token}")
# Also save to local keyring for convenience
save_token(token)
print("\n✅ Token also saved to local system keyring.")
print("\n" + "=" * 50)
print("📝 IMPORTANT: For automatic re-authentication")
print("=" * 50)
print("\nIf you have MFA enabled on your Monarch account,")
print("add your MONARCH_MFA_SECRET to your .env file:")
print("\n MONARCH_MFA_SECRET=your_totp_secret_here")
print("\nYou should have saved this secret when you first")
print("set up Google Authenticator/Authy for Monarch Money.")
print("\nThis allows the MCP server to automatically re-authenticate")
print("when your token expires.")
print("\nYou also need to add your credentials:")
print(" MONARCH_EMAIL=your_email@example.com")
print(" MONARCH_PASSWORD=your_password")
print("=" * 50)
else:
print("❌ Failed to retrieve token from MonarchMoney instance.")
except Exception as e:
print(f"\n❌ Setup failed: {e}")
if __name__ == "__main__":
asyncio.run(main())