pequod-mcp
pequod-mcp — "the Gam"
SEC-primary-source ETF holdings + identifier crosswalk for agents.
An MCP (Model Context Protocol) server that gives AI agents the complete holdings of any US-registered ETF straight from SEC EDGAR N-PORT filings — not a top-10 scrape — plus a set of identifier-crosswalk tools (ticker, CUSIP/SEDOL, FIGI → resolved symbol) backed by OpenFIGI and SEC reference data. Runs locally over stdio; no vendor market-data subscriptions required.
Tools
Tool | What it does | Sources |
| Ticker → SEC CIK + entity metadata (name, SIC, exchanges, fiscal year end) | SEC |
| Raw ticker + optional exchange code → Yahoo-convention symbol, verified | Exchange-suffix map (pure string mapping) + SEC + OpenFIGI |
| CUSIP (or SEDOL) → symbol, with cross-source verification | OpenFIGI (one batched request) + SEC name/ticker agreement |
| Bloomberg FIGI → symbol, with cross-source verification | OpenFIGI + SEC name/ticker agreement |
| Any US ETF → complete holdings list from its latest monthly N-PORT filing (name, ticker, ISIN, FIGI, LEI, shares, USD value, % of net assets, country, currency) | SEC EDGAR N-PORT XML |
All tools are read-only.
How verification works
Crosswalk results are verified without any market-data vendor:
SEC registry check — if the mapped ticker is a US SEC registrant, the entity title in
company_tickers.jsonmust agree with the OpenFIGI security name. A gross name mismatch vetoes the mapping (verification: "name_veto") rather than returning a plausible-looking wrong symbol.OpenFIGI mapping — non-US symbols (outside SEC's registry) verify on the OpenFIGI mapping itself, labeled
verification: "openfigi"so you can tell the confidence tiers apart.
Yahoo Finance symbology (.SW, .T, .L, … suffixes) is applied as a
pure string convention — the default path makes no network calls to
Yahoo.
Install
# with uv
uv pip install pequod-mcp
# or with pip
pip install pequod-mcpRun it directly (stdio):
pequod-mcpOptional: OpenFIGI API key
The server works without a key (OpenFIGI anonymous rate limits apply). For heavier use, get a free key at https://www.openfigi.com/api and set:
export API_OpenFIGI="your-key-here"Optional: Yahoo enrichment extra
An opt-in extra adds a live Yahoo quote block to crosswalk results. It is off by default and never used otherwise; enabling it means you accept the Yahoo Finance terms of use yourself.
pip install 'pequod-mcp[yahoo]'
export PEQUOD_YAHOO_VERIFY=1Configure in Claude
Claude Desktop (claude_desktop_config.json) or any MCP client with a
stdio transport:
{
"mcpServers": {
"pequod": {
"command": "pequod-mcp",
"env": {
"API_OpenFIGI": "your-key-here"
}
}
}
}Claude Code:
claude mcp add pequod -e API_OpenFIGI=your-key-here -- pequod-mcpAgent workflow examples
1. "What does SCHD actually hold?"
Agent: lookup_cik("SCHD")
→ { cik: "0000884394", entity_name: "SCHWAB STRATEGIC TRUST", found: true }
Agent: get_etf_holdings("SCHD", cik="0000884394")
→ { fund_name, report_date, source_url (the actual EDGAR filing),
total_holdings: ~100, holdings: [ { name, ticker, isin, figi,
balance, value_usd, pct_val, ... } ] }The agent gets every position with weights, plus the EDGAR URL for citation — auditable back to the primary source.
2. "I have a CUSIP from a 13F — what stock is this?"
Agent: resolve_cusip("594918104")
→ { yahoo_symbol: "MSFT", verified: true, verification: "openfigi+sec",
company_name: "MICROSOFT CORP", cik: "0000789019",
openfigi: { figi: "BBG000BPH459", ... } }If OpenFIGI's mapping disagrees with SEC's registry on who the ticker
belongs to, the tool refuses (verification: "name_veto") instead of
handing back a wrong symbol.
3. "Compare two dividend ETFs' overlap."
Agent: get_etf_holdings("SCHD") → complete holdings A
Agent: get_etf_holdings("VYM") → complete holdings B
Agent: joins on isin (or ticker), computes overlap weight, reports the
shared names — all from two tool calls, both citing SEC filings.Data provenance
All holdings data comes from SEC EDGAR primary sources (Form N-PORT filings, the submissions API, and
company_tickers.json). Identifier crosswalks come from the OpenFIGI API (FIGI is an open OMG standard).No CUSIPs in output. Tool outputs carry ticker, ISIN, FIGI, and LEI; CUSIP fields present in the underlying filings are deliberately stripped.
SEC fair access respected: a declared User-Agent on every request, a throttle well under EDGAR's published rate limit, and an on-disk cache (
.cache/next to the module, override withPEQUOD_CACHE_DIR) forcompany_tickers.json(24 h) and N-PORT documents (30 days — filed documents are immutable).Fail-loud policy: if EDGAR is unreachable or a filing cannot be parsed, tools return an error. There is no degraded or partial fallback source — you either get filing-backed data or a clear failure.
N-PORT filings are published on a lag (holdings are typically ~1–2 months behind). The
report_dateandsource_urlfields tell you exactly which period you are looking at.Not investment advice. This server relays public regulatory filings and open identifier mappings; verify independently before making investment decisions.
Environment variables
Variable | Default | Purpose |
| (unset) | OpenFIGI API key (higher rate limits) |
|
| On-disk cache location |
| (off) | Opt-in Yahoo enrichment (needs the |
|
| Server log verbosity |
Development
pip install -e '.[dev]'
pytest # fully offline — fixture filings, no live networkLicense
Apache-2.0 — see LICENSE. Copyright 2026 AB Evergreen Analytics LLC.