TickerInside ETF Holdings
Server Details
US ETF and mutual fund holdings, which ETFs hold a stock, overlap, look-through. Free, no API key.
- Status
- Healthy
- Uptime
- 100.0% over 20 days
- Last Tested
- Transport
- Streamable HTTP · MCP 2025-11-25
- URL
TDQS
Scored across 13 tools
Most tools have clearly distinct purposes, and the descriptions do heavy lifting with explicit 'Not for...' cross-references (e.g. compare_etfs vs get_etf_overlap_matrix, get_etf_holdings vs get_etf_holdings_changes vs get_etf_holdings_history). The holdings/changes/history trio and the several portfolio-level analytics tools (lookthrough, risk, overlap_matrix, find_diversifying_etfs) sit close together and could occasionally be confused, but the boundary rules are unusually well specified.
Most tools follow a get_etf_* noun-scoped convention, but there are deviations: find_diversifying_etfs, find_etfs_holding_stock, compare_etfs, compare_stocks, and list_etfs use different verb prefixes. The verb_noun pattern is broadly readable, and the etf/etfs plurality inconsistency is minor.
Thirteen tools is well within the sweet spot and each maps to a distinct analytical need (holdings, flows, ownership, overlap, portfolio risk/lookthrough, comparison, discovery). No tool feels redundant or padded.
The surface covers the ETF-holdings lifecycle thoroughly: coverage discovery, holdings, holdings changes/history, flows, issuer ownership, overlap, and portfolio-level analysis. Minor gaps exist (no dedicated screener or single-stock fundamentals tool beyond compare_stocks), but core workflows and CRUD-like read operations are well covered.
Available Tools
13 toolscompare_etfsOverlap and risk of two ETFsARead-onlyIdempotentInspect
Use this when the user names exactly two US ETFs and asks how much they overlap, whether one duplicates the other, or how they differ in cost and risk. Returns the overlap by weight and each ETF's share held in common, the largest shared holdings, the correlation of weekly returns over up to three years, and each ETF's cost, return, volatility and worst fall (most ETFs read from SEC filings have no return or risk figures here), with both holdings dates. Two bond ETFs are compared by issuer overlap, option income stock ETFs (JEPI, QYLD) by their stocks alone. An ETF read from SEC filings that is leveraged, inverse, under half in stock or half in swaps and futures, a trust or pool (metal, crypto, currency, futures), a multi-asset, sponsor-file or prospectus-only ETF, or a bond ETF beside a stock ETF is compared by weekly returns alone, with the reason. Not for three or more ETFs (get_etf_overlap_matrix).
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | A US ETF ticker, for example VOO or SCHD. Case does not matter. | |
| b | Yes | The other US ETF ticker, for example QQQ. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pair | No | |
| funds | No | |
| source | No | |
| covered | No | |
| overlap | No | In percent. |
| comparable | No | |
| weeks_used | No | |
| not_covered | No | |
| prices_as_of | No | |
| correlation_3y | No | |
| holdings_as_of | No | |
| issuer_overlap | No | By issuer, in percent. |
| not_comparable | No | |
| holdings_source | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive, closed-world), and the description goes well beyond them: it discloses the degradation modes (SEC-filing ETFs with no return/risk figures, leveraged/inverse/trust/multi-asset cases compared by weekly returns alone, with reason). This is unusually rich behavioral context.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the trigger condition and outcome list, and every clause carries information. It is dense and long, but the exhaustive edge-case enumeration largely earns its space rather than padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, yet the description still specifies the shape of returns and the many reduced-output edge cases, plus holdings dates. Combined with annotation and schema coverage, an agent has everything needed to call and interpret it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% with per-parameter descriptions and examples, so baseline is 3; the description adds value by constraining both parameters to US ETF tickers and requiring exactly two, which the schema does not state.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb (compare) and resource (two US ETFs) and enumerates the exact questions it answers: overlap, duplication, cost/risk difference. It clearly distinguishes itself from siblings like get_etf_overlap_matrix and get_etf_holdings by naming them or their domain.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Opens with an explicit trigger ('when the user names exactly two US ETFs') and closes with an explicit exclusion plus the alternative ('Not for three or more ETFs (get_etf_overlap_matrix)'). The when/when-not/alternative triad is fully covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
compare_stocksStock comparison and weight in an ETFRead-onlyIdempotentInspect
Use this when the user asks how two US stocks compare on size, valuation, returns, risk or correlation, or what weight and rank one stock has inside one named ETF, for example META in QQQ. For two stocks it returns market cap, P/E and dividend yield from market data, returns, volatility, worst fall, beta, the correlation of weekly returns over up to three years and the covered ETFs holding both. For a stock and an ETF it returns whether the ETF holds the stock, at what weight and rank among the shares it holds outright, with the date of the ETF's holdings; a derivative-based ETF's swaps, futures and options are in its profile (get_etf_holdings), not here. A stock is in the data with about two years of US prices, and sooner for a recent listing a covered ETF holds. Returns are past, not a forecast. Not for comparing two ETFs (compare_etfs), or a company's business or products.
| Name | Required | Description | Default |
|---|---|---|---|
| a | Yes | A US stock ticker, for example NVDA. An ETF ticker also works on one side, for example QQQ. | |
| b | Yes | The other ticker, for example AMD. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pair | No | |
| source | No | |
| covered | No | |
| membership | No | For a stock and an ETF. |
| weeks_used | No | |
| not_in_data | No | |
| prices_as_of | No | |
| correlation_3y | No | |
| funds_holding_both | No | |
| funds_holding_both_count | No |
find_diversifying_etfsETFs that diversify a portfolioARead-onlyIdempotentInspect
Use this when the user asks which ETFs would diversify an ETF or a portfolio of ETFs, what could be added to diversify it, or which ETFs moved least with what they hold. Ranks a fixed, published list of 30 large US ETFs across six kinds of exposure (US, sector, international and emerging market stocks, bonds and commodities) by the correlation of their weekly returns with the portfolio's over up to three years, and returns the ETF of lowest correlation in each of the three groups whose lowest is lowest, with its correlation on the weeks the portfolio fell, the portfolio's volatility with 10% in it and its overlap by weight, then the next ETFs of the list. Takes 1 to 6 ETFs held. A measurement of past co-movement, not investment advice; every answer carries that note. Not for the overlap of ETFs the user names (compare_etfs, get_etf_overlap_matrix) or the risk of the portfolio itself (get_etf_portfolio_risk).
| Name | Required | Description | Default |
|---|---|---|---|
| positions | Yes | The ETFs held, 1 to 6, for example [{"ticker": "VOO", "amount": 60000}, {"ticker": "QQQ", "amount": 20000}]. Give an amount for every position or for none; with none, every ETF counts equally. |
Output Schema
| Name | Required | Description |
|---|---|---|
| note | No | |
| answer | No | |
| lowest | No | |
| covered | No | |
| page_url | No | |
| question | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish a safe, idempotent, closed-world read, and the description adds substantial context beyond them: the fixed 30-ETF universe, the correlations are backward-looking weekly returns over up to three years, the 1-6 holding cap, the specific derived figures returned (down-week correlation, volatility with 10% weighting, weight overlap), and the mandatory not-investment-advice note on every answer.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the trigger conditions and the exclusion list, which is the right ordering. It is dense but mostly earns its length, though the nested clause describing the correlation groups ('the three groups whose lowest is lowest') is convoluted and the return-value detail partly duplicates the output schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only analytical tool with full annotation coverage and an output schema, the description supplies everything an agent needs: trigger, universe, methodology, holding limit, disclaimer, and explicit sibling routing. No material gap remains.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the nested position object, the all-or-none amount rule and ticker casing are already documented in the schema. The description only restates the 1-to-6 holding limit, adding no format or unit detail beyond what the structured field already provides.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific capability (ranking ETFs by diversification benefit for a held portfolio), the mechanism (correlation of weekly returns on a fixed 30-ETF list across six exposure groups), and the output shape. It explicitly distinguishes itself from compare_etfs, get_etf_overlap_matrix and get_etf_portfolio_risk by naming them as the wrong tools for adjacent questions.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Opens with the exact user phrasings that select this tool ('which ETFs would diversify', 'what could be added', 'which moved least with what they hold') and closes with an explicit 'Not for...' clause naming three sibling alternatives and the question each actually answers. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
find_etfs_holding_stockETFs that hold a stockARead-onlyIdempotentInspect
Use this when the user asks which ETFs hold a stock, which ETF holds the most of it, how many ETFs hold it, or whether it is in VOO, SPY, IVV, QQQ, VTI or SCHD. Returns the covered US ETFs that hold it, largest weight first, each with its weight, rank, dollars, holdings date and source, plus the count, how many hold it as their largest position, the ETFs and issuers with the most dollars in it, and one sentence to quote. The list keeps the heaviest holders; whether the six ETFs above hold it is in every answer for a stock with its own file, unless compact is true. ETFs holding it through swaps, futures or options are listed apart, as notional exposure. A private company's name in place of a ticker (ANTHROPIC, OPENAI) gives the US funds holding it, each stake and value per share from its SEC filing. Not for one stock's weight in another ETF (compare_stocks) or the share ETFs own (get_etf_ownership).
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | How many ETFs to return, sorted by the stock's weight in each ETF, largest first, from 1 to 200; 50 when left out. | |
| ticker | Yes | The stock's ticker, not the company name, for example NVDA for Nvidia. A line listed outside the US carries its market after a dot, for example 7203.JP (Toyota in Tokyo), SAN.FR (Sanofi in Paris) or 005930.KR (Samsung Electronics); an earlier key without the market, such as 7203, is read as the key it became. A key ending in .PFD is not a market: it is the issuer's preferred shares, a US line apart from the common stock (JPM.PFD, held by preferred stock ETFs). | |
| compact | No | true for an answer about half the length. It keeps the counts, rank_summary (how many ETFs hold the stock as their largest or a top 10 position), name_collision (ETFs whose name contains the company's name) and the sentence to quote. It leaves out top_by_value (the ETFs holding the most dollars of it), membership (whether VOO, SPY, IVV, QQQ, VTI and SCHD hold it, and its weight in the three largest sector or industry ETFs that hold it), by_issuer (the issuers holding the most dollars), fee_per_1000 (the yearly cost, in the cheapest ETFs, of each $1,000 of the stock held through them) and each ETF's rank, positions and value. |
Output Schema
| Name | Required | Description |
|---|---|---|
| held | No | |
| name | No | |
| answer | No | One sentence to quote. |
| source | No | |
| ticker | Yes | |
| held_by | No | Largest weight first. |
| membership | No | |
| rank_summary | No | |
| funds_holding | Yes | |
| funds_by_source | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations declare read-only, idempotent, non-destructive, closed-world behavior, and the description still adds substantial operational context beyond them: results are ordered largest-weight-first, the heaviest holders dominate the list, membership answers persist unless compact=true, swap/futures/options exposure is reported separately as notional, and private-company names map to SEC filings. This is a rich behavioral profile a caller cannot get from annotations alone.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Usage triggers and the anti-pattern routing are front-loaded, and each sentence conveys distinct information. It is still one very long, dense paragraph that repeats some return-field detail already implied by the output schema and the compact parameter description.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-ticker lookup with rich annotations and an output schema, the description covers triggers, alternatives, ordering, edge cases (non-US tickers, preferred shares, private companies, notional exposure) and the compact trade-off. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% and the three parameter descriptions are already detailed, including the default for top and the full content delta for compact. The description restates the ticker formats and compact effects rather than adding new semantics, beyond noting that the six-ETF membership check appears in every answer unless compact is true. Baseline 3 is appropriate when the schema carries the parameter burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific verb+resource ('ETFs that hold a stock') and enumerates the exact question shapes it answers, including which ETF holds the most, how many hold it, and index-membership checks. It explicitly separates itself from compare_stocks and get_etf_ownership, so an agent can route without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives concrete when-to-use triggers (the user's question phrasings, the six specific ETFs) and explicit when-not-to-use cases with named alternatives ('Not for one stock's weight in another ETF (compare_stocks) or the share ETFs own (get_etf_ownership)'). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_etf_flowsETF buying and sellingARead-onlyIdempotentInspect
Use this when the user asks how much money went into or out of US ETFs or one ETF, whether ETFs are buying or selling a stock, or which stocks entered or left an index fund. Without a ticker, returns the day's ETF inflows and outflows and the largest net additions and reductions of stocks. With an ETF's ticker (QQQ), its net creations and redemptions in dollars on each of the last 20 closes. With a stock's ticker, the net change in shares held by the US ETFs read daily from their issuers' files on the latest market close, its value at the files' own prices, the ETFs that added and trimmed, a 20-close series, index entries and exits and corporate actions. A change mixes creations of the ETFs' own shares with rebalancing; beyond_growth leaves out the first. Mergers, spin-offs and splits are no trades: left out of the sums. Not for which ETFs hold a stock (find_etfs_holding_stock) or one ETF's holdings changes (get_etf_holdings_changes).
| Name | Required | Description | Default |
|---|---|---|---|
| ticker | No | An ETF ticker for its own money flows, for example QQQ, or a stock ticker, for example NVDA, or a line listed abroad such as 7203.JP. Leave it out for the day's flows. |
Output Schema
| Name | Required | Description |
|---|---|---|
| date | No | The market close of the figures. |
| latest | No | |
| series | No | |
| ticker | No | |
| covered | No | |
| how_to_quote | No | |
| index_events | No | |
| added_by_value | No | |
| reduced_by_value | No | |
| corporate_actions | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/idempotentHint and no destructive behavior, so the safety profile is covered. The description genuinely adds beyond that: data provenance ('read daily from their issuers' files'), inclusion rules ('Mergers, spin-offs and splits are no trades: left out of the sums'), and the creation-vs-rebalancing distinction in a change. The one blemish is a reference to 'beyond_growth' behavior with no corresponding schema parameter, which muddies rather than clarifies.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is front-loaded well, opening with the use case before the mechanics. But it is one dense block paragraph, and a large share of it narrates return contents (20-close series, net additions, index entries/exits) that an output schema already carries, so several sentences do not earn their place for a single-parameter tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool with one optional parameter, annotations, and an output schema, the description covers selection, data sources, and inclusion/exclusion rules completely. The only gap is the dangling 'beyond_growth' reference, which points at behavior the schema does not expose and could leave an agent guessing how to trigger it.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the baseline is 3, but the description goes further by mapping each ticker kind (ETF like QQQ, stock like NVDA, foreign line like 7203.JP, or omitted) to a distinct output shape, which adds real meaning over the schema text. The unexplained 'beyond_growth' mention slightly undercuts the precision.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a specific resource (US ETF money flows) and spells out three distinct invocation modes keyed off the ticker argument, so an agent can immediately tell what it returns for no ticker, an ETF ticker, and a stock ticker. It also explicitly separates itself from find_etfs_holding_stock and get_etf_holdings_changes, which is unusually strong sibling differentiation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It opens with explicit trigger conditions ('Use this when the user asks how much money went into or out of US ETFs...') and closes with explicit exclusions naming the two sibling tools that cover adjacent questions. When-to-use and when-not-to-use are both stated rather than inferred.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_etf_holdingsETF holdings and profileARead-onlyIdempotentInspect
Use this when the user asks what a US ETF or mutual fund holds or its sectors, cost, size, returns and risk. Returns the holdings largest first with their weights, category, sector, mega-cap tech and country weights, expense ratio, assets, top 10 weight, 1, 3 and 5-year returns, volatility, beta and worst fall, with each file's date; most ETFs read from SEC filings have no return or risk figures here. Returns are past, not a forecast. A bond ETF gives its lines by issuer, coupon and maturity, with duration; an ETF read from SEC filings that is leveraged, inverse, under half in stock or half in swaps and futures lists its shares, and its contracts apart as notional exposure; an option income ETF read as a stock ETF (JEPI, QYLD) lists its stocks, not its options or notes; a trust what its filing says it holds; a prospectus-only ETF its objective. Not for comparing ETFs (compare_etfs) or the ETFs holding a stock (find_etfs_holding_stock).
| Name | Required | Description | Default |
|---|---|---|---|
| ticker | Yes | A US ETF ticker, for example VOO or SCHD. Case does not matter. | |
| holdings | No | How many of the largest holdings to return, from 0 to 500; 25 when left out. 0 returns the figures without holdings. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| source | No | |
| ticker | No | |
| covered | No | |
| category | No | |
| holdings | No | |
| breakdown | No | |
| positions | No | |
| not_covered | No | |
| aum_billions | No | In billions of US dollars. |
| prices_as_of | No | |
| beta_vs_sp500 | No | |
| return_1y_pct | No | |
| return_3y_pct | No | |
| return_5y_pct | No | |
| holdings_as_of | No | |
| volatility_pct | No | |
| holdings_source | No | |
| expense_ratio_pct | No | |
| top_10_weight_pct | No | |
| worst_fall_3y_pct | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly/idempotent/non-destructive/closed-world, but the description adds substantive behavioral context: holdings are ordered largest first, most SEC-filing ETFs lack return or risk figures here, returns are historical, and it details special-case behavior for bond, leveraged/inverse, option-income, trust, and prospectus-only ETFs. This is well beyond what the structured fields convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The purpose and return list are front-loaded, and every sentence carries information. However, the middle special-case sentence is long and syntactically tangled ('an ETF read from SEC filings that is leveraged, inverse, under half in stock or half in swaps and futures lists its shares...'), which slows parsing.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a tool of this complexity the coverage is thorough: trigger, return shape, ordering, data-availability caveats, and edge-case fund types are all stated, and an output schema exists so return formatting need not be explained. Nothing an agent needs to call it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so both parameters (ticker, holdings) are already fully documented in the schema including defaults, range, and the '0 returns figures without holdings' behavior. The description adds no syntax or format detail beyond the schema, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource ('what a US ETF or mutual fund holds or its sectors, cost, size, returns and risk') and enumerates the exact fields returned. It also distinguishes itself from siblings by name, so an agent can separate it from compare_etfs or find_etfs_holding_stock without opening any schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It opens with an explicit trigger ('Use this when the user asks what...') and closes with explicit exclusions routing to alternatives ('Not for comparing ETFs (compare_etfs) or the ETFs holding a stock (find_etfs_holding_stock)'). Both the when and the when-not are spelled out with named substitutes.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_etf_holdings_changesETF holdings changesARead-onlyIdempotentInspect
Use this when the user asks what a US ETF bought, sold, added or dropped, or how the weights of its holdings changed, recently or since a date. Returns, for each step from one issuer file to the next, the lines that entered and exited with their weights and the lines whose weight moved by 0.05 points or more, before and after, which includes price moves and not only trades, with the turnover measures; the latest step when no date is given. Kept for the stock ETFs read daily from their issuers' own files; another ETF comes back with the reason it has no history. A step across a change in how the files are keyed or read is marked restated and lists no trades. Not for an ETF's holdings on one date (get_etf_holdings) or its overlap over time (get_etf_holdings_history).
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | The most lines listed in each of entered, exited and moved for one step, largest first. The counts are always whole. | |
| since | No | Only the steps to a file dated on or after this date, written YYYY-MM-DD, for example 2026-09-15. | |
| ticker | Yes | A US ETF ticker, for example VOO or SCHD. Case does not matter. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| steps | No | Oldest first; each step's lines largest first. |
| source | No | |
| ticker | No | |
| covered | No | |
| history | No | |
| last_file | No | |
| first_file | No | |
| moved_threshold_pp | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the read-only/idempotent safety profile, and the description adds substantial behavior beyond them: step-wise entered/exited/moved output with a 0.05-point threshold, inclusion of price moves rather than trades only, turnover measures, default to the latest step, coverage limited to stock ETFs read daily, and restated steps listing no trades. That is rich operational context an agent could not infer from structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the trigger and scope, then edge cases, with no filler sentences. It is a dense single paragraph and a few clauses ('before and after, which includes price moves and not only trades, with the turnover measures') are convoluted, but every sentence carries information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return values need not be explained, yet the description still outlines the shape and covers the non-obvious cases (ETFs with no history, restated steps). Nothing an agent needs to call this correctly appears to be missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, and the schema already documents limit and since thoroughly. The description adds one thing the schema does not: the default behavior of returning the latest step when no date is given, which clarifies how `since` is optional in practice.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a precise verb and resource: returns the lines that entered/exited an ETF's holdings and the weights that moved, step by step. It explicitly distinguishes itself from get_etf_holdings (single-date holdings) and get_etf_holdings_history (overlap over time), so an agent can route without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Opens with an explicit trigger ('when the user asks what a US ETF bought, sold, added or dropped... recently or since a date') and closes with named exclusions pointing at the two sibling tools. When-to-use, when-not, and alternatives are all present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_etf_holdings_historyETF holdings historyARead-onlyIdempotentInspect
Use this when the user asks how a US ETF's holdings evolved over time, what it held in a past year or quarter, how often its holdings file changes, or how its overlap with its closest ETFs moved. For the US ETFs that report their stock holdings to the SEC, returns each quarterly Form N-PORT report since 2019 with its date, filing, position count, top 10 weight and five largest positions, and the address of every position at a date. For the stock ETFs read from their issuers' own files, also returns each archived file date (from 1 September 2026) with its position count and top 10 weight, each step's entered, exited and moved counts and turnover, and the overlap by weight with its ten closest ETFs; a step across a change in how the files are read is marked restated. Not for the lines one step added or dropped (get_etf_holdings_changes).
| Name | Required | Description | Default |
|---|---|---|---|
| since | No | Only the steps to a file dated on or after this date, written YYYY-MM-DD, for example 2026-09-15. | |
| ticker | Yes | A US ETF ticker, for example VOO or SCHD. Case does not matter. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| files | No | Oldest first. |
| steps | No | Oldest first. |
| source | No | |
| ticker | No | |
| cadence | No | |
| covered | No | |
| history | No | |
| last_file | No | |
| file_dates | No | |
| first_file | No | |
| overlap_by_weight_pct | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Despite annotations already declaring readOnly/idempotent/non-destructive, the description adds substantial behavioral context beyond them: coverage starting 2019 for SEC reporters, archived file dates from 1 September 2026 for issuer-sourced ETFs, the meaning of a 'restated' step across a methodology change, and the exact set of returned fields. This is rich disclosure the annotations cannot convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the when-to-use clause and no filler sentences, but the middle exposition is delivered as one very long, multi-clause sentence that strains readability. Information-dense and non-redundant, but structure could be tightened.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a history tool with an output schema already present, the description supplies everything an agent needs: trigger conditions, data provenance and coverage windows, the 'restated' caveat, and the explicit sibling exclusion. Nothing essential is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100% with only two parameters, so the schema already documents both `ticker` and the `since` date filter. The description adds conceptual context about 'steps' and file dates but no syntax or format detail the schema lacks, so baseline 3 is appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (returns historical holdings evolution: quarterly Form N-PORT reports and archived issuer file dates) and explicitly distinguishes itself from sibling get_etf_holdings_changes. An agent can tell exactly what data this returns without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The opening clause enumerates concrete user intents that should trigger this tool (how holdings evolved, what it held in a past year/quarter, how often the file changes, overlap movement), and the closing sentence explicitly excludes the added/dropped-lines case and routes to get_etf_holdings_changes. Both when-to-use and when-not are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_etf_overlap_matrixOverlap across many ETFsARead-onlyIdempotentInspect
Use this when the user lists three to thirty US ETFs, often a portfolio, and asks which of them duplicate each other or whether the list is diversified across companies; two give one pair. Returns every pair ranked by overlap by weight, with the share of each ETF held in common and the count of companies in both, and the holdings date and source of each ETF in those pairs. It measures diversification by the holdings the ETFs share, not by how their returns move together. Bond ETFs are paired by issuer overlap and listed apart. Uncovered tickers are named and skipped; commodity, multi-asset, sponsor-file and prospectus-only ETFs and ETFs read from SEC filings that are leveraged, inverse, under half in stock or half in swaps and futures are listed as not comparable, each with its reason. Not for the companies underneath (get_etf_portfolio_lookthrough) or how ETFs move together (get_etf_portfolio_risk).
| Name | Required | Description | Default |
|---|---|---|---|
| tickers | Yes | 2 to 30 US ETF tickers, for example ["VOO", "QQQ", "SCHD"]: three or more give the matrix, two give one pair. |
Output Schema
| Name | Required | Description |
|---|---|---|
| pairs | No | In percent, largest first. |
| source | No | |
| covered | No | |
| skipped | No | |
| computed | No | |
| not_covered | No | |
| prices_as_of | No | |
| holdings_as_of | No | |
| not_comparable | No | |
| holdings_source | No | |
| issuer_overlap_pairs | No | By issuer, in percent, largest first. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the readOnly/idempotent annotations it discloses the return shape (every pair ranked by weight overlap, shared share, common-company count, holdings date/source), the measurement method (shared holdings, not return correlation), and rich degradation behavior: uncovered tickers named and skipped, and a long list of non-comparable ETF categories each with a reason. This is substantive behavioral context annotations never convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the usage trigger and organized from purpose to output to edge cases to exclusions. Dense but nearly every sentence carries unique information; the long enumeration of non-comparable categories is verbose yet genuinely useful for interpreting partial results.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With an output schema present the description need not detail return values, yet it still characterizes them, and it covers inputs, semantics, failure modes, and alternatives. Nothing an agent needs to select or invoke this tool correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the schema already documents the 2-30 range and the 'two give one pair' behavior, so the description largely restates structured fields. It confirms the ticker semantics but adds no format or edge-case detail the schema lacks, making baseline 3 appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource (produces an overlap matrix across 3-30 US ETFs) and the user intent it serves (duplicate detection, diversification check). It explicitly distinguishes itself from the two nearest siblings, get_etf_portfolio_lookthrough and get_etf_portfolio_risk, so an agent can route without opening schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Front-loads the trigger ('user lists three to thirty US ETFs... asks which duplicate each other'), covers the degenerate two-ticker case, and names explicit not-for alternatives with their own use cases. When-to-use, when-not, and alternatives are all present.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_etf_ownershipETF ownership of a stockARead-onlyIdempotentInspect
Use this when the user asks how much of a US company ETFs own, or what share of its stock sits in ETFs. Returns a lower bound: at least this percent of the shares outstanding is held by the covered US ETFs, from this many ETFs, with the shares held, the SEC's count of shares outstanding and its date, the holdings dates, the method, whether the percent is of the whole company or of the ticker's class, and where the figure ranks among the stocks measured. It is a lower bound because ETFs outside the coverage are not counted. A stock without a figure comes back with the reason. Not for the list of ETFs that hold the stock (find_etfs_holding_stock).
| Name | Required | Description | Default |
|---|---|---|---|
| ticker | Yes | A US stock ticker, for example NVDA or BRK.B. BRK-B and BRK/B are read as BRK.B. |
Output Schema
| Name | Required | Description |
|---|---|---|
| name | No | |
| basis | No | company when every class is counted, class when the ticker's class alone is. |
| figure | Yes | |
| market | No | |
| source | No | |
| ticker | Yes | |
| covered | No | |
| holdings_as_of | No | |
| shares_outstanding | No | |
| shares_outstanding_as_of | No | |
| etf_ownership_pct_at_least | No | The percent of the shares outstanding held by the covered US ETFs, at least. |
| shares_held_by_covered_etfs | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover the safety profile (readOnly, idempotent, non-destructive), so the description clears the lower bar. It goes well beyond by disclosing the key semantic caveat that the result is a lower bound and why (ETFs outside the coverage are not counted), and by stating the failure behavior ('A stock without a figure comes back with the reason').
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the usage trigger, and the caveat plus exclusion are placed well. However, the run-on enumeration of return fields ('the shares held, the SEC's count of shares outstanding and its date, the holdings dates, the method...') largely duplicates the output schema and is the least economical part of the text.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so the description need not explain return values, yet it still supplies the crucial interpretation aid (lower bound, ranking basis, class-vs-company scope) and the missing-data case. Nothing an agent needs to call this correctly is absent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100% and the single ticker parameter is fully documented in the schema, including the BRK.B normalization rule. The description adds no parameter-level meaning beyond that, so the baseline 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('how much of a US company ETFs own') and immediately scopes it to US companies, which an agent can act on without opening the schema. It also explicitly names the sibling it is not (find_etfs_holding_stock), so routing is unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Opens with an explicit trigger ('Use this when the user asks how much of a US company ETFs own, or what share of its stock sits in ETFs') and closes with an explicit exclusion plus the alternative to use instead ('Not for the list of ETFs that hold the stock (find_etfs_holding_stock)'). Both when-to-use and when-not are covered.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_etf_portfolio_lookthroughCompanies inside a portfolioARead-onlyIdempotentInspect
Use this when the user gives a portfolio of US ETFs and asks which companies they own, how much of one company they hold, or how concentrated it is. Returns the companies underneath, each with its percent of what is looked through, its value when amounts are given and the ETFs it comes through, plus the count of holdings, by ticker, and the top 10 weight; for one company, raise top until it shows, up to 200. It measures diversification by single companies, not by how ETFs move together. Without amounts, every ETF counts equally. Uncovered tickers (US stocks among them), bond, commodity, multi-asset, sponsor-file and prospectus-only ETFs, and ETFs read from SEC filings that are leveraged, inverse, under half in stock or half in swaps and futures are named and left out of the percentages and the value. Amounts are not stored. Not for duplicate ETFs (get_etf_overlap_matrix) or risk (get_etf_portfolio_risk).
| Name | Required | Description | Default |
|---|---|---|---|
| top | No | How many companies to return, largest first, from 1 to 200; 25 when left out. | |
| currency | No | The currency of the amounts, for example USD or EUR. Echoed back with the values; nothing is converted. Left out, the amounts still weigh the ETFs and the currency reads unstated. | |
| positions | Yes | The ETFs of the portfolio, 1 to 60, for example [{"ticker": "VOO", "amount": 40000}, {"ticker": "QQQ", "amount": 25000}] with "currency": "USD" beside it. Give an amount for every position or for none; with none, every ETF counts equally. |
Output Schema
| Name | Required | Description |
|---|---|---|
| funds | No | |
| priced | No | |
| source | No | |
| covered | No | |
| skipped | No | |
| computed | No | |
| currency | No | |
| companies | No | Largest first; value in the amounts' currency. |
| not_covered | No | |
| prices_as_of | No | |
| holdings_as_of | No | |
| holdings_source | No | |
| portfolio_value | No | |
| top_10_weight_pct | No | |
| distinct_companies | No | |
| looked_through_pct | No | |
| not_looked_through | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations only cover the read-only/idempotent/no-world safety profile, and the description adds substantial behavior beyond that: uncovered tickers and specific excluded ETF categories are named and dropped from the math, amounts are not stored, equal weighting without amounts, and the top-raising behavior for surfacing a single company. This is genuinely informative context the annotations do not convey.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the when-to-use sentence, and every subsequent sentence carries a distinct fact (exclusions, weighting, non-storage, alternatives). It is dense and occasionally run-on ('for one company, raise top until it shows, up to 200'), which costs it the top mark, but there is essentially no filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists so return values need not be explained, and the description still covers the exclusion policy, weighting rules, top limits, and storage behavior. For a 3-param look-through tool this leaves no significant gap an agent needs.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds meaning above the schema: 'for one company, raise top until it shows, up to 200' guides how to use top, and 'Without amounts, every ETF counts equally' clarifies the amount semantics across positions. It reinforces rather than merely restates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource: tells the agent it returns the individual companies underneath a portfolio of US ETFs, with weight/value/ETF provenance. It explicitly distinguishes itself from siblings by naming get_etf_overlap_matrix (duplicates) and get_etf_portfolio_risk (risk) as not-this. An agent can route correctly without opening the schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Opens with an explicit when-to-use condition (user gives a portfolio of US ETFs and asks which companies they own, how much of one company, or concentration) and closes with explicit when-not-to-use plus the alternative siblings. Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_etf_portfolio_riskPortfolio risk breakdownARead-onlyIdempotentInspect
Use this when the user gives a portfolio of US ETFs and asks where its risk comes from or how its ETFs move together. Returns the portfolio's volatility, each position's share of the risk and of the capital, the diversification ratio, independent bets, the beta to the S&P 500, and the correlation and covariance of weekly returns over up to three years. It measures diversification by how the ETFs move together, not by companies held. Every ETF needs a year of weekly prices, which most ETFs read from SEC filings do not have here. Uncovered tickers are named and skipped. A trust or pool (bitcoin, gold), a bond, multi-asset or leveraged, inverse or other derivative-based ETF counts from its own weekly prices when it has them, named in read_from_prices. Past, not a forecast. Not for the companies held (get_etf_portfolio_lookthrough).
| Name | Required | Description | Default |
|---|---|---|---|
| currency | No | The currency of the amounts, for example USD or EUR. Echoed back with the values; nothing is converted. Left out, the amounts still weigh the ETFs and the currency reads unstated. | |
| positions | Yes | The ETFs of the portfolio, 1 to 60, for example [{"ticker": "VOO", "amount": 40000}, {"ticker": "QQQ", "amount": 25000}] with "currency": "USD" beside it. Give an amount for every position or for none; with none, every ETF counts equally. |
Output Schema
| Name | Required | Description |
|---|---|---|
| source | No | |
| covered | No | |
| skipped | No | |
| computed | No | |
| currency | No | |
| positions | No | |
| weeks_used | No | |
| correlation | No | Weekly returns; rows in the order of labels. |
| not_covered | No | |
| prices_as_of | No | |
| holdings_as_of | No | |
| volatility_pct | No | Annualised. |
| holdings_source | No | |
| beta_vs_sp500_1y | No | |
| beta_vs_sp500_3y | No | |
| independent_bets | No | |
| read_from_prices | No | |
| diversification_ratio | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish this is a safe, read-only, idempotent, closed-world call, and the description adds substantial context beyond them: the one-year weekly-price coverage requirement, that uncovered tickers are named and skipped, how trusts/bonds/leveraged/inverse ETFs are handled via read_from_prices, the up-to-three-year window, and that output is historical rather than a forecast.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loads the use case and then layers coverage constraints and exclusions, so every sentence carries information. It is dense and slightly long, but not padded or repetitive.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With read-only annotations and an output schema present, the description only needs to cover scope, triggering conditions, coverage limits, and sibling routing – and it does all of those. An agent has everything needed to call it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the currency echo behavior, the per-line amount weighting, and the all-or-none amount rule are already fully documented in the schema. The prose adds no format or syntax detail beyond that, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('portfolio risk breakdown' returning volatility, risk share, diversification ratio, beta, correlations) for a clearly bounded input type (US ETFs). It distinguishes itself from siblings by naming get_etf_portfolio_lookthrough as the wrong tool for the related question.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Opens with an explicit when-to-use trigger ('user gives a portfolio of US ETFs and asks where its risk comes from or how its ETFs move together') and closes with an explicit when-not / alternative ('Not for the companies held (get_etf_portfolio_lookthrough)'). Nothing is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_etfsCoverage and ETF searchARead-onlyIdempotentInspect
Use this when the user asks whether a US ETF is covered, wants to find an ETF by name or ticker, or asks how many ETFs the data covers and how recent it is. Returns the date of the data and the count of covered ETFs by source: the issuers' own holdings files, SEC Form N-PORT filings, trusts' filings, sponsors' files and prospectuses, and how many of the US-listed ETFs that is. With query, it returns up to 50 matching ETFs with their names, sources and categories; without query, it also lists every covered ticker by source unless include_tickers is false, a long answer. Mutual funds, closed-end funds and funds listed outside the US are not covered. Not for an ETF's holdings or figures (get_etf_holdings).
| Name | Required | Description | Default |
|---|---|---|---|
| query | No | A ticker or words from an ETF's name, for example VOO or semiconductor. Case does not matter. | |
| source | No | Only the ETFs read from the issuers' own files, only the stock ETFs from SEC filings, only the fixed income ETFs, only the multi-asset ETFs, only the derivative-based ETFs, only the trusts and pools, only the ETFs from their sponsors' files, or only the ETFs with only a prospectus file. | |
| include_tickers | No | Whether an answer without query lists every covered ticker, by source, and only those of source when it is given. true or left out adds the lists, a long answer; false returns the counts and dates alone. |
Output Schema
| Name | Required | Description |
|---|---|---|
| as_of | No | |
| source | Yes | |
| issuers | Yes | |
| matches | No | |
| match_count | No | |
| funds_covered | Yes | |
| us_listed_etfs | No | |
| funds_by_source | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare a safe read (readOnlyHint, idempotentHint, openWorldHint=false), but the description adds real behavioral weight: the 50-result cap on queries, the distinction between the with-query and without-query response shapes, the warning that omitting include_tickers returns 'a long answer', and that counts are broken out by source. These are operationally relevant behaviors not encoded in annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with the when-to-use clause, then response shape, then parameter effects, then exclusions and the sibling pointer. It is dense and slightly run-on in the middle enumerating sources, but nearly every clause carries routing or behavior information; little is padding.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
An output schema exists, so return-value detail is optional, yet the description still tells the agent what shape the answer takes (counts by source, date of data, optional ticker lists) and the truncation limit. Combined with full schema coverage and safety annotations, an agent has everything needed to call this correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description goes beyond it by explaining the consequence of include_tickers ('lists every covered ticker by source' vs 'counts and dates alone') and the 50-match ceiling implied for query. It does not explain the source enum values, but those are already documented verbosely in the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Opens with a concrete verb+resource ('list covered US ETFs') and immediately scopes it to search, coverage counts, and data recency. It explicitly distinguishes itself from the closest sibling by ending with 'Not for an ETF's holdings or figures (get_etf_holdings)', so an agent can separate this from get_etf_holdings, get_etf_flows and the compare_* tools without reading schemas.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives explicit trigger conditions ('when the user asks whether a US ETF is covered, wants to find an ETF by name or ticker, or asks how many ETFs the data covers') and explicit exclusions (mutual funds, closed-end funds, non-US listings). It also names the alternative tool for the adjacent need, which is exactly what a routing decision requires.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
1 tool update
- Changed
get_etf_flows1 field changed- changed
Input schema / properties / ticker / descriptionPrevious value: -"A stock ticker, for example NVDA, or a line listed abroad such as 7203.JP. Leave it out for the day's largest moves."New value: +"An ETF ticker for its own money flows, for example QQQ, or a stock ticker, for example NVDA, or a line listed abroad such as 7203.JP. Leave it out for the day's flows."
6 tool updates
- Changed
compare_stocks1 field changed- changed
Output schema / properties / membership / descriptionPrevious value: -"For a stock and a fund."New value: +"For a stock and an ETF."
- Added
find_diversifying_etfs - Changed
find_etfs_holding_stock4 fields changed- changed
Input schema / properties / compact / descriptionPrevious value: -"true for an answer about half the length. It keeps the counts, rank_summary (how many funds hold the stock as their largest or a top 10 position), name_collision (funds whose name contains the company's name) and the sentence to quote. It leaves out top_by_value (the funds holding the most dollars of it), membership (whether VOO, SPY, IVV, QQQ, VTI and SCHD hold it, and its weight in the three largest sector or industry funds that hold it), by_issuer (the issuers holding the most dollars), fee_per_1000 (the yearly cost, in the cheapest funds, of each $1,000 of the stock held through them) and each fund's rank, positions and value."New value: +"true for an answer about half the length. It keeps the counts, rank_summary (how many ETFs hold the stock as their largest or a top 10 position), name_collision (ETFs whose name contains the company's name) and the sentence to quote. It leaves out top_by_value (the ETFs holding the most dollars of it), membership (whether VOO, SPY, IVV, QQQ, VTI and SCHD hold it, and its weight in the three largest sector or industry ETFs that hold it), by_issuer (the issuers holding the most dollars), fee_per_1000 (the yearly cost, in the cheapest ETFs, of each $1,000 of the stock held through them) and each ETF's rank, positions and value." - changed
Input schema / properties / ticker / descriptionPrevious value: -"The stock's ticker, not the company name, for example NVDA for Nvidia. A line listed outside the US carries its market after a dot, for example 7203.JP (Toyota in Tokyo), SAN.FR (Sanofi in Paris) or 005930.KR (Samsung Electronics); an earlier key without the market, such as 7203, is read as the key it became. A key ending in .PFD is not a market: it is the issuer's preferred shares, a US line apart from the common stock (JPM.PFD, held by preferred stock funds)."New value: +"The stock's ticker, not the company name, for example NVDA for Nvidia. A line listed outside the US carries its market after a dot, for example 7203.JP (Toyota in Tokyo), SAN.FR (Sanofi in Paris) or 005930.KR (Samsung Electronics); an earlier key without the market, such as 7203, is read as the key it became. A key ending in .PFD is not a market: it is the issuer's preferred shares, a US line apart from the common stock (JPM.PFD, held by preferred stock ETFs)." - changed
Input schema / properties / top / descriptionPrevious value: -"How many funds to return, sorted by the stock's weight in each fund, largest first, from 1 to 200; 50 when left out."New value: +"How many ETFs to return, sorted by the stock's weight in each ETF, largest first, from 1 to 200; 50 when left out." - changed
Output schema / properties / held_by / items / properties / weight_pct / descriptionPrevious value: -"The stock's weight in the fund."New value: +"The stock's weight in the ETF."
- Changed
get_etf_portfolio_lookthrough2 fields changed- changed
Input schema / properties / currency / descriptionPrevious value: -"The currency of the amounts, for example USD or EUR. Echoed back with the values; nothing is converted. Left out, the amounts still weigh the funds and the currency reads unstated."New value: +"The currency of the amounts, for example USD or EUR. Echoed back with the values; nothing is converted. Left out, the amounts still weigh the ETFs and the currency reads unstated." - changed
Input schema / properties / positions / descriptionPrevious value: -"The funds of the portfolio, 1 to 60, for example [{\"ticker\": \"VOO\", \"amount\": 40000}, {\"ticker\": \"QQQ\", \"amount\": 25000}] with \"currency\": \"USD\" beside it. Give an amount for every position or for none; with none, every fund counts equally."New value: +"The ETFs of the portfolio, 1 to 60, for example [{\"ticker\": \"VOO\", \"amount\": 40000}, {\"ticker\": \"QQQ\", \"amount\": 25000}] with \"currency\": \"USD\" beside it. Give an amount for every position or for none; with none, every ETF counts equally."
- Changed
get_etf_portfolio_risk2 fields changed- changed
Input schema / properties / currency / descriptionPrevious value: -"The currency of the amounts, for example USD or EUR. Echoed back with the values; nothing is converted. Left out, the amounts still weigh the funds and the currency reads unstated."New value: +"The currency of the amounts, for example USD or EUR. Echoed back with the values; nothing is converted. Left out, the amounts still weigh the ETFs and the currency reads unstated." - changed
Input schema / properties / positions / descriptionPrevious value: -"The funds of the portfolio, 1 to 60, for example [{\"ticker\": \"VOO\", \"amount\": 40000}, {\"ticker\": \"QQQ\", \"amount\": 25000}] with \"currency\": \"USD\" beside it. Give an amount for every position or for none; with none, every fund counts equally."New value: +"The ETFs of the portfolio, 1 to 60, for example [{\"ticker\": \"VOO\", \"amount\": 40000}, {\"ticker\": \"QQQ\", \"amount\": 25000}] with \"currency\": \"USD\" beside it. Give an amount for every position or for none; with none, every ETF counts equally."
- Changed
list_etfs2 fields changed- changed
Input schema / properties / query / descriptionPrevious value: -"A ticker or words from a fund's name, for example VOO or semiconductor. Case does not matter."New value: +"A ticker or words from an ETF's name, for example VOO or semiconductor. Case does not matter." - changed
Input schema / properties / source / descriptionPrevious value: -"Only the funds read from the issuers' own files, only the stock ETFs from SEC filings, only the fixed income funds, only the multi-asset funds, only the derivative-based funds, only the trusts and pools, only the funds from their sponsors' files, or only the funds with only a prospectus file."New value: +"Only the ETFs read from the issuers' own files, only the stock ETFs from SEC filings, only the fixed income ETFs, only the multi-asset ETFs, only the derivative-based ETFs, only the trusts and pools, only the ETFs from their sponsors' files, or only the ETFs with only a prospectus file."
3 tool updates
- Changed
get_etf_holdings_changes1 field changed- changed
Output schema / properties / steps / descriptionPrevious value: -"Oldest first, the lines of each step largest first."New value: +"Oldest first; each step's lines largest first."
- Changed
get_etf_portfolio_lookthrough2 fields changed- changed
Output schema / properties / companies / descriptionPrevious value: -"Largest first, value in the currency of the amounts."New value: +"Largest first; value in the amounts' currency." - added
Output schema / properties / looked_through_pctAdded value: +{ + "type": [ + "number", + "null" + ] +}
- Changed
get_etf_portfolio_risk1 field changed- changed
Output schema / properties / correlation / descriptionPrevious value: -"Of weekly returns, rows in the order of labels."New value: +"Weekly returns; rows in the order of labels."
3 tool updates
- Changed
get_etf_holdings2 fields changed- added
Output schema / properties / breakdownAdded value: +{ + "type": "object" +} - added
Output schema / properties / categoryAdded value: +{ + "properties": { + "id": { + "type": "string" + }, + "label": { + "type": "string" + }, + "rule": { + "type": [ + "string", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] +}
- Changed
get_etf_portfolio_risk2 fields changed- removed
Output schema / properties / not_looked_throughRemoved value: -{ - "items": { - "properties": { - "ticker": { - "type": "string" - }, - "why": { - "type": "string" - } - }, - "required": [ - "ticker", - "why" - ], - "type": "object" - }, - "type": "array" -} - added
Output schema / properties / read_from_pricesAdded value: +{ + "items": { + "properties": { + "ticker": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "ticker", + "why" + ], + "type": "object" + }, + "type": "array" +}
- Changed
list_etfs2 fields changed- added
Output schema / properties / matches / items / properties / categoryAdded value: +{ + "type": [ + "string", + "null" + ] +} - added
Output schema / properties / matches / items / properties / category_idAdded value: +{ + "type": [ + "string", + "null" + ] +}
21 tool updates
- Added
compare_etfs - Removed
compare_funds - Removed
etf_ownership - Added
find_etfs_holding_stock - Removed
fund_changes - Removed
fund_history - Removed
fund_profile - Added
get_etf_flows - Added
get_etf_holdings - Added
get_etf_holdings_changes - Added
get_etf_holdings_history - Added
get_etf_overlap_matrix - Added
get_etf_ownership - Added
get_etf_portfolio_lookthrough - Added
get_etf_portfolio_risk - Added
list_etfs - Removed
list_funds - Removed
look_through - Removed
overlap_matrix - Removed
risk_decomposition - Removed
stock_exposure
11 tool updates
- Changed
compare_funds3 fields changed- changed
Input schema / properties / a / descriptionPrevious value: -"A US ETF ticker, for example VOO. Case does not matter."New value: +"A US ETF ticker, for example VOO or SCHD. Case does not matter." - changed
Input schema / properties / b / descriptionPrevious value: -"The other US ETF ticker."New value: +"The other US ETF ticker, for example QQQ." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "comparable": { + "type": "boolean" + }, + "correlation_3y": { + "type": [ + "number", + "null" + ] + }, + "covered": { + "type": "boolean" + }, + "funds": { + "additionalProperties": { + "properties": { + "beta_vs_sp500": { + "type": [ + "number", + "null" + ] + }, + "expense_ratio_pct": { + "type": [ + "number", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "return_3y_pct": { + "type": [ + "number", + "null" + ] + }, + "volatility_pct": { + "type": [ + "number", + "null" + ] + }, + "worst_fall_3y_pct": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" + }, + "type": "object" + }, + "holdings_as_of": { + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "type": "object" + }, + "holdings_source": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "issuer_overlap": { + "description": "By issuer, in percent.", + "properties": { + "by_weight": { + "type": [ + "number", + "null" + ] + }, + "issuers_in_both": { + "type": [ + "integer", + "null" + ] + }, + "share_of_a": { + "type": [ + "number", + "null" + ] + }, + "share_of_b": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" + }, + "not_comparable": { + "items": { + "properties": { + "ticker": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "ticker", + "why" + ], + "type": "object" + }, + "type": "array" + }, + "not_covered": { + "items": { + "type": "string" + }, + "type": "array" + }, + "overlap": { + "description": "In percent.", + "properties": { + "by_weight": { + "type": [ + "number", + "null" + ] + }, + "companies_in_both": { + "type": [ + "integer", + "null" + ] + }, + "share_of_a": { + "type": [ + "number", + "null" + ] + }, + "share_of_b": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" + }, + "pair": { + "items": { + "type": "string" + }, + "type": "array" + }, + "prices_as_of": { + "type": [ + "string", + "null" + ] + }, + "source": { + "properties": { + "cite_as": { + "type": "string" + }, + "license": { + "type": "string" + }, + "links": { + "items": { + "properties": { + "api_url": { + "type": "string" + }, + "page_url": { + "type": [ + "string", + "null" + ] + }, + "ticker": { + "type": "string" + } + }, + "required": [ + "ticker", + "page_url", + "api_url" + ], + "type": "object" + }, + "type": "array" + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "links", + "license", + "cite_as" + ], + "type": "object" + }, + "weeks_used": { + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" +}
- Changed
compare_stocks3 fields changed- changed
Input schema / properties / a / descriptionPrevious value: -"A US stock ticker, for example NVDA. An ETF ticker also works."New value: +"A US stock ticker, for example NVDA. An ETF ticker also works on one side, for example QQQ." - changed
Input schema / properties / b / descriptionPrevious value: -"The other ticker."New value: +"The other ticker, for example AMD." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "patternProperties": { + "^[A-Z0-9.\\-^=/ *&]{1,16}$": { + "properties": { + "beta": { + "description": "Over three years.", + "type": [ + "number", + "null" + ] + }, + "dividend_yield_pct": { + "type": [ + "number", + "null" + ] + }, + "expense_ratio_pct": { + "type": [ + "number", + "null" + ] + }, + "kind": { + "enum": [ + "stock", + "fund" + ], + "type": "string" + }, + "market_cap_bn": { + "type": [ + "number", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "pe": { + "type": [ + "number", + "null" + ] + }, + "return_1y_pct": { + "type": [ + "number", + "null" + ] + }, + "return_3y_pct": { + "type": [ + "number", + "null" + ] + }, + "volatility_pct": { + "type": [ + "number", + "null" + ] + }, + "worst_fall_3y_pct": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "kind" + ], + "type": "object" + } + }, + "properties": { + "correlation_3y": { + "type": [ + "number", + "null" + ] + }, + "covered": { + "type": "boolean" + }, + "funds_holding_both": { + "items": { + "properties": { + "fund": { + "type": "string" + }, + "holdings_as_of": { + "type": [ + "string", + "null" + ] + }, + "weight_a_pct": { + "type": [ + "number", + "null" + ] + }, + "weight_b_pct": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "fund" + ], + "type": "object" + }, + "type": "array" + }, + "funds_holding_both_count": { + "type": [ + "integer", + "null" + ] + }, + "membership": { + "description": "For a stock and a fund.", + "properties": { + "holdings_as_of": { + "type": [ + "string", + "null" + ] + }, + "in_fund": { + "type": "boolean" + }, + "rank": { + "type": [ + "integer", + "null" + ] + }, + "weight_pct": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "in_fund" + ], + "type": "object" + }, + "not_in_data": { + "items": { + "type": "string" + }, + "type": "array" + }, + "pair": { + "items": { + "type": "string" + }, + "type": "array" + }, + "prices_as_of": { + "type": [ + "string", + "null" + ] + }, + "source": { + "properties": { + "api_urls": { + "items": { + "type": "string" + }, + "type": "array" + }, + "license": { + "type": "string" + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "license", + "api_urls" + ], + "type": "object" + }, + "weeks_used": { + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" +}
- Changed
etf_ownership1 field changed- changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "basis": { + "description": "company when every class is counted, class when the ticker's class alone is.", + "type": [ + "string", + "null" + ] + }, + "covered": { + "type": "boolean" + }, + "etf_ownership_pct_at_least": { + "description": "The percent of the shares outstanding held by the covered US ETFs, at least.", + "type": [ + "number", + "null" + ] + }, + "figure": { + "type": "boolean" + }, + "holdings_as_of": { + "properties": { + "newest": { + "type": [ + "string", + "null" + ] + }, + "oldest": { + "type": [ + "string", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] + }, + "market": { + "properties": { + "rank_by_pct_held": { + "description": "1 for the stock most held by percent.", + "type": [ + "integer", + "null" + ] + }, + "stocks_with_a_figure": { + "type": [ + "integer", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "shares_held_by_covered_etfs": { + "type": [ + "number", + "null" + ] + }, + "shares_outstanding": { + "type": [ + "number", + "null" + ] + }, + "shares_outstanding_as_of": { + "type": [ + "string", + "null" + ] + }, + "source": { + "properties": { + "api_url": { + "type": "string" + }, + "license": { + "type": "string" + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "api_url", + "license" + ], + "type": "object" + }, + "ticker": { + "type": "string" + } + }, + "required": [ + "ticker", + "figure" + ], + "type": "object" +}
- Changed
fund_changes3 fields changed- changed
Input schema / properties / since / descriptionPrevious value: -"Only the steps to a file dated on or after this date, YYYY-MM-DD."New value: +"Only the steps to a file dated on or after this date, written YYYY-MM-DD, for example 2026-09-15." - changed
Input schema / properties / ticker / descriptionPrevious value: -"A US ETF ticker, for example VOO. Case does not matter."New value: +"A US ETF ticker, for example VOO or SCHD. Case does not matter." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "covered": { + "type": "boolean" + }, + "first_file": { + "type": [ + "string", + "null" + ] + }, + "history": { + "type": "boolean" + }, + "last_file": { + "type": [ + "string", + "null" + ] + }, + "moved_threshold_pp": { + "type": [ + "number", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "source": { + "properties": { + "api_url": { + "type": "string" + }, + "license": { + "type": [ + "string", + "null" + ] + }, + "provider": { + "type": "string" + }, + "terms": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "provider", + "api_url" + ], + "type": "object" + }, + "steps": { + "description": "Oldest first, the lines of each step largest first.", + "items": { + "properties": { + "date": { + "type": [ + "string", + "null" + ] + }, + "entered": { + "items": { + "properties": { + "ticker": { + "type": "string" + }, + "weight_pct": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "entered_count": { + "type": [ + "integer", + "null" + ] + }, + "exited": { + "items": { + "properties": { + "previous_weight_pct": { + "type": [ + "number", + "null" + ] + }, + "ticker": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "exited_count": { + "type": [ + "integer", + "null" + ] + }, + "moved": { + "items": { + "properties": { + "after_pct": { + "type": [ + "number", + "null" + ] + }, + "before_pct": { + "type": [ + "number", + "null" + ] + }, + "ticker": { + "type": "string" + } + }, + "type": "object" + }, + "type": "array" + }, + "moved_count": { + "type": [ + "integer", + "null" + ] + }, + "names_turnover_pp": { + "type": [ + "number", + "null" + ] + }, + "previous": { + "type": [ + "string", + "null" + ] + }, + "restated": { + "type": "boolean" + }, + "traded_pp": { + "type": [ + "number", + "null" + ] + }, + "weights_moved_pp": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "ticker": { + "type": "string" + } + }, + "type": "object" +}
- Changed
fund_history3 fields changed- changed
Input schema / properties / since / descriptionPrevious value: -"Only the steps to a file dated on or after this date, YYYY-MM-DD."New value: +"Only the steps to a file dated on or after this date, written YYYY-MM-DD, for example 2026-09-15." - changed
Input schema / properties / ticker / descriptionPrevious value: -"A US ETF ticker, for example VOO. Case does not matter."New value: +"A US ETF ticker, for example VOO or SCHD. Case does not matter." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "cadence": { + "type": [ + "string", + "null" + ] + }, + "covered": { + "type": "boolean" + }, + "file_dates": { + "type": [ + "integer", + "null" + ] + }, + "files": { + "description": "Oldest first.", + "items": { + "properties": { + "holdings_as_of": { + "type": [ + "string", + "null" + ] + }, + "positions": { + "type": [ + "integer", + "null" + ] + }, + "top10_weight_pct": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "first_file": { + "type": [ + "string", + "null" + ] + }, + "history": { + "type": "boolean" + }, + "last_file": { + "type": [ + "string", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "overlap_by_weight_pct": { + "additionalProperties": { + "description": "[date, percent] pairs, oldest first.", + "items": { + "type": "array" + }, + "type": "array" + }, + "type": "object" + }, + "source": { + "properties": { + "api_url": { + "type": "string" + }, + "license": { + "type": [ + "string", + "null" + ] + }, + "provider": { + "type": "string" + }, + "terms": { + "type": [ + "string", + "null" + ] + } + }, + "required": [ + "provider", + "api_url" + ], + "type": "object" + }, + "steps": { + "description": "Oldest first.", + "items": { + "properties": { + "date": { + "type": [ + "string", + "null" + ] + }, + "entered": { + "type": [ + "integer", + "null" + ] + }, + "exited": { + "type": [ + "integer", + "null" + ] + }, + "moved": { + "type": [ + "integer", + "null" + ] + }, + "names_turnover_pp": { + "type": [ + "number", + "null" + ] + }, + "previous": { + "type": [ + "string", + "null" + ] + }, + "restated": { + "type": "boolean" + }, + "traded_pp": { + "type": [ + "number", + "null" + ] + }, + "weights_moved_pp": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" + }, + "type": "array" + }, + "ticker": { + "type": "string" + } + }, + "type": "object" +}
- Changed
fund_profile3 fields changed- changed
Input schema / properties / holdings / descriptionPrevious value: -"How many of the largest holdings to return. 0 for none."New value: +"How many of the largest holdings to return, from 0 to 500; 25 when left out. 0 returns the figures without holdings." - changed
Input schema / properties / ticker / descriptionPrevious value: -"A US ETF ticker, for example VOO. Case does not matter."New value: +"A US ETF ticker, for example VOO or SCHD. Case does not matter." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "aum_billions": { + "description": "In billions of US dollars.", + "type": [ + "number", + "null" + ] + }, + "beta_vs_sp500": { + "type": [ + "number", + "null" + ] + }, + "covered": { + "type": "boolean" + }, + "expense_ratio_pct": { + "type": [ + "number", + "null" + ] + }, + "holdings": { + "items": { + "properties": { + "ticker": { + "type": "string" + }, + "weight_pct": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "ticker", + "weight_pct" + ], + "type": "object" + }, + "type": "array" + }, + "holdings_as_of": { + "type": [ + "string", + "null" + ] + }, + "holdings_source": { + "type": "string" + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "not_covered": { + "items": { + "type": "string" + }, + "type": "array" + }, + "positions": { + "type": [ + "integer", + "null" + ] + }, + "prices_as_of": { + "type": [ + "string", + "null" + ] + }, + "return_1y_pct": { + "type": [ + "number", + "null" + ] + }, + "return_3y_pct": { + "type": [ + "number", + "null" + ] + }, + "return_5y_pct": { + "type": [ + "number", + "null" + ] + }, + "source": { + "properties": { + "cite_as": { + "type": "string" + }, + "license": { + "type": "string" + }, + "links": { + "items": { + "properties": { + "api_url": { + "type": "string" + }, + "page_url": { + "type": [ + "string", + "null" + ] + }, + "ticker": { + "type": "string" + } + }, + "required": [ + "ticker", + "page_url", + "api_url" + ], + "type": "object" + }, + "type": "array" + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "links", + "license", + "cite_as" + ], + "type": "object" + }, + "ticker": { + "type": "string" + }, + "top_10_weight_pct": { + "type": [ + "number", + "null" + ] + }, + "volatility_pct": { + "type": [ + "number", + "null" + ] + }, + "worst_fall_3y_pct": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" +}
- Changed
list_funds2 fields changed- changed
Input schema / properties / include_tickers / descriptionPrevious value: -"false leaves out the ticker lists."New value: +"Whether an answer without query lists every covered ticker, by source, and only those of source when it is given. true or left out adds the lists, a long answer; false returns the counts and dates alone." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "as_of": { + "type": [ + "string", + "null" + ] + }, + "funds_by_source": { + "additionalProperties": { + "type": [ + "integer", + "null" + ] + }, + "type": "object" + }, + "funds_covered": { + "type": [ + "integer", + "null" + ] + }, + "issuers": { + "items": { + "type": "string" + }, + "type": "array" + }, + "match_count": { + "type": [ + "integer", + "null" + ] + }, + "matches": { + "items": { + "properties": { + "name": { + "type": [ + "string", + "null" + ] + }, + "source": { + "type": "string" + }, + "ticker": { + "type": "string" + } + }, + "required": [ + "ticker", + "source" + ], + "type": "object" + }, + "type": "array" + }, + "source": { + "properties": { + "api_url": { + "type": "string" + }, + "license": { + "type": "string" + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "api_url", + "license" + ], + "type": "object" + }, + "us_listed_etfs": { + "properties": { + "covered": { + "type": [ + "integer", + "null" + ] + }, + "directory_of": { + "type": [ + "string", + "null" + ] + }, + "listed": { + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" + } + }, + "required": [ + "funds_covered", + "funds_by_source", + "issuers", + "source" + ], + "type": "object" +}
- Changed
look_through6 fields changed- changed
Input schema / properties / currency / descriptionPrevious value: -"The currency of the amounts, for example USD. Echoed back; nothing is converted."New value: +"The currency of the amounts, for example USD or EUR. Echoed back with the values; nothing is converted. Left out, the amounts still weigh the funds and the currency reads unstated." - changed
Input schema / properties / positions / descriptionPrevious value: -"The funds in the portfolio. Amounts are optional; with none, every fund counts equally."New value: +"The funds of the portfolio, 1 to 60, for example [{\"ticker\": \"VOO\", \"amount\": 40000}, {\"ticker\": \"QQQ\", \"amount\": 25000}] with \"currency\": \"USD\" beside it. Give an amount for every position or for none; with none, every fund counts equally." - changed
Input schema / properties / positions / items / properties / amount / descriptionPrevious value: -"What this line is worth, in one currency for all lines."New value: +"What this line is worth, in the same unit on every line, for example 40000. Only the proportions between lines count for the percentages." - changed
Input schema / properties / positions / items / properties / ticker / descriptionPrevious value: -"A US ETF ticker, for example VOO. Case does not matter."New value: +"A US ETF ticker, for example VOO or SCHD. Case does not matter." - changed
Input schema / properties / top / descriptionPrevious value: -"How many companies to return."New value: +"How many companies to return, largest first, from 1 to 200; 25 when left out." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "companies": { + "description": "Largest first, value in the currency of the amounts.", + "items": { + "properties": { + "ticker": { + "type": "string" + }, + "value": { + "type": [ + "number", + "null" + ] + }, + "weight_pct": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "ticker", + "weight_pct" + ], + "type": "object" + }, + "type": "array" + }, + "computed": { + "type": "boolean" + }, + "covered": { + "type": "boolean" + }, + "currency": { + "type": [ + "string", + "null" + ] + }, + "distinct_companies": { + "type": [ + "integer", + "null" + ] + }, + "funds": { + "type": [ + "integer", + "null" + ] + }, + "holdings_as_of": { + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "type": "object" + }, + "holdings_source": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "not_covered": { + "items": { + "type": "string" + }, + "type": "array" + }, + "not_looked_through": { + "items": { + "properties": { + "ticker": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "ticker", + "why" + ], + "type": "object" + }, + "type": "array" + }, + "portfolio_value": { + "type": [ + "number", + "null" + ] + }, + "priced": { + "type": "boolean" + }, + "prices_as_of": { + "type": [ + "string", + "null" + ] + }, + "skipped": { + "properties": { + "not_covered": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "source": { + "properties": { + "cite_as": { + "type": "string" + }, + "license": { + "type": "string" + }, + "links": { + "items": { + "properties": { + "api_url": { + "type": "string" + }, + "page_url": { + "type": [ + "string", + "null" + ] + }, + "ticker": { + "type": "string" + } + }, + "required": [ + "ticker", + "page_url", + "api_url" + ], + "type": "object" + }, + "type": "array" + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "links", + "license", + "cite_as" + ], + "type": "object" + }, + "top_10_weight_pct": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" +}
- Changed
overlap_matrix3 fields changed- changed
Input schema / properties / tickers / descriptionPrevious value: -"2 to 30 US ETF tickers."New value: +"2 to 30 US ETF tickers, for example [\"VOO\", \"QQQ\", \"SCHD\"]: three or more give the matrix, two give one pair." - changed
Input schema / properties / tickers / items / descriptionPrevious value: -"A US ETF ticker, for example VOO. Case does not matter."New value: +"A US ETF ticker, for example VOO or SCHD. Case does not matter." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "computed": { + "type": "boolean" + }, + "covered": { + "type": "boolean" + }, + "holdings_as_of": { + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "type": "object" + }, + "holdings_source": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "issuer_overlap_pairs": { + "description": "By issuer, in percent, largest first.", + "items": { + "properties": { + "by_weight": { + "type": [ + "number", + "null" + ] + }, + "issuers_in_both": { + "type": [ + "integer", + "null" + ] + }, + "pair": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "required": [ + "pair", + "by_weight" + ], + "type": "object" + }, + "type": "array" + }, + "not_comparable": { + "items": { + "properties": { + "ticker": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "ticker", + "why" + ], + "type": "object" + }, + "type": "array" + }, + "not_covered": { + "items": { + "type": "string" + }, + "type": "array" + }, + "pairs": { + "description": "In percent, largest first.", + "items": { + "properties": { + "by_weight": { + "type": [ + "number", + "null" + ] + }, + "companies_in_both": { + "type": [ + "integer", + "null" + ] + }, + "pair": { + "items": { + "type": "string" + }, + "type": "array" + }, + "share_of_first": { + "type": [ + "number", + "null" + ] + }, + "share_of_second": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "pair", + "by_weight" + ], + "type": "object" + }, + "type": "array" + }, + "prices_as_of": { + "type": [ + "string", + "null" + ] + }, + "skipped": { + "properties": { + "not_covered": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "source": { + "properties": { + "cite_as": { + "type": "string" + }, + "license": { + "type": "string" + }, + "links": { + "items": { + "properties": { + "api_url": { + "type": "string" + }, + "page_url": { + "type": [ + "string", + "null" + ] + }, + "ticker": { + "type": "string" + } + }, + "required": [ + "ticker", + "page_url", + "api_url" + ], + "type": "object" + }, + "type": "array" + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "links", + "license", + "cite_as" + ], + "type": "object" + } + }, + "type": "object" +}
- Changed
risk_decomposition5 fields changed- changed
Input schema / properties / currency / descriptionPrevious value: -"The currency of the amounts, for example USD. Echoed back; nothing is converted."New value: +"The currency of the amounts, for example USD or EUR. Echoed back with the values; nothing is converted. Left out, the amounts still weigh the funds and the currency reads unstated." - changed
Input schema / properties / positions / descriptionPrevious value: -"The funds in the portfolio. Amounts are optional; with none, every fund counts equally."New value: +"The funds of the portfolio, 1 to 60, for example [{\"ticker\": \"VOO\", \"amount\": 40000}, {\"ticker\": \"QQQ\", \"amount\": 25000}] with \"currency\": \"USD\" beside it. Give an amount for every position or for none; with none, every fund counts equally." - changed
Input schema / properties / positions / items / properties / amount / descriptionPrevious value: -"What this line is worth, in one currency for all lines."New value: +"What this line is worth, in the same unit on every line, for example 40000. Only the proportions between lines count for the percentages." - changed
Input schema / properties / positions / items / properties / ticker / descriptionPrevious value: -"A US ETF ticker, for example VOO. Case does not matter."New value: +"A US ETF ticker, for example VOO or SCHD. Case does not matter." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "beta_vs_sp500_1y": { + "type": [ + "number", + "null" + ] + }, + "beta_vs_sp500_3y": { + "type": [ + "number", + "null" + ] + }, + "computed": { + "type": "boolean" + }, + "correlation": { + "description": "Of weekly returns, rows in the order of labels.", + "properties": { + "labels": { + "items": { + "type": "string" + }, + "type": "array" + }, + "rows": { + "items": { + "items": { + "type": [ + "number", + "null" + ] + }, + "type": "array" + }, + "type": "array" + } + }, + "type": "object" + }, + "covered": { + "type": "boolean" + }, + "currency": { + "type": [ + "string", + "null" + ] + }, + "diversification_ratio": { + "type": [ + "number", + "null" + ] + }, + "holdings_as_of": { + "additionalProperties": { + "type": [ + "string", + "null" + ] + }, + "type": "object" + }, + "holdings_source": { + "additionalProperties": { + "type": "string" + }, + "type": "object" + }, + "independent_bets": { + "type": [ + "number", + "null" + ] + }, + "not_covered": { + "items": { + "type": "string" + }, + "type": "array" + }, + "not_looked_through": { + "items": { + "properties": { + "ticker": { + "type": "string" + }, + "why": { + "type": "string" + } + }, + "required": [ + "ticker", + "why" + ], + "type": "object" + }, + "type": "array" + }, + "positions": { + "items": { + "properties": { + "share_of_capital_pct": { + "type": [ + "number", + "null" + ] + }, + "share_of_risk_pct": { + "type": [ + "number", + "null" + ] + }, + "ticker": { + "type": "string" + }, + "value": { + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "ticker", + "share_of_capital_pct", + "share_of_risk_pct" + ], + "type": "object" + }, + "type": "array" + }, + "prices_as_of": { + "type": [ + "string", + "null" + ] + }, + "skipped": { + "properties": { + "not_covered": { + "items": { + "type": "string" + }, + "type": "array" + } + }, + "type": "object" + }, + "source": { + "properties": { + "cite_as": { + "type": "string" + }, + "license": { + "type": "string" + }, + "links": { + "items": { + "properties": { + "api_url": { + "type": "string" + }, + "page_url": { + "type": [ + "string", + "null" + ] + }, + "ticker": { + "type": "string" + } + }, + "required": [ + "ticker", + "page_url", + "api_url" + ], + "type": "object" + }, + "type": "array" + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "links", + "license", + "cite_as" + ], + "type": "object" + }, + "volatility_pct": { + "description": "Annualised.", + "type": [ + "number", + "null" + ] + }, + "weeks_used": { + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" +}
- Changed
stock_exposure4 fields changed- changed
Input schema / properties / compact / descriptionPrevious value: -"true for the counts, rank_summary, name_collision and the sentence to quote, without top_by_value, membership, by_issuer and fee_per_1000 and without each fund's rank, positions and value: about half the length."New value: +"true for an answer about half the length. It keeps the counts, rank_summary (how many funds hold the stock as their largest or a top 10 position), name_collision (funds whose name contains the company's name) and the sentence to quote. It leaves out top_by_value (the funds holding the most dollars of it), membership (whether VOO, SPY, IVV, QQQ, VTI and SCHD hold it, and its weight in the three largest sector or industry funds that hold it), by_issuer (the issuers holding the most dollars), fee_per_1000 (the yearly cost, in the cheapest funds, of each $1,000 of the stock held through them) and each fund's rank, positions and value." - changed
Input schema / properties / ticker / descriptionPrevious value: -"A stock ticker, for example NVDA. A line listed outside the US carries its market after a dot, for example 7203.JP (Toyota in Tokyo), SAN.FR (Sanofi in Paris) or 005930.KR (Samsung Electronics); an earlier key without the market, such as 7203, is read as the key it became. A key ending in .PFD is not a market: it is the issuer's preferred shares, a US line apart from the common stock (JPM.PFD, held by preferred stock funds)."New value: +"The stock's ticker, not the company name, for example NVDA for Nvidia. A line listed outside the US carries its market after a dot, for example 7203.JP (Toyota in Tokyo), SAN.FR (Sanofi in Paris) or 005930.KR (Samsung Electronics); an earlier key without the market, such as 7203, is read as the key it became. A key ending in .PFD is not a market: it is the issuer's preferred shares, a US line apart from the common stock (JPM.PFD, held by preferred stock funds)." - changed
Input schema / properties / top / descriptionPrevious value: -"How many funds to return, heaviest first."New value: +"How many funds to return, sorted by the stock's weight in each fund, largest first, from 1 to 200; 50 when left out." - changed
Output schema / (root)Previous value: -nullNew value: +{ + "properties": { + "answer": { + "description": "One sentence to quote.", + "type": [ + "string", + "null" + ] + }, + "funds_by_source": { + "properties": { + "issuer_files": { + "type": [ + "integer", + "null" + ] + }, + "sec_nport": { + "description": "null when the SEC filings were not searched.", + "type": [ + "integer", + "null" + ] + } + }, + "type": "object" + }, + "funds_holding": { + "type": [ + "integer", + "null" + ] + }, + "held": { + "type": "boolean" + }, + "held_by": { + "description": "Largest weight first.", + "items": { + "properties": { + "fund": { + "type": "string" + }, + "holdings_as_of": { + "type": [ + "string", + "null" + ] + }, + "holdings_source": { + "type": "string" + }, + "value_usd_m": { + "type": [ + "number", + "null" + ] + }, + "weight_pct": { + "description": "The stock's weight in the fund.", + "type": [ + "number", + "null" + ] + } + }, + "required": [ + "fund", + "weight_pct" + ], + "type": "object" + }, + "type": "array" + }, + "membership": { + "items": { + "properties": { + "fund": { + "type": "string" + }, + "held": { + "type": "boolean" + }, + "weight": { + "type": [ + "number", + "null" + ] + } + }, + "type": "object" + }, + "type": [ + "array", + "null" + ] + }, + "name": { + "type": [ + "string", + "null" + ] + }, + "rank_summary": { + "properties": { + "top10_in": { + "type": [ + "integer", + "null" + ] + }, + "top_holding_in": { + "type": [ + "integer", + "null" + ] + } + }, + "type": [ + "object", + "null" + ] + }, + "source": { + "properties": { + "api_url": { + "type": "string" + }, + "cite_as": { + "type": "string" + }, + "license": { + "type": "string" + }, + "page_url": { + "type": [ + "string", + "null" + ] + }, + "provider": { + "type": "string" + } + }, + "required": [ + "provider", + "page_url", + "api_url", + "license", + "cite_as" + ], + "type": "object" + }, + "ticker": { + "type": "string" + } + }, + "required": [ + "ticker", + "funds_holding" + ], + "type": "object" +}
Related MCP Connectors
Independent US ETF data: holdings, fees, overlap, returns, each with its source and date.
SEC filings, financial statements, metrics, insider and institutional holdings as structured data
SEC Form N-PORT — fund and ETF holdings, asked security-first.
US insider trades, 13F, 13D/G, Form 144, politician trades, financials and short interest. Free.
Related MCP Servers
AlicenseAqualityAmaintenanceCorrelation, ETF holdings overlap, beta, volatility and diversifiers for 4,700+ US stocks and ETFs, any of 11.3M pairs. Free API, no key, read-only.6559 npm2MIT- AlicenseAqualityBmaintenanceEnables users to find which ETFs hold a given stock or company by name or ticker, compare fund fees, size and returns, inspect top holdings, and search or discover funds by theme. Data is pulled live from Yahoo Finance and requires no API key.7174 PyPI1MIT
- AlicenseAqualityBmaintenanceMCP server providing complete US ETF holdings from SEC EDGAR N-PORT filings and identifier crosswalk tools (ticker, CUSIP, FIGI) for AI agents.5Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables querying SEC Form N-PORT data to find which mutual funds and ETFs hold a given security, view a fund's reported portfolio positions, and check data coverage and scope.16 npmMIT
Glama MCP Gateway
Add one secure layer between your agents and this server.