ByteTree MCP
MCP Tool Reference
The 13 read-only data tools exposed by ByteTree MCP. Each tool wraps the same data plane as the REST API; the REST cross-link on each section shows the equivalent endpoint where one exists, so you can pick the surface that fits the task.
ByteTree MCP exposes 14 tools in total. The one not documented below is ping — a health check that takes no inputs, returns pong with a server timestamp, and reaches no data. Your client may show fewer than fourteen if you have individual tools switched off in its settings.
All input schemas use Zod under the hood and validate at the server. Symbols are uppercased internally; dates are ISO YYYY-MM-DD; field projections (fields?: string[]) are honoured wherever present.
Field names like byteTrendCapr200w, trendRegimeLocal30d, trendAge200w, capr, marketCapUsd are ByteTree-proprietary — see the Concepts page for definitions before reasoning about values.
Asset discovery
list_assets
List assets from the ByteTree registry with optional filters. Returns a paginated envelope (count/total/limit/offset/data). Each row carries the full asset document — identifiers (symbol, ISIN), classification (type, status, sector, industry), region/country, currency, exchange (under metadata.exchange), market cap (mktCap in local currency, mktCapUsd in USD) — plus the latest Weekly and Daily ByteTrend CAPR scores (byteTrendCapr200w and byteTrendCapr30d) and their trend regimes. Use get_latest_metrics for the full metrics blob including the Local-variant ByteTrend scores and ~100 other fields.
REST equivalent: GET /api/assets
| Name | Type | Required | Description |
|---|---|---|---|
type |
enum stock | crypto | etf | index | commodity | fx |
Optional | Asset type filter |
status |
string | Optional | Status filter, e.g. "active" |
sector |
string | Optional | Direct sector match |
q |
string | Optional | Case-insensitive text search on symbol or name |
universe |
string | Optional | Membership filter: keep only assets in this product-dataset universe (e.g. "bytetrend"; list_grouping_configs lists the slugs). Combines with every other filter, so adding it narrows the result. Omit it to cover the whole market — there is no macro value here |
dimension |
string | Optional | Filter on a global dimension: "region", "sector", "industry", "type" or "country". Pass together with group (both or neither). Works with or without universe |
group |
string | Optional | Group label within dimension (e.g. "North America", "Technology"). Pass together with dimension |
limit |
int 1–1000 | Optional | Max rows (default 500) |
offset |
int ≥ 0 | Optional | Pagination offset (default 0) |
Response: { count, total, limit, offset, data: AssetDocument[] }
get_asset
Registry detail for a single asset: identifiers (symbol, ISIN), classification (type, status, sector, industry), region/country, currency, exchange, and market cap. Does not include metrics — use get_latest_metrics for ByteTrend scores, trend regimes, returns, and the rest of the metrics blob. The id is a ticker symbol (uppercased internally).
REST equivalent: GET /api/assets/:symbol
| Name | Type | Required | Description |
|---|---|---|---|
id |
string (min 1) | Required | Ticker symbol (e.g. AAPL, BTCUSD) |
Response: AssetDocument on success, { id, found: false } on 404.
Metrics
get_latest_metrics
The most recently computed metrics row for a symbol. Includes the four ByteTrend scores (Weekly Local byteTrendLocal200w, Weekly CAPR byteTrendCapr200w, Daily Local byteTrendLocal30d, Daily CAPR byteTrendCapr30d), the four trend regime labels, Weekly trend age (trendAge200w), drawdown, Sharpe, beta, market cap, and ~100 other fields. Returns the newest computed row whatever its age, so check its date before treating the values as current — an asset with a data gap, or one that is no longer updated, returns its last row, which can be weeks old. Returns { symbol, data: null } only when the symbol has no metrics at all.
Surfaces ByteTree-proprietary signals: CAPR (Currency-Adjusted Price Relative — asset USD price ÷ the same-day MSCI World close), ByteTrend (0–5 composite score in two arcs — Weekly with 200-week/30-week MAs, Daily with 200-day/30-day MAs), and trend regimes (Leading / Emerging / Weakening / Bear / Neutral). Read the Concepts page or the bytetree://glossary resource for predicates and full definitions before reasoning about these fields — these terms are not in any LLM training set.
REST equivalent: GET /api/metrics/latest, GET /api/metrics/:symbol/latest
| Name | Type | Required | Description |
|---|---|---|---|
symbol |
string (min 1) | Required | Ticker symbol (e.g. AAPL, BTCUSD) |
Response: { symbol, data: MetricsRow | null }
get_metrics_series
Time-series of computed metrics for a symbol. Returns { symbol, count, data: [{ date, …metricFields }] } with metrics merged into each row. Use fields to project a subset (e.g. ["byteTrendCapr200w", "returnUsd1M", "closeUsd"]) — without it, every metric field (~100 per row) is returned, which compounds quickly.
Defaults to a 90-day window ending today when neither from nor to is supplied — pass from (and optionally to) explicitly to widen the range, and lean on fields to keep the response under the 800 KB tool-result cap. Row cadence matches the price-data feed for the asset type: stocks have one row per trading day (no Sat/Sun/holiday rows); crypto has one row per calendar day (24/7 markets), up to the previous day (UTC). A crypto row’s price and scores are normally final once published; forward returns still fill in as their windows pass (below).
Forward-return fields (returnFwdUsd1D, 1W, 1M, 3M, 6M, 12M) are populated on historical rows where the forward window is fully observable — useful for signal-conditional analysis like “what was the 3M forward return on every date a stock hit byteTrendCapr200w === 5?”. The latest few rows naturally show null forward-returns whose windows extend past the last observed close.
REST equivalent: GET /api/metrics/:symbol
| Name | Type | Required | Description |
|---|---|---|---|
symbol |
string (min 1) | Required | — |
fields |
string[] | Optional | Metric field names to include in each row |
from |
string YYYY-MM-DD |
Optional | Start date (defaults to 90 days ago if neither bound is supplied) |
to |
string YYYY-MM-DD |
Optional | End date |
Response: { symbol, count, data: Array<{ date, …metricFields }> }
rank_assets
Rank active assets by a chosen metric and return the top/bottom N with their latest values. Composed over the bulk metrics map, so the universe is bounded by the 7-day metric staleness window — assets whose latest metrics row is older than seven days (e.g. data-gap symbols) drop out of rankings naturally rather than appearing with stale values. Nulls are excluded from the ranking.
The metric enum mixes ByteTree-proprietary signals (Weekly and Daily ByteTrend scores 0–5 in Local and CAPR variants, the Weekly trend age trendAge200w) with standard finance metrics; read the Concepts page for the precise predicates behind ByteTrend, CAPR, and trend regimes before interpreting the values.
REST equivalent: none — server-side ranking is MCP-only today.
| Name | Type | Required | Description |
|---|---|---|---|
metric |
enum (see below) | Required | Metric to rank by |
order |
enum asc | desc |
Optional | Sort direction (default desc — top-of-ranking first) |
type |
enum stock | crypto | etf | index | commodity | fx |
Optional | Filter by asset type |
status |
string | Optional | Filter by status, e.g. "active" |
limit |
int 1–500 | Optional | Max rows (default 20) |
Metric enum (27 values)
byteTrendLocal200w, byteTrendLocal30d, byteTrendCapr200w, byteTrendCapr30d, changeLocal200w, changeLocal30d, changeCapr200w, changeCapr30d, returnUsd1W, returnUsd1M, returnUsd3M, returnUsd6M, returnUsd12M, volatility30w, sharpe52w, beta52w, drawdown52w, drawdownATH, trendAge200w, marketCapUsd, relStrengthRaw1M, relStrengthRaw3M, relStrengthRaw12M, relStrengthCapped1M, relStrengthCapped3M, relStrengthCapped12M, returnVolRatio
Response: { metric, order, count, total, data: Array<{ symbol, value: number }> }
get_metric_distribution
Cross-sectional distribution of a single metric across the active asset universe, sampled over a date range. The analytical primitive for “describe how the present came to be” — regime tracking (“what fraction of stocks were at Weekly CAPR ByteTrend >= 4 each week over 3 years?”), cohort drift (“how has median Weekly trend age in Asia Pacific evolved?”), and event windows (“score distribution in the 90 days before vs after a major drawdown”).
Output shape branches on the metric:
- ByteTrend scores yield
bucketskeyed"0"–"5"with all six keys present. trendAge200wyieldsbucketskeyed by lower-bound day-count ("0","5","30","90","365","1825").- Continuous metrics (returns, ratios, levels, market cap) yield
statsonly with nobucketsblock.
Default frequency is weekly to keep payloads sane; daily over a multi-year window will hit the server-side >5000-projected-rows guard and 400. Asset filters mirror list_assets — type, status, sector, q, universe, and dimension+group — except type=fx is rejected (no per-asset distribution surface for FX).
With weekly or monthly frequency each row pools every asset-day in the step, so n and the bucket counts are asset-days, not assets — only daily rows are per-asset snapshots. See Asset-days, not assets.
REST equivalent: GET /api/metrics/distribution
| Name | Type | Required | Description |
|---|---|---|---|
metric |
enum (see below) | Required | Metric to compute the distribution of |
from |
string YYYY-MM-DD |
Required | Start date |
to |
string YYYY-MM-DD |
Optional | End date (default today) |
frequency |
enum daily | weekly | monthly |
Optional | Sampling frequency (default weekly) |
type |
enum stock | crypto | etf | index | commodity |
Optional | fx excluded |
status |
string | Optional | Filter by status |
sector |
string | Optional | Direct sector match |
q |
string | Optional | Text search on symbol or name |
universe |
string | Optional | Membership filter: keep only assets in this product-dataset universe (e.g. "bytetrend"; list_grouping_configs lists the slugs). Combines with every other filter, so adding it narrows the result. Omit it to cover the whole market — there is no macro value here |
dimension |
string | Optional | Filter on a global dimension: "region", "sector", "industry", "type" or "country". Pass together with group (both or neither). Works with or without universe |
group |
string | Optional | Group label within dimension (e.g. "North America", "Technology"). Pass together with dimension |
Metric enum (~40 values — superset of rank_assets)
byteTrendLocal200w, byteTrendLocal30d, byteTrendCapr200w, byteTrendCapr30d, changeLocal200w, changeLocal30d, changeCapr200w, changeCapr30d, scoreVelocity5d200w, divergenceLocal, divergenceCapr, trendAge200w, closeUsd, capr, marketCapUsd, returnUsd1W, returnUsd1M, returnUsd3M, returnUsd6M, returnUsd12M, returnFwdUsd1M, returnFwdUsd3M, returnFwdUsd6M, returnFwdUsd12M, volatility30w, sharpe52w, beta52w, drawdown52w, drawdownATH, maxDrawdown30w, maxDrawdown52w, relStrengthRaw1M, relStrengthRaw3M, relStrengthRaw12M, relStrengthCapped1M, relStrengthCapped3M, relStrengthCapped12M, returnVolRatio, cumulHighs12w, volumeConfirmation30d
Response: { generatedAt, metric, frequency, count, data: Array<{ date, n, stats: { mean, median, p25, p75, p90 }, buckets?: Record<string, number> }> }
get_regime_transitions
Regime-transition event log across the active asset universe — the analytical primitive for “when did regime X fire historically and what did the world look like at that moment?”. Returns one row per detected transition with { symbol, transitionDate, fromRegime, toRegime, metricsAtTransition: {…} }.
The Weekly CAPR window (200w-CAPR) additionally carries confirmedTransitionDate (same as transitionDate for this window — included for clarity), pendingStartDate (the day the candidate streak began, typically four rows earlier in the time-sorted series), and trendAgeAtTransition (always 5 in continuous operation per the confirmation rule).
The other three windows — Weekly Local (200w-Local), Daily CAPR (30d-CAPR), Daily Local (30d-Local) — are raw-only with no confirmation machinery, so those three extra fields are omitted entirely from the response and transitionDate IS the same-day change.
regime is required when direction is "into" or "outOf"; pass direction: "any" (and omit regime) for unfiltered scans of every regime change in the window.
Asset filters mirror list_assets — type, status, sector, q, universe, and dimension+group — except type=fx is excluded (no per-asset regime surface for FX).
Defaults to a 90-day window ending today when neither from nor to is supplied — the same default the series tools use. Widen explicitly with from (and optionally to) for historical scans: a date-less call asking for “every Leading Trend transition” returns the last 90 days, not all history, and does so without an error to tell you the range was narrowed.
The server returns at most 5000 transitions and answers 400 when a query would exceed that — when you widen the range (especially with direction: "any"), narrow with an asset filter (type, sector, universe, or dimension+group) to stay under the cap. A scan too broad to finish in time also comes back as a clean 400 (“query too broad”) asking you to narrow the range or add a filter. Supplying only to still applies the 90-day look-back, anchored on to.
See the Concepts page for regime predicates, the Weekly CAPR confirmation state machine, and Weekly-vs-Daily distinctions.
REST equivalent: GET /api/metrics/regime-transitions
| Name | Type | Required | Description |
|---|---|---|---|
window |
enum 200w-CAPR | 200w-Local | 30d-CAPR | 30d-Local |
Required | Regime variant to scan |
regime |
string | Conditionally required | Required when direction is "into" or "outOf" |
direction |
enum into | outOf | any |
Optional | Default "into" |
from |
string YYYY-MM-DD |
Optional | Start date. When omitted, 90 days before to (or before today) |
to |
string YYYY-MM-DD |
Optional | End date |
type |
enum stock | crypto | etf | index | commodity |
Optional | fx excluded |
status, sector, q, universe, dimension, group |
— | Optional | Same semantics as list_assets |
fields |
string[] | Optional | Projection for metricsAtTransition. Default: closeUsd, byteTrendCapr200w, byteTrendCapr30d, returnUsd1M, marketCapUsd, sharpe52w |
Response: { generatedAt, regime, window, direction, appliedRange: { from, to, defaulted }, count, data }, where each row in data is:
- Weekly CAPR (
200w-CAPR):{ symbol, transitionDate, confirmedTransitionDate, pendingStartDate, fromRegime, toRegime, trendAgeAtTransition, metricsAtTransition }—pendingStartDateisnullwhen the transition falls in the first few days of the range - Other three windows:
{ symbol, transitionDate, fromRegime, toRegime, metricsAtTransition }
appliedRange.defaulted is true when the 90-day look-back was applied — check it before reading a small result as a genuine absence of transitions.
Prices and FX
get_prices
Raw OHLCV price data for a symbol. Returns { symbol, count, data: [{ date, open, high, low, close, volume }] }. Adjusted close is the default (split- and dividend-adjusted). Pass raw: true for the unmodified series with split discontinuities preserved — useful for forensic checks but rarely what an LLM should default to.
Defaults to a 90-day window ending today when neither from nor to is supplied — pass from explicitly to widen, but watch the response size for multi-year queries on liquid stocks. Multi-year OHLCV on an active stock can exceed the 800 KB tool-result cap; if it does, the tool returns an error with narrowing guidance — retry with a tighter from (or chunk the range).
FX symbols return a narrower close-only row shape { date, close } since the FX store does not carry OHLV.
REST equivalent: GET /api/prices/:symbol
| Name | Type | Required | Description |
|---|---|---|---|
symbol |
string (min 1) | Required | — |
from |
string YYYY-MM-DD |
Optional | Defaults to 90 days ago if neither bound is supplied |
to |
string YYYY-MM-DD |
Optional | — |
raw |
boolean | Optional | If true, returns unadjusted prices (default false — adjusted) |
Response: { symbol, count, data: Array<{ date, open, high, low, close, volume }> } (or { date, close } for FX)
get_fx_rates
Historical FX rates for a currency pair (e.g. GBPUSD, EURUSD). Returns { symbol, count, data: [{ date, close }] } — close-only, since the FX store does not carry OHLV.
REST equivalent: GET /api/fx/:symbol/prices (the route this tool calls); GET /api/rates/:pair for full OHLC
| Name | Type | Required | Description |
|---|---|---|---|
pair |
string (min 1) | Required | FX pair symbol (e.g. GBPUSD) |
from |
string YYYY-MM-DD |
Optional | — |
to |
string YYYY-MM-DD |
Optional | — |
Response: { symbol, count, data: Array<{ date, close }> } on success, { pair, found: false } on 404.
Universes and groups
list_grouping_configs
Discover the product-dataset universe slugs accepted by get_group_metrics and by the universe asset filter. Returns one row per populated universe — universe (slug), label, source, rule, enabled, sortOrder, and memberCount (how many active assets resolve into it). Populated baskets are listed and memberCount shows each one’s size; baskets with no current members are omitted, so the roster grows as curated baskets fill. macro, the five dimensions across every active asset, is the open cross-market dataset, not a universe, so it is queried through get_group_metrics (its default) rather than listed here. Dimensions (region, sector, industry, type, country) are shared across the surface, not per-universe.
source names how a universe’s membership is determined: rule — a screen over asset types (e.g. bytetrend); manual — a hand-picked basket; or portfolio — a curated portfolio. The rule field carries the asset-type filter that defines a rule screen; it is null for manual / portfolio. memberCount is the number of active assets currently resolved into the universe.
REST equivalent: GET /api/universes
No input.
Response: { count, total, limit, offset, data: Array<{ universe, label, source, rule, enabled, sortOrder, memberCount }> }
get_group_metrics
Group-level computed metrics for a (universe, dimension, group) tuple — e.g. (macro, region, "North America") or (macro, sector, "Technology"). Without from/to returns the most recent row only; with a date range returns the time series.
Aggregate fields include assetCount, ByteTrend averages across all four arc/variant combinations (Weekly Local avgByteTrendLocal200w, Weekly CAPR avgByteTrendCapr200w, Daily Local avgByteTrendLocal30d, Daily CAPR avgByteTrendCapr30d, plus median/pctScore equivalents), trend distribution and dominant trend, equal- and cap-weighted return aggregates over 1W/1M/3M/6M/12M, and risk metrics (avgVolatility30w, avgSharpe52w, totalMarketCapUsd, avgDrawdown52w, avgRelStrengthCapped3M/12M).
macro is the open cross-market dataset and the default when universe is omitted: the five dimensions (region, sector, industry, type, country) across every active asset. The product-dataset universes (e.g. bytetrend; use list_grouping_configs for the live roster) group their own membership. An unknown or unpopulated universe is refused with a clean not-found error, so a hidden basket’s existence is never confirmed. Dimensions (region, sector, industry, type, country) are shared across the surface.
Aggregate fields use the same ByteTree-proprietary signals as the per-asset metrics; the Concepts page has predicates and definitions.
REST equivalent: GET /api/macro/:dimension/:group for macro (the default); GET /api/universes/:universe, GET /api/universes/:universe/:dimension, GET /api/universes/:universe/:dimension/:group for the product-dataset universes
| Name | Type | Required | Description |
|---|---|---|---|
dimension |
string (min 1) | Required | e.g. "region", "sector", "industry", "type", "country" |
group |
string (min 1) | Required | e.g. "North America", "Technology" |
universe |
string | Optional | Default "macro" (the open cross-market dataset); also accepts product-dataset slugs like "bytetrend" — see list_grouping_configs |
from |
string YYYY-MM-DD |
Optional | Omit to get the latest row only |
to |
string YYYY-MM-DD |
Optional | — |
fields |
string[] | Optional | Project a subset of aggregate fields |
Response: { count, dimension, group, data: Array<{ date, …aggregateFields }> }
Analysis
summarise_dataset
High-level overview of the ByteTree dataset. Returns asset counts by type and status, per-type price-data date envelopes (earliest, latest, total record count), an FX summary (record count, date range), and a concepts block with one-line definitions of the ByteTree-proprietary signals (CAPR, ByteTrend, Local-vs-CAPR, trend regimes).
Use as a starting tool for any prompt that needs to orient itself — the concepts block ensures the model gets the right framing before it reasons over downstream tool responses. The bytetree://glossary resource (or the Concepts page) has the full definitions.
REST equivalent: GET /api/summary, which this tool calls. The tool adds an inline concepts block that the REST route doesn’t have.
No input.
Response: { <summary fields from /api/summary>, concepts: { CAPR, ByteTrend, localVsCapr, trendRegimes, glossary } }
compare_assets
Side-by-side comparison of the latest metrics for a small basket of symbols (1–10). Returns { count, fields, data: [{ symbol, found, date, …projectedFields }] } — every row has the same keys so the response encodes as a compact tabular form even when some symbols are missing.
Each row is the newest computed row for its symbol whatever its age, so compare the date column before comparing values: a symbol with a data gap, or one no longer updated, can sit weeks behind the rest of the basket. date is YYYY-MM-DD, and null when found is false.
The default field set is the canonical 24-field mix: all four ByteTrend scores (Weekly Local/CAPR + Daily Local/CAPR), their daily changes, all four trend regime labels, USD returns over 1W–12M, risk metrics (volatility, Sharpe, beta, drawdowns), Weekly trend age, and market cap. Override via fields for narrower comparisons.
The ByteTrend score, CAPR, and trend regime fields are ByteTree-proprietary; read the Concepts page for definitions before interpreting the values — comparing Weekly Local (byteTrendLocal200w) to Weekly CAPR (byteTrendCapr200w) for the same symbol isolates absolute vs relative leadership, which is what this tool is most useful for.
REST equivalent: none — composable over REST today, MCP exposes as a single tool.
| Name | Type | Required | Description |
|---|---|---|---|
symbols |
string[] (length 1–10) | Required | Each symbol is uppercased internally |
fields |
string[] | Optional | Default: the canonical 24-field set (see below) |
Default fields projection (24 fields)
byteTrendLocal200w, byteTrendLocal30d, byteTrendCapr200w, byteTrendCapr30d, changeLocal200w, changeLocal30d, changeCapr200w, changeCapr30d, trendRegimeLocal200w, trendRegimeLocal30d, trendRegimeCapr200w, trendRegimeCapr30d, returnUsd1W, returnUsd1M, returnUsd3M, returnUsd6M, returnUsd12M, volatility30w, sharpe52w, beta52w, drawdown52w, drawdownATH, trendAge200w, marketCapUsd
Response: { count, fields: string[], data: Array<{ symbol, found, date, …projectedFields }> }