feat: add automatic re-authentication with MFA support
All checks were successful
Build and Push Monarch MCP Docker Image / build (push) Successful in 8s

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
This commit is contained in:
Ben
2025-12-24 15:45:43 +00:00
parent 27ef7f0e1e
commit 6fc09d956f
6 changed files with 153 additions and 65 deletions

41
PLAN.md Normal file
View File

@@ -0,0 +1,41 @@
# Implementation Plan: Automatic Re-authentication with MFA
## Problem
The Monarch Money API token expires periodically. Currently, there is no automatic refresh mechanism, causing the MCP server to fail until manually re-authenticated.
## Objective
Implement automatic re-authentication functionality that detects expired tokens and transparently re-authenticates using stored credentials and an MFA secret (TOTP).
## Proposed Solution
Use `pyotp` to generate MFA codes programmatically and wrap API calls with retry logic that handles authentication failures.
## Prerequisites
- `pyotp` library (Installed)
- User needs to add `MONARCH_MFA_SECRET` to their environment variables.
## Implementation Steps
### 1. Update `auth.py`
- Add logic to handle re-authentication using `pyotp`.
- Implement a `login_with_mfa()` function that:
- Uses `MONARCH_EMAIL` and `MONARCH_PASSWORD`.
- Uses `MONARCH_MFA_SECRET` with `pyotp` to generate a TOTP code if MFA is requested.
- Updates the active client session.
### 2. Create Re-authentication Decorator/Wrapper
- Create a Python decorator (e.g., `@retry_on_auth_error`) in `auth.py` or a new utility module.
- This decorator will:
1. Execute the decorated function (API call).
2. Catch specific exceptions indicating authentication failure (e.g., `LoginFailedException`, `RequestFailedException` with 401/403 status).
3. Call the re-authentication logic.
4. Retry the original function.
### 3. Apply Wrapper in `server.py`
- Apply the decorator to the MCP tool implementations (`get_accounts`, `get_transactions`, etc.) or wrap the client calls to ensure they auto-recover from expired tokens.
### 4. Update `login_setup.py`
- Modify the setup script to display the MFA Secret (seed) to the user during the initial login process.
- Instruct the user to save this as `MONARCH_MFA_SECRET` in their `.env` file alongside `MONARCH_TOKEN`.
## Verification
- Test by simulating an expired token and verifying that the system automatically logs in using the MFA secret and completes the request.