Skip to main content
Glama
README.md
RiskModels provides clean dividend-adjusted total returns, factor risk decomposition, return attribution, and ETF-executable hedge ratios for US equities — over REST, a typed SDK, and a built-in MCP server. The dataset is **simulation-grade**: it covers on the order of **16,000 US stocks** across the full historical panel, while **at each month end** the model’s headline universe is the **largest ~3,000 by market cap**—the set the API surfaces for everyday returns, risk, and hedging.

**Post-regression outputs** (hedge ratios, explained-risk decompositions, and related L1–L3 series) are served from the first date whose full estimation window is covered: **hedge ratios from 2010-12-08**, **explained-risk shares and stock variance from 2011-12-07**, **L\* residual levels from 2013-01-01**. **Split- and dividend-adjusted returns** (the inputs to the rolling regressions) begin **2006-01-04**. The API is AI-agent ready, including a built-in Model Context Protocol (MCP) server for seamless integration with LLMs.

# RiskModels API Developer Portal

[![CI](https://github.com/BlueWaterCorp/RiskModels_API/actions/workflows/ci.yml/badge.svg)](https://github.com/BlueWaterCorp/RiskModels_API/actions/workflows/ci.yml)
[![Live Docs](https://img.shields.io/badge/Live%20Docs-riskmodels.net%2Fdocs%2Fapi-6366f1)](https://riskmodels.net/docs/api/erm3)
[![OpenAPI](https://img.shields.io/badge/OpenAPI-3.0.3-85ea2d)](OPENAPI_SPEC.yaml)
[![PyPI](https://img.shields.io/pypi/v/riskmodels-py.svg)](https://pypi.org/project/riskmodels-py/)
[![smithery badge](https://smithery.ai/badge/service-c09f/riskmodels)](https://smithery.ai/servers/service-c09f/riskmodels)

This repository is the **authoritative public API reference** for the [RiskModels](https://riskmodels.net) equity risk model API, featuring:

- 📖 **Model methodology** — [ERM3 overview](https://riskmodels.app/docs/methodology) (canonical; also mirrored on [riskmodels.net](https://riskmodels.net/docs/methodology/erm3-l3))
- 📚 **Comprehensive API Documentation** — OpenAPI 3.0.3 specification, guides, and examples
- 🌐 **Developer Portal** — Beautiful Next.js site (this repo) deployed at **riskmodels.app**
- 🐍 **Python & TypeScript Examples** — Production-ready code in `examples/`
- 🤖 **AI Agent Integration** — MCP server, OAuth2, and agent manifest

---

## Use in Cursor (Agent Plugin)

This repository is an [Agent Plugins](https://agent-plugins.org) package: `plugin.json` and `mcp.json` at the repository root. The plugin connects Cursor to the hosted RiskModels MCP server. It contains no code that runs on your machine and no credentials.

| File | What it declares |
|------|------------------|
| [`plugin.json`](./plugin.json) | Plugin `riskmodels` 1.0.0, Apache-2.0 |
| [`mcp.json`](./mcp.json) | One server, `riskmodels`: Streamable HTTP at `https://riskmodels.app/api/mcp/openai` |

### Install

1. In Cursor, open the Marketplace and search for **RiskModels**.
2. Install it for your user or for the current project.
3. Cursor adds the `riskmodels` MCP server. Its tools appear once you sign in.

### Sign in

The server uses OAuth 2.1 with PKCE. Cursor handles the flow, and nothing goes in the plugin files:

1. When Cursor first connects to the `riskmodels` server, the server asks for sign-in and Cursor opens a browser at riskmodels.app.
2. Sign in with Google or an email link, or choose **Sign in with a password instead**.
3. The consent screen shows **Signed in as <email>**. If that is the wrong account, click **Use a different account** first, then **Allow**.
4. Cursor stores the token. The tools are read-only: they return data and never place orders or change your account.

### Pricing and account

- A RiskModels account is required. New accounts start with **$20 of prepaid credit**. A payment method is collected at signup for verification and is not charged until you top up.
- Usage is pay-as-you-go and billed per tool call against that balance. Most single-stock calls cost **$0.005**; fundamentals cost $0.02, and a full portfolio exposure report costs $0.25. Rates and plans: [riskmodels.app/pricing](https://riskmodels.app/pricing).
- Optional: link a brokerage account (Alpaca, Connect Trade or Plaid) in [riskmodels.net](https://riskmodels.net) **Settings**, and `riskmodels_get_my_positions` reads that book.

### Example: NVDA

Ask in Cursor's agent chat:

> Decompose NVDA's risk with RiskModels and give me the ETF hedge for a $100,000 position.

The agent calls `riskmodels_decompose` for the market / sector / subsector / stock-specific split of NVDA's variance and the hedge ratio at each level. Then it calls `riskmodels_decompose` again with a dollar amount to turn those ratios into dollar trades in SPY and the sector and subsector ETFs. The numbers are live model output as of the latest trading day.

The Claude plugin ([`claude-plugin/`](./claude-plugin/)) and the local developer MCP server ([`.cursor/mcp.json`](./.cursor/mcp.json), [`mcp/`](./mcp/)) are separate and unchanged.

---

## 🚀 Quick Links

- **Python SDK — AOM quickstart (Google Colab):** [Open notebook](https://colab.research.google.com/github/BlueWaterCorp/RiskModels_API/blob/main/sdk/notebooks/riskmodels_aom_colab.ipynb) · source: [`sdk/notebooks/riskmodels_aom_colab.ipynb`](sdk/notebooks/riskmodels_aom_colab.ipynb)
- **Developer Portal:** [riskmodels.app](https://riskmodels.app)
- **Live API Docs:** [riskmodels.net/docs/api/erm3](https://riskmodels.net/docs/api/erm3)
- **ERM3 methodology:** [riskmodels.app/docs/methodology](https://riskmodels.app/docs/methodology)
- **Get API Key:** [riskmodels.app/get-key](https://riskmodels.app/get-key)
- **API Terms:** [riskmodels.net/terms/api](https://riskmodels.net/terms/api)
- **Issues:** [github.com/BlueWaterCorp/RiskModels_API/issues](https://github.com/BlueWaterCorp/RiskModels_API/issues)
- **PyPI (Python SDK):** [riskmodels-py](https://pypi.org/project/riskmodels-py/)

### Canonical URLs (REST, OpenAPI, and docs)

Use these **only** for integrations and tooling:

| What | URL |
|------|-----|
| **REST base** (OpenAPI `servers`) | `https://riskmodels.app/api` |
| **Deployed OpenAPI JSON** (same spec as [`OPENAPI_SPEC.yaml`](./OPENAPI_SPEC.yaml)) | `https://riskmodels.app/openapi.json` |
| **Interactive API reference** (this portal) | [`/api-reference`](https://riskmodels.app/api-reference) |

**Important:** The hostname **`api.riskmodels.app`** is not used for the public API or machine-readable docs. Older links or docs that mention it should be treated as obsolete; use **`riskmodels.app`** (apex) as above.

---

## 📖 API Overview

The RiskModels API provides institutional-grade equity risk analysis:

- **Daily factor decompositions** — market, sector, subsector explained-risk fractions for the headline **~3,000** largest US stocks by market cap (month-end universe)
- **Hedge ratios** — dollar-denominated ETF hedge amounts (L1/L2/L3) designed to remain executable with liquid raw ETFs
- **Historical time series** — split- and dividend-adjusted returns (2006-01-04–present) plus rolling hedge ratios (**2010-12-08–present**) and ER (**2011-12-07–present**; factor outputs need a full regression window)
- **AI-agent ready** — OAuth2, per-request billing, machine-readable manifests

**Data coverage:** **~16,000** US stocks in the historical panel; **~3,000** largest by market cap at each **month end** for headline outputs. Updated daily. **Hedge ratios:** **2010-12-08** through present. **Explained risk:** **2011-12-07** through present. **L\* levels:** **2013-01-01** through present. **Adjusted return series:** **2006-01-04** through present.

---

## Why The Engine Matters

RiskModels is designed to be useful for real portfolio work, not just descriptive analytics:

- **Built to be time-safe** — the engine is designed to avoid common sources of forward contamination such as recycled tickers, snapshot shares, and retroactive universe contraction
- **Grounded in a real Security Master** — ticker-level outputs sit on top of a point-in-time identity layer built for identifier continuity, symbol changes, and historically defensible shares data
- **Hierarchical by design** — the model separates market, sector, and subsector structure rather than collapsing everything into a flat beta view
- **Tradeable in practice** — the published hedge ratios are designed to work with liquid ETFs at execution time, not only with synthetic or orthogonalized factors
- **Built on adjusted return series** — split- and dividend-adjusted returns make the decomposition and hedge ratios more economically consistent over long horizons

For a deeper explanation of the engine design choices behind these claims, see the methodology docs and API reference.

---

## 🐍 Python SDK (riskmodels-py)

Prefer the Python SDK over raw REST for agent-native workflows — ticker resolution, semantic field normalization, validation with instructional errors, and LLM-ready context formatting are built in.

**Install** ([PyPI](https://pypi.org/project/riskmodels-py/)):

[![PyPI version](https://img.shields.io/pypi/v/riskmodels-py.svg)](https://pypi.org/project/riskmodels-py/)

```bash
pip install riskmodels-py
# Optional — xarray cube from batch Parquet/CSV:
# pip install riskmodels-py[xarray]
# Optional — snapshot PDF rendering:
# pip install riskmodels-py[pdf]
```

**Quickstart:**

```python
from riskmodels import RiskModelsClient, to_llm_context

client = RiskModelsClient.from_env()
pa = client.analyze({"NVDA": 0.4, "AAPL": 0.6})
print(to_llm_context(pa))
```

**Snapshot generation** (institutional PDF reports):

```python
from riskmodels.snapshots import get_data_for_r1, render_r1_to_pdf

client = RiskModelsClient.from_env()
data = get_data_for_r1("NVDA", client)       # fetch → R1Data (caches to JSON)
render_r1_to_pdf(data, "NVDA_R1_Risk.pdf")   # render → PDF (~0.3s, no API)
```

**Documentation:**

- [Package README](./sdk/README.md) — install, methods, agent-native helpers
- [Quickstart](/quickstart) — 60-second setup path
- [API Docs](/docs/api) — agent-native helpers reference table

---

## Risk intelligence

Charts below are **generated from live API data** (`get_rankings` + MAG7 L3 batch metrics) via [`scripts/generate_readme_assets.py`](./scripts/generate_readme_assets.py). Set `RISKMODELS_API_KEY` (free tier is sufficient), run the script from the repo root, then commit `./assets/` and `./public/docs/readme/`.

### MAG7 — L3 σ-scaled decomposition

<p align="center">
  <img src="./assets/mag7_l3_sigma_rr.png" width="680" alt="MAG7 L3 sigma-scaled risk ratios and residual HR share" />
  <br>
  <sub>Same “tech” label, different subsector DNA — bar length ∝ annualized σ; segments = σ × L3 market/sector/subsector risk ratios + residual (HR share). <code>POST /batch/analyze</code> via SDK <code>save_mag7_l3_sigma_rr_png</code></sub>
</p>

### Cross-sectional rankings

<p align="center">
  <img src="./assets/ranking_cohorts.png" width="680" alt="Ranking by cohort" />
  <br>
  <sub>Universe / sector / subsector rank percentile breakdown</sub>
</p>

---

## 🤖 MCP Server (v3.0.0-agent)

RiskModels includes a first-class [MCP (Model Context Protocol)](https://modelcontextprotocol.io) server, enabling AI agents to directly query risk data and perform factor analysis.

**MCP Connection (hosted API):**
- **Endpoint (Streamable HTTP, POST):** `https://riskmodels.app/api/mcp`
- **Named endpoints:** `/api/mcp/openai` and `/api/mcp/sse` remain supported
- **Authentication:** Bearer token (API key or OAuth2 JWT)
- **Discovery:** `https://riskmodels.app/.well-known/mcp.json` (see [OPENAPI_SPEC.yaml](./OPENAPI_SPEC.yaml))

**Local MCP server (`mcp/` in this repo, `@riskmodels/mcp` 2.0.0)** — stdio transport for Cursor / Claude Desktop / Zed. Tool set 2.0 is one registry shared with the hosted endpoints: 25 tools locally, 26 hosted (adds `riskmodels_render_artifact`):

`riskmodels_get_stock_snapshot`, `riskmodels_decompose`, `riskmodels_compare`, `riskmodels_get_returns`, `riskmodels_get_return_attribution`, `riskmodels_get_residual_returns`, `riskmodels_get_residual_signal`, `riskmodels_get_macro_correlation`, `riskmodels_get_fundamentals`, `riskmodels_analyze_portfolio`, `riskmodels_get_portfolio_risk_snapshot`, `riskmodels_portfolio_exposure`, `riskmodels_decompose_selection_vs_drift`, `riskmodels_get_my_positions`, `riskmodels_get_rankings`, `riskmodels_screen_rankings`, `riskmodels_get_cohorts`, `riskmodels_get_peers`, `riskmodels_search`, `riskmodels_resolve_security_identity`, `riskmodels_get_filer`, `riskmodels_get_fund`, `riskmodels_get_etf`, `riskmodels_get_benchmark_fit`, `riskmodels_get_factor_returns`.

The REST catalog, response schemas and OpenAPI spec are MCP resources (`riskmodels:///capabilities`, `riskmodels:///schemas/{path}`, `riskmodels:///openapi`). Tool list, prices and the 1.x → 2.0 migration table: [`mcp/README.md`](./mcp/README.md#tool-set-20). Outside MCP, call the **REST API** or the **Python SDK** (`riskmodels-py`).

See [mcp/README.md](./mcp/README.md) for install and config.

**Anthropic Claude (Managed Agents vs Messages API):** internal engineering design for optional cloud-hosted agents, billing, and compliance — see [docs/ANTHROPIC_CLOUD_AGENTS.md](./docs/ANTHROPIC_CLOUD_AGENTS.md).

---

## ⌨️ Command-line CLI (`riskmodels`)

The npm package in [`cli/`](./cli/) installs the `riskmodels` binary: config, SQL query (billed API or direct Supabase), schema introspection, balance, and static agent manifests.

**Install from npm:**

```bash
npm install -g riskmodels
riskmodels --help
```

**Develop from this repo:**

```bash
cd cli
npm ci
npm run build
npm run install:global   # optional: npm link for local testing
```

**Publish to npm** (maintainers): procedure is documented in the private **BWMACRO** monorepo (`docs/RISKMODELS_CLI_NPM_PUBLISHING.md`), not here. Only publish from the **`cli/`** directory — the repo root Next.js app is not published to npm.

---

## 💻 Developer Portal (This Repo)

This repo now includes a **Next.js developer portal** with:

- ✨ Hero landing page with feature highlights
- 📚 MDX-powered documentation (README_API.md, AUTHENTICATION_GUIDE.md)
- 🔍 Interactive API reference (Redoc OpenAPI viewer)
- 💡 Code examples with syntax highlighting and copy buttons
- 🎯 Step-by-step quickstart guide

### Local Development

```bash
# Install dependencies
npm install

# Option A: Copy env template and fill in Supabase/Stripe keys manually
cp .env.example .env.local

# Option B: Use Doppler (recommended for team consistency)
# Ensure `doppler login` is done, then:
doppler secrets download --no-file --format env > .env.local

# Generate OpenAPI JSON for Redoc
npm run build:openapi

# Run dev server
npm run dev
```

**Screenshot Capture Hygiene:**

When capturing site screenshots for audit or documentation:
1. **Ensure the build passes first:** `npm run build` must complete without errors
2. **Verify the dev server serves HTTP 200:** Visit `http://localhost:3000` and confirm pages render (not "Internal Server Error")
3. **Run the capture script:** `python3 capture_site.py` (requires Playwright)

The script will skip pages returning HTTP 500 or containing "Internal Server Error" content. Screenshots with server errors should never be committed to the repository.

**Environment Management with Doppler:**

This repo uses [Doppler](https://doppler.com) for secrets management. The `doppler.yaml` is pre-configured for the `erm3` project:

```bash
# Verify setup (should show project: erm3, config: dev)
doppler setup

# List all secrets
doppler secrets

# Get a specific secret
doppler secrets get STRIPE_SECRET_KEY

# Export dev secrets to .env.local for curl testing and local dev
npm run doppler:env

# Push production secrets to Vercel (requires vercel login + project link)
npm run vercel:sync-env:doppler
```

**For curl/API testing with Doppler secrets:**

```bash
# 1. Export secrets to .env.local
npm run doppler:env

# 2. Source them for your shell session
source .env.local

# 3. Use in curl commands
curl -H "Authorization: Bearer $RISKMODELS_API_SERVICE_KEY" \
  https://riskmodels.app/api/health
```

See [DEPLOYMENT.md](DEPLOYMENT.md) for detailed Vercel/Doppler integration.

Visit [http://localhost:3000](http://localhost:3000)

### Build & Deploy

```bash
# Build for production
npm run build

# Start production server
npm start
```

**Deployment:** See [DEPLOYMENT.md](DEPLOYMENT.md) for Vercel setup, env vars, and Supabase/Stripe config.

---

## 📂 Repository Structure

```
RiskModels_API/
├── app/                      # Next.js app
│   ├── api/                  # API routes (REST)
│   ├── page.tsx              # Hero landing page
│   ├── layout.tsx            # Root layout with Navbar/Footer
│   ├── docs/[[...slug]]/     # MDX docs renderer
│   ├── api-reference/        # Redoc OpenAPI viewer
│   ├── examples/             # Code examples showcase
│   └── quickstart/           # Quickstart guide
├── components/               # React components (new)
│   ├── Navbar.tsx
│   ├── Footer.tsx
│   ├── Hero.tsx
│   ├── CodeBlock.tsx
│   └── Logo.tsx
├── content/docs/             # MDX content (new)
│   ├── api.mdx
│   └── authentication.mdx
├── cli/                      # Command-line CLI (`riskmodels`)
├── sdk/                      # Python SDK (`riskmodels-py`) source
│   └── riskmodels/snapshots/ # Snapshot PDF pipeline (R1 shipped, R2–P4 planned)
├── examples/                 # Runnable examples
│   ├── python/
│   └── typescript/
├── mcp/                      # MCP (Model Context Protocol) server
├── public/                   # Static assets (new)
│   ├── transparent_logo.svg
│   └── openapi.json          # Generated from OPENAPI_SPEC.yaml
├── styles/                   # Global styles (new)
├── lib/                      # Utilities (new)
├── OPENAPI_SPEC.yaml         # Canonical OpenAPI spec
├── README_API.md             # API reference (source for content/docs/api.mdx)
├── AUTHENTICATION_GUIDE.md   # Auth guide (source for content/docs/authentication.mdx)
├── SEMANTIC_ALIASES.md       # Field definitions
└── package.json              # Next.js deps (new)
```

---

## 🛠️ Tech Stack (Developer Portal)

- **Framework:** Next.js 15 (App Router)
- **Styling:** Tailwind CSS 3.4, dark mode default
- **MDX:** @next/mdx for documentation
- **API Reference:** Redoc (OpenAPI 3.0 viewer)
- **Code Highlighting:** Custom CodeBlock with copy button
- **Fonts:** Inter (system-ui fallback)
- **Colors:** Blue primary (`hsl(217, 91%, 60%)`), zinc/slate dark palette

---

## 📄 Documentation Files

| Document | Description |
|---|---|
| [README_API.md](README_API.md) | Complete API overview, endpoints, key concepts |
| [API_TERMS.md](API_TERMS.md) | API Terms of Service ([riskmodels.net/terms/api](https://riskmodels.net/terms/api)) |
| [PLAID_HOLDINGS_UX.md](PLAID_HOLDINGS_UX.md) | Plaid connection flow and holdings API user experience |
| [AUTHENTICATION_GUIDE.md](AUTHENTICATION_GUIDE.md) | Bearer token, OAuth2, Supabase JWT, rate limits |
| [DOCS_PROCESS.md](DOCS_PROCESS.md) | Process for adding new documentation |
| [SEMANTIC_ALIASES.md](SEMANTIC_ALIASES.md) | Field definitions, units, formulas |
| [RESPONSE_METADATA.md](RESPONSE_METADATA.md) | `_agent` block, response headers, pricing |
| [ERROR_SCHEMA.md](ERROR_SCHEMA.md) | Error codes and recovery patterns |
| [OPENAPI_SPEC.yaml](OPENAPI_SPEC.yaml) | OpenAPI 3.0.3 specification (v3.0.0-agent) |
| [docs/SNAPSHOT_ROADMAP.md](docs/SNAPSHOT_ROADMAP.md) | Snapshot suite roadmap, ADRs, and implementation phases |
| [docs/SNAPSHOT_CONTENT_MAP.md](docs/SNAPSHOT_CONTENT_MAP.md) | 8-page content spec with wireframes and JSON schemas |
| [docs/SNAPSHOT_FRONTEND_ARCH.md](docs/SNAPSHOT_FRONTEND_ARCH.md) | Pure-Matplotlib rendering pipeline architecture |

---

## 🔗 Related

- **[ERM3](https://github.com/conradgann/ERM3)** — Python risk model computation engine (open source)

---

## 🤝 Contributing

We welcome pull requests, especially to improve the **OpenAPI spec** — clearer descriptions, better schemas, and more examples help everyone.

1. **OpenAPI spec:** [CONTRIBUTING.md](CONTRIBUTING.md) — PRs to `OPENAPI_SPEC.yaml` are encouraged
2. **Issues:** [Open an issue](https://github.com/BlueWaterCorp/RiskModels_API/issues) for bugs or feature requests
3. **Examples:** Submit new examples via PR to `examples/`
4. **Docs:** Improve documentation by editing MDX files in `content/docs/`

---

## 📧 Support

- **API Support:** [service@riskmodels.app](mailto:service@riskmodels.app)
- **Issues:** [github.com/BlueWaterCorp/RiskModels_API/issues](https://github.com/BlueWaterCorp/RiskModels_API/issues)
- **Status:** [riskmodels.net/status](https://riskmodels.net/status) · API metrics [riskmodels.app/api/status](https://riskmodels.app/api/status)

---

## 📜 License

See [LICENSE](LICENSE) for details.

**© 2026 Blue Water Macro Corp. All rights reserved.**
# Deploy trigger: Tue Jun  9 16:13:22 PDT 2026


TDQS

A4.5/5.0

Scored across 24 tools

Disambiguation5/5

Each tool targets a distinct resource+action and nearly every description includes explicit 'not for X (use Y)' routing, e.g. the closely related get_returns vs get_return_attribution vs get_residual_returns vs get_residual_signal are clearly separated. The four portfolio tools (analyze_portfolio, get_portfolio_risk_snapshot, portfolio_exposure, decompose_selection_vs_drift) overlap most, but size/short/long-only/purpose boundaries are spelled out, so selection is tractable.

Naming Consistency4/5

All tools share the riskmodels_ prefix and most follow a get_<noun> or verb_noun pattern (get_stock_snapshot, get_rankings, screen_rankings, analyze_portfolio). A few drop the verb or use noun phrases (decompose, compare, portfolio_exposure, decompose_selection_vs_drift), which is a minor deviation but still readable.

Tool Count4/5

24 tools is on the heavy side but the server spans a genuinely broad domain: single-stock risk, returns/attribution, macro, screening, portfolios, funds, 13F filers and ETFs. Each tool maps to a distinct endpoint and earns its place, so the count is justified rather than bloated.

Completeness5/5

Coverage is comprehensive across the equity-risk lifecycle: fundamentals, metrics snapshots, per-stock and universe rankings/screens, returns and factor/residual attribution, macro factors and correlations, peers/cohorts, entity search, and full portfolio construction/hedging/attribution. The fund, filer, ETF and benchmark-fit tools round out the security-master side, leaving no obvious dead ends.

Maintenance

ActivityActive
ResponsivenessUnresponsive