Ava Advisor
fund.ava/ava-advisorVersion 1.0.1Your AI watches the markets so you can live your life. Financial intelligence for everybody.
Status
Responds339 msAnswered our handshake without sign-in.- Last checked
- Nov 14, 2026, 14:31 UTC
- Latency
- 339 ms
- Remotes responding
- 1 of 1
- Sign-in
- No sign-in
- Hosting
- Hosted outside the EU (detected)
- Registry data as of
- Nov 14, 2026, 22:14 UTC
Data from the official MCP Registry, checked by run.zero. How we check
Connect
Streamable HTTP
https://mcp.ava.fund/mcpResponds339 msNo sign-in
Claude Code
claude mcp add --transport http ava-advisor https://mcp.ava.fund/mcpClaude Desktop and claude.ai
Settings > Connectors > Add custom connector
Name: ava-advisor
Remote MCP server URL: https://mcp.ava.fund/mcpCursor
{
"mcpServers": {
"ava-advisor": {
"url": "https://mcp.ava.fund/mcp"
}
}
}VS Code
code --add-mcp '{"name":"ava-advisor","type":"http","url":"https://mcp.ava.fund/mcp"}'Built your own server? run.zero hosts MCP servers on European infrastructure.
Tools
37 tools
Read-only | Idempotent | Open world | ||
|---|---|---|---|---|
add_to_playlist🔴 WRITE — add one or more STOCKS/assets to a playlist (batch, idempotent). Each entry may be an exact
Ava Advisor ticker OR a name/symbol the server resolves (any asset class: stock/ETF/commodity/crypto/FX). An
ambiguous name (e.g. same name across markets) returns a `needs_confirmation` reconfirm — pick the exact ticker
and re-call. `playlist_id` from `list_playlists`. Re-adding an existing ticker is a harmless no-op. Returns
`{added, skipped, item_count}` — ⚠️ RELAY any `skipped` to the user; never drop it silently. | No | No | Yes | Not declared |
briefThe generalized ANALYST BRIEF — one composed "how is <scope> doing right now?" picture (pulse + net direction,
top_stories, winners/losers, aspect_heatmap, top_entities, top_assets) for any AND-combination of scopes. ⭐ Use to
SUMMARIZE a scope (theme / news category / country / sector / aspect) — NOT a raw article list (that's
search_news/news_feed). ⛔ NOT for a single COMPANY or market INDEX ("how is AAPL / the S&P doing?" →
options_sentiment + stock_impact/news_feed; an index maps to an ETF, not a brief scope). For a sector×region the
quickest path is pulse(kind='theme', target='banks', country=…); use brief for one precise GICS cohort or an AND-combo.
Scope by ≥1 of (CSV for several) — REQUIRED (never whole-market):
• `news_type` — a category; use ONLY these EXACT names: product_tech, ma_partnership, industry_thematic,
earnings_results, corporate_action, management_governance, analyst_rating, macro_economic, geopolitics,
commodity_supply, regulatory_legal, cybersecurity_digital_trust, digital_finance_tokenization,
price_action_technical, crypto_related, forex_related, analyst_forecast. (commodity→commodity_supply;
central-bank/rates→macro_economic — there is NO 'monetary_policy'.)
• `country` (ISO-2) · `aspect` (impact channel) · `gics` (code or plain English) · `megatrend` (theme name/id).
⚠️ News coverage starts 2026-01-01. `node`+`ripple` appear only when a SINGLE megatrend anchors the brief. | Not declared | Yes | Not declared | Not declared |
cot_extremes⭐ FUTURES / CFTC-COT speculative positioning extremes — which commodity / FX / rate / equity-INDEX
FUTURES have the CROWD at a 3-year extreme right now (NOT single-stock equity options → for 'stretched
put/call' or crowded STOCK names use options_scan). The discovery scan across every tracked
futures market at once. COT / FUTURES lens ONLY. Surfaces stretched positioning (≥90th or ≤10th
percentile of its own 3y history) that could unwind hard on a shock — a contrarian-RISK map, NOT buy/sell
calls (an extreme can persist). Use for 'where is FUTURES positioning most crowded / stretched right now?'.
🔴 WRONG TOOL for single-STOCK options crowding — 'stretched put/call', 'one-sided / crowded equity names',
'most extreme options positioning across stocks': for those use options_scan (pattern='crowded / one-sided' —
the equity-options opana lens across ~557 US optionable names). Narrate each `read` plainly. | Not declared | Yes | Not declared | Not declared |
create_playlist🔴 WRITE — create a new feed playlist (owner-scoped). Do NOT auto-create from a possible typo:
call `list_playlists` FIRST and only create when the name genuinely doesn't exist, or the user
confirms a new one. Returns the created playlist {id, name, …}. | No | No | No | Not declared |
edit_screenCHANGE a screener formula you already have — add, remove or replace conditions as ops; the server places,
resolves and merges them and checks the result (no engine JSON to write). Use it for EVERY change while building a
screen with the user; use screen_unified (mode 'run') when the user wants to SEE the stocks of a formula.
Returns {ok, criteria (the new formula, saved shape — screen_unified takes it verbatim in `criteria`), changes
(what each op became: status resolved|snapped, value, snaps / dropped / assumed = what the engine read differently),
issues (what did not go in: code, and `nearest` / `candidates` = alternatives ready to send back as an op's value),
keep (the user-set paths after the change), reset, charts (when conditions were split across charts), count?}.
Nothing is saved — the client decides what to apply. | Not declared | Yes | Not declared | Not declared |
etf_profileWhat a US ETF / fund HOLDS: top holdings with % of NAV, sector (GICS) and country weights, plus the fund facts
— AUM, expense ratio, benchmark / index or active, holdings count, top-10 concentration, tracking difference
(SEC N-PORT / N-CEN filings; `as_of` dates say how fresh). Use it for "what does SCHD hold", "how concentrated is
QQQ", "SPY vs VOO fees", "sector mix of XLE". ETFs rarely have news of their own — for "why is it moving" pair
this with stock_impact / pulse on the top holdings. Non-fund tickers → `not_a_fund`. | Not declared | Yes | Not declared | Not declared |
financials⭐ Company FINANCIAL STATEMENTS — income / balance / cash-flow + auto-detected abnormality signals. Read ONE
company or COMPARE up to 8 (revenue, growth, margins, ROE, FCF…), on a clean normalized feed uniform across every
industry (banks, insurers, REITs).
🔴 To compare SEVERAL, pass them ALL in ONE call (tickers='TSLA.US,MSFT.US') — a single call aligns them on a
common basis+currency and costs a fraction of N calls. Pick ONE `period` (quarterly already carries YoY).
🎚 `fields`: leave EMPTY for the DIGEST (small default — headline + ratios + capital-return + signals; covers most
compares); set it for specific line items, a whole statement ('income'|'balance'|'cashflow'), or 'all'.
⏱ `period` = the window (5y / 2022 / 2022-2023 / 5q / 2024Q2), mapped to each fiscal year. 🌐 currency=USD (auto for
multi-company) converts totals at each period's date. 🗣 The digest carries a plain `read` (facts, not advice) and may
carry `_notes` (per-period comparability flags — the warning is FACT, each `likely_causes` is an inferred lead to VERIFY).
📏 LIMITS: ≤8 companies · ≤20 fields · ~4–5y history. A non-equity/unlisted entry → `ok:false`.
🔴 pulse(kind='asset') on a stock ALREADY embeds this digest — call financials only for a dedicated read/compare or a
specific fields/statement pull, not right after pulse(kind='asset'). | Not declared | Yes | Not declared | Not declared |
fred_series"What is <macro indicator> / is it high vs history / how has it moved" — ONE FRED series, feature-extracted.
Pass a macro CONCEPT (the server resolves it to the canonical series_id + the right transform) or an exact id.
Returns `series` (transformed points) + an `analysis` block: `latest` (+date — always say as-of-when), `trend`,
`change` (vs prior/YoY/window), `peak`/`trough`, and 🔑 `percentile`+`z_score` vs the window's own history (the
money-shot for "high or low?" — e.g. unemployment 8th pct = historically very low), `volatility`, a one-line
`read`. 🔵 `transform` matters and is auto-picked from the resolved series ("inflation" = pc1 YoY % of a price
index, a rate = lin) — override only deliberately. QUOTE the `read`; narrate the percentile. Compare two = call
once per concept and diff. A concept that isn't a FRED series (ISM/PMI, a commodity SPOT price → pulse(kind='commodity'))
→ honest no_match, not a fabrication. US-govt series are public domain (`_license_note`). | Not declared | Yes | Not declared | Not declared |
get_noteThe FULL saved note (including its `body`) by id — owner-scoped. Use after `query_notes` when you
need the complete content, not just the summary. | Not declared | Yes | Not declared | Not declared |
latest_quoteThe LATEST TRADED PRICE today for US stocks / ETFs — a DELAYED intraday quote (typically ~15 minutes behind),
with today's change vs the previous close. Use it when the user asks about TODAY during the US session ("why is
UBER down today", "where is NVDA trading"): every other price tool is END-OF-DAY (last close). US listings only —
any other market returns `not_covered` (use stock_prices). Pair the move with today's news (stock_impact /
search_news) for the why. State the quote time and that it is delayed; it is not a live tick. | Not declared | Yes | Not declared | Not declared |
list_playlistsList the user's OWN feed playlists (id, name, emoji, item_count, items[{kind,ref_id,label}]).
🔴 Call this FIRST whenever the user refers to a playlist BY NAME ("add X to My Tech List") — you
match the (possibly mistyped / mis-spaced) name against the REAL names yourself. If the user didn't
say WHICH and they own more than one, ASK which one (show the names). If they own NONE, offer to
create one. Owner-scoped — only ever the user's own playlists. A playlist drives their news Feed. | Not declared | Yes | Not declared | Not declared |
list_portfoliosList the user's OWN portfolios (id, name, base_currency, account_type, nav, total_return_pct,
unrealized_pnl, position_count, …) so you can pick one to analyze. Call this FIRST whenever the user
says 'my portfolio' without a number — show the names, then pass the chosen `id` to
`portfolio_context`. Owner-scoped: only ever the user's own portfolios.
If `count` is 0 (they own none), the response carries a `note` with a create link — relay THAT
(invite them to create a portfolio) instead of saying an empty 'you have no portfolios'. | Not declared | Yes | Not declared | Not declared |
list_themesBrowse / discover the megatrend taxonomy (25 tier-1 families + sub-nodes) — resolve a theme id. | Not declared | Yes | Not declared | Not declared |
news_feedThe filtered impact feed — news by megatrend/country/aspect/direction/news_type, across stocks,
FX, crypto, COMMODITIES (metals/energy) and private cos. Use for 'negative tariff news on
Semiconductors', 'macro news moving European stocks', 'copper / metals news', etc. Near-duplicate
stories are MERGED by default (+`dup_count`); `collapse=false` for the raw feed. `limit` = how many
(default 20, max 50); narrow the filters rather than paging deep. TIME-SCOPE with `from_`/`to` (ISO)
or a `window` ('90d','qtd','ytd','1y'). To COMPARE periods, call once per period and compare the
results. ⚠️ News starts 2026-01-01 — older ranges return nothing (no coverage, not 'no news').
`megatrend` accepts a plain name/slug/concept ('foundry', 'AI chips') — resolved server-side to node id(s). | Not declared | Yes | Not declared | Not declared |
options_scanFind STOCKS by an options-behaviour pattern (opana lens) across the ~557 US optionable names — returns
ranked UNDERLYINGS each with a plain-language `because` + `metrics` (value, and prev→delta for a trend/flip).
STOCK scanner only: it does NOT pick option contracts/strikes/expiries (for one named stock's detail use
`options_sentiment`). The `pattern` is a key OR plain English (the server resolves it) — its `temporal_mode`
decides the read (level = now, rising/falling = ~2-week trend, flip = reversal). A `supported:'no'`/`'future'` pattern returns an empty
list + an honest note (say so, don't substitute). US-capped — state that in the answer. | Not declared | Yes | Not declared | Not declared |
options_sentimentWhat the US OPTIONS MARKET is saying — the POSITIONING lens (~547 popular US optionable names,
stocks + ETFs). Pairs with the news→impact read: for "how is <X> doing?" fetch THIS *and*
`stock_impact`/`news_feed` and fuse them (news = what's happening + WHY; options = how the market is
positioned — direction lean via put/call, fear/greed via skew, IV level, dealer-gamma stability,
max-pain pinning, notable expiries). For a name the user HOLDS it shows how the market is hedging that
position. Broad-INDEX question → pass the liquid ETF proxy: S&P 500→`SPY`, Nasdaq 100→`QQQ`, Dow→
`DIA`, Russell 2000→`IWM`, 20y Treasuries→`TLT`, Gold→`GLD`. Tickers = bare US symbol or `SYMBOL.US`
(`NVDA`/`NVDA.US`); US-only. `style` = `plain` (everyday language, default) | `technical`.
TWO MODES:
• SINGLE deep read — pass `ticker=<one>` (+ optional `as_of`). Returns the FULL narrative payload
(horizons, buckets, per-signal `read`+`because`, `_guide`). Use for a focused "how is NVDA doing".
• BATCH / COMPARE — pass `tickers=[...]` and/or `dates=[...]` → ONE call returns a COMPACT grid, one
small row per (ticker × date) cell: `spot`, `positioning_score` ([-1,+1], + bullish), per-horizon
positioning, and medium-term signal `reads`. THIS is how you answer "NVDA vs AAPL, last week vs
this week" — do NOT fire the single tool N×M times. `dates=[]` (omit) → a single "latest" column.
📅 HISTORICAL: `as_of`/`dates` = ISO date/timestamp; the snapshot AT-OR-BEFORE that instant. A bare
date (`2026-07-15`) is read as END of that day. Every response carries `available_from`/`available_to`
(the stored window); a cell whose date predates it comes back `covered:false` with the range — relay
THAT honestly (say history only goes back to `available_from`), never invent an older reading.
⚠️ Narrate from `read`+`because` (or the batch `reads`); DON'T recompute, DON'T compare raw O/S or IV
across assets, `baseline_pending | Not declared | Yes | Not declared | Not declared |
portfolio_contextAn LLM-ready snapshot of ONE of the user's OWN portfolios (owner-scoped) — analyze it directly.
NO window → default: `meta` · `summary` · a `lifetime`(all-time) + `recent`(~12mo) block, EACH with
`performance` (return/cagr/sharpe/sortino/calmar/drawdown/vol/win_rate) + `attribution` · `positions`
· `closed_positions` (realized_pnl) · `composition` (point-in-time holdings) · `allocation` ·
`concentration` (HHI) · `inferred_behavior` · `flags`. `portfolio_id` from `list_portfolios`; 404 if
not the user's.
TIME WINDOW — `from_`/`to` (ISO) or `window` (`7d|30d|90d|180d|1y|mtd|qtd|ytd`): REPLACES lifetime+
recent with ONE `window` block (that span's `performance` + `attribution` + `nav_trend`) and scopes
`composition` to match. So ANY period's return + drivers is answerable. `snapshots` = composition
granularity only (`year|quarter|month|week|day|off`).
🔴 MANDATORY for period questions: the default / `lifetime` / `recent` blocks DO NOT contain the
performance or attribution of an arbitrary period (e.g. Q1-2025, "H1 2024"). To answer ANY specific
period — or to COMPARE periods (Q1/25 vs Q1/26, 2023 vs 2025) — you MUST call this tool AGAIN with
`from_`/`to` (or `window`) for EACH period, then compare the returned `window` blocks. NEVER derive a
period's return/sharpe/drawdown/attribution from the default view — those numbers aren't in it; making
them up is a hard error. If you haven't fetched a period's window, say you need to fetch it, don't guess.
HOW TO ANALYZE (research-analyst framing — see avaadvisor://policy):
• Lead with the sharpest thing: a non-empty `flag`, or the biggest concentration / drawdown / tilt.
• "What drove the return / drawdown / strengths & weaknesses" (for the default OR a window) → read
`attribution.contributors[]` (per-holding `pnl_contribution` + `pct_of_nav_change` + `held` window;
reconciles to `nav_change` to the cent, INCLUDES since-sold names). Don't esti | Not declared | Yes | Not declared | Not declared |
positioning⭐ How the FUTURES market is POSITIONED — the CFTC Commitment of Traders lens for commodities, FX,
rates and equity indices (the non-equity TWIN of options_sentiment; the two together cover positioning
for every asset class). Answers 'is this trade crowded?', 'is the smart money leaning the other way?',
'is the good news already priced into positioning?'. Returns: `crowding` (the speculative crowd at a
3-year extreme = a contrarian RISK, NOT a timing call), `smart_vs_crowd` (are commercial hedgers — who
know the physical/fundamental side — leaning against the crowd), `momentum` (building or unwinding; a
flip = regime change), `fragility` (a few big traders holding it = reverses fast), and ⭐
`news_vs_positioning` (does recent news CONFIRM the crowd → priced-in, or CONTRADICT a crowded position →
unwind risk). Weekly, as of the prior TUESDAY. For a RATE/YIELD asset (`.GB`/`.MM`) a long futures =
positioned for LOWER yields (the reads already say it that way). 🗣 Every feature carries a PLAIN `read`
— narrate it in EVERYDAY language for a beginner (no 'net'/'percentile'/'basis' jargon); say what it
MEANS for risk. Facts, not advice — the verdict is yours. A stock / uncovered asset → `__notfound`: say
futures positioning doesn't apply and use options_sentiment / the news read instead. | Not declared | Yes | Not declared | Not declared |
price_seriesA SMALL, bounded price SERIES for drawing a chart (a device screen, a sparkline) plus headline numbers —
the counterpart of `stock_prices`, which is a digested read with no series. Returns ticker, name, metric_kind
(`yield` = a bond yield / rate: levels in %, moves in bps via period_change_bps / change_bps_by_period), currency,
range, interval (`day`|`week`|`month`), period_start_date / period_end_date, last_close, period_change_pct,
period_high / period_low (+ their dates), last_volume, average_daily_volume, change_pct_by_period
{1w, 1mo, 3mo, ytd, 1y}, and `series` {dates, closes[, volumes]} as parallel arrays (≤ 65 points). EOD daily
data, split/dividend-adjusted closes — the last point is the LAST CLOSE, not an intraday quote. Weekly/monthly
points are each period's last close. Use this when a chart or a few chart numbers are needed; for "is it
cheap / extended / why is it moving" use `stock_prices` or `pulse(kind='asset')`. | Not declared | Yes | Not declared | Not declared |
private_moversOff-coverage / private companies the news moved within a theme — the 'beyond tickers' surface.
`limit` = how many (default 20, max 50). Returns {companies, count, total, note?} — honor `note` when
`total` > `count` (it's a top slice, not the whole set). | Not declared | Yes | Not declared | Not declared |
pulseONE market-pulse read across every subject type — a news + market lens on an asset, a theme/sector, a
commodity, a bond/rate/curve, a macro dashboard, or your portfolio. Pick `kind`, put the subject in `target`.
Replaces the per-type asset/theme/commodity/bond/macro/portfolio pulse tools. | Not declared | Yes | Not declared | Not declared |
query_notesRecall the USER'S OWN saved notes — their personal investment knowledge base (owner-scoped, only
ever their notes). Two combinable ways:
• SEMANTIC recall via `q` — natural language ("what did I say about foundry manufacturing?"); results
are ranked by MEANING with a `similarity` score (cross-language OK).
• Structured filters: `stock` (a ticker → their notes about it), `theme` (a sector/trend NAME →
resolved to the megatrend, subtree included), `gics` (6-digit code), `tag`, `note_type`
(reference/tracking/thesis/decision), `since` (e.g. '30d').
📌 `stock` + `relation` (direct|indirect|any, default any) splits how a note relates to that ticker —
same idea as newsfeed direct/indirect: `direct` = the note is ABOUT it (a subject); `indirect` = it's
only REFERENCED (e.g. a peer named in a note about ANOTHER stock — a "NVDA vs peers" note surfaces
under AMD as indirect). Every returned note carries a `relation` label when you filter by `stock`, so
you can say "1 note about AMD + 1 that only mentions it". Use `relation="direct"` for "notes really
about X".
Returns note SUMMARIES + linked entities + `similarity` — NOT the full body (call `get_note(id)` for
that). `limit` default 10 (max 50).
🔴 FUSE personal + live: when the user asks about something they've likely noted, pair this with the
live read — e.g. `pulse(kind='asset', target=NVDA)` AND "your NVDA thesis from last week said …". That personal-
knowledge + live-graph combination is the whole point of the notes layer. | Not declared | Yes | Not declared | Not declared |
relationshipsCompetitors + peers of a company (news-derived relationship graph). `limit` caps EACH list
(default 15, max 50). Each side carries `total`/`count`/`note` — a big `total` (peers often run to
hundreds) means you're seeing a TOP slice; say so rather than implying it's the complete set. | Not declared | Yes | Not declared | Not declared |
remove_from_playlist🔴 WRITE — remove one or more stocks (by ticker) from a playlist (batch). `playlist_id` from
`list_playlists`. Returns `{removed, not_found, item_count}` — relay `not_found` (a ticker that
wasn't in the playlist) to the user. | Yes | No | Yes | Not declared |
screen_dividends💰 THE income screener — "which stocks pay a high / reliable / growing DIVIDEND?" Ranks the DIVIDEND-PAYING
universe (all payers, not just news-covered) and hands you the raw pieces to tell a real income name from a YIELD
TRAP (don't trust a headline yield).
🔴 A multi-metric ask that also needs P/E / financial-health (dividend AND low P/E AND healthy) belongs in
screen_unified (a `fundamental` leg + `dividend_min_streak_years`/`dividend_min_cagr` gate). THIS tool is the
dividend specialist (no P/E filter) but it both INCLUDES (`gics`) and EXCLUDES (`exclude_gics`) a sector.
Scope (country/gics) is OPTIONAL — omit both for a fast whole-market rank.
🔴 `no_cut_streak_yrs` is a bounded RELIABILITY signal, capped at 10 (clean across the tracked decade incl. 2020/
2022 stress) — NOT the dividend's full age; never state a multi-decade "aristocrat/king" streak, say "clean 10y+".
Each row's `dividend` block decomposes the yield: `yield_pct` (forward/sustainable — quote this), `yield_trailing_pct`
(>> yield_pct ⇒ a special inflated it), `payout_ratio` (>1 = unsustainable), `ttm_div_yoy_pct`, `no_cut_streak_yrs`,
`last_cut_year`, `cagr_5y_pct`, plus `week52_high/low` + `pe_ratio`/`pb_ratio`/`eps` + a `news` block. 🔴 Never rank on
yield alone: high yield + recent `last_cut_year` + negative yoy + high payout + bad news = TRAP; high yield from a
price drop + intact/growing dividend + long streak = possible VALUE. Read the payload's `_guide`. limit default 15 (max 50). | Not declared | Yes | Not declared | Not declared |
screen_stocks⭐ The cohort SCREENER: "which stocks in <a group> are interesting / winning / losing / most-talked-about,
and how cheap or expensive do they trade?" Ranks the companies in a scope by how news is hitting them (lead with
the winners-vs-losers split), and EVERY row carries its VALUATION (P/E, P/B, dividend yield, 52w) — so this is
also the tool for "which in <group> are cheap / worth investing" (pulse(kind='theme')/brief are news-only, no valuation —
pull P/E from here; P/B leads for banks/insurers).
⚠️ Rows are a NEWS-RANKED, CAPPED SUBSET, not the full cohort — do NOT compute a sector/peer AVERAGE from them
(biased sample). For "cheaper/richer than the sector average / below-above the group / undervalued vs peers" use
screen_unified with a `below_average`/`above_average` pattern (proper cap-weighted, outlier-cleaned benchmark).
Scope ≥1 REQUIRED (never whole-universe): megatrend / gics / country — combine freely.
Each row = {symbol, name, country, gic_code, market_cap_usd, impact:{news_count, pos, neg, ambiguous,
net_direction, top_relevance, aspects, top_reason}, fundamentals:{pe_ratio, pb_ratio, dividend_yield_pct,
week52_high, week52_low}}; `direction_split` pre-tallies winners/losers. ⚠️ per-stock impact scoring exists only
from ~2026-07-03 — an earlier window returns empty (say so, not "nothing happened"). One ticker → pulse(kind='asset');
a group's overall pulse → pulse(kind='theme'); a sector-average benchmark → screen_unified. | Not declared | Yes | Not declared | Not declared |
screen_unifiedEXECUTE a unified screen = universe ∩ fundamental ∩ technical ∩ options (any leg optional; each grammar resolved
server-side — key or plain English). Returns {universe, count, sort, executed_criteria (the resolved request that ran — save/re-run it verbatim), results:[{head_listing_id, ticker, name, score,
matched_legs, matched:{ta, fundamental:{<metric>:{value, basis, window?, series?, periods?}}}, context}], notes}.
Evidence keys == the leg name you sent (TA→matched.ta, fundamentals→matched.fundamental, NOT technical/financial);
`matched_legs` lists which leg(s) a row passed. A thin intersection adds partial:true + per-leg near-misses — never
present a partial/one-leg row as a full match; read `notes` (names the tighter leg + how to broaden).
Time windows are PER-LEG: TA 'within last N bars' = top-level `window_bars`; a fundamental trend's span = that
condition's `N`. Options leg is US-optionable only (~557 → US-capped); sort='options' ranks by it; an
options-vs-price divergence = just send the phrase in `options`. FAILS LOUD: an unsupported pattern/operand/concept
returns a 400, so count:0 with NO error = a VALID query that matched zero now (loosen / widen window_bars, don't say
'can't do X'); `notes` may say 'insufficient history' (not a no-match) or which basis was screened. Over-fetches a
~4× buffer (cap 100) so 'show me more' is served from these rows — don't re-call. | Not declared | Yes | Not declared | Not declared |
search_newsSEMANTIC news search across ALL covered asset classes — stocks, FX, crypto, COMMODITIES (metals
like copper/gold, energy like oil), and private companies. Articles matched by MEANING, impact-labeled
(title, publisher, entities, direction, why). USE THIS for 'copper news', 'metals', 'gold', etc.
instead of a web search. `entity_type` keeps only stock/forex/crypto/commodity/private hits. For a
FILTERED feed by aspect/direction/country use `news_feed`. `limit` = how many (default 20, max 50).
TIME-SCOPE with `from_`/`to` (ISO dates, e.g. '2026-04-01') or a `window` ('90d','qtd','ytd','1y').
⚠️ News coverage starts 2026-01-01 — older ranges return nothing (that's no COVERAGE, not 'no news').
Returns {match_quality, top_similarity, note, results}. If match_quality is 'weak'/'none', the corpus
has no strongly relevant news — do NOT present these results as evidence; say so and use another route. | Not declared | Yes | Not declared | Not declared |
stock_impactHow news moved a specific company/asset (incl commodities like GOLD.COMM) — per-article impact
(direction + aspect + why), most recent first. Near-duplicate stories are MERGED by default (each row
= one story + `dup_count`); `collapse=false` for the raw feed. `limit` = how many (default 20, max 50). Ordered by how hard each story hits this entity (`relevance`, 1.0 = directly about it; a market wrap that touches it ranks lower), then recency; `companies_in_story` says when it is one of several
— heavily-covered assets have HUNDREDS, so keep it small + narrow. TIME-SCOPE with `from_`/`to` (ISO)
or `window` ('90d','qtd','1y'); to COMPARE periods, call once per period. ⚠️ News starts 2026-01-01 —
older ranges return nothing (no coverage, not 'no news'; price/volatility history goes back decades).
🔵 BONDS/RATES: a specific tenor/rate (`US-2Y.GB`, `SOFR.MM`) with no news of its own returns the
country's benchmark-10Y macro news tagged `scope:'curve_macro'` + `macro_source` — narrate those as
curve-wide central-bank context, not tenor-specific. 📏 MAGNITUDE: for a listed, priced asset each story has
`price_move` = close-to-close % of the session it landed in (`day_pct`) and of the next one (`next_day_pct`) —
the market's reaction next to the direction. It is the WHOLE day's move (other news counts too), not the story's
isolated effect; say so. End-of-day prices: a story from today has no session close yet. | Not declared | Yes | Not declared | Not declared |
stock_pricesPrice context for a tradable ticker (stock / ETF / index-ETF / forex / crypto / commodity), split &
dividend-ADJUSTED — a DIGESTED read, NOT a raw bar series: windowed changes (1w/1mo/3mo/ytd/1y), 52-week
range + `drawdown_from_52w_high_pct` (how far below the peak), realized vol + `realized_vol_percentile_1y`
(is today's vol high vs its OWN year), trend vs SMA50/200, volume conviction (`up_down_volume_ratio_1mo`,
rvol). `*_read` fields are ready plain-language labels — quote them, don't re-derive. Reach for this on
"is it cheap/extended / how has it moved / why is it dropping" — the LEVEL that makes a news+options read
actionable (or use `pulse(kind='asset')` to get price + news + options in one). `to` = as-of date (point-in-time,
YYYY-MM-DD, features as of that day); `from_` bounds history (narrowing below ~1y nulls the long windows).
For a SECTOR/theme (not one ticker) use `pulse(kind='theme')`, not this. 🔵 BONDS/RATES: if `metric_kind` ==
"yield" (a `.GB` govt-bond yield like US-10Y.GB or a `.MM` rate like SOFR.MM) the stored value is a
LEVEL, not a price — narrate each window's `change_bps` in BASIS POINTS, NOT `change_pct` (a % of a
yield is sign-inverted + the wrong unit; e.g. US-10Y 1y = "+52 bps", not "+12%"). Bonds also carry
per-window `price_proxy_pct` + top-level `mod_duration` = an L1 bond-PRICE estimate (≈ −ModDur×Δy) for
"the bond fell ~4%" narration (label it an ESTIMATE; for an exact bond return point to a bond ETF like
TLT/IEF). Volume fields (`rvol`, `up_down_volume_ratio_1mo`, …) are `null` for a yield — don't present
volume conviction; and yield↑ ⇒ bond price↓. | Not declared | Yes | Not declared | Not declared |
stock_prices_batchThe same digested price context for UP TO 50 tickers in ONE call — a watchlist / cohort snapshot
("which of these names are most extended, or deepest in drawdown"). Returns `results` (in input order)
+ `unresolved` (unknown / no-price-history tickers). `to`/`from_` as in `stock_prices`. | Not declared | Yes | Not declared | Not declared |
suggest_ctaAfter answering, propose 1-2 data-backed 'explore further' hooks that pull the user into the
graph's moat (ripple/relations/commodity/off-coverage). Server-side: theme_summary(has ripple/
entities/aspects) + a semantic news search, then deepseek curates ONLY data-backed hooks.
Validated in /tmp/mcp-gate/cta_tool.js (there via direct probes; here via the summary composite). | Not declared | Yes | Not declared | Not declared |
theme_playersTHE roster tool: investable MEMBER companies of a theme (curated membership). Rolls up sub-themes
(a parent node returns its children's members too). Use this — not screen_stocks — for 'who are the
players / real names in <theme>' (screen_stocks is a NEWS-ranked subset gated to news-epicenter members).
`country='all'` (default) gives the complete cross-market list; an ISO-2 scopes to one trading venue.
Different from top_entities (news-derived). `limit` = how many (default 20, max 50; big themes have many).
Returns {stocks, count, total, note?} — if `total` > `count` it's a TOP SLICE: say so, don't present it
as the full roster (raise `limit`). | Not declared | Yes | Not declared | Not declared |
theme_summaryPre-composed analyst brief for a megatrend theme: pulse, winners/losers, top entities, aspect
heatmap, ripple. `theme` = a theme name or id/slug; `window` = 7d/30d/90d/1y/mtd/qtd/ytd. | Not declared | Yes | Not declared | Not declared |
tradeInternational TRADE STATISTICS — countries' import/export flows, partners, rankings and balances from UN Comtrade
(official customs data). NOT securities trading: it never places, routes or executes an order. Pick `mode`; each mode reads a subset of the params (see each param's note). | Not declared | Yes | Not declared | Not declared |
wb_series"<structural indicator> for <country>, over time / vs other countries" — World Bank annual data,
feature-extracted (open data, 3 credits). Pass a structural CONCEPT (the server resolves it to the canonical
indicator + variant) or an exact indicator id. Returns `results:[{country, series:[{year,value}], analysis}]`
(one per country); `analysis` = `latest`(+year), `trend`, `cagr_pct`, `change`, `peak`/`trough`. ⭐ For a
MULTI-COUNTRY call (comma-sep `country`) a top-level `ranking` orders them by the latest value — the
cross-country compare FRED can't do. Annual STRUCTURAL data → read levels + CAGR, not high-frequency moves.
A country/year with no data is omitted (never interpolated). The right VARIANT (%GDP vs US$ vs per-capita) is
picked from your `context`. A concept that isn't World-Bank structural (CPI/unemployment → fred_series) → honest
no_match. Surface `_license_note` when showing data. | Not declared | Yes | Not declared | Not declared |
write_note🔴 WRITE — save a NOTE to the user's account (this PERSISTS data; it is NOT a read/lookup). Typical
flow: FIRST give the user your complete answer as usual, THEN — as the final step of the turn — call
`write_note` once to keep it.
🔴 IF YOUR ANSWER CONTAINED A TABLE / NUMERIC COMPARISON, keep it as a MARKDOWN table in `body` — lead with
the table, do NOT re-narrate the numbers into prose. Saving a figures answer as a wall of prose is the #1
note-quality failure; preserving structure OUTRANKS "distilling into a paragraph". (The figures are extracted
from these markdown tables later for charts — so a clean table with clear headers is what makes that possible.)
CONTENT: `subject` (short title), `body` (MARKDOWN — keep tables as tables, absolute headers like `FY2025`),
`summary` (1–2 sentences), `note_type` (reference/tracking/thesis/decision), `category`, `tags` — see each field.
ENTITY LINKS make the note findable + joinable to the graph — fill whenever the note touches specific things;
the server RESOLVES plain names for you. `stocks` (the subjects) · `mentioned_stocks` (referenced) · `gics`
(sector/theme, code or plain English) · `megatrend_ids` (advanced raw id) · `portfolio_id`.
🧭 LINK THE NOTE'S HOME — the theme/sector, not just the stocks. If the note is about a TREND/tech/mechanism
("what is HBM", "solid-state batteries") or an established INDUSTRY/SECTOR ("retail", "airlines", "pharma"),
put the word(s) straight in `gics` (plain English — the server resolves each and routes a theme→megatrend).
A note whose subject is a trend or a sector, saved with EMPTY `gics`, means you SKIPPED this. The only correct
empties: a single-stock note (stocks only) or a general concept with no home (P/E, EBITDA — don't force it;
tags/body still make it findable by semantic search).
WHEN TO SAVE — this is the investor's knowledge base; CAPTURE substantive investment content generously
(reference/under | No | No | No | Not declared |
Details
- Registry status
- Active
- Published
- Nov 5, 2026
- Updated
- Nov 5, 2026
- Categories (suggested)
- Finance and paymentsSuggested categories are assigned automatically from the registry text and may be wrong. Verified operators can correct them.
- GDPR
- Not declared