Skip to main content

Empower Personal Dashboard (empower-personal-dashboard)

CI PyPI version License: MIT Python: 3.9+ PRs Welcome Privacy: Zero-PII

A standalone, modern Python client and CLI for Empower Personal Dashboard (formerly Personal Capital).

Empower Personal Dashboard aggregates linked financial institutions—including banking, checking, high-yield savings, credit cards, mortgages, 401(k) plans, traditional/Roth IRAs, 529 plans, and taxable brokerage accounts.

This library provides full programmatic and CLI access to:

  • Account Balances & Net Worth Totals: Aggregate cash, investment, credit, mortgage, loan, and other asset balances.
  • Investment Holdings & Positions: Security-level positions, quantities, market prices, cost basis, weights, and daily value changes across all investment accounts.
  • Account Transactions: Multi-year transaction history with date-range filters, account filtering, category mapping, and reverse-chronological ordering.
  • Two-Phase Persistent Authentication: One-time interactive 2FA setup (SMS or Email) with device binding, followed by completely unattended periodic runs.
  • Unified Migration Awareness: Automatic detection and transparent routing for accounts migrated to Empower's unified API endpoint (pc-api.empower-retirement.com).
  • Text Sanitization: Built-in stripping of Unicode replacement characters (\ufffd) often injected by upstream broker feeds.
  • Zero External Dependencies: Pure Python built only on standard requests.

Table of Contents


Installation

From PyPI

# Core package and CLI
pip install empower-personal-dashboard

# With Model Context Protocol (MCP) agent support:
pip install "empower-personal-dashboard[mcp]"

# With Beancount Plain-Text Accounting export support:
pip install "empower-personal-dashboard[beancount]"

# With all optional dependencies:
pip install "empower-personal-dashboard[all]"

From Source (Local Development)

# Clone and install locally in editable mode
git clone https://github.com/petry-projects/empower-personal-dashboard.git
cd empower-personal-dashboard
pip install -e .

Or install directly from GitHub:

pip install git+https://github.com/petry-projects/empower-personal-dashboard.git

Quickstart CLI

1. One-Time Setup (2FA Authentication & Device Binding)

Run the interactive setup to authenticate with your Empower credentials and complete the 2FA challenge:

empower --login

This binds the device and saves an authenticated session file to ~/.empower_personal_dashboard_session.json with secure owner-only POSIX permissions (0600). Subsequent runs operate completely unattended without passwords or 2FA prompts.

2. Unattended Data Extraction

# Extract balances and display aligned table
empower

# Extract balances, holdings, and transactions with companion CSV exports
empower --all --csv

# Extract only investment holdings and positions
empower --holdings --limit 20

# Extract transactions for a specific date range
empower --transactions --start-date 2026-01-01 --end-date 2026-09-30 --limit 50

# Output in JSON or Markdown format
empower --format markdown
empower --all --format json

3. Beancount Plain-Text Accounting (PTA) Export

Export double-entry ledgers, ground-truth balance assertions, and commodity price points directly into Beancount format:

# Export modular ledger directory (main.bean, accounts.bean, balances.bean, prices.bean, transactions.bean)
empower --all --beancount --output-beancount ./ledger/

# Export to a single Beancount ledger file
empower --all --beancount --output-beancount ./my_finances.bean

# Use a custom YAML mapping configuration for category rules and account aliases
empower --all --beancount --beancount-map ~/.empower_beancount_map.yaml

# Stream Beancount directives directly to stdout
empower --transactions --format beancount

4. Offline Sandbox Mode

Test the CLI without entering credentials or making network requests:

empower --sandbox --all --csv
empower --sandbox --all --beancount --output-beancount ./ledger/

Python API Usage

Extract Balances & Net Worth

from empower_personal_dashboard import EmpowerDashboardClient

# Automatically loads saved session from ~/.empower_personal_dashboard_session.json
client = EmpowerDashboardClient()

balances = client.fetch_balances()
print(f"Total Net Worth: ${balances.net_worth:,.2f}")
print(f"Total Investments: ${balances.total_investment:,.2f}")
print(f"Total Cash: ${balances.total_cash:,.2f}")

for acct in balances.accounts:
    print(f"  [{acct['account_type']}] {acct['firm_name']} - {acct['account_name']}: ${acct['balance']:,.2f}")

Extract Investment Holdings

holdings = client.fetch_holdings()
print(f"Total Portfolio Value: ${holdings.total_value:,.2f}")

for pos in holdings.holdings[:10]:
    ticker = pos.get('ticker') or 'N/A'
    print(f"  {ticker:<6} {pos['description']:<35} {pos['quantity']:>8.2f} shs @ ${pos['price']:>7.2f} = ${pos['value']:>10.2f}")

Extract Transactions

transactions = client.fetch_transactions(
    start_date="2026-01-01",
    end_date="2026-09-30",
    limit=50,
)
print(f"Total Transactions: {transactions.total_transactions}")
print(f"Net Cashflow: ${transactions.net_cashflow:,.2f}")

for tx in transactions.transactions[:10]:
    sign = "+" if tx["is_credit"] or tx["is_cash_in"] else "-"
    print(f"  {tx['transaction_date']} | {tx['account_name'][:20]:<20} | {tx['description'][:30]:<30} | {sign}${tx['amount']:,.2f}")

Model Context Protocol (MCP) Server

Connect your Empower Personal Dashboard to AI agents (Claude Desktop, Antigravity CLI, Cursor, Windsurf, Claude Code) via the Model Context Protocol (MCP).

Installation with MCP Support

pip install "empower-personal-dashboard[mcp]"

Or run directly without installation via uvx:

uvx --from "empower-personal-dashboard[mcp]" empower-mcp

Configuration for AI Agents

1. Claude Desktop (claude_desktop_config.json)

{
  "mcpServers": {
    "empower": {
      "command": "empower-mcp"
    }
  }
}

2. Antigravity CLI / Cursor / VS Code (mcp.json)

{
  "mcpServers": {
    "empower": {
      "command": "python3",
      "args": ["-m", "empower_personal_dashboard.mcp_server"]
    }
  }
}

MCP Tools & Resources

Tool Parameters Description
get_net_worth_summary format Ultra-lightweight summary (net worth, cash, investments, credit/debt, loans) minimizing LLM context (~100 tokens). Supports format='json', 'markdown', or 'table'.
get_balances account_types, include_inactive, format Per-account balances grouped by type (CASH, INVESTMENT, CREDIT, etc.) with masked account numbers and optional Markdown/Table rendering.
get_holdings ticker, account_id, aggregate_by_ticker, sort_by, min_value, limit, format Security-level positions, quantities, prices, cost basis, and allocations. Supports cross-account ticker consolidation (aggregate_by_ticker=True), sorting, threshold filtering, and pre-formatted tables.
get_transactions start_date, end_date, days, account_id, category, spending_only, income_only, transaction_type, min_amount, max_amount, limit, format Account activity filtered by absolute date or relative lookback (days=1, days=7), strict spending/income filters, transaction types, min/max amounts, and Markdown/Table rendering.
export_data destination_dir, scope, export_csv, start_date, end_date, limit Programmatically export balances, holdings, and transactions to disk in JSON, JSONL, and companion CSV files (matching CLI empower --all --csv).
get_export_options None Discover supported export formats, scopes, CLI flags, and usage commands.
check_auth_status None Health check verifying that local session authentication is active.
  • Resources:
    • empower://balances/summary (Real-time net worth and asset class totals JSON)
    • empower://holdings/portfolio (Portfolio positions JSON)
    • empower://accounts/list (Linked accounts list JSON)
    • empower://export/options (Documentation of export options, formats, and CLI flags Markdown)
  • Prompts:
    • portfolio_review: Audits asset allocation, equity vs fixed-income balance, and cash drag.
    • spending_audit: Cashflow and spending audit over past N days.
    • recent_purchases_audit: Reviews retail purchases, credit card charges, and subscriptions over past N days.
    • top_holdings_review: Consolidates and reviews top investment holdings across all accounts.

Testing in Offline Sandbox Mode

Test the MCP server without credentials or network calls:

empower-mcp --sandbox

OpenAPI 3.1 Specification & Contract Testing

empower-personal-dashboard maintains a formal, machine-readable OpenAPI 3.1 specification (also accessible via the repository root symlink openapi.yaml) documenting the reverse-engineered Empower Personal Dashboard RPC wire protocol and canonical financial domain schemas.

Two-Tier Architecture

As formalized in ADR-0002:

  1. Tier 1 (Upstream Wire Protocol): Documents the private RPC-over-HTTP POST endpoints (/api/login/identifyUser, /api/credential/challengeSms, /api/newaccount/getAccounts, /api/invest/getHoldings, /api/transaction/getUserTransactions), spHeader envelopes, error handling, session cookies (JSESSIONID), and CSRF tokens (X-CSRF).
  2. Tier 2 (Canonical Domain Schemas): Defines normalized component schemas matching the Python dataclasses (DashboardBalances, AccountBalance, DashboardHoldings, InvestmentHolding, DashboardTransactions, Transaction) and the NetWorthSummary payload consumed by the CLI and Model Context Protocol (FastMCP) server.

Local Validation & Preview

You can validate and preview the OpenAPI 3.1 specification locally using Redocly CLI:

# Validate specification syntax and rules
npx --yes @redocly/cli@2.57.0 lint docs/openapi.yaml

# Launch interactive documentation preview server
npx --yes @redocly/cli@2.57.0 preview-docs docs/openapi.yaml

# Run hermetic contract unit tests (requires pip install -e ".[test]")
PYTHONPATH=. python3 -m unittest tests/test_openapi_contract.py

Architecture & Authentication Lifecycle

sequenceDiagram
    autonumber
    actor User as User / Script
    participant CLI as empower CLI
    participant Client as EmpowerDashboardClient
    participant API as pc-api.empower-retirement.com
    participant Disk as ~/.empower_personal_dashboard_session.json

    rect rgb(240, 248, 255)
    note over User, Disk: Phase 1: One-Time 2FA Bootstrap (--login)
    User->>CLI: empower --login
    CLI->>Client: login(username, password)
    Client->>API: GET / (fetch initial window.csrf)
    Client->>API: POST /login/identifyUser
    API-->>Client: Require 2FA (authLevel: USER_IDENTIFIED)
    Client-->>User: Prompt: Challenge via SMS or Email?
    User->>Client: Selects SMS
    Client->>API: POST /credential/challengeSms
    API-->>User: Sends 6-digit SMS code
    User->>CLI: Enters 6-digit code
    Client->>API: POST /credential/authenticateSms
    Client->>API: POST /credential/authenticatePassword (bindDevice=true)
    API-->>Client: 200 OK + Device Bound Session Cookies
    Client->>Disk: Save cookies & CSRF to session.json (mode 0600)
    end

    rect rgb(245, 255, 245)
    note over User, Disk: Phase 2: Unattended Automated Extraction
    User->>CLI: empower --all --csv
    CLI->>Client: Initialize (loads session.json)
    Client->>API: POST /newaccount/getAccounts
    Client->>API: POST /invest/getHoldings
    Client->>API: POST /transaction/getUserTransactions
    Client-->>CLI: Typed models (Balances, Holdings, Transactions)
    CLI->>Disk: Write JSON, JSONL, and CSV datasets
    end

PyPI Packaging & Automated Publishing

empower-personal-dashboard adopts the automated, tokenless PyPI Trusted Publishing (OIDC) approach pioneered in don-petry/brand-ops.

1. Tokenless Trusted Publishing Architecture

Releases publish directly from GitHub Actions without storing long-lived, sensitive API tokens:

  • GitHub Actions exchanges its cryptographic OIDC ID token with PyPI for a short-lived upload token.
  • PyPI validates the repository (petry-projects/empower-personal-dashboard), workflow (publish.yml), and environment (pypi).

2. Onboarding Steps (First Release Setup)

Before publishing the first release, the account owner registers a Pending Publisher on PyPI:

  1. Log in to pypi.org/manage/account/publishing/.
  2. Under "Add a pending publisher", enter:
    • PyPI Project Name: empower-personal-dashboard
    • Owner: petry-projects
    • Repository name: empower-personal-dashboard
    • Workflow name: publish.yml
    • Environment name: pypi
  3. Click "Add publisher".

3. Local Onboarding & Verification

Run the onboarding tool to inspect registry availability, build the sdist and wheel, and verify package metadata:

# Probe PyPI status, build sdist/wheel, and run twine verification
python scripts/pypi_onboard.py

4. Automated Publishing Workflow

  • Automatic: Creating a GitHub Release automatically builds and publishes packages to PyPI via .github/workflows/publish.yml.
  • Manual Trigger (with Dry Run): You can also run the workflow manually via workflow_dispatch with dry_run: true (default) to test artifact generation without releasing.

Security & Privacy Model

  1. Zero-PII Commitment: All test suites, mock fixtures, and sample documentation use 100% synthetic financial records. Real user names, balances, account numbers, and transaction descriptions are never stored or committed.
  2. Owner-Only Session Storage: Saved session tokens are written using atomic temporary files with restricted POSIX file permissions (0600).
  3. Secret Redaction: When running in --debug mode or with logging enabled, passwords, pins, and 2FA verification codes are automatically masked (***REDACTED***).
  4. No Password Storage: The client does not store your account password; it persists only the session cookies and CSRF token generated upon device binding.

Development & Testing

# Clone the repository
git clone https://github.com/petry-projects/empower-personal-dashboard.git
cd empower-personal-dashboard

# Install in editable mode with development dependencies
pip install -e ".[dev]"

# Run unit tests (offline, deterministic)
PYTHONPATH=. python3 -m unittest discover tests

# Verify syntax and byte compilation
python3 -m compileall empower_personal_dashboard tests

Contributing & Agent Standards

  • CONTRIBUTING.md: Guidelines for opening issues, reporting API changes, coding conventions, and pull request workflows.
  • AGENTS.md: Canonical development standards, Test-Driven Development (TDD) rules, and security guidelines for AI coding agents (extending petry-projects/.github/AGENTS.md).
  • CLAUDE.md: Agent instructions for Claude Code.

License

This project is licensed under the terms of the MIT License.

Metadata

Release files for empower-personal-dashboard 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for empower-personal-dashboard 0.1.1
File Size Uploaded
empower_personal_dashboard-0.1.1.tar.gz 76.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for empower-personal-dashboard 0.1.1
File Interpreter ABI Platform
empower_personal_dashboard-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 128.5 kB

Release files / empower_personal_dashboard-0.1.1.tar.gz

Download URL empower_personal_dashboard-0.1.1.tar.gz
Size 76.4 kB
Tags Source
SHA-256 checksum
How to use checksums
6250192446af1fb850c429fd9d3ac0a8f8587349f3d31de7ec7874d51bf7fc34
BLAKE2b-256 checksum
How to use checksums
394aefcb48759feea1d540e2257793946b08c4951f61fb422b7f35ad763b2a90
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release files / empower_personal_dashboard-0.1.1-py3-none-any.whl

Download URL empower_personal_dashboard-0.1.1-py3-none-any.whl
Size 52.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3655e24344931c50e02ce81eced88e2f49dbe895ba59225eb886cb174f66b8a2
BLAKE2b-256 checksum
How to use checksums
d7ea0d6307bc9915ddf5311a476680e14c7c9cf242e2ca2d5c8db7f62627ed25
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 3, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page