Python client for the Empower (Personal Capital) unofficial API
Project description
personalcapital2
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
Decimalprecision, not raw JSON - CLI (
pc2) — structured JSON to stdout, pipe tojq, 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 |
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.
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"}
}
}
}
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. Headless 2FA is not yet supported (tracked in #5) — non-TTY environments will fail fast with a structured EmpowerAuthError rather than hanging on the prompt.
Known API quirks
This library uses Empower's unofficial internal web API, which is not affiliated with Empower and may change without notice.
is_spendingis unreliable on refunds. Usetransaction_type(e.g."Refund") instead.performanceandbenchmarksshare one API call.get_performance()returns both in a singlePerformanceResult.get_accountsmay not list all accounts with holdings. Some accounts (employer 401k plans, crypto exchanges) can appear inget_holdings,get_account_balances, andget_performancebut not inget_accounts. Useget_holdingsto discover investment account IDs.- Fee fields can be
NaN. The API returns"NaN"forfees_per_year,fund_fees,total_fee, andadvisory_fee_percentageon some investment accounts (401k plans, crypto, RSUs). These are coerced toNone— the account is not dropped. get_spendingignores date range and interval. The API always returns current-period spending for all three interval types (MONTH, WEEK, YEAR), regardless of thestart_date,end_date, orintervalparameters.- Sessions expire. Typically 1-2 days. Run
pc2 loginagain on auth errors.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file personalcapital2-0.2.2.tar.gz.
File metadata
- Download URL: personalcapital2-0.2.2.tar.gz
- Upload date:
- Size: 132.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b0bff9723d5309313ba2483bf33c03df347e11e80d46ce937942be02010ad622
|
|
| MD5 |
717cafc033edaa82a4bdc7eacdf445c1
|
|
| BLAKE2b-256 |
8c1a56069dcddc3a7bf4a715bc81e2d329c7d6e2255603103620d76ad830a8ff
|
Provenance
The following attestation bundles were made for personalcapital2-0.2.2.tar.gz:
Publisher:
release.yml on wpwilson10/personalcapital2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
personalcapital2-0.2.2.tar.gz -
Subject digest:
b0bff9723d5309313ba2483bf33c03df347e11e80d46ce937942be02010ad622 - Sigstore transparency entry: 1399032733
- Sigstore integration time:
-
Permalink:
wpwilson10/personalcapital2@385b9481e1b07708353934c024f862f9e6578a0e -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/wpwilson10
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@385b9481e1b07708353934c024f862f9e6578a0e -
Trigger Event:
push
-
Statement type:
File details
Details for the file personalcapital2-0.2.2-py3-none-any.whl.
File metadata
- Download URL: personalcapital2-0.2.2-py3-none-any.whl
- Upload date:
- Size: 50.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1d2b3c9d4f9b0301cf314b17dc4cdb46a6202bc372c6bfa777149150666d7178
|
|
| MD5 |
db1263fbd2cf0ab9e1a712b19963b303
|
|
| BLAKE2b-256 |
e700a069791e3a0be47d5321646a3d4498d09664e50fb413df06d2b1b713671e
|
Provenance
The following attestation bundles were made for personalcapital2-0.2.2-py3-none-any.whl:
Publisher:
release.yml on wpwilson10/personalcapital2
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
personalcapital2-0.2.2-py3-none-any.whl -
Subject digest:
1d2b3c9d4f9b0301cf314b17dc4cdb46a6202bc372c6bfa777149150666d7178 - Sigstore transparency entry: 1399032784
- Sigstore integration time:
-
Permalink:
wpwilson10/personalcapital2@385b9481e1b07708353934c024f862f9e6578a0e -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/wpwilson10
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@385b9481e1b07708353934c024f862f9e6578a0e -
Trigger Event:
push
-
Statement type: