The Monarch Money API incorrectly processes @include(if: false) GraphQL
directives, causing errors on goals-related fields. Tool commented out
until upstream issue is resolved. See budget_bug.md for details.
The Monarch Money API returns errors for goals-related GraphQL fields
(lines 119-131 in query). Setting use_legacy_goals=False and use_v2_goals=False
skips these problematic fields while still returning budget data.
The monarchmoney library's get_budgets() returns budgetData.monthlyAmountsByCategory
and categoryGroups, not a simple 'budgets' array. Updated parsing to correctly
extract budget data by category with monthly planned/actual/remaining amounts.
- Add validate_account_id() for get_account_holdings input validation
- Fix double logging bug in retry_on_auth_error decorator
- Remove emojis from log messages for cleaner log parsing
- Make PORT and LOG_LEVEL environment variables functional
- Delete redundant requirements.txt (pyproject.toml is authoritative)
- Clarify MONARCH_PORT is for Docker Compose only in .env.example
Dockerfile was failing because we tried to install in editable mode
before copying the src directory. Copy src/ first so that uv can
find the package structure properly.
Change from requirements.txt to pyproject.toml as source of truth for
dependencies. This ensures pyotp is properly installed in the Docker image
when built. Using 'uv pip install -e .' will install the package
with all dependencies from pyproject.toml.
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
The previous implementation added health route directly to mcp_app and
returned it, which broke MCP's internal /mcp endpoint routing.
Now matches the working pattern from komodo-mcp-custom:
- Mount mcp_app at / inside a parent Starlette app
- Pass lifespan=mcp_app.lifespan for proper task group init
- Health check is a separate route in the parent app