Python client for the Empower (Personal Capital) unofficial API
Project description
personalcapital2
Typed Python client for the Empower (formerly Personal Capital) API. Authenticate, fetch your financial data, and get back clean dataclasses. Based on haochi/personalcapital and traviscook21/personalcapital (both MIT), rewritten with type safety, structured error handling, and a typed model layer.
Install
Not yet on PyPI — install directly from GitHub:
pip install git+https://github.com/wpwilson10/personalcapital2.git
# or with uv
uv add git+https://github.com/wpwilson10/personalcapital2.git
Quick start
from datetime import date
from personalcapital2 import EmpowerClient, authenticate
client = authenticate() # interactive login with 2FA
result = client.get_accounts()
for acct in result.accounts:
print(f"{acct.name:<30} {acct.firm_name}")
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}")
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) |
Sessions are saved and reused until they expire (typically 1-2 days). The session path can also be overridden per-command with --session.
CLI
A command-line tool is included as pc2. All output is structured JSON — data to stdout, errors to stderr. Run pc2 --help for full usage.
pc2 login # authenticate (interactive 2FA)
pc2 accounts # list linked accounts
pc2 transactions --start 90d # last 90 days
pc2 net-worth --start yb --format csv # YTD net worth as CSV
pc2 performance --start mb-6 --account-ids 123,456
See CLI Reference for all commands, date shortcuts, exit codes, and error format.
Python API
| Method | Returns | Description |
|---|---|---|
get_accounts() |
AccountsResult |
Linked accounts + aggregate summary |
get_transactions(start, end) |
TransactionsResult |
Transactions + categories + cashflow summary |
get_holdings() |
HoldingsResult |
Investment holdings + total value |
get_net_worth(start, end) |
NetWorthResult |
Daily net worth + change summary |
get_account_balances(start, end) |
AccountBalancesResult |
Daily account balances |
get_performance(start, end, account_ids) |
PerformanceResult |
Investment + benchmark performance |
get_quotes(start, end) |
QuotesResult |
Portfolio vs benchmark + market quotes |
get_spending(start, end, interval) |
SpendingResult |
Current spending (all intervals, see quirks) |
All dates are datetime.date, financial values are decimal.Decimal, models are frozen dataclasses. See Python API docs for response containers and examples, Model Reference for every field and type.
MCP Server
An MCP tool server exposes all data methods to AI agents (Claude Code, Claude Desktop, etc.) over stdio. Requires the [mcp] extra:
pip install "personalcapital2[mcp]"
Start the server (requires a valid session from pc2 login):
pc2 mcp
Client configuration
Add to your MCP client config (Claude Code settings.json, Claude Desktop claude_desktop_config.json, etc.):
{
"mcpServers": {
"empower": {
"type": "stdio",
"command": "pc2",
"args": ["mcp"],
"env": {"PC2_SESSION_PATH": "~/.config/personalcapital2/session.json"}
}
}
}
All 8 data tools are available: get_accounts, get_transactions, get_holdings, get_net_worth, get_account_balances, get_performance, get_quotes, get_spending. Tools return JSON strings and handle errors gracefully — expired sessions return a message telling the agent to ask the user to re-run pc2 login.
See MCP Testing Guide for how to test the server during development.
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.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.
Development
uv sync
uv run pytest
uv run pyright .
uv run ruff check .
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.1.0.tar.gz.
File metadata
- Download URL: personalcapital2-0.1.0.tar.gz
- Upload date:
- Size: 116.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3481f54906a2ed102a45934b2099a163a52ca652436ea5a768b0373c44563578
|
|
| MD5 |
cfd29b04275cace951fcf7f7797211f6
|
|
| BLAKE2b-256 |
3c8dfce8e1a59af5ebb1980ae3459f99ef6a5323185d7546e0242b5f7af366e2
|
Provenance
The following attestation bundles were made for personalcapital2-0.1.0.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.1.0.tar.gz -
Subject digest:
3481f54906a2ed102a45934b2099a163a52ca652436ea5a768b0373c44563578 - Sigstore transparency entry: 1249889494
- Sigstore integration time:
-
Permalink:
wpwilson10/personalcapital2@2b3e11c4b3aa4e07a3096fabbdccb925fadcd6e2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/wpwilson10
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2b3e11c4b3aa4e07a3096fabbdccb925fadcd6e2 -
Trigger Event:
push
-
Statement type:
File details
Details for the file personalcapital2-0.1.0-py3-none-any.whl.
File metadata
- Download URL: personalcapital2-0.1.0-py3-none-any.whl
- Upload date:
- Size: 45.9 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 |
e12857d4f07e9240bb41d4a4e318b07ceca2f76ffb18923509005773b2976e9a
|
|
| MD5 |
b486a1a51a558f2c423c8d4ef7db0576
|
|
| BLAKE2b-256 |
9bd78bd690eb66f256b88e2ca32889b8b49bb53bc6b7097b6544f61f8845b19a
|
Provenance
The following attestation bundles were made for personalcapital2-0.1.0-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.1.0-py3-none-any.whl -
Subject digest:
e12857d4f07e9240bb41d4a4e318b07ceca2f76ffb18923509005773b2976e9a - Sigstore transparency entry: 1249889545
- Sigstore integration time:
-
Permalink:
wpwilson10/personalcapital2@2b3e11c4b3aa4e07a3096fabbdccb925fadcd6e2 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/wpwilson10
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
release.yml@2b3e11c4b3aa4e07a3096fabbdccb925fadcd6e2 -
Trigger Event:
push
-
Statement type: