Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/riskmodels-app:riskmodels-app-mcp-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: RiskModels MCP API
version: 3.0.0-agent
description: 'POST /decompose returns variance shares and ETF hedge ratios for any US equity, separating factor exposure from the residual bet so you can hedge what you don''t want. Daily history to 2000 across ~3,000 US equities.
Precision equity risk intelligence platform with AI agent integration.
**New in v3.0.0-agent:**
- OAuth2 client credentials flow for machine-to-machine auth
- Plaid Investments integration for live portfolio sync
- MCP (Model Context Protocol) server for AI agent tools
- Compliance manifests for AI marketplace integration
- Per-key rate limiting and scoped access control
**Data**: Universe `uni_mc_3000` (top ~3,000 US stocks by market cap), date range 2000 to present (deep panel; stock-specific skill series from ~2001 after warmup), updated daily end-of-day. Model outputs are computed by the ERM3 regression system (Huber/Ridge), with Zarr v2 archives on Google Cloud Storage for research pipelines. The live API reads primarily from Supabase **V3** tables: long-form `security_history` (returns, volatility, L1/L2/L3 hedge ratios and explained-risk metrics), wide latest rows in `security_history_latest`, identity in `symbols`, plus supporting surfaces such as `trading_calendar`, `erm3_landing_chart_cache`, and `macro_factors`. Cross-sectional **rankings** (`GET /rankings/*`) are served from precomputed rank metric keys in `security_history`, not a separate `erm3_rankings` table. Hedge ratios (`*_hr`) are **dollar_ratio** ETF notionals per $1 stock and are distinct from regression **betas** (`l1_mkt_beta`, `l2_sec_beta`, `l3_sub_beta`), which are dimensionless coefficients from the hierarchical L1/L2/L3 regression. Both are exposed under `MetricsV3` and on `security_history_latest`. See `SEMANTIC_ALIASES.md` for the full HR-vs-beta convention.
**Authentication Methods:**
1. Session cookies (web app)
2. API Key/Secret via Bearer token (external integrations)
3. OAuth2 client credentials (AI agents, npm package)
**Security Features:**
- GCP KMS envelope encryption for portfolio data
- Cryptographic shredding on key deletion
- HMAC-SHA256 webhook verification
- Row-level security (RLS) via Supabase
**Pricing**: Per-request billing with prepaid balance. Cached responses are free. Many metered responses include `_agent.cost_usd` in the JSON body; others bill silently — always check the `X-API-Cost-USD` response header when present. Metered operations also expose `x-pricing` (OpenAPI extension) with `capability_id`, `tier` (`baseline` | `premium`), `model`, `cost_usd`, `billing_code`, and optional `min_charge` / per-token fields — aligned with `GET /pricing` and `lib/agent/capabilities.ts`.
**Lineage**: JSON data responses include `_metadata` (model version, data_as_of, factor set) and headers `X-Risk-Model-Version`, `X-Data-As-Of`, `X-Factor-Set-Id`, `X-Universe-Size`. Parquet and CSV bodies omit `_metadata`; use the same `X-Risk-*` headers on the HTTP response.
**Tabular exports (Parquet / CSV):** For bulk historical loads, time-series endpoints accept `format=parquet` or `format=csv`, or (when `format` is omitted) `Accept: application/vnd.apache.parquet` or `Accept: text/csv`. Successful responses use `Content-Type: application/vnd.apache.parquet` or `text/csv; charset=utf-8` and `Content-Disposition: attachment` with a descriptive filename. Each export is a single flat table; column names and types match the per-operation schemas referenced in the response media type descriptions (aligned with JSON row objects or zipped parallel arrays). Parquet is produced via schema inference from the first row (UTF8 strings, DOUBLE floats, INT64 integers, BOOLEAN, TIMESTAMP_MILLIS for JavaScript Date values). CSV uses a header row, comma separators, UTF-8, and RFC 4180-style quoting when needed. Prefer Parquet for typed columnar stacks (pandas, Polars, Arrow); use CSV for spreadsheets and lightweight scripting.'
contact:
name: RiskModels Support
email: service@riskmodels.app
url: https://riskmodels.app
termsOfService: https://riskmodels.app/legal
license:
name: Commercial
url: https://riskmodels.app/legal
servers:
- url: https://riskmodels.app/api
description: Production — all metered endpoints (`/metrics`, `/snapshot`, `/decompose`, `/batch/analyze`, `/portfolio/*`, etc.).
- url: https://riskmodels.app
description: Discovery origin — `/.well-known/*` manifests (`mcp.json`, `ai-plugin.json`, `agentic-disclosure.json`) live at the site origin without the `/api` prefix. Generated clients that hard-code the first server entry must strip `/api` before requesting these paths.
security:
- BearerAuth: []
tags:
- name: MCP
description: Model Context Protocol server endpoints for AI agents.
paths:
/mcp/sse:
get:
summary: MCP Streamable HTTP Connection
description: 'Model Context Protocol endpoint using the Streamable HTTP transport (successor to the legacy SSE+companion-POST pattern). A single URL handles both `GET` (optional server→client event stream) and `POST` (client→server JSON-RPC 2.0 messages).
**Discovery:** The MCP server manifest is published at `https://riskmodels.app/.well-known/mcp.json` for automated client discovery.
**Connection:**
- Transport: Streamable HTTP (stateless mode)
- Authentication: `Authorization: Bearer ` (preferred) or
`?api_key=` query param (for `EventSource`, which can''t set
custom headers).
- Tool-call billing: charged per-invocation on the underlying REST
endpoint (e.g. `riskmodels_get_stock_snapshot` bills the same as `GET /metrics/{ticker}`).
- **POST requests:** send `Accept: application/json, text/event-stream` (required by some MCP clients;
omitting it can yield **406 Not Acceptable**).
**Usage — mcp-remote proxy:**
```json
{
"mcpServers": {
"riskmodels": {
"command": "npx",
"args": ["mcp-remote", "https://riskmodels.app/api/mcp/sse"],
"env": { "AUTHORIZATION": "Bearer rm_agent_live_..." }
}
}
}
```'
operationId: mcpServerSSE
tags:
- MCP
security:
- BearerAuth: []
- OAuth2AuthorizationCode:
- mcp:read
responses:
'200':
description: SSE connection established
content:
text/event-stream:
schema:
type: string
format: event-stream
example: 'data: {"jsonrpc":"2.0","method":"notifications/initialized","params":{...}}
data: {"jsonrpc":"2.0","method":"notifications/ping","params":{"timestamp":1234567890}}
'
'401':
description: Authentication required
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Insufficient balance.
content:
application/json:
schema:
$ref: '#/components/schemas/InsufficientBalance'
'429':
description: Rate limit exceeded.
headers:
Retry-After:
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimitExceeded'
post:
summary: MCP JSON-RPC Request
description: 'Send JSON-RPC 2.0 messages to the MCP server.
**Available methods:**
- `tools/list` - List available MCP tools
- `tools/call` - Invoke an MCP tool
- `resources/list` - List available resources
- `resources/read` - Read a resource'
operationId: mcpServerRPC
tags:
- MCP
security:
- BearerAuth: []
- OAuth2AuthorizationCode:
- mcp:read
requestBody:
required: true
content:
application/json:
schema:
type: object
required:
- jsonrpc
- method
- id
properties:
jsonrpc:
type: string
enum:
- '2.0'
method:
type: string
example: tools/call
params:
type: object
id:
oneOf:
- type: string
- type: integer
example:
jsonrpc: '2.0'
method: tools/call
params:
name: riskmodels_get_stock_snapshot
arguments:
ticker: NVDA
id: 1
responses:
'200':
description: JSON-RPC response
content:
application/json:
schema:
type: object
properties:
jsonrpc:
type: string
enum:
- '2.0'
result:
type: object
error:
type: object
properties:
code:
type: integer
message:
type: string
id:
oneOf:
- type: string
- type: integer
'401':
description: Authentication required
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'402':
description: Insufficient balance.
content:
application/json:
schema:
$ref: '#/components/schemas/InsufficientBalance'
'429':
description: Rate limit exceeded.
headers:
Retry-After:
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/RateLimitExceeded'
/.well-known/mcp.json:
get:
summary: MCP Server Manifest
servers:
- url: https://riskmodels.app
description: Site origin (discovery)
description: 'Model Context Protocol server connection manifest. Enables AI model clients to discover and connect to the RiskModels MCP server.
**Discovery URL:** Served at the **site origin** (`https://riskmodels.app/.well-known/mcp.json`), not under `/api`.'
operationId: getMCPManifest
tags:
- MCP
security: []
responses:
'200':
description: MCP server manifest
content:
application/json:
schema:
type: object
properties:
mcpServers:
type: object
additionalProperties:
type: object
properties:
name:
type: string
description:
type: string
url:
type: string
format: uri
transport:
type: string
enum:
- sse
- stdio
auth:
type: object
capabilities:
type: object
tools:
type: array
items:
$ref: '#/components/schemas/MCPTool'
components:
schemas:
MCPTool:
type: object
description: 'MCP tool descriptor as returned by `tools/list`. Tools are discoverable via `https://riskmodels.app/.well-known/mcp.json` or by connecting to the SSE endpoint at `https://riskmodels.app/api/mcp/sse` and calling `tools/list`.
'
properties:
name:
type: string
enum:
- riskmodels_analyze_portfolio
- riskmodels_compare
- riskmodels_decompose
- riskmodels_decompose_selection_vs_drift
- riskmodels_get_benchmark_fit
- riskmodels_get_cohorts
- riskmodels_get_etf
- riskmodels_get_factor_returns
- riskmodels_get_filer
- riskmodels_get_fund
- riskmodels_get_fundamentals
- riskmodels_get_macro_correlation
- riskmodels_get_my_positions
- riskmodels_get_peers
- riskmodels_get_portfolio_risk_snapshot
- riskmodels_get_rankings
- riskmodels_get_residual_returns
- riskmodels_get_residual_signal
- riskmodels_get_return_attribution
- riskmodels_get_returns
- riskmodels_get_stock_snapshot
- riskmodels_portfolio_exposure
- riskmodels_render_artifact
- riskmodels_screen_rankings
- riskmodels_search
description: 'MCP tool names (tool set 2.0, `@riskmodels/mcp` 2.0.0). One registry (`registerRiskModelsTools`) serves all
three surfaces: the npm stdio server registers 24 tools; the hosted endpoints `/api/mcp/sse` and
`/api/mcp/openai` register the same 24 plus `riskmodels_render_artifact` (25). Every tool is read-only and
calls an existing REST route, billed at that route''s price; each description states when to use the tool,
what it returns, data freshness and price. The REST catalog, response schemas and this spec are MCP
resources (`riskmodels:///capabilities`, `riskmodels:///schemas/{path}`, `riskmodels:///openapi`).
Tool-to-route table and the 1.x migration table: mcp/README.md (Tool set 2.0).
'
description:
type: string
inputSchema:
type: object
description: JSON Schema describing the tool's input parameters.
outputSchema:
type: object
description: JSON Schema describing the tool's output structure.
RateLimitExceeded:
type: object
description: Returned when the per-minute rate limit is exceeded (HTTP 429).
properties:
error:
type: string
enum:
- RATE_LIMIT_EXCEEDED
example: RATE_LIMIT_EXCEEDED
message:
type: string
example: Rate limit exceeded. Retry after 2026-03-08T12:34:56Z
retry_after:
type: string
format: date-time
description: ISO timestamp after which the client may retry.
example: '2026-03-08T12:34:56Z'
limit:
type: integer
description: Requests allowed per minute for this key.
example: 60
InsufficientBalance:
type: object
description: Returned when the account prepaid balance is exhausted (HTTP 402).
properties:
error:
type: string
enum:
- INSUFFICIENT_BALANCE
example: INSUFFICIENT_BALANCE
message:
type: string
example: 'Insufficient balance. Current balance: $0.00. Top up at https://riskmodels.app/billing'
balance_usd:
type: number
format: float
example: 0
top_up_url:
type: string
format: uri
example: https://riskmodels.app/billing
ErrorResponse:
type: object
properties:
error:
type: string
description: Machine-readable error code.
example: TICKER_NOT_FOUND
message:
type: string
description: Human-readable error description with suggested action.
example: Ticker 'XYZABC' not found in universe 'uni_mc_3000'. Check ticker spelling or try a different universe.
code:
type: integer
description: HTTP status code.
example: 404
history_starts:
type: string
format: date
description: 'Earliest non-null daily close or return date for the resolved security. Present only when a historical request ends before the security''s own history begins.
'
details:
type: object
properties:
field:
type: string
example: ticker
received:
type: string
example: XYZABC
universe:
type: string
example: uni_mc_3000
suggestion:
type: string
example: Check for typos or use ticker search endpoint
securitySchemes:
BearerAuth:
type: http
scheme: bearer
bearerFormat: rm_agent_{environment}_{random}_{checksum}
description: 'API key in format `rm_agent_{live|test}_{random}_{checksum}` or `rm_user_{random}_{checksum}`. Obtain via `POST /api/auth/provision` or from riskmodels.app/settings → API Keys. Include as: `Authorization: Bearer rm_agent_live_...`
'
OAuth2AuthorizationCode:
type: oauth2
description: 'OAuth 2.0 authorization code flow with PKCE (S256), used by MCP clients (Claude Desktop, Cursor, ChatGPT Developer Mode, Grok) that self-register via `POST /api/oauth/register`. Public clients only — no `client_secret` is issued and `token_endpoint_auth_method` is `none`.
The access token this flow returns **is** an `rm_user_*` API key (1 h TTL, 30 d rotating refresh token), so it authenticates every `BearerAuth` operation below, not just `/api/mcp/sse`. Scope is currently informational: the API records the presented scope for telemetry but authorises by key validity and account balance, not by scope.
Discovery metadata: `/.well-known/oauth-authorization-server`.
'
flows:
authorizationCode:
authorizationUrl: https://riskmodels.app/oauth/authorize
tokenUrl: https://riskmodels.app/api/oauth/token
refreshUrl: https://riskmodels.app/api/oauth/token
scopes:
mcp:read: Read access to risk analytics (the only scope the authorization server advertises)