# RiskModels (npm · @riskmodels/mcp)

Dividend-adjusted US equity total returns, risk decomposition, attribution & ETF hedge ratios

- Trust score: 68/100 (medium)
- Change this week: +15
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-03

## Components

- remote · `riskmodels.app`: 38/100, [markdown](https://verifymcp.io/servers/bluewatercorp-riskmodels/api-mcp-sse.md), [page](https://verifymcp.io/servers/bluewatercorp-riskmodels/api-mcp-sse)
- npm · `@riskmodels/mcp`: 68/100 (this document), [markdown](https://verifymcp.io/servers/bluewatercorp-riskmodels/riskmodels-mcp.md), [page](https://verifymcp.io/servers/bluewatercorp-riskmodels/riskmodels-mcp)

## Channel facts

- Registry: `npm`
- Package: `@riskmodels/mcp`
- Version: `1.0.6`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-03.

- **Supply Chain Security**: 87/100
  - No malware found by supply-chain analysis.
  - Only part of the dependency tree could be resolved (96 of 100), so this covers what we could see, not the whole tree.
  - No install/post-install scripts declared.
  - Only part of the dependency tree could be resolved (96 of 100), so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 32/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - License check failed: no license is declared.
  - Actively maintained (last published 53 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 81/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (good).
  - Tool/resource definitions use about 2925 tokens (~76/item across 38 items; 29 tools + 9 resources), lean.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 27/100
  - Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.
- **Tool Coverage**: 99/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 96% of tool parameters carry a description.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

## Install

### Claude

```bash
claude mcp add bluewatercorp-riskmodels -- npx -y @riskmodels/mcp
```

### Codex

```bash
codex mcp add bluewatercorp-riskmodels -- npx -y @riskmodels/mcp
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "bluewatercorp-riskmodels": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@riskmodels/mcp"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add bluewatercorp-riskmodels --command npx --arg -y --arg @riskmodels/mcp
```

### Hermes

```yaml
mcp_servers:
  bluewatercorp-riskmodels:
    command: "npx"
    args: ["-y", "@riskmodels/mcp"]
```

### Other

```json
{
  "mcpServers": {
    "bluewatercorp-riskmodels": {
      "command": "npx",
      "args": [
        "-y",
        "@riskmodels/mcp"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-03 (score 68, +1)

No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

### 2026-08-02 (score 67, +31)

- [security regression] Provenance: unverified → fail
- [security improvement] Install scripts: unverified → pass
- [security improvement] Known CVEs: unverified → partial
- [security improvement] Malware scan: unverified → pass
- [functional regression] License: unverified → fail
- [functional improvement] Dependency health: unverified → partial
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] Stability: unverified → 0.23

### 2026-08-01 (score 36, −11)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-31 (score 47, −6)

- [security regression] Provenance: unverified → fail
- [security regression] Malware scan: pass → unverified
- [security improvement] Install scripts: unverified → pass
- [functional regression] License: unverified → fail
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] Schema quality: unverified → good

### 2026-07-27 (score 53)

First indexed and scored.

## MCP tools (29)

### `riskmodels_decompose` (~111 tokens)

RiskModels Single-Stock Decomposition

L3 four-bet view: decompose one stock into additive market, sector, subsector, and residual layers (same semantics as POST /decompose exposure/hedge). Returns chart_data and plain_english. To compare standalone L1 vs L2 vs L3 hedge solutions (HR/ER + ETF legs), call riskmodels_get_hedge_levels or read hedge_levels on the API response.

Input parameters:

- `ticker` (string, required): Ticker symbol, e.g. NVDA or AAPL

### `riskmodels_get_returns` (~130 tokens)

RiskModels Stock Total Returns

Daily dividend-adjusted total (gross) return series for any US stock or ETF (GET /ticker-returns), with per-day L3 market/sector/subsector hedge ratios and explained-risk fractions (sum to ~1.0). Up to 15 years of point-in-time, time-safe history. Use for performance tracking, backtests, or as the clean returns input to any risk or attribution work.

Input parameters:

- `ticker` (string, required): Ticker symbol, e.g. NVDA or AAPL
- `years` (integer): Years of daily history (default 1, max 15)

### `riskmodels_get_return_attribution` (~194 tokens)

RiskModels Return Attribution (factor vs residual)

Daily return attribution (GET /returns-decomposition): decomposes each day's gross return into additive L1/L2/L3 factor (market/sector/subsector) and residual (stock-specific) return components from ds_erm3_returns. Isolates the residual return series — the stock-picking / alpha component — for manager-skill evaluation and stat-arb. Set include_lstar for the Lstar-dispatched residual series.

Input parameters:

- `include_lstar` (boolean): Include lstar + lstar_residual_return arrays (default false)
- `market_factor_etf` (string): Market factor ETF (default SPY)
- `threshold` (number): Marginal ER threshold for Lstar derivation (default 0.01)
- `ticker` (string, required): Ticker symbol, e.g. NVDA or AAPL
- `years` (integer): Calendar years of daily history (default 1)

### `riskmodels_get_hedge_levels` (~84 tokens)

RiskModels L1/L2/L3 hedge_levels

Canonical L1, L2, and L3 hedge snapshots (semantic HR/ER + hedge_etfs) from GET /metrics/{ticker}. Use this when you need to compare which cascade depth to trade, distinct from decompose four-bet exposure.

Input parameters:

- `ticker` (string, required): Ticker symbol, e.g. NVDA or AAPL

### `riskmodels_compare` (~48 tokens)

RiskModels Multi-Ticker Comparison

Compare tickers across market, sector, subsector, and residual risk layers. Prefer grouped bar charts when chart_data is present.

Input parameters:

- `tickers` (array, required): Ticker symbols to compare

### `riskmodels_hedge_position` (~61 tokens)

RiskModels Position Hedge

Scale ETF hedge ratios for a ticker to a dollar position. Returns chart-ready hedge notionals.

Input parameters:

- `dollars` (number, required): Dollar notional of the stock position
- `ticker` (string, required): Ticker symbol, e.g. NVDA

### `riskmodels_analyze_portfolio` (~85 tokens)

RiskModels Portfolio hedge_levels aggregate

Holdings-weighted L1/L2/L3 hedge_levels across names via POST /batch/analyze (hedge_ratios). Returns normalized portfolio.portfolio_hedge_levels and per-ticker blocks when present.

Input parameters:

- `positions` (array, required): Positions with weight or dollars (combined per ticker)
- `years` (integer): Batch lookback window, default 1

### `riskmodels_hedge_portfolio` (~74 tokens)

RiskModels Portfolio ETF hedge notionals

Batch hedge_ratios at a chosen cascade level (L1/L2/L3), scale HRs by dollar notionals per ticker, and aggregate ETF USD hedge legs.

Input parameters:

- `level` (string): Cascade depth; default L3
- `positions` (array, required)
- `years` (integer)

### `riskmodels_portfolio_decompose` (~45 tokens)

RiskModels Portfolio Decomposition

Decompose a weighted portfolio into market, sector, subsector, and residual risk layers.

Input parameters:

- `positions` (array, required): Portfolio positions as ticker plus weight or dollars

### `riskmodels_whitepaper_example` (~45 tokens)

RiskModels Live White-Paper Example

Run a live example from the RiskModels white paper. Returns chapter text plus SDK/API output with chart_data.

Input parameters:

- `exampleId` (string, required): White-paper example id

### `riskmodels_search_tickers` (~109 tokens)

RiskModels Ticker Search

Resolve a symbol or company name to RiskModels tickers (GET /tickers). Free — use this first to turn a name like "Nvidia" into a ticker before any analysis tool. mag7=true returns the Magnificent Seven.

Input parameters:

- `include_metadata` (boolean): Include extra metadata per match
- `mag7` (boolean): Return the MAG7 set
- `search` (string): Symbol or company-name fragment, e.g. "nvidia" or "NVDA"

### `riskmodels_search_filers` (~88 tokens)

RiskModels 13F Filer Search

Find 13F filers by name (GET /13f/filers/search). Free — resolve a manager like "Berkshire" to a bw_filer_id before pulling its snapshot, holdings, or concentration.

Input parameters:

- `limit` (integer): Max results (default 25)
- `q` (string, required): Filer name fragment, e.g. "berkshire"

### `riskmodels_search_etfs` (~81 tokens)

RiskModels ETF Search

Find ETFs in the canonical universe by symbol or name (GET /data/etf/search). Free — resolve a hedge/benchmark ETF before pulling its metrics or holdings.

Input parameters:

- `limit` (integer): Max results (default 25)
- `q` (string): Symbol or name fragment, e.g. "semiconductor" or "SMH"

### `riskmodels_get_rankings` (~104 tokens)

RiskModels Cross-Sectional Rankings

Where a stock sits in its sector/universe percentile for a given metric (GET /rankings/{ticker}) — peer analytics / manager-skill context.

Input parameters:

- `cohort` (string): Peer cohort, e.g. sector or universe
- `metric` (string): Ranking metric (see riskmodels_get_capability id=rankings)
- `ticker` (string, required): Ticker symbol, e.g. NVDA
- `window` (string): Lookback window

### `riskmodels_screen_rankings` (~149 tokens)

RiskModels Rankings Screen

Full cross-section rank screen (POST /rankings/screen): server-side percentile/decile filtering across the universe for a metric. Use to build screens, not single-ticker lookups.

Input parameters:

- `as_of` (string): As-of date (YYYY-MM-DD)
- `cohort` (string, required): Peer cohort
- `decile` (integer): Restrict to a decile (1-10)
- `limit` (integer): Max rows (default 100)
- `metric` (string, required): Ranking metric
- `min_percentile` (number): Minimum percentile filter
- `sector_filter` (string): Restrict to a sector
- `window` (string, required): Lookback window

### `riskmodels_get_macro_correlation` (~135 tokens)

RiskModels Macro Factor Correlation

Exposure of a stock's returns to macro drivers like rates and volatility (POST /correlation). Defaults to the L3 residual return so it isolates idiosyncratic macro sensitivity.

Input parameters:

- `factors` (array): Macro factor ids to test (default: standard set)
- `method` (string): "pearson" (default) or "spearman"
- `return_type` (string): Return series to correlate (default "l3_residual")
- `ticker` (string, required): Ticker symbol, e.g. NVDA
- `window_days` (integer): Rolling window in days (default 252)

### `riskmodels_get_residual_signal` (~100 tokens)

RiskModels Residual Mean-Reversion Signal

Aggregate the L3 residual mean-reversion (stat-arb) signal across a basket (POST /signals/residual-reversion/basket). Optional weights and a minimum signal-quality quintile filter.

Input parameters:

- `signal_quality_min_quintile` (integer): Drop names below this signal-quality quintile (1-5)
- `tickers` (array, required): Basket tickers
- `weights` (array): Optional weights, aligned to tickers

### `riskmodels_get_filer_snapshot` (~77 tokens)

RiskModels 13F Filer Snapshot

Composed JSON snapshot for one 13F filer (GET /13f/filers/{bw_filer_id}/snapshot): registry + latest metrics + concentration. Resolve bw_filer_id via riskmodels_search_filers first.

Input parameters:

- `bw_filer_id` (string, required): Filer id from riskmodels_search_filers

### `riskmodels_get_filer_holdings` (~86 tokens)

RiskModels 13F Filer Holdings

Top-N current holdings of a 13F filer (GET /13f/filers/{bw_filer_id}/holdings). Resolve bw_filer_id via riskmodels_search_filers first.

Input parameters:

- `bw_filer_id` (string, required): Filer id from riskmodels_search_filers
- `top` (integer): Number of holdings (default 25)

### `riskmodels_get_etf` (~61 tokens)

RiskModels ETF Metrics

Latest canonical metrics for one ETF (GET /data/etf/{ticker}): registry metadata + portfolio surface. Resolve the ticker via riskmodels_search_etfs if unsure.

Input parameters:

- `ticker` (string, required): ETF ticker, e.g. SMH

### `riskmodels_get_etf_holdings` (~62 tokens)

RiskModels ETF Holdings

Top-N current holdings of an ETF (GET /data/etf/{ticker}/holdings).

Input parameters:

- `ticker` (string, required): ETF ticker, e.g. SMH
- `top` (integer): Number of holdings (default 25)

### `riskmodels_call_endpoint` (~147 tokens)

RiskModels Generic Capability Call

Escape hatch for any capability without a dedicated tool. Run riskmodels_list_endpoints (and riskmodels_get_capability for params), then call with that capability's method + endpoint path. Path is relative to the API root (a leading "/api" is stripped). Blocked: SQL (/cli/query), Plaid, and chat endpoints — use the REST API directly for those.

Input parameters:

- `body` (object): JSON body (POST)
- `method` (string, required): HTTP method from list_endpoints
- `path` (string, required): Endpoint path from list_endpoints, e.g. "/industry-panel" or "/data/benchmark/SPY"
- `query` (object): Query parameters

### `riskmodels_list_endpoints` (~28 tokens)

List RiskModels API Endpoints

List all public API capabilities (id, name, method, endpoint, short description)

### `riskmodels_get_capability` (~45 tokens)

Get RiskModels Capability Details

Get full capability details (parameters, pricing, examples) by id

Input parameters:

- `id` (string, required): Capability id (e.g. ticker-returns, risk-decomposition)

### `riskmodels_get_schema` (~61 tokens)

Get RiskModels Response Schema

Get JSON schema for an API response by path (e.g. ticker-returns-v2.json)

Input parameters:

- `path` (string, required): Schema path or filename (e.g. ticker-returns-v2.json or /schemas/ticker-returns-v2.json)

### `get_l3_decomposition` (~126 tokens)

L3 Hierarchical Risk Decomposition

Daily EOD hierarchical orthogonal decomposition for a single ticker: market → sector → subsector → residual. Returns parallel time-series arrays plus hedge ratios. Historical data from GCP zarr; latest snapshot from Supabase. Data freshness: daily after US market close (see _data_as_of).

Input parameters:

- `market_factor_etf` (string): Market factor ETF for L1 (default SPY)
- `ticker` (string, required): Stock ticker symbol, e.g. NVDA, AAPL
- `years` (integer): Years of daily history to return (1–15)

### `get_metrics` (~89 tokens)

Latest Risk Metrics Snapshot

Latest daily EOD risk metrics for a ticker from the Supabase _latest table: L1/L2/L3 hedge ratios (SPY, sector ETF, subsector ETF), explained-risk fractions, daily volatility, price close, market cap. Single-row snapshot. Data freshness: daily after US market close.

Input parameters:

- `ticker` (string, required): Stock ticker symbol, e.g. NVDA, AAPL

### `get_portfolio_risk_snapshot` (~153 tokens)

Portfolio Risk Snapshot

Bundled portfolio risk report for up to 100 positions: variance decomposition (market / sector / subsector / residual / systematic), portfolio 23-day volatility, and optional diversification analytics with sector/subsector ETF correlation matrices. Returns JSON by default. Response is cached per-user per-portfolio for 1 hour.

Input parameters:

- `as_of_date` (string): YYYY-MM-DD override for the snapshot date
- `include_diversification` (boolean): Include diversification metrics (adds latency)
- `positions` (array, required): Positions as { ticker, weight } pairs. Weights need not sum to 1.
- `title` (string)
- `window_days` (integer): Rolling window in trading days for diversification

### `post_snapshot` (~199 tokens)

Canonical Portfolio Snapshot

Run a canonical risk snapshot on a portfolio (1–100 positions): L3 variance decomposition (market / sector / subsector / residual / systematic), L3 hedge ratios per position, frozen-weight daily return attribution (gross + market / sector / subsector strips + residual), cumulative return and drawdown over the lookback window, and a risk_summary with dominant drivers, concentration flags, and top exposures. This is the canonical RiskModels public surface — same response shape across UI, CLI, SDK, and agents. Provide either weight or shares for every position (do not mix). Bills as portfolio-risk-snapshot ($0.25 per request).

Input parameters:

- `benchmark` (string): Optional benchmark ticker (reserved for comparison views)
- `lookback_days` (integer): Trading days of history for return curves and attribution series (default 252)
- `portfolio` (array, required): Portfolio positions. Use weights for every position OR shares for every position — do not mix.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/bluewatercorp-riskmodels/riskmodels-mcp#diagnostics

## Score history

- 2026-08-03: 68
- 2026-08-02: 67
- 2026-08-01: 36
- 2026-07-31: 47
- 2026-07-29: 53
- 2026-07-28: 53
- 2026-07-27: 53

## Links

- npm package: https://www.npmjs.com/package/@riskmodels/mcp
- Socket report: https://socket.dev/npm/package/@riskmodels/mcp
- Repository: https://github.com/BlueWaterCorp/RiskModels_API
- Website: https://riskmodels.app/
- Changelog RSS feed: https://verifymcp.io/servers/bluewatercorp-riskmodels/riskmodels-mcp/changelog.xml
- Changelog JSON feed: https://verifymcp.io/servers/bluewatercorp-riskmodels/riskmodels-mcp/changelog.json
- HTML version of this page: https://verifymcp.io/servers/bluewatercorp-riskmodels/riskmodels-mcp
