SPB Git forge

spb/hfmarketdata

Public

Open high-frequency market data platform — FirstRate full-history downloader, DuckDB/Parquet lake, open REST API and React docs platform (www.hfmarketdata.io)

127commits 1branches 0releases
24.7 MBsize
maindefault branch
11 days agolast push
JavaScript 53.7% Python 38.3% CSS 4.6% TypeScript 3.1%
9.6 KB

hfmarketdata-mcp demo — asking Claude Code for the CL term structure

hfmarketdata-mcp

The official MCP server for HF Market Data — 1-minute to daily bars for stocks, ETFs, futures, crypto, indices and FX since 2007, individual futures contracts, custom continuous series, term structures, options chains with Greeks and point-in-time SEC fundamentals, straight into Claude Code, Cursor, Codex or any MCP client.

npm node MCP tools tests license


# Quickstart (60 seconds)

bash
# 1. Install (pick one)
npm i -g hfmarketdata-mcp                                                   # from npm (once published)
npm i -g https://www.hfmarketdata.io/downloads/hfmarketdata-mcp-1.0.0.tgz   # direct tarball, works today

# 2. Check the connection (keyless works out of the box: 30 requests/hour)
hfmarketdata-mcp --selftest
# OK https://www.hfmarketdata.io (312 ms, keyless) — datasets: stock, etf, futures, futures_contracts, crypto, index, fx, options

# 3. Add it to Claude Code
claude mcp add hfmarketdata -e HFMD_API_KEY=hfmd_live_… -- npx -y hfmarketdata-mcp

Then just ask:

"Plot me the CL term structure" · "Compare ESZ25 and ESH26 over 30 days" · "Screen US stocks with PE<15 and FCF yield>6% and show their last 3 quarters"

The platform is entirely free. Keyless mode has low hourly limits (30 requests / hour); a free API key (free account at https://www.hfmarketdata.io/signup) gives 120 requests / minute, and higher limits are granted on request by e-mail to contact@spboucher.ai (also free). Set the key as HFMD_API_KEY; the server never logs it. Details: https://www.hfmarketdata.io/limits.

# Tools

Tool What it does Backed by
search_symbols Find tickers (stock/etf/crypto/index/fx), futures roots or optionable underlyings /v1/{asset}/tickers, /v1/futures/roots, /v1/options/tickers
get_bars OHLCV bars 1min…1day for one or many symbols; vendor continuous futures; individual contracts (ESZ25) /v1/bars/{asset}/{ticker}, /v1/bars/{asset}?tickers=, /v1/futures/contract/{symbol}/bars
get_futures_contracts Every expiration of a root with expiry / FND / status / volume / OI /v1/futures/{root}/contracts
get_futures_chain Listed contracts as of a date, front month first /v1/futures/{root}/chain
get_continuous Server-built continuous series: roll=volume|open_interest|calendar, adjust=none|back_adjusted|ratio, depth /v1/futures/{root}/continuous
get_term_structure The curve on a date (prices, spreads, OI) — contango / backwardation /v1/futures/{root}/term-structure
get_options_chain EOD chain with IV and Greeks, filters by expiry / strikes / side; list_expirations /v1/options/chain/{t}, /v1/options/expirations/{t}
get_coverage What exists for a contract or a ticker's fundamentals, gaps included /v1/futures/contract/{s}/coverage, /v1/fundamentals/{t}/coverage
get_financial_statements Income / balance / cash-flow, annual or quarterly, point-in-time; single XBRL fact history with concept /v1/fundamentals/{t}/statements, /v1/fundamentals/{t}/facts/{concept}
get_ratios Latest P/E, P/B, EV/EBITDA, FCF yield, ROE, margins, leverage… /v1/fundamentals/{t}/ratios
get_ratios_daily Daily ratio history recomputed with the fundamentals known that day /v1/fundamentals/{t}/ratios/daily
screen_fundamentals filters="pe<15,roe>0.15,fcf_yield>0.06" + sort="fcf_yield:desc" (+ as_of) /v1/fundamentals/screener
get_filings 10-K / 10-Q / 8-K / 4 / 13F… with URLs /v1/fundamentals/{t}/filings
subscribe_filings Opens wss://…/v1/stream, subscribes to filings, returns up to N messages within a bounded time window websocket

Resources: hfmarketdata://status (live dataset inventory) · hfmarketdata://limits (rate limits + your headroom). Prompts: term-structure-analysis(root, as_of?, compare_to?) · compare-contracts(symbol_a, symbol_b, days?) · fundamentals-snapshot(ticker, quarters?).

# Behaviour every tool shares

  • HFMD_BASE_URL (default https://www.hfmarketdata.io) and HFMD_API_KEY (optional) are the only configuration.
  • format=json is always requested; both the v1 envelope {count,data} and the v2 envelope {data,meta} are understood.
  • Outputs are compact tables {"columns":[…],"rows":[[…]]}. The default limit is 500 rows (max 5 000); above 200 rows the tool returns the count, the first/last 15 rows, per-column numeric ranges and a hint to narrow the request — so a careless "all 1-minute bars since 2010" cannot flood the context.
  • Rate-limit headroom (X-RateLimit-Remaining-*, reset) is appended to every result; a 429 comes back as a clear message with Retry-After and a reminder that a free API key lifts the low keyless limits.
  • Errors are uniform: HF Market Data error <status> <CODE>: <message> [Docs: …], whether the API answered with the v2 {"error":{code,message,docs}} envelope or the legacy {"detail"}.
  • subscribe_filings is bounded by design (max_messages ≤ 100, timeout_seconds ≤ 120) and closes the socket when it returns; it needs Node ≥ 22 (global WebSocket) or Node 20 with --experimental-websocket.
  • Read-only: no tool ever writes anything anywhere.

# Configuration snippets

# Claude Code

bash
claude mcp add hfmarketdata -e HFMD_API_KEY=hfmd_live_… -- npx -y hfmarketdata-mcp
# tarball install instead of npm:
npm i -g https://www.hfmarketdata.io/downloads/hfmarketdata-mcp-1.0.0.tgz && claude mcp add hfmarketdata -e HFMD_API_KEY=hfmd_live_… -- hfmarketdata-mcp

Or in .mcp.json at the root of a project (shared with your team):

json
{
  "mcpServers": {
    "hfmarketdata": {
      "command": "npx",
      "args": ["-y", "hfmarketdata-mcp"],
      "env": { "HFMD_API_KEY": "hfmd_live_…" }
    }
  }
}

# Cursor — .cursor/mcp.json (project) or ~/.cursor/mcp.json (global)

json
{
  "mcpServers": {
    "hfmarketdata": {
      "command": "npx",
      "args": ["-y", "hfmarketdata-mcp"],
      "env": { "HFMD_API_KEY": "hfmd_live_…" }
    }
  }
}

One-click (best effort): cursor://anysphere.cursor-deeplink/mcp/install?name=hfmarketdata&config=<base64 of the JSON object above> — generated for you on https://www.hfmarketdata.io/integrations/cursor.

# Codex — ~/.codex/config.toml

toml
[mcp_servers.hfmarketdata]
command = "npx"
args = ["-y", "hfmarketdata-mcp"]
env = { HFMD_API_KEY = "hfmd_live_…" }

# Claude Desktop — claude_desktop_config.json

json
{ "mcpServers": { "hfmarketdata": { "command": "npx", "args": ["-y", "hfmarketdata-mcp"], "env": { "HFMD_API_KEY": "hfmd_live_…" } } } }

Keyless? Simply drop the env block.

# Example session

text
> Compare ESZ25 and ESH26 over 30 days

⏺ get_coverage(kind="futures_contract", symbol="ESZ25") … get_bars(asset="futures_contract", symbol="ESZ25", start="2025-08-05") …
⏺ Over the last 30 sessions ESH26 traded at a 61.5 → 58.0 point premium to ESZ25 (calendar spread narrowing 3.5 pts as
  financing expectations eased). Volume is still 96 % in ESZ25; the roll window usually opens ~8 sessions before the
  December expiry (2025-12-19). One session (2025-09-01, Labor Day) is missing in both legs — not interpolated.

# Development

bash
npm install
npm test            # vitest — 45 tests, every tool mocked (fetch + websocket)
npm run build       # tsc → dist/
node dist/index.js --selftest
node scripts/live-smoke.mjs   # real stdio round-trip against www.hfmarketdata.io
npm run inspect     # MCP Inspector UI

# Release

bash
npm version 1.0.x
npm run build && npm test
npm pack                     # → hfmarketdata-mcp-1.0.x.tgz (this is what /downloads serves)
npm publish --dry-run        # inspect the file list
npm publish --access public  # requires the maintainer's npm login (npm login / NPM_TOKEN)

Until the package is on the npm registry, npx -y hfmarketdata-mcp resolves nothing: use the tarball URL above or npm i -g ./hfmarketdata-mcp-1.0.0.tgz.

# Project layout

text
src/index.ts      bin — stdio transport, --help/--version/--selftest
src/server.ts     createServer(): 14 tools · 2 resources · 3 prompts
src/tools.ts      tool catalogue (zod schemas + handlers), runTool()
src/client.ts     fetch wrapper: auth, format=json, rate headers, uniform HfmdError
src/format.ts     compact tables, head/tail summaries
src/stream.ts     bounded websocket consumer
src/resources.ts  hfmarketdata://status · hfmarketdata://limits
src/prompts.ts    term-structure-analysis · compare-contracts · fundamentals-snapshot
test/             vitest (mocked fetch + fake WebSocket + in-memory MCP transport)
scripts/          live-smoke.mjs · record-demo.md

# Licence

MIT © Simon-Pierre Boucher — data by FirstRate Data and SEC EDGAR, served by HF Market Data. Questions: contact@spboucher.ai.