FolioForecast Python SDK and MCP server — portfolio optimization, stress testing, and asset metadata for AI agents, robo-advisors, and fintech apps.
Project description
folioforecast
Python SDK and MCP server for FolioForecast — programmatic portfolio optimization for AI agents, robo-advisors, and fintech apps.
One API call to optimize, search, or stress-test any portfolio. Same engine that powers the FolioForecast web app, wrapped in a clean Python interface and a drop-in Model Context Protocol server for Claude Desktop, Claude Code, Cursor, and Windsurf.
Install
pip install folioforecast
For the MCP server:
pip install "folioforecast[mcp]"
Python 3.10+.
Get an API key
Sign up at folioforecast.com and create a key. Production keys start with ff_live_; sandbox keys start with ff_test_ (no billing).
SDK quick start
import folioforecast as ff
client = ff.Client(api_key="ff_live_...")
result = client.optimize(
tickers=["AAPL.US", "MSFT.US", "GOOGL.US", "AMZN.US"],
goal="max_sharpe",
)
print(result.weights) # {'AAPL.US': 0.30, 'MSFT.US': 0.25, ...}
print(result.metrics) # {'sharpe': 1.42, 'volatility': 0.18, ...}
All SDK methods are synchronous. Use it inside asyncio.to_thread(...) if you need to call it from an async context.
Ticker search
hits = client.search_tickers("apple", limit=5)
for h in hits:
print(h.symbol, h.name, h.exchange)
Free — 0 compute units.
Stress test
result = client.stress_test(
tickers=["SPY.US", "TLT.US", "GLD.US"],
weights={"SPY.US": 0.6, "TLT.US": 0.3, "GLD.US": 0.1},
scenarios=["2008_gfc", "covid_2020"],
)
print(result.scenarios)
Asset metadata
meta = client.asset_metadata(tickers=["AAPL.US", "AGG.US", "GLD.US"])
for m in meta:
print(m.symbol, m.sector, m.asset_class)
Usage and billing
print(client.usage()) # current period compute units consumed / remaining
print(client.health()) # API status
Error handling
from folioforecast import AuthError, BillingError, RateLimitError, APIError
try:
client.optimize(tickers=["AAPL.US"], goal="max_sharpe")
except AuthError:
print("API key is missing or invalid")
except BillingError:
print("Add a payment method at https://www.folioforecast.com/hub?tab=settings")
except RateLimitError as e:
print(f"Slow down — retry after {e.retry_after}s")
except APIError as e:
print(f"API error {e.status_code}: {e}")
Context-manager use
with ff.Client(api_key="ff_live_...") as client:
result = client.optimize(tickers=["VOO.US", "AGG.US"], goal="min_volatility")
MCP server for Claude Desktop
The folioforecast[mcp] extra installs a full MCP server so Claude Desktop (and other MCP clients) can call the FolioForecast API directly.
1. Install
pip install "folioforecast[mcp]"
2. Configure Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"folioforecast": {
"command": "folioforecast-mcp",
"env": {
"FOLIOFORECAST_API_KEY": "ff_live_your_key_here"
}
}
}
}
Restart Claude Desktop. You should see the FolioForecast tools appear in the attachment menu.
3. Try it
In a new Claude Desktop chat, ask:
Optimize a portfolio of AAPL, MSFT, GOOGL, and AMZN for maximum Sharpe ratio.
Claude will call optimize_portfolio and show you the weights and metrics.
Works in
Claude Desktop, Claude Code, Cursor, Windsurf, and any other MCP-capable client. Does not work in claude.ai web, the Claude mobile app, or claude.com — those surfaces do not load third-party MCP servers. For ChatGPT, use the pre-built FolioForecast Custom GPTs instead.
Tools exposed
| Tool | Description | Cost |
|---|---|---|
optimize_portfolio |
Run mean-variance optimization across 20 methods (Sharpe, min-vol, risk parity, Kelly, CVaR, etc.) | 1–2 units |
search_tickers |
Search 165,000+ tickers by symbol or name | Free |
stress_test |
Crisis scenario analysis (2008 GFC, COVID, etc.) | 1 unit/scenario |
get_asset_metadata |
Sector, industry, asset class, market cap | 0.1 units/ticker |
Parity note: this Python package mirrors the four portfolio tools in the Node MCP server at v1.0.0. Budget and retirement tools are rolling out in the next release.
Environment variables
| Variable | Required | Description |
|---|---|---|
FOLIOFORECAST_API_KEY |
Yes (for MCP server) | Your API key |
FOLIOFORECAST_API_URL |
No | Override the base URL (default: https://www.folioforecast.com/api/v1) |
The SDK accepts api_key as a constructor argument and falls back to the env var if omitted.
Links
- Docs: https://www.folioforecast.com/developers
- OpenAPI spec: https://www.folioforecast.com/api/v1/openapi.yaml
- Dashboard / key management: https://www.folioforecast.com/hub?tab=settings
- Repository: https://github.com/shadow6-actual/V6_EODHD_POpt
License
MIT — see LICENSE.
FolioForecast is a calculation engine. Your AI does the thinking — we do the math. Results are historical analysis, not predictions. Not financial advice.
Project details
Release history Release notifications | RSS feed
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 folioforecast-0.1.1.tar.gz.
File metadata
- Download URL: folioforecast-0.1.1.tar.gz
- Upload date:
- Size: 13.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2449b92daee88fd287950edc1d3e05b60bd14ad9e2ddf697b9bfb2fb6a577674
|
|
| MD5 |
28d4af58edbf5714819d8fff83c775fa
|
|
| BLAKE2b-256 |
86849d914bfa701792cbdf4856ca7f3f018a0e3d15e1165292f8261a72ffa18d
|
File details
Details for the file folioforecast-0.1.1-py3-none-any.whl.
File metadata
- Download URL: folioforecast-0.1.1-py3-none-any.whl
- Upload date:
- Size: 15.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.3
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
72fb04140f5b2fbd5b327554ed278639babccf36d434f6cb466f00bd691788cb
|
|
| MD5 |
f156970768c270bc177efd274d4be632
|
|
| BLAKE2b-256 |
fa229be66b7aea624d77787824ebb2852eb1ef9ea933ebb8ea90a368ac3f6a12
|