Skip to main content

Python client for the Empower (Personal Capital) unofficial API

Project description

personalcapital2

CI PyPI Python License

Get your financial data out of Empower (formerly Personal Capital) and into your own tools. Track net worth over time, analyze spending, monitor investment performance, or let an AI agent answer questions about your finances.

Three interfaces, one library:

  • Python API — frozen dataclasses with Decimal precision, not raw JSON
  • CLI (pc2) — structured JSON to stdout, pipe to jq, scripts, or spreadsheets
  • MCP server — give Claude or other AI agents direct access to your financial data

Built on the reverse-engineering work of haochi/personalcapital and traviscook21/personalcapital (both MIT).

Install

pip install personalcapital2
# or with uv
uv add personalcapital2

Quick start

from datetime import date
from personalcapital2 import authenticate

client = authenticate()  # interactive login with 2FA

result = client.get_accounts()
for acct in result.accounts:
    print(f"{acct.name:<30} ${acct.balance}")
print(f"Net worth: ${result.summary.networth:,.2f}")

result = client.get_transactions(date(2026, 1, 1), date(2026, 3, 31))
for txn in result.transactions:
    print(f"{txn.date}  {txn.description:<30}  ${txn.amount:.2f}")
print(f"Net cashflow: ${result.summary.net_cashflow:,.2f}")

Authentication

authenticate() reads credentials from environment variables, falling back to interactive prompts:

Variable Purpose
EMPOWER_EMAIL Empower account email
EMPOWER_PASSWORD Empower account password
EMPOWER_2FA_MODE sms or email — skips the interactive 2FA-method prompt (read only when 2FA is required)
PC2_SESSION_PATH Custom session file location (default: ~/.config/personalcapital2/session.json)

Credentials are sent directly to Empower's servers over HTTPS — this library never stores, logs, or transmits them anywhere else. Sessions are saved and reused until they expire — typically within ~24 hours, sometimes sooner. The session path can also be overridden per-command with --session.

Headless / agentic workflows

For unattended invocation (cron, GitHub Actions, n8n, AI agents) set the credential and mode env vars and pipe the 6-digit verification code on stdin:

EMPOWER_EMAIL=... EMPOWER_PASSWORD=... EMPOWER_2FA_MODE=sms \
    printf '%s\n' "$CODE" | pc2 login

The orchestrator owns SMS / email pickup — pc2 reads the code from stdin. Codes are deliberately not configurable via env var (short-lived secrets in the environment leak through /proc/PID/environ and shell history). Without EMPOWER_2FA_MODE set, the method-selection prompt blocks in non-TTY environments and the command exits with InteractiveAuthRequired.

CLI

The pc2 command outputs structured JSON (data to stdout, errors to stderr). Designed for scripting and AI agents — every error includes a machine-readable type and recovery suggestion.

pc2 accounts                                # all linked accounts
pc2 transactions --start 90d                # last 90 days of transactions
pc2 holdings                                # current investment positions
pc2 net-worth --start yb --format csv       # YTD net worth as CSV
pc2 performance --start mb-6 --account-ids 123,456
pc2 spending                                # current month/week/year spending

Date shortcuts: 30d (days ago), mb / me (month begin/end), yb / ye (year begin/end), mb-3 (3 months ago). See CLI Reference for the full list.

Python API

All methods return frozen dataclasses with datetime.date and decimal.Decimal fields. See API Reference for methods, response containers, and examples, and Model Reference for every field and type.

MCP Server

An MCP tool server gives AI agents (Claude Code, Claude Desktop, etc.) direct access to your financial data. The agent can call tools like get_transactions or get_holdings and reason over the results.

pip install "personalcapital2[mcp]"
pc2 login   # authenticate first
pc2 mcp     # start the server

Client config (Claude Code / Claude Desktop):

{
  "mcpServers": {
    "empower": {
      "type": "stdio",
      "command": "pc2",
      "args": ["mcp"],
      "env": {
        "PC2_SESSION_PATH": "~/.config/personalcapital2/session.json",
        "EMPOWER_EMAIL": "you@example.com",
        "EMPOWER_PASSWORD": "...",
        "EMPOWER_2FA_MODE": "sms"
      }
    }
  }
}

When the cached session expires mid-conversation, the agent recovers in chat without dropping to a terminal: it calls start_authentication, asks you for the 6-digit code, then calls complete_authentication with the code. The server reads the credentials and EMPOWER_2FA_MODE from this env block.

Security note: EMPOWER_PASSWORD in the MCP client config sits plaintext on disk in that config file (e.g. claude_desktop_config.json, .mcp.json). This is the canonical pattern for MCP server credentials and is consistent with the trust model — the same client already has access to all your financial data via this server — but worth flagging so you can decide whether the convenience is worth the storage.

The server is token-aware — large responses are automatically truncated to fit within context limits (~12,500 tokens by default, configurable via PC2_MCP_MAX_CHARS), while summaries are always preserved in full.

The CLI and MCP server follow an agent-first design: structured JSON errors with recovery suggestions, meaningful exit codes, self-documenting help text, and non-interactive TTY detection.

CLI exit codes:

Code Meaning
0 success
1 authentication error (no session, expired, 2FA required)
2 usage error (bad arguments, unknown command)
3 API error (request failed, rate limited, HTTP 4xx/5xx from Empower)
4 unexpected error
5 network error (transport-level failure reaching Empower)

Session recovery

Stale cached sessions are handled automatically: if a data command finds the saved session expired, the CLI re-authenticates and retries the request once. Set EMPOWER_EMAIL and EMPOWER_PASSWORD to avoid a mid-command password prompt during recovery; for fully headless flows that may hit 2FA, also set EMPOWER_2FA_MODE and pipe the code on stdin (see Headless / agentic workflows above).

Known API quirks

This library uses Empower's unofficial internal web API, which is not affiliated with Empower and may change without notice.

  • is_spending is unreliable on refunds. Use transaction_type (e.g. "Refund") instead.
  • performance and benchmarks share one API call. get_performance() returns both in a single PerformanceResult.
  • get_accounts may not list all accounts with holdings. Some accounts (employer 401k plans, crypto exchanges) can appear in get_holdings, get_account_balances, and get_performance but not in get_accounts. Use get_holdings to discover investment account IDs.
  • Fee fields can be NaN. The API returns "NaN" for fees_per_year, fund_fees, total_fee, and advisory_fee_percentage on some investment accounts (401k plans, crypto, RSUs). These are coerced to None — the account is not dropped.
  • get_spending ignores date range and interval. The API always returns current-period spending for all three interval types (MONTH, WEEK, YEAR), regardless of the start_date, end_date, or interval parameters.
  • Sessions expire. Typically ~24 hours, sometimes sooner. CLI users run pc2 login again; MCP users let the agent call start_authentication / complete_authentication. Stale-session recovery handles this automatically when EMPOWER_EMAIL/EMPOWER_PASSWORD (and EMPOWER_2FA_MODE if needed) are set.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

personalcapital2-0.3.0.tar.gz (139.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

personalcapital2-0.3.0-py3-none-any.whl (53.6 kB view details)

Uploaded Python 3

File details

Details for the file personalcapital2-0.3.0.tar.gz.

File metadata

  • Download URL: personalcapital2-0.3.0.tar.gz
  • Upload date:
  • Size: 139.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for personalcapital2-0.3.0.tar.gz
Algorithm Hash digest
SHA256 386f8d6862d1cf7d48ffea00accfd305428b87db708490d93f6fc30f95af0ba7
MD5 5304d5533d47eea9854761b6a216b65c
BLAKE2b-256 f31d87b9bb1efddc5961c0a437c9329989f221c58966f59361681f55d0cbcc86

See more details on using hashes here.

Provenance

The following attestation bundles were made for personalcapital2-0.3.0.tar.gz:

Publisher: release.yml on wpwilson10/personalcapital2

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file personalcapital2-0.3.0-py3-none-any.whl.

File metadata

File hashes

Hashes for personalcapital2-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 96f71d2e8b7b3447a1d5cec7dd297782c6a8d3cd820b59d865393393bbd1895f
MD5 a02879cd55470c1a983d33e40605922f
BLAKE2b-256 80bcf2e24b6eba742f6ba38d716eb813295db08639611a39764dcef0ba8c8bb9

See more details on using hashes here.

Provenance

The following attestation bundles were made for personalcapital2-0.3.0-py3-none-any.whl:

Publisher: release.yml on wpwilson10/personalcapital2

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page