Free demo of Fortunest: a sample multi-broker portfolio your AI can query. No account needed.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
DEMO portfolio (synthetic, shared, read-only). Read ONE dimension of the portfolio's allocation — where the money is, and how far that is from the user's saved targets — instead of the whole context. dimension: assetClass, sector, region, currency, cap, type, account (default assetClass; there is no separate broker dimension — an account label IS its broker). depth (1-30, default 10) keeps the largest segments and groups the rest into `other`; a segment already named 'Other' is the app's own fold of its smallest segments. withTargets (default true) adds targetPct and driftPct in percentage points wherever the user has saved a target, and raises a target nothing matched so a 0% holding against a target is never invisible; targets exist for assetClass and sector only. weightBasis says what weightPct is a percent OF: 'portfolio' for every breakdown dimension, and 'accounts' for dimension=account, where the weights are a percent of the accounts' combined value (totalValue) because an asset held in no account is outside that split. Every value is in the display currency. `pending` names holdings whose market data has not landed — they are in no segment, so the split is not final while it is there. Describes the portfolio; never investment advice.
Pick your client. Values in capitals, like YOUR_TOKEN, are yours to fill in.
Run in a terminal
claude mcp add --transport http portfolio-demo https://app.fortunest.ai/mcp/demo
DEMO portfolio (synthetic, shared, read-only). Read ONE dimension of the portfolio's allocation — where the money is, and how far that is from the user's saved targets — instead of the whole context. dimension: assetClass, sector, region, currency, cap, type, account (default assetClass; there is no separate broker dimension — an account label IS its broker). depth (1-30, default 10) keeps the largest segments and groups the rest into `other`; a segment already named 'Other' is the app's own fold of its smallest segments. withTargets (default true) adds targetPct and driftPct in percentage points wherever the user has saved a target, and raises a target nothing matched so a 0% holding against a target is never invisible; targets exist for assetClass and sector only. weightBasis says what weightPct is a percent OF: 'portfolio' for every breakdown dimension, and 'accounts' for dimension=account, where the weights are a percent of the accounts' combined value (totalValue) because an asset held in no account is outside that split. Every value is in the display currency. `pending` names holdings whose market data has not landed — they are in no segment, so the split is not final while it is there. Describes the portfolio; never investment advice.
| Argument | Type | Description |
|---|---|---|
| depth | integer | |
| dimension | any | |
| withTargets | boolean |
{
"type": "object",
"required": [],
"properties": {
"depth": {
"type": "integer",
"maximum": 30,
"minimum": 1
},
"dimension": {
"enum": [
"assetClass",
"sector",
"region",
"currency",
"cap",
"type",
"account"
]
},
"withTargets": {
"type": "boolean"
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). The Portfolio value chart's lines on up to 6 dates, from the series the chart draws: value, valueDate, change and returnPct since the chart start (from), ranking, highestBenchmark. date: YYYY-MM-DD or "today" (one or a list; omitted = today). lines: "Portfolio Total", an account, type:/sector:/category:<name>, or "inflation" (the inflation hurdle; adds real returns). from: YYYY-MM-DD, or "" for the first transaction. benchmarks: keys or custom benchmark names. In the in-app chat lines, benchmarks and from default to the chart on screen. A benchmark line is the same money flows invested in that benchmark instead: every day the portfolio bought or sold securities, the same amount buys or sells the benchmark at that day's price, and a later chart start opens it with the whole portfolio value bought on that day.
| Argument | Type | Description |
|---|---|---|
| date | any | |
| from | string | |
| lines | array | |
| benchmarks | array |
{
"type": "object",
"required": [],
"properties": {
"date": {
"anyOf": [
{
"type": "string",
"maxLength": 10,
"minLength": 1
},
{
"type": "array",
"items": {
"type": "string",
"maxLength": 10,
"minLength": 1
},
"maxItems": 6,
"minItems": 1
}
]
},
"from": {
"type": "string",
"maxLength": 10,
"minLength": 0
},
"lines": {
"type": "array",
"items": {
"type": "string",
"maxLength": 80,
"minLength": 1
},
"maxItems": 12,
"minItems": 0
},
"benchmarks": {
"type": "array",
"items": {
"anyOf": [
{
"enum": [
"sp500",
"world",
"nasdaq",
"bonds",
"gold",
"usd",
"btc"
]
},
{
"type": "string",
"maxLength": 60,
"minLength": 1
}
]
},
"maxItems": 7,
"minItems": 0
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read one to five exact section labels from the product docs index; missing sections are reported rather than fabricated.
| Argument | Type | Description |
|---|---|---|
| labels* | array |
{
"type": "object",
"required": [
"labels"
],
"properties": {
"labels": {
"type": "array",
"items": {
"type": "string",
"maxLength": 200,
"minLength": 1
},
"maxItems": 5,
"minItems": 1
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Search the actual product documentation and return bounded matched sections with source links.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| query* | string |
{
"type": "object",
"required": [
"query"
],
"properties": {
"limit": {
"type": "integer",
"maximum": 8,
"minimum": 1
},
"query": {
"type": "string",
"maxLength": 300,
"minLength": 1
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read the portfolio's forward calendar as a dated list instead of the whole context: earnings dates, ex-dividend and dividend-pay days for the holdings the Events card tracks, central-bank rate decisions and scheduled data releases for the portfolio's jurisdictions, and the tax-free lot maturities from the Taxes digest. kinds filters to any of: earnings, dividends, macro, maturities (default all). days is the window ahead (1-365, default 30, today counts as upcoming); symbols filters to those tickers; limit (1-50, default 20) and offset page the list, which is sorted by date and, on a shared date, by position size. byKind counts the whole window BEFORE the kinds filter, so one call shows what else is coming. servedFrom says where the answer came from: 'context' is the assistant's cached list (the nearest 20 events within 45 days), 'engine' means the events calendar itself was asked for the full window. THE EARNINGS CALENDAR: ask with kinds=['earnings'] alone and the answer is one row PER SYMBOL instead of one per date (bySymbol true) — symbol, name, scope, weightPct, nextEarnings (its next reporting day inside the window), lastReport {date, epsActual, epsEstimate, surprisePct, verdict} and filingUrl/filingSearchUrl when a filing is known, sorted soonest first with companies that have no date in the window last. scope picks whose: holdings (default), watchlist (the user's favourites, up to 20) or both. past is days BACK for recent reports (0-180, default 0). scope and past apply to that per-symbol answer only. This is the multi-symbol view market_lookup can only give one symbol at a time. Dates only — never a forecast of what will be reported, and never advice.
| Argument | Type | Description |
|---|---|---|
| days | integer | |
| past | integer | |
| kinds | array | |
| limit | integer | |
| scope | any | |
| offset | integer | |
| symbols | array |
{
"type": "object",
"required": [],
"properties": {
"days": {
"type": "integer",
"maximum": 365,
"minimum": 1
},
"past": {
"type": "integer",
"maximum": 180,
"minimum": 0
},
"kinds": {
"type": "array",
"items": {
"enum": [
"earnings",
"dividends",
"macro",
"maturities"
]
},
"maxItems": 4,
"minItems": 1
},
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1
},
"scope": {
"enum": [
"holdings",
"watchlist",
"both"
]
},
"offset": {
"type": "integer",
"maximum": 500,
"minimum": 0
},
"symbols": {
"type": "array",
"items": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"maxItems": 30,
"minItems": 1
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read the whole portfolio as one small digest (at most 16 000 characters, about 4 000 tokens) instead of the enormous get_context union: asOf, the value/cash/day-change/P-L totals with the per-account split, time-weighted and money-weighted performance, the six risk headlines (max drawdown, current drawdown, volatility p.a., Sharpe, Sortino, worst day), the ten largest holdings by weight with weight, value, day change and total gain, the asset-class and sector allocation with target drift where targets are set, the trade plan's buy/sell/net totals and order counts, the next five calendar events, the data-quality warning counts by kind, the strategy profile, the central-bank policy rates with the risk regime, the user's own trades of the context window (newest first), the subscription tier and its limits, and the user's saved memories and standing notes in full. include ⊆ [memories, notes] LISTS WHICH of the two optional blocks to keep — both when it is omitted, only the ones named when it is given, and neither for include: []. Every amount is in displayCurrency and every field ending in Pct is a percentage. Start here, then call a focused view for the detail; trimmed names any list that had to be shortened to fit.
| Argument | Type | Description |
|---|---|---|
| include | array |
{
"type": "object",
"required": [],
"properties": {
"include": {
"type": "array",
"items": {
"enum": [
"memories",
"notes",
"strategy",
"macro",
"recentTrades"
]
},
"maxItems": 5,
"minItems": 0
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read the Trade plan card: suggested orders, their company ratings and decision reasons, buy/sell/net/leftover amounts, constraints and sellLotCoverage. Each order's amountEur is the card's Amount, sharePct its Share (percent of that side's budget), rating its Rating (0-100, 50 neutral, null for funds/crypto) and, on sells, taxFreeValueEur/nextMaturity its Tax-free now column; the card's Run historical backtest button opens the historical simulation the backtest_trades tool runs. tradePlanning carries saved controls; planning describes the result. Invest is new money; sales are independent and their proceeds stay cash. Every amount uses displayCurrency; the Eur suffix is legacy. Each '…Eur' field now also ships under its currency-neutral name (amountEur→amount, buyEur→buy, valueEur→value, totalEur→totalAmount); the '…Eur' twins are DEPRECATED and will be removed — read the neutral name. include:['candidates'] adds ranked candidates with inclusion, exclusion or cap reasons; ['taxOrientation'] adds tax lots. Funds/crypto have no company rating. No orders are placed. Default notes are brief; docs carries docs_lookup labels for the simplified planner, verbose:true includes full notes. unavailableReason explains a missing plan. symbols {buys, sells} lists the plan's tickers, ready to pass as `symbols` to holding, market_lookup, price_on or trade_candidates in ONE call. Each sell order carries taxFreeValueEur/taxFreeQty (the whole position's tax-free capacity today) beside taxFreeEur (the exempt slice of that one order), and nextMaturity {date, qty, valueEur} — the earliest still-future time-test date for that holding, what to report when taxFreeValueEur is 0 ('nothing is tax-free today; the next lot matures on …'); null where no open lot has a maturity date at all. The same orders and contextRevision are in get_context portfolio.tradePlan.
| Argument | Type | Description |
|---|---|---|
| include | array | |
| verbose | boolean |
{
"type": "object",
"required": [],
"properties": {
"include": {
"type": "array",
"items": {
"enum": [
"candidates",
"bothSides",
"taxOrientation"
]
},
"maxItems": 3,
"minItems": 1
},
"verbose": {
"type": "boolean"
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read ONE position in depth — the asset drawer, as data. Give symbol, or symbols for SEVERAL positions in one call (up to 25; the two are mutually exclusive and one of them is required). A batch answers {batch: true, symbols, results keyed by ticker, missing, truncated} — never call this once per ticker when you already know the list. The symbol may be held or merely on the watchlist. include picks the blocks: fundamentals (valuation, growth, fair value, analyst view), lots (open and tax-free quantity, next maturity), news (the cached recent headlines), insider (the 3-month Form 4 digest), events (its upcoming earnings/dividend dates), correlations (which holdings it moves with), warnings (the data-quality sentences naming it) and priceHistory, whose window is the separate range argument (1m, 3m, 6m, 1y, ytd, max — default 3m) and which comes back downsampled to at most 120 points, and description (the drawer's two-sentence profile of what the company does, where it is headquartered and where it operates, with its provenance: yahoo for the market-data feed, ai when a fast AI model wrote it — the app's own, or this user's own provider — facts when the app composed it from the listing's own data), and checks (strengths & things to watch, as sourced facts). With no include the position line alone comes back. A position under 0.1% of the portfolio answers grouped=true: held, with its position line (value, weight) when the summary has it, and no lot data. Blocks that did not fit the result budget are listed in dropped (ask for them singly), and an unknown symbol answers ok=false with the closest symbols the user actually holds or watches, never an invented position.
| Argument | Type | Description |
|---|---|---|
| range | any | |
| symbol | string | |
| include | array | |
| symbols | array | Several tickers in ONE call — up to 25. Send this instead of calling once per ticker; `symbol` and `symbols` are mutually exclusive. The answer is keyed by symbol under `results`, with `missing` naming the ones that had no data. |
{
"type": "object",
"required": [],
"properties": {
"range": {
"enum": [
"1m",
"3m",
"6m",
"1y",
"ytd",
"max"
]
},
"symbol": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"include": {
"type": "array",
"items": {
"enum": [
"fundamentals",
"lots",
"news",
"insider",
"events",
"correlations",
"warnings",
"priceHistory",
"description",
"checks"
]
},
"maxItems": 8,
"minItems": 0
},
"symbols": {
"type": "array",
"items": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"maxItems": 25,
"minItems": 1,
"description": "Several tickers in ONE call — up to 25. Send this instead of calling once per ticker; `symbol` and `symbols` are mutually exclusive. The answer is keyed by symbol under `results`, with `missing` naming the ones that had no data."
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read the holdings table — the positions themselves — instead of the whole context. sort: weight (default), value, dayChange (today's money move), dayChangePct (today's move in percent), gainPct, gainAbs, loss (biggest losses first), name, symbol; order desc|asc overrides the sensible default for the key. limit is 1-50 (default 10) with offset/nextOffset paging. filter narrows by account label, assetClass (Equities, Bonds, Gold & commodities, Real estate, Crypto, Cash, Other), category, sector, region, currency, an explicit symbols list and minWeight (a PERCENT, so 5 means 5%). fields picks the row width: core (symbol, name, weightPct, value, dayChangePct, dayChangeAbs, totalGainPct, totalGainAbs, quantity, assetClass, sector, category, accounts), fundamentals (adds valuation, growth, fair value, analyst view), lots (adds open quantity, tax-free quantity and the next maturity) or all. Every field ending in Pct is a PERCENT (4.32 = 4.32%). total counts the filtered list, not the page. Positions under 0.1% of the portfolio have no row: smallHoldingsGrouped gives their count, value and combined weight; a filter by symbols, assetClass, category or sector also names the matching ones, with their category, under notListed — held, but without a row. 'Top 5 holdings' is one call: sort=weight, limit=5.
| Argument | Type | Description |
|---|---|---|
| sort | any | |
| limit | integer | |
| order | any | |
| fields | any | |
| filter | object | |
| offset | integer |
{
"type": "object",
"required": [],
"properties": {
"sort": {
"enum": [
"weight",
"value",
"dayChange",
"dayChangePct",
"gainPct",
"gainAbs",
"loss",
"name",
"symbol"
]
},
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1
},
"order": {
"enum": [
"desc",
"asc"
]
},
"fields": {
"enum": [
"core",
"fundamentals",
"lots",
"all"
]
},
"filter": {
"type": "object",
"required": [],
"properties": {
"region": {
"type": "string",
"maxLength": 80,
"minLength": 1
},
"sector": {
"type": "string",
"maxLength": 80,
"minLength": 1
},
"account": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"symbols": {
"type": "array",
"items": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"maxItems": 60,
"minItems": 0
},
"category": {
"type": "string",
"maxLength": 48,
"minLength": 1
},
"currency": {
"type": "string",
"maxLength": 12,
"minLength": 1
},
"minWeight": {
"type": "number",
"maximum": 100,
"minimum": 0
},
"assetClass": {
"enum": [
"Equities",
"Bonds",
"Gold & commodities",
"Real estate",
"Crypto",
"Cash",
"Other"
]
}
},
"additionalProperties": false
},
"offset": {
"type": "integer",
"maximum": 1000,
"minimum": 0
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read the Trades tab's Money flow card: the cash spent on purchases and raised by sales per week, month or year, from the same rows as the Recent trades card. period is 'week' (ISO weeks, Monday start), 'month' (calendar months, the default) or 'year' (calendar years, the current one to date); count is how many periods back, up to and including the current one (1-260; default 26 weeks, 24 months or 10 years, the card's own). Each item is one period, newest first: start (the period's first day), purchases (the card's Purchases bar) and sales (its Sales bar) — the display-currency cash at each trade's own date, fees included where the broker reports them — net = sales − purchases (the Net line: positive when the period sold more than it bought), buys, sells and trades (execution counts) and unpriced (trades with no derivable amount: counted, never summed). A period without trades is zeros, not a gap. totals sums the whole window; limit/offset page the periods (nextOffset). Transfers, corrections, staking credits, in-kind fees and corporate actions are not trades and never counted.
| Argument | Type | Description |
|---|---|---|
| count | integer | |
| limit | integer | |
| offset | integer | |
| period | any |
{
"type": "object",
"required": [],
"properties": {
"count": {
"type": "integer",
"maximum": 260,
"minimum": 1
},
"limit": {
"type": "integer",
"maximum": 260,
"minimum": 1
},
"offset": {
"type": "integer",
"maximum": 260,
"minimum": 0
},
"period": {
"enum": [
"week",
"month",
"year"
]
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read the user's OWN executed buys and sells — trade history, never recommendations; the rows of the Trades tab's Recent trades card. since is a number of days back (1-3650, default 90); symbol and side (buy or sell) filter; limit is 1-100 (default 20) with offset/nextOffset, newest first. Each item carries date, side, symbol, name, qty, the account it was filed from and amountEur — the trade's cash value in the display currency at its own trade date, fees included where the broker reports them; a row with no derivable display-currency amount carries nativeAmount plus nativeCurrency (price×qty in the trade's own currency) instead. Transfers between the user's own accounts, ledger corrections, staking credits, in-kind fees and corporate actions are not trades and are never listed — the same rows as the Trades tab's Recent trades card. servedFrom says whether the rows came from the chat context's own trade window ('context') or from the full history ('engine'), and window says which stretch was actually read. detail=true reads the card's own table instead (servedFrom 'engine') and adds its other columns to every row: price (the execution price, in priceCurrency, the trade's own currency), fee (the broker-reported fee in the display currency, only when there was one) and changePct (the Since trade column: how the asset's price moved from this execution to today in its own listing currency, split-adjusted, as a FRACTION — 0.25 = +25%; on a sale, what the sold units did since; absent without a current price), plus cardTotal, the count of every trade the card lists (its 'N of M'). The card's sort and filters imply detail: sort (a column; change = Since trade) with order, query (name/ticker terms), type (asset type, e.g. 'ETF funds') and from/to (ISO days; either replaces since). Each '…Eur' field now also ships under its currency-neutral name (amountEur→amount, buyEur→buy, valueEur→value, totalEur→totalAmount); the '…Eur' twins are DEPRECATED and will be removed — read the neutral name.
| Argument | Type | Description |
|---|---|---|
| to | string | |
| from | string | |
| side | any | |
| sort | any | |
| type | string | |
| limit | integer | |
| order | any | |
| query | string | |
| since | integer | |
| detail | boolean | |
| offset | integer | |
| symbol | string |
{
"type": "object",
"required": [],
"properties": {
"to": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"maxLength": 10,
"minLength": 1
},
"from": {
"type": "string",
"pattern": "^\\d{4}-\\d{2}-\\d{2}$",
"maxLength": 10,
"minLength": 1
},
"side": {
"enum": [
"buy",
"sell"
]
},
"sort": {
"enum": [
"date",
"asset",
"side",
"price",
"change",
"qty",
"amount",
"fee",
"account"
]
},
"type": {
"type": "string",
"maxLength": 40,
"minLength": 1
},
"limit": {
"type": "integer",
"maximum": 100,
"minimum": 1
},
"order": {
"enum": [
"desc",
"asc"
]
},
"query": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"since": {
"type": "integer",
"maximum": 3650,
"minimum": 1
},
"detail": {
"type": "boolean"
},
"offset": {
"type": "integer",
"maximum": 5000,
"minimum": 0
},
"symbol": {
"type": "string",
"maxLength": 120,
"minLength": 1
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read the portfolio's risk picture in selectable pieces instead of the whole context. include (default ['metrics']) ⊆ metrics, drawdown, correlations, diversification, benchmarks, fxAttribution, fingerprint. metrics = volatility, Sharpe, Sortino, max and current drawdown, best and worst day, plus the note on what the per-holding risk figures mean. drawdown = the max drawdown's peak, trough, recovery and length, and the current one. correlations = the strongest pairs, strongest absolute correlation first, with the effective number of independent bets. diversification = the 0-100 score, its grade, the sub-scores and the card's own takeaways. benchmarks = one row per selected benchmark with its own return and the portfolio's beta and correlation to it. fxAttribution = how much of the return came from the currencies rather than from the assets. fingerprint = the Portfolio Fingerprint card: six axes (value, growth, past, health, income, diversification) scored 0-6 by fixed pass/fail checks, each with its measured value, threshold and coverage, plus the card's one-line verdict. range (all | 1y, default all) applies to the ratio metrics only — 1y gives the trailing-year volatility, Sharpe and Sortino plus the rolling 12-month envelope, while drawdowns, correlations and diversification are always whole-history. UNITS: volatility, maxDrawdown, currentDrawdown, correlation and the daily returns bestDay.ret and worstDay.ret are FRACTIONS (0.18 = 18%); a field ending in Pct is a percent. Statistics of the user's own history; never investment advice.
| Argument | Type | Description |
|---|---|---|
| range | any | |
| include | array |
{
"type": "object",
"required": [],
"properties": {
"range": {
"enum": [
"all",
"1y"
]
},
"include": {
"type": "array",
"items": {
"enum": [
"metrics",
"drawdown",
"correlations",
"diversification",
"benchmarks",
"fxAttribution",
"fingerprint"
]
},
"maxItems": 7,
"minItems": 0
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read what the app knows about the user's SIMULATIONS — the Simulator tab's future projection, the goal seek, the what-if and the historical trade replay — without running any of them. It never starts a simulation and never starts a job. include (default ['summary']) ⊆ summary, whatif, dcaGoal, backtest. IMPORTANT: the future projection, the DCA goal and the what-if are computed on demand in the app and stored NOWHERE on the server — the only copy of what the user ran is the live-UI line 'last simulation — …' in the current turn's context; each block says resultsStoredOnServer: false and serves the INPUTS instead, so an absent result is never read as a zero. summary = what the portfolio is worth now plus the actual return, volatility and strategy horizon a projected line has to be judged against (whole-history figures; the simulator averages over its own lookback window). whatif = the `before` side a what-if is measured from (value, cash, diversification, portfolio fundamentals) and the verb that computes the `after`. dcaGoal = the goal seek's inputs, including the saved Trades-tab budget, which is NOT a recurring contribution. backtest = the historical trade replay, which IS kept server-side for an hour from when it was STARTED (the prune clock runs from the job's creation, not from its completion): state, progress and, once complete, its summary, window, coverage gaps and warnings; backtestId picks one, the default is the newest, and the per-day series, trades, decisions and assumptions are get_workload's answer, not this one's. Amounts are in the display currency; a field ending in Pct is a percent. Describes the user's own simulations; never investment advice.
| Argument | Type | Description |
|---|---|---|
| include | array | |
| backtestId | string |
{
"type": "object",
"required": [],
"properties": {
"include": {
"type": "array",
"items": {
"enum": [
"summary",
"whatif",
"dcaGoal",
"backtest"
]
},
"maxItems": 4,
"minItems": 0
},
"backtestId": {
"type": "string",
"maxLength": 64,
"minLength": 1
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read actual tax-lot summary and optionally one symbol. Illustrative orientation only; do not estimate missing tax figures.
| Argument | Type | Description |
|---|---|---|
| symbol | string |
{
"type": "object",
"required": [],
"properties": {
"symbol": {
"type": "string",
"maxLength": 120,
"minLength": 1
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read one slice of the illustrative tax-lot orientation (the Taxes tab) instead of the whole context. view is required: 'maturities' = the open lots whose time test is coming up, soonest first (date; daysToExempt = days left until that date, the Taxes tab's 'N days to go'; symbol, qty, valueEur); 'openLots' = the per-asset lot lines, largest position first (openQty, taxFreeQty, taxFreeValueEur, nextMaturity, warnings); 'annual' = the realized-gains table per year, newest year first (proceedsEur = gross, feesEur = broker fees deducted, timeExemptGainEur, capTaxableGainEur = the part of time-test gains the exempt-proceeds cap taxed, netTaxableGainEur, estimatedTaxEur); 'ytd' = this year's proceeds against the limit, the exempt-proceeds cap (exemptGainsCap: time-test-exempt proceeds, scope 'crypto' from 2026), what is already sellable tax-free and the next maturity. symbol (one ticker) or symbols (several, in one call) filter maturities and openLots; year filters annual; limit is 1-50 (default 10) with offset/nextOffset. Every answer carries activeRules. Approximate orientation only — not tax advice and never input for a tax report. Each '…Eur' field now also ships under its currency-neutral name (amountEur→amount, buyEur→buy, valueEur→value, totalEur→totalAmount); the '…Eur' twins are DEPRECATED and will be removed — read the neutral name.
| Argument | Type | Description |
|---|---|---|
| view* | any | |
| year | integer | |
| limit | integer | |
| offset | integer | |
| symbol | string | |
| symbols | array | Narrow to SEVERAL tickers in one call — the batch form of symbol, up to 25. The two are mutually exclusive. |
{
"type": "object",
"required": [
"view"
],
"properties": {
"view": {
"enum": [
"maturities",
"openLots",
"annual",
"ytd"
]
},
"year": {
"type": "integer",
"maximum": 2100,
"minimum": 1900
},
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1
},
"offset": {
"type": "integer",
"maximum": 500,
"minimum": 0
},
"symbol": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"symbols": {
"type": "array",
"items": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"maxItems": 25,
"minItems": 1,
"description": "Narrow to SEVERAL tickers in one call — the batch form of symbol, up to 25. The two are mutually exclusive."
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read buy or sell candidates. side is required (buy or sell). Each row carries one company rating (0-100, 50 neutral), its reasons, the plan decision (included/excluded/capped with reasons and amount), input coverage, and ownedEur (null when not held). A candidate the lot engine has lots for (every sell candidate, and a buy candidate that is already held) also carries taxFreeValueEur and taxFreeQty — how much of the position has already passed the holding-period test, in the display currency and in units — and nextMaturity {date, qty, valueEur}, the earliest still-future time-test date for that holding: with taxFreeValueEur 0 it is what to say instead of 'nothing', and it is absent where no open lot has a maturity date (no time test applies). All three are absent where there are no tracked lots. Funds/crypto have rating null. Legacy score is action strength, not the company rating. criteriaWeights gives the saved weights; buyCandidateSource names the buy list — side=buy holds exactly that universe (owned, starred, or both, per Settings > Trades), so a symbol outside it is not scored and has no row; side=sell is always the holdings. symbol (one ticker), symbols (SEVERAL tickers in one call — never ask once per ticker), driver and owned narrow the list. fields attaches extra fundamentals to EVERY row under fundamentals — forwardPE, peg, marketCap, fcfYield, analystUpside, fairValue and the rest — so 'forward P/E and PEG for the recommended buys' is ONE call, not one per candidate. limit is 1-25 (default 10) with offset/nextOffset. why=true is the answer to 'why is WDC scored 72': every item then also carries why, the per-criterion breakdown the Trades tab's score expander shows — criterion, label, raw (in unit), weight, the 0-100 score, contribution (its points: the contributions add up to the rating) and one sentence from the engine, plus stage — the earnings stage that splits Quality and Valuation between their profit rows and growth readings. One the data could not support has score null and applied false — it drops out and the remaining weights renormalize rather than counting as zero. why is expensive, so pass symbol (or a small limit) with it: at most 3 breakdowns come back per call. These are CANDIDATES, not orders: what to actually buy and sell, with amounts, is get_trade_plan. Each '…Eur' field now also ships under its currency-neutral name (amountEur→amount, buyEur→buy, valueEur→value, totalEur→totalAmount); the '…Eur' twins are DEPRECATED and will be removed — read the neutral name.
| Argument | Type | Description |
|---|---|---|
| why | boolean | |
| side* | any | |
| limit | integer | |
| owned | boolean | |
| driver | any | |
| fields | array | Extra fundamentals to attach to EVERY candidate in the answer, under `fundamentals`: name, sector, industry, price, marketCap, forwardPE, trailingPE, peg, fcfYield, earningsGrowth, revenueGrowth, returnOnEquity, profitMargins, dividendYield, targetMeanPrice, analystUpside, shortPercentOfFloat, fairValue, fairValueUpsidePct. |
| offset | integer | |
| symbol | string | |
| symbols | array | Narrow to SEVERAL tickers in one call — the batch form of symbol, up to 25. The two are mutually exclusive. |
{
"type": "object",
"required": [
"side"
],
"properties": {
"why": {
"type": "boolean"
},
"side": {
"enum": [
"buy",
"sell"
]
},
"limit": {
"type": "integer",
"maximum": 25,
"minimum": 1
},
"owned": {
"type": "boolean"
},
"driver": {
"enum": [
"group_consensus",
"valuation",
"fairValue",
"analystUpside",
"momentum",
"drawdown",
"quality",
"dividend",
"quality_growth",
"valuation_sales"
]
},
"fields": {
"type": "array",
"items": {
"enum": [
"name",
"sector",
"industry",
"price",
"marketCap",
"forwardPE",
"trailingPE",
"peg",
"fcfYield",
"earningsGrowth",
"revenueGrowth",
"returnOnEquity",
"profitMargins",
"dividendYield",
"targetMeanPrice",
"analystUpside",
"shortPercentOfFloat",
"fairValue",
"fairValueUpsidePct"
]
},
"maxItems": 19,
"minItems": 1,
"description": "Extra fundamentals to attach to EVERY candidate in the answer, under `fundamentals`: name, sector, industry, price, marketCap, forwardPE, trailingPE, peg, fcfYield, earningsGrowth, revenueGrowth, returnOnEquity, profitMargins, dividendYield, targetMeanPrice, analystUpside, shortPercentOfFloat, fairValue, fairValueUpsidePct."
},
"offset": {
"type": "integer",
"maximum": 500,
"minimum": 0
},
"symbol": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"symbols": {
"type": "array",
"items": {
"type": "string",
"maxLength": 120,
"minLength": 1
},
"maxItems": 25,
"minItems": 1,
"description": "Narrow to SEVERAL tickers in one call — the batch form of symbol, up to 25. The two are mutually exclusive."
}
},
"additionalProperties": false
}DEMO portfolio (synthetic, shared, read-only). Read the portfolio's data-quality warnings — what the import could not read, what it assumed, and what could not be priced — instead of the whole context. Each item carries the engine's own sentence verbatim plus its kind, the `account` that raised it and the symbols it names. kind filters to one of: parse, unpriced, fx, delisted, openingCash, shortCredit, openingBalance, writeOff, skippedRows, exportWindow, missingHistory, other. symbol filters to the warnings naming that holding. byKind counts the FULL list, not the filtered page, so one call shows what else exists. Paginate with limit/offset and nextOffset. These are import and valuation caveats, never investment advice.
| Argument | Type | Description |
|---|---|---|
| kind | any | |
| limit | integer | |
| offset | integer | |
| symbol | string |
{
"type": "object",
"required": [],
"properties": {
"kind": {
"enum": [
"parse",
"unpriced",
"fx",
"delisted",
"openingCash",
"shortCredit",
"openingBalance",
"writeOff",
"skippedRows",
"exportWindow",
"missingHistory",
"other"
]
},
"limit": {
"type": "integer",
"maximum": 50,
"minimum": 1
},
"offset": {
"type": "integer",
"maximum": 500,
"minimum": 0
},
"symbol": {
"type": "string",
"maxLength": 120,
"minLength": 1
}
},
"additionalProperties": false
}We read every tool's name, description and inputs the way the model will, looking for instructions hidden from you. A clean result means no warning signs, not a guarantee. Scanned Nov 10, 2026.