npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

tickerinside-mcp

v1.10.0

Published

Holdings, overlap, correlation and look-through risk for US ETFs. Free data, no key.

Readme

tickerinside-mcp

What is inside a US ETF, and what you actually hold once you look through the funds to the companies underneath.

TickerInside is an open, machine-readable database of US ETF holdings, with the source and date of each holding. This is its MCP server, over the free data at tickerinside.com: no key, no account, no per-user quota. Each answer names the file it came from, the issuer's own holdings file or the fund's SEC filing, with a link where it can be checked.

Install: one URL

The server answers at this address, so most clients need nothing installed:

https://tickerinside.com/mcp

Claude. TickerInside is available in Claude's connector directory: open https://claude.ai/directory/tickerinside and click Connect. There is nothing to sign in to, and once connected it works in Claude Desktop and the mobile apps too. As a custom connector instead: in claude.ai, open Customize, then Connectors, click + Add, choose Add custom connector, paste the URL above and choose No sign in.

Claude Code

claude mcp add --transport http tickerinside https://tickerinside.com/mcp

Codex CLI

codex mcp add tickerinside --url https://tickerinside.com/mcp

Gemini CLI

gemini mcp add --transport http tickerinside https://tickerinside.com/mcp

Other clients. Cursor, VS Code and any client that accepts a remote MCP server: add a server named tickerinside with the URL above. It speaks Streamable HTTP, keeps no session and asks for no authorization. It answers MCP 2026-07-28, where a client opens with server/discover and each request carries its protocol version in _meta with no handshake, and the revisions from 2024-11-05 to 2025-11-25, which open with initialize, on the same URL. This package, over stdio, speaks the revisions up to 2025-11-25.

Or run it locally with npx

This package runs the same twelve tools on your own machine, with Node 20 or later. The remote server runs this package's own tool code, so the answers are the same; only where the arithmetic runs differs. Use it when a client only runs local servers, or when you would rather it ran on your machine.

npx -y tickerinside-mcp@latest

Claude Code

claude mcp add tickerinside -- npx -y tickerinside-mcp@latest

Codex CLI

codex mcp add tickerinside -- npx -y tickerinside-mcp@latest

Cursor, Claude Desktop, VS Code and other clients: add a server named tickerinside with command npx and arguments ["-y", "tickerinside-mcp@latest"]. @latest makes npx fetch the current version rather than run one it cached earlier.

What it answers that other tools do not

Most fund tools report allocation and sector weights. This one answers the two questions a holder actually has.

How much of a company do I own, in money, across all my funds. Paste four funds with what each is worth and it returns the companies underneath, ranked, with the amount carried on each and which funds it comes through.

Which of my positions produces my risk rather than my capital. It returns an Euler decomposition of portfolio variance, so the shares sum to one hundred, and the squared diversification ratio, which counts positions that behave differently rather than positions held. Four funds frequently turn out to be one and a bit independent bets.

It is also not limited to comparisons someone wrote by hand. Each fund file carries its full holdings and, where the price history is in the data, 156 weekly returns, so the server computes any pair, any basket, and any covariance matrix from the data itself.

Tools

Every tool only reads, and says so in its annotations, so clients can run it without asking each time. Each has a short title for a client's list, and a description that opens on the questions it answers, says what it returns, and ends on what it is not for, naming the tool that answers that instead.

| Tool | What it returns | | --- | --- | | list_etfs | Every covered US ETF, the date of the data, and where each fund's holdings come from, or the funds whose ticker or name matches a query. | | get_etf_holdings | One fund: holdings with weights, cost, assets, returns, volatility, beta over three years and one, worst fall, concentration. | | compare_etfs | Any two funds: overlap measured three ways, the largest shared holdings, correlation, covariance, cost and risk for both, beta over three years and one. | | get_etf_overlap_matrix | Every pair in a list of 2 to 30 funds, ranked by overlap by weight. | | get_etf_portfolio_lookthrough | The companies under a portfolio, in percent and in money, with the funds each comes through. | | get_etf_portfolio_risk | Portfolio volatility and beta, each position's share of the risk, the diversification ratio, and both matrices. | | find_etfs_holding_stock | The covered funds holding one stock, heaviest first, with each fund's holdings date and source, the stock's rank in the fund and the dollars held; how many funds have it as their largest holding, the funds with the most dollars in it, whether it is in VOO, SPY, IVV, QQQ, VTI and SCHD, the issuers holding the most, the cheapest exposure per $1,000, and one sentence to quote; compact for the counts and the sentence alone. | | compare_stocks | Two US stocks side by side, their correlation, and the funds holding both. A fund works on one side. | | get_etf_ownership | How much of one US stock the covered ETFs own, as a lower bound: at least this percent of its shares outstanding, from this many funds, with the SEC's count and both dates. | | get_etf_holdings_history | One fund's holdings history from its issuer's files: every file date with its position count and top 10 weight, one line per step from a file to the next, and how its overlap with its ten closest funds moved. | | get_etf_holdings_changes | What one fund added and dropped from one issuer file to the next since a date, and the weights that moved, which include price moves and not only trades, before and after, with the file each step is compared with. | | get_etf_flows | Whether the ETFs read daily from their issuers' files bought or sold a stock: the net change in shares held on the latest market close, its value at the files' own prices, the funds adding and trimming, a 20-day series, index entries and exits and corporate actions (mergers, spin-offs, takeovers and splits are no trades); without a ticker, the day's largest net additions and reductions. |

Older tool names (list_funds, fund_profile, compare_funds, overlap_matrix, look_through, risk_decomposition, stock_exposure, etf_ownership, fund_history, fund_changes) still work.

Prompts

Since 1.10.0 the server also offers five prompts, ready questions a client can show its user. Each returns one user message that asks the question in plain words and names the tool that answers it. In Claude Code each is a command named after the server: for a server added as tickerinside, for example /mcp__tickerinside__what_does_this_etf_hold VOO. Type a list without spaces, as VOO,QQQ,SCHD or VOO:60,QQQ:40, since Claude Code passes a prompt's argument up to its first space.

| Prompt | Argument | What it asks | | --- | --- | --- | | what_does_this_etf_hold | ticker, for example VOO | One fund's largest holdings with their weights, its cost and size, and the date of its holdings file (get_etf_holdings). | | which_etfs_hold_this_stock | ticker, for example NVDA | The funds holding one stock, heaviest first, each with its weight and holdings date (find_etfs_holding_stock). | | do_my_etfs_overlap | tickers, for example VOO,QQQ,SCHD | How much 2 to 30 funds hold in common, by weight (compare_etfs for two, get_etf_overlap_matrix for more). | | what_is_inside_my_etf_portfolio | holdings, for example VOO:60,QQQ:40 | The companies under a portfolio, how much of each and the funds each comes through (get_etf_portfolio_lookthrough). | | are_etfs_buying_this_stock | ticker, for example NVDA | Whether the ETFs read daily bought or sold a stock on the latest market close, and the value (get_etf_flows). |

A missing, unknown or malformed argument is answered with the JSON-RPC error -32602 and the reason, as an unknown prompt is. So is a list that ends with a comma or a semicolon, such as VOO:60,, which is how a list typed with spaces arrives from Claude Code.

What an answer looks like

An answer about funds carries prices_as_of and holdings_as_of, because holdings refresh when the issuer publishes, daily for some funds and monthly for others, and the two dates are returned rather than merged into one. It also says where each fund's holdings come from (holdings_source): the issuer's own file, the fund's latest SEC Form N-PORT filing (for the other US stock ETFs, bond, credit and mortgage ETFs, multi-asset ETFs, and leveraged, inverse and option-based ETFs), which describes the portfolio at a quarter end, months before it is read, and is dated to that quarter end, or the trust's own SEC filing (for a gold, bitcoin or currency trust or a commodity pool, which file no Form N-PORT), or the sponsor's own file (sponsor_files, a fund too new for a Form N-PORT, read from the holdings its sponsor publishes and dated to that file), or its prospectus (prospectus: a fund with no holdings yet, whose stated objective is quoted and whose first holdings filing replaces it; nothing overlaps it). A fixed income ETF gives its lines by issuer, coupon and maturity, with no identifier, and its average coupon, maturity and duration; compare_etfs and get_etf_overlap_matrix give fixed income funds their issuer overlap (the smaller weight of each issuer both hold, summed), labelled as issuer overlap and never mixed with overlap by shares. A leveraged or option-based ETF gives its swaps, futures and options as notional exposure in percent of net assets, never as shares held, and find_etfs_holding_stock lists such funds apart from the funds that hold a stock.

Every answer also carries a source block with the JSON file the figures came from and the licence. Answers about funds and about who holds a stock add the page on the site where the figure can be checked, when there is one, and a cite_as line to put under a quoted figure. An answer with a one-year beta also names SPY's file, which that beta is measured against, in benchmark_url.

A ticker outside the coverage is an ordinary answer, not an error. It comes back with covered: false, the tickers that were not found, the six issuers that are covered and the SEC layer beside them, so an assistant can tell its user what is covered instead of retrying. In a basket, the covered funds are answered and the others are listed under skipped. Only input that the caller must fix, such as an amount on some lines and not others, or an argument the tool's schema does not name, comes back as an error.

Every answer is JSON text, and the same answer as an object in structuredContent, every field and every row, so a client that reads one and a client that reads the other read the same thing. Each tool states what it returns in its outputSchema: the dates, the source block and the key figures and rows a program reads, with their types. An error carries no structured part.

The three overlap measures, because they disagree

Published overlap figures for the same pair of funds differ across sites, because sites quote different measures without naming them.

  • Overlap by weight is the sum, across every company both funds hold, of the smaller of its two weights. Symmetric, and the headline figure.
  • Share of A held in common is the part of A's own weight sitting in companies B also holds, as a percentage of A. Not symmetric, and the gap between the two directions is usually the interesting part.
  • Companies in both is a plain count, useful for seeing when a high weight overlap rests on very few names.

Some sites publish these by counting positions rather than by weight, which is a fourth number again. Every response here says which measure it is.

Checking it

Covariance is annualised and in percent squared, so the diagonal is each fund's variance. Divide an off-diagonal by the two volatilities and you get back the correlation printed beside it. That is the whole method, and it is published so it can be checked rather than believed.

Correlation and covariance are measured on the weeks every fund in the answer has, and weeks_used says how many. A fund younger than three years has empty weeks at the start of its series, and they are left out rather than read as a 0% return. The three-year beta is the one in each fund's file; the one-year beta is measured against SPY over the last 52 weeks, from at least 40 of them.

Coverage and limits

US ETFs from iShares, SPDR, Vanguard, Invesco and Global X, each from the issuer's own full holdings file, and the other US stock ETFs, Schwab's among them, from their latest SEC Form N-PORT filing, which have holdings but in most cases no prices, cost or risk figures; bond, credit, mortgage, multi-asset, leveraged, inverse and option-based ETFs from the same filings, trusts and commodity pools from their own SEC filings, funds too new for a Form N-PORT from the holdings their sponsors publish on their own sites, and, for a fund with no holdings yet, its prospectus. list_etfs returns the universe and its counts, the sources apart, and how many of the US-listed ETFs that is. This README gives no count, because it is published far less often than the data moves: the counts of the day are in the coverage object of https://tickerinside.com/api/v1/index.json. US stocks with three years of price history are covered as instruments too, with sector, valuation, returns, risk and 156 weekly returns each, which is what compare_stocks runs on. So is a US stock with a shorter history when a fund read from an issuer file or a stock ETF from SEC filings holds it in a file dated since it listed, the price data has its closes since its listing, or a year of them, the last at most five sessions old, and Nasdaq Trader's directory lists it under its name. Such a stock comes with its holders and last close, and with its one-year return once its weekly closes cover a year. Its three- and five-year figures and its correlation are null until it has the weekly series. It covers ETFs: mutual funds and exchange-traded notes are not part of it.

The npm package reads the public API at https://tickerinside.com/api/v1 and keeps each file for an hour, since the data changes every weeknight. It fetches the files of the funds and stocks you ask about (/fund/<ticker>.json, which answers for every fund, and /sec/<ticker>.json; /etf/<ticker>.json for a fixed income, multi-asset, derivative-based, trust, pool, sponsor-file or prospectus fund when /fund/ does not answer for it, which the index below says), the index of what is covered (/index.json, read for that and once when the server starts, for the fund count), the list of funds with their names and pages (/funds-columns.json, or /funds.json where the site has no such file, and /funds.json for a search of list_etfs), and, for a stock without a file of its own, the shard of the reverse index its first letter points to (/holders/<letter>.json), SPY's file (/fund/spy.json), the benchmark of the one-year beta, for get_etf_ownership the ledger's summary (/ownership.json), for get_etf_holdings_history and get_etf_holdings_changes the fund's history file (/history/<ticker>.json), and for get_etf_flows the flows (/flows.json and /flows/<ticker>.json), which are under the history terms of https://tickerinside.com/legal/#history rather than CC BY 4.0. Every request carries a User-Agent naming the package and its version, and nothing else is sent: the amounts passed to get_etf_portfolio_lookthrough or get_etf_portfolio_risk never leave your machine. When a file cannot be read, the answer to the model says so in one line and the reason is written to stderr, which your client keeps in its log for the server.

The same data as a free JSON API

Every answer is computed from static JSON files anyone can read from their own code, with no key and no sign-up, CORS open:

curl -s https://tickerinside.com/api/v1/fund/voo.json

The reference, with recipes for Python, JavaScript and Excel, is at https://tickerinside.com/api/, the same reference as one text file for coding agents at https://tickerinside.com/llms-full.txt, and the OpenAPI 3.1 description at https://tickerinside.com/api/openapi.json. What last night's build did is in https://tickerinside.com/api/v1/status.json, and the live checks of the site and of the remote server, made every five minutes, in https://tickerinside.com/api/v1/uptime.json.

Terms

Data under CC BY 4.0: credit TickerInside by name, in text or with a link; both are accepted. Code under MIT. Derived from issuers' public holdings files, the SEC's public Form N-PORT data sets, the shares outstanding companies report to the SEC in XBRL, and end of day prices, provided as is with no warranty of accuracy.

This is a measurement of what funds hold and how they have behaved. It is not investment advice, and it does not know your situation.

Errors and data requests: [email protected]