SEC 13F β institutional ownership, asked security-first.
Copy the AI prompt to install this server into Claude Code, Cursor, or another agent β or use 1-click editor setup below.
One-click editor setup isnβt available for this listing yet β we donβt have a confirmed install command, and weβd rather show nothing than point your editor at the wrong package or host. Follow the projectβs own setup instructions, linked above.
Institutional ownership from SEC Form 13F, asked security-first. Hosted, keyless to the caller.
Deltas are a first-class citizen here, not an afterthought: manager_changes and security_flows
answer "what changed" directly, because a static holdings snapshot isn't a newsletter β a change is.
Part of Pipeworx β an MCP gateway connecting AI agents to 1683+ live data sources.
who_owns(security, limit?) β which managers hold a security, ranked by position size. Accepts a
company name, a ticker (resolved live through OpenFIGI β see "Ticker resolution" below) or a
9-character CUSIP.manager_portfolio(manager, limit?) β every position one manager reported, largest first (current
quarter only β see manager_changes for what changed).manager_changes(manager, quarter?, compare_to?, limit?) β what one manager NEW-ed, EXITED,
INCREASED or DECREASED between two loaded quarters. Defaults to the manager's two most recent
loaded quarters.security_flows(security, limit?) β total position value and holder count per loaded quarter for
one security, plus which managers bought/sold/added/trimmed between the two most recent quarters.manager_profile(manager) β concentration (top-5/top-10 % of portfolio), turnover between the two
most recent loaded quarters, and top positions. Does not include sector exposure β 13F carries
no industry/sector field, and this pack does not fabricate one.holdings_coverage() β which SEC release windows and quarters are loaded, filings/holdings counts
per quarter, and whether there's enough loaded to diff (can_diff_quarters).13F reports positions by CUSIP; there is no ticker column anywhere in the dataset. CUSIP identifiers
are proprietary to CUSIP Global Services, so this pack does not build, cache, or redistribute a bulk
CUSIPβticker crosswalk (same discipline as the paywalled-standards rule). Instead, a ticker-shaped
input (e.g. "NVDA") is resolved live, per call, through OpenFIGI's public mapping API β openly
licensed Bloomberg FIGI β to get the security's canonical name, which is then matched against
issuer_name in our own already-ingested holdings, preferring the candidate with the largest
aggregate value (a real operating company's smallest institutional line still dwarfs a themed/
leveraged ETF's largest one). Every response that used this path reports matched_on: "ticker_via_openfigi" and what it resolved to (resolved_via.cusip, .figi, .issuer_name) β never
silently. Before this, who_owns("NVDA") matched issuer_name ILIKE '%NVDA%' and returned "Direxion
Daily NVDA Bull 2X ETF" ranked alongside the real NVIDIA CORPORATION position β a silent wrong answer,
not a missing feature.
The ingest program only accepts a local build when it makes a question possible that the upstream
cannot answer. This is the clean case: the SEC publishes 13F manager-first, and so does every API
over it. Our own edgar_institutional_holdings says so in its description β answering "which
funds hold $TICKER" means running it once per manager, a loop over ~8,000 filers. That is a shape
problem, not a rate-limit problem, and no upstream fixes it. One indexed query over the flat table
inverts it.
Stated here and in every response, because 13F is routinely over-read:
matched_on.A single manager can report the same security on several lines β different investment discretion, or
puts and calls alongside the common. who_owns collapses lines per manager before ranking.
Without that you get the largest lines rather than the largest holders, which is a different list
that looks equally plausible.
Source: https://www.sec.gov/data-research/sec-markets-data/form-13f-data-sets β one rolling
3-month ZIP carrying seven TSVs. Three are used: SUBMISSION (accession β CIK), COVERPAGE
(accession β manager) and INFOTABLE (the holdings, ~3.8M rows/release, 396MB uncompressed).
The filename encodes its window (01mar2026-31may2026_form13f.zip) and is not derivable β
releases do not land on calendar quarters. Both the worker config and the script read SEC's index
page for the newest link; a hardcoded quarter would ingest once and serve stale data forever.
workers/data-pipeline (sec-13f-submissions, sec-13f-managers,
sec-13f-holdings).supabase CLI):
node scripts/ingest-sec-13f.mjs --only holdings.PIPEWORX_INTERNAL_SECRET, the credential every
fleet session already carries β no raw DB key): node scripts/ingest-sec-13f-admin.mjs --url https://www.sec.gov/files/structureddata/data/form-13f-data-sets/<window>_form13f.zip. Posts
through POST /admin/sec13f_load on the gateway (table-allowlisted, β€3,000 rows/call, same ceiling
as every other hosted ingest here). This is how the second quarter (fleet #339, needed so
manager_changes/security_flows have something real to diff) was loaded.shared/src/freshness.ts at a 200-day SLA β release cadence plus the
~45-day filing lag, so a missed release trips it within a quarter.Schema and indexes: supabase/migrations/061_sec_13f.sql. The (cusip, value_usd DESC) index is
what makes the inversion viable; without it this is a 3.8M-row sequential scan and the build
is slower than the API it replaced.
Measured 2026-09-04 loading quarters 3-8 (fleet #1245, going from 2 quarters to 8 for
manager_changes/security_flows to have a real trend to show):
No reviews yet β be the first to share how this listing worked for you.
Showcase your server listing on GitHub or your project documentation. Embed this dynamic SVG badge to highlight official listing status and live engagement.
[](https://allmcps.com/mcp/sec-13f)<a href="https://allmcps.com/mcp/sec-13f"><img src="https://allmcps.com/api/badge/sec-13f?style=directory" alt="Sec 13f on AllMCPs" /></a>