Skip to main content
Glama

Bullrun: Global Stock & UCITS ETF Research

An MCP server for researching stocks and ETFs beyond the US. Find global stock candidates, compare UCITS ETF costs and overlap, and inspect company risks from your MCP client. Every figure shows its date, reporting period and native currency, and missing data is reported as unknown. Public research needs no API key or Bullrun account. Connect your free Bullrun account when you want to save research, read your portfolios or create a reviewable paper-portfolio draft.

Free: 700 successful MCP tool calls per rolling 30 days. Pro and active trials: 1,000 successful tool calls per rolling 5 hours. Bullrun Pro costs CHF 5/month or CHF 50/year. See plans and subscription details, then connect the account endpoint through OAuth to use your Pro allowance. Website screening and manual research have separate allowances.

Bullrun MCP server Bullrun Research MCP server

Public research

https://mcp.bull-run.org/mcp (Streamable HTTP)

Personal research and portfolios

https://mcp.bull-run.org/account/mcp (OAuth)

Research tools only, no sign-in

https://mcp.bull-run.org/research/mcp (the 39 research tools, no account tools or prompts)

Web app

bull-run.org

Registry

org.bull-run/bullrun

Glama

Server · Connector

mcprush

Bullrun MCP · Bullrun Research (research tools only, with quotas per installation)

Privacy

Privacy policy

Connect

Add the hosted endpoint as a remote MCP server in your client. Public market research is anonymous. To save a research shortlist or work with your portfolios, add the account endpoint above and authorize the requested OAuth scopes. These features, including AI-generated drafts, are available to signed-in free accounts. Free use includes 700 successful MCP tool calls per rolling 30 days, per free account or anonymous network, shared across the official public, research and OAuth endpoints. Connected Pro and active-trial accounts get 1,000 successful tool calls per rolling 5 hours. Each successful call counts once, regardless of how much data it loads; failed calls use no allowance. Allowances refill automatically as earlier calls leave the rolling window. Temporary capacity limits and tool pacing may ask you to wait; follow the reply's retry guidance. Website and marketplace allowances are unchanged. Your shortlist persists in Research Shortlist, and paper drafts remain pending until you review and accept them. Saving never enables monitoring or email.

{
  "mcpServers": {
    "bullrun": { "url": "https://mcp.bull-run.org/mcp" }
  }
}

Configuration formats vary by client. See the connection guide.

Related MCP server: Yahoo Finance MCP Server

Start with a research question

  • “Find Nestlé's stock listing and show the available company data.”

  • “List your preset stock screens, then find European companies with positive earnings and free cash flow.”

  • “Show six months of Apple's daily prices, RSI and moving averages.”

  • “Find peers for Microsoft and compare their fundamentals.”

  • “Show recent company news for NVIDIA, with publication dates and freshness.”

  • “Which UCITS funds track the S&P 500 at the lowest ongoing cost?”

  • “Compare the underlying overlap of these two ETFs.”

  • “Which companies share suppliers or customers with Apple?”

Use the prompt menu for find_ml_candidates (compare model candidates with business fundamentals), compare_ucits_costs (fund-level cost comparison) and research_shortlist_briefing (review your saved queue). These workflows retrieve research; saving requires your instruction.

Tools

Version 0.8.1 exposes 48 focused tools in both hosted and local builds (39 research tools on the marketplace connection). The exact tools and parameters are available through MCP tools/list.

Workflow

Tools

Find stocks and screen

search_stocks, screen_stocks, find_stock_peers

Prices and news

get_stock_price_history, get_company_news, get_stock_metrics

Fundamentals

compare_stocks, get_financial_history, get_quality_moat_metrics, get_revenue_breakdown

Coverage and optional datasets

get_company_data_coverage, get_forward_estimates, get_operating_kpis, get_earnings_call_transcript

Company risk and dependencies

get_company_risk, get_company_relationships, compare_company_exposures, get_company_risk_history, screen_risk_board, get_risk_movers

Corporate calendar

get_corporate_calendar

ETF discovery

search_etfs, screen_etfs, get_etf_filter_options, get_etf_index_group, get_etf_fund

ETF research

get_etf_snapshot, get_etf_holdings, get_etf_timeseries, get_etf_exposures, get_etf_risk, compare_etfs, simulate_etf_cost

Macro

get_global_markets_overview, get_country_macro, get_macro_indicators, get_macro_history

Bullrun valuation models

get_valuation_model, screen_valuation_model

Research Shortlist (sign-in)

save_research_shortlist, list_research_shortlist

Personal portfolios (sign-in)

list_portfolios, get_portfolio_context, get_portfolio_analytics, get_capabilities

Reviewable paper drafts (sign-in)

create_portfolio_from_positions, create_portfolio_draft, create_position_draft

The consolidated tools preserve existing defaults and fetch extra analysis only when requested:

  • screen_stocks({action: "list_presets"}) lists transparent rules without running a screen. Pass a preset such as profitable_value to run it, or supply custom rules; do not combine preset and custom rule inputs.

  • compare_etfs({tickers: [...], include: ["overlap"]}) returns pairwise shared holdings, weighted overlap, snapshot dates and partial-coverage warnings. Other comparison modules can be requested alongside overlap.

  • get_portfolio_analytics({portfolioId, candidateTicker, includeLookThrough: true}) adds ETF/direct-holding duplicate exposure. It requires portfolio access and retains the selected privacyMode; ordinary analytics does not fetch holdings look-through.

Migrating older clients

The four retired names remain available in the opt-in compatibility catalog at https://mcp.bull-run.org/legacy/mcp. OAuth clients that need a login challenge can use https://mcp.bull-run.org/account/legacy/mcp. Both retain the existing authentication rules. The modern endpoints omit these aliases:

Legacy name

Modern call

screen_stock_presets

screen_stocks with action: "list_presets" or a named preset

analyze_etf_overlap

compare_etfs with include: ["overlap"]

analyze_portfolio_fit

get_portfolio_analytics with candidateTicker and includeLookThrough: true

query_etfs

search_etfs, get_etf_snapshot, get_etf_holdings, and get_etf_timeseries, according to the requested operation

Reconnect after changing endpoints; modern and compatibility sessions cannot be shared. For local compatibility, run node dist/stdio.js --legacy-tools. Legacy responses retain their existing fields and units, including raw fractional ratios in query_etfs; modern ETF ratios use percentage points.

Read the returned coverage and dates. Stored prices are daily observations, not live stock quotes. Technical indicators and price returns use stored closes; an adjusted total-return series is not implied. Weekly/monthly bars are aggregated from daily data. News reads return cached articles and, except on the research endpoint, can request a bounded background refresh; an empty result is not proof that no news exists.

Consensus estimates use available Yahoo revenue/EPS targets and EPS revisions; EBITDA, management guidance and revenue revisions are not supplied by this feed. Estimate reads can queue a free consensus refresh, and US transcript reads a bounded import of the latest two calls from the existing free DefeatBeta source; the first cached response may be empty while that runs. The research endpoint (/research/mcp) queues nothing: its news, estimate and transcript reads return stored rows only, so every tool there is read-only. Non-US transcript coverage is not configured. Operating KPI observations remain limited to stored rows, with no broad KPI ingestion pipeline. Use get_company_data_coverage before relying on an optional dataset. Missing data is unknown. A risk band describes measured strain, and a model valuation gap describes relative pricing; neither is a price target or buy/sell recommendation.

The same UCITS fund can trade on several venues under different symbols. Resolve ISINs with get_etf_fund and treat those listings as one holding when evaluating overlap.

Shortlist access uses read:shortlist and write:shortlist. Reconnect the account endpoint to grant these scopes if you connected an older version. save_research_shortlist takes 1-20 exact stock or ETF listing tickers; confirmed saves and individual failures are returned separately.

Successful answers offer an optional contextual link to Bullrun's charts, screens, company networks or saved draft. Link descriptions identify settings that the app cannot reproduce. Opening a draft link never accepts it or changes holdings.

Local stdio build

The remote endpoint is the simplest connection. To build the connector for local clients or directory inspection:

npm ci
npm run build
node dist/stdio.js

The stdio build reads public data from https://bull-run.org by default. Set BULLRUN_API_BASE to use another Bullrun API deployment. Anonymous stdio clients cannot read personal portfolios or create drafts.

Release verification

npm test
npm run test:catalog

The public repository contains the MCP connector, not the application database or data services. The connector source, version and catalog are synchronized from the application repository's release process. MIT license.

Available Tools

48 tools
compare_company_exposuresCompare shared company exposuresA
Read-only
Inspect

Compare the cached company relationship graphs of two to five stock tickers. Finds shared suppliers, customers, competitors and partners, including cross-role overlaps, using stable company entity IDs or exact tickers only. Returns directed direct relationships with VERIFIED vs SUGGESTED/NEEDS_REVIEW status, confidence, sole-source flags, disclosed metrics with meaning/unit/period, and primary-source URLs/dates. Shared groups reference the evidence-bearing relationship rows by ID. Missing graphs or edges mean unknown coverage. One cached graph read per company (plus a ticker lookup when the typed ticker has no graph); never starts paid discovery, infers exposure weights or estimates portfolio losses. Read-only.

NameRequiredDescriptionDefault
rolesNoCounterparty roles from EACH subject company's point of view; default all four. Suppliers and customers preserve the direction of SUPPLIES_TO.
tickersYesTwo to five distinct Bullrun listing tickers, e.g. AAPL, BMW or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN. Company names are not accepted here.
verifiedOnlyNoOnly VERIFIED edges when true. The default also includes SUGGESTED/NEEDS_REVIEW edges, explicitly labelled with their individual confidence and evidence.
limitPerCompanyNoMaximum direct relationships returned per input company. Shared counterparties are prioritized; totals and any truncation are reported.

Output Schema

NameRequiredDescription
totalsYes
tickersYes
webPageNo
warningsYes
companiesYes
methodologyYes
retrievedAtYes
platformLinkNo
relationshipsYes
requestedRolesYes
sharedCounterpartiesYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the read-only annotations: discloses the result taxonomy (VERIFIED vs SUGGESTED/NEEDS_REVIEW with confidence and evidence), sole-source flags, metric meaning/unit/period, source URLs/dates, and that shared groups reference relationship rows by ID. It also warns that missing graphs or edges mean unknown coverage rather than no relationship, and disclaims what it does not do (no discovery cost, no inferred weights or loss estimates).

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose and scope are front-loaded, and the 'one cached graph read / never starts paid discovery' sentence carries high-value cost information. The returns sentence is long and partially duplicates the output schema, but nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Complete and then some: an output schema exists, yet the description still characterizes result semantics (statuses, evidence links, truncation) which helps interpretation. The only gap is the 'entity IDs or exact tickers' wording that is not backed by any input parameter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents tickers, roles, verifiedOnly and limitPerCompany; the description adds little parameter-specific detail. It also says inputs may be 'stable company entity IDs or exact tickers only', which conflicts with the schema whose only input array is ticker strings and which states company names are not accepted — a mild ambiguity an agent must resolve from the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Compare the cached company relationship graphs of two to five stock tickers') and enumerates what is compared (suppliers, customers, competitors, partners, including cross-role overlaps). This is clearly distinguishable from the single-company sibling get_company_relationships.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives real operating context: cached reads only, one graph read per company plus a ticker lookup, never starts paid discovery, and points to search_stocks when a ticker is unknown. It does not explicitly say when to prefer this over get_company_relationships or compare_stocks, so the exclusion guidance is implicit rather than stated.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_etfsCompare ETFsA
Read-only
Inspect

Return a normalized side-by-side comparison of two to ten ETFs across selected classification, market, fund-data, cost, income, benchmark, price-performance, price-risk, holdings, and optional overlap modules. Include overlap to measure pairwise shared securities and weighted overlap from latest stored holdings, matched by security identity rather than ticker alone; cash, currency and derivatives are excluded. Missing holdings make overlap unavailable, while partial holdings make it a lower bound. Only requested modules run; overlap alone fetches no price history. Leaders are mechanical extrema, not recommendations. Currency, holdings dates and coverage caveats are explicit. Read-only.

NameRequiredDescriptionDefault
includeNoSelected comparison modules. overlap is opt-in and returns pairwise shared holdings and weighted overlap from each fund's latest stored snapshot.
tickersYesTwo to ten exact Bullrun ETF listing tickers.
topSharedLimitNoMaximum shared holdings per ETF pair when overlap is requested; does not limit the snapshots used in overlap calculations.
performanceDaysNoWindow in calendar days back from each fund's newest close; the start is the last close on or before that day. 365 matches the fund page and the screener's 1-year return.

Output Schema

NameRequiredDescription
rowsYes
leadersYes
overlapNo
tickersYes
webPageNo
coverageYes
warningsYes
platformLinkNo
requestedModulesYes

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/closed annotations, it discloses real behavior: overlap requires stored holdings, missing holdings make overlap unavailable, partial holdings make it a lower bound, overlap alone triggers no price history, and leaders are mechanical extrema rather than recommendations. Currency, holdings-date and coverage caveats being explicit sets expectations for the output.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action, then layers on module selection and overlap edge cases; every sentence carries information. It is dense and long for a description, with the caveat sentences packable into one, which keeps it just under top marks.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Output schema covers return shape and annotations cover the safety profile, so the description's remaining burden is scope and edge-case behavior — both handled thoroughly via module opt-in, overlap availability bounds, and explicit caveats about currency and holdings dates.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already carries tickers, include enum, topSharedLimit and performanceDays semantics. The description reinforces the opt-in nature of the overlap module but adds no format or constraint detail beyond the schema, so baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (side-by-side comparison), resource (ETFs), cardinality (two to ten), and scope (named modules). The resource naming also disambiguates it from compare_stocks without needing to reference the sibling explicitly.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

"Only requested modules run" and "overlap is opt-in" give clear guidance on how and when to use the costly modules, and the caveat about overlap alone fetching no price history tells an agent what not to expect. It never explicitly routes to alternatives (e.g., get_etf_snapshot for a single fund), so it stops short of a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

compare_stocksCompare stocksA
Read-only
Inspect

Compare two to five stock tickers in one compact structured response: annual fundamentals and growth, quality ratios, stored valuation and Bullrun model context, and measured risk dials. Reports each fiscal year, source date, native quote/reporting currency and missing coverage. No currency conversion, quarterly-to-annual substitution, buy/sell ranking or generated research. Read-only.

NameRequiredDescriptionDefault
includeNoSelected compact modules. Fundamentals and quality use the latest usable ANNUAL fiscal year only; valuation includes stored multiples and Bullrun model context; risk includes measured dials.
tickersYesTwo to five distinct Bullrun stock tickers, e.g. AAPL, BMW, NESN, 6324.T or 7203. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN. Company names are not accepted here.

Output Schema

NameRequiredDescription
rowsYes
tickersYes
webPageNo
coverageYes
warningsYes
methodologyYes
retrievedAtYes
platformLinkNo
requestedModulesYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/destructive=false, and the description adds real behavioral context beyond them: each fiscal year and source date are reported, native quote/reporting currency is preserved with no conversion, missing coverage is surfaced, and no ranking or generated narrative is produced. That is exactly the kind of expectation-setting that prevents misuse of a multi-source aggregation tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and output inventory, then caveats. The single long clause-list sentence is dense but every element (currencies, source dates, coverage gaps, exclusions) earns its place; it could be broken into two sentences for readability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a 2-parameter schema at full coverage, an output schema present, and annotations covering the safety profile, the description supplies the remaining needed context: scope limits, currency handling, missing-data reporting, and the absence of ranking or narrative. Nothing an agent needs before calling is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so 3 is the baseline, but the description adds a mapping of the four include modules to their semantics (annual latest-usable fiscal year only for fundamentals/quality, stored multiples and model context for valuation, measured dials for risk) and reinforces the 2-5 ticker range. This duplicates some schema text but clarifies intent; the ticker-format guidance lives mostly in the schema, not the description.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Compare) and resource (two to five stock tickers) plus exactly what the response contains: fundamentals, quality ratios, valuation/model context, and risk dials. An agent can tell this is a multi-ticker aggregation tool, though it never names its nearest siblings (compare_etfs, find_stock_peers, get_financial_history) to route around them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit negative scope ('No currency conversion, quarterly-to-annual substitution, buy/sell ranking or generated research') which tells the agent what it will not get, and names search_stocks as the alternative for resolving tickers by name or ISIN. It stops short of stating when to prefer this over individual per-stock calls or peer comparison tools.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_portfolio_draftCreate a portfolio draftAInspect

Use when the user wants you to BUILD or PROPOSE a brand-new portfolio for them — e.g. "build me a portfolio", "put together a dividend portfolio", "draft a portfolio of AI stocks", "create a new portfolio for $10k". Generates a REVIEWABLE paper-portfolio draft for the signed-in Bullrun user from a natural-language brief (e.g. "a diversified European dividend portfolio"). Requires OAuth with the write:drafts scope. Available to signed-in free accounts; daily usage limits and portfolio capacity still apply. This is DRAFT-ONLY and never changes any live position: the draft is saved to the user's account and appears in the Bullrun Portfolio tab under "Pending AI drafts", where the user reviews it and explicitly accepts it to create a new portfolio (or discards it). To suggest additions to an EXISTING portfolio instead, use create_position_draft. Tickers are chosen only from Bullrun's priced stock/ETF universe; pass instrumentUniverse for stocks only, ETFs only, or a mix. If the brief is vague, first ask ONE quick round of up to three multiple-choice questions (investing style, region focus, and size), each with a default the user can accept with "just pick for me", then build; skip any dimension the user already specified and do not interrogate across multiple turns.

NameRequiredDescriptionDefault
promptNoWhat kind of portfolio to draft, e.g. "a defensive dividend portfolio of large EU stocks". Optional: if you omit it, the server collects a quick style/region/size brief from the user directly (a native form on clients that support elicitation; otherwise it asks you to gather those first).
maxPositionsNoMaximum number of holdings (3-20, default 10).
startingCashNoStarting cash in USD (default 10000).
instrumentUniverseNoCandidate universe: stocks only, ETFs only, or a mix. Default mix unless the prompt says otherwise.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only say non-readOnly/non-destructive; the description adds what actually matters: OAuth write:drafts scope required, free-account eligibility with daily limits and portfolio capacity, and the crucial disclosure that nothing is live — the draft lands in 'Pending AI drafts' and needs explicit user acceptance or discard. That is behavioral context the structured fields cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the trigger condition and use-case examples, then scope, then side effects, then the alternative. It is long and slightly redundant ('DRAFT-ONLY and never changes any live position' is restated by the save/review sentence), but nearly every sentence carries operational information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Covers everything an agent needs for a 4-param, zero-required mutation: auth scope, entitlement limits, universe constraints, clarification fallback, and the post-call outcome (saved draft visible in the Portfolio tab pending acceptance). No output schema exists, and the description supplies the return context anyway.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns more by explaining that tickers come only from Bullrun's priced stock/ETF universe and by clarifying that prompt is optional with server-side or elicitation-based brief collection. It does not add much on maxPositions/startingCash beyond the schema defaults.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource ('BUILD or PROPOSE a brand-new portfolio') plus concrete trigger phrasings, and explicitly separates it from create_position_draft (existing portfolios) and implicitly from create_portfolio_from_positions. An agent can pick this tool without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives when-to-use triggers, the when-not case ('to suggest additions to an EXISTING portfolio, use create_position_draft'), and a concrete clarification protocol: one round of up to three multiple-choice questions with defaults, skipping already-specified dimensions and avoiding multi-turn interrogation.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_portfolio_from_positionsSave a portfolio from explicit holdingsAInspect

Use when YOU (or the user) have ALREADY decided the exact holdings and want them saved as-is — e.g. after researching and settling on a specific basket with target weights. Persists a REVIEWABLE paper-portfolio draft built from the tickers you supply, sized by weight (percent) or by explicit USD amount. Unlike create_portfolio_draft this does NOT use the LLM and NEVER re-selects tickers: your basket lands exactly as given. Like the other draft tools it is available to signed-in free accounts within daily usage limits and portfolio capacity, and needs OAuth with the write:drafts scope. DRAFT-ONLY: the draft is saved to the user's Bullrun account and appears in the Portfolio tab under "Pending AI drafts", where the user reviews it and explicitly accepts it (creating a NEW portfolio) or discards it — it never changes any live position. Tickers must exist in Bullrun's priced stock/ETF universe; any that cannot be priced are returned in unresolved and skipped (use search_etfs / get_etf_snapshot / screen_stocks / get_stock_metrics to confirm exact tickers first). For a vague brief where the model should pick, use create_portfolio_draft instead.

NameRequiredDescriptionDefault
nameNoPortfolio name. Default "Custom Portfolio Draft".
cashPctNoExplicit cash percentage to hold back. Overrides the weight-remainder rule.
positionsYesThe exact holdings to persist (1-30). Tickers are used verbatim, never re-selected.
startingCashNoTotal portfolio cash in USD. Default 10000 in weight mode; the sum of amounts in amount mode.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses OAuth write:drafts scope, free-account daily limits and portfolio capacity, that the call is draft-only and never mutates a live position, the review/accept/discard lifecycle, and the side effect that unpriceable tickers surface in `unresolved` and are skipped. The non-destructive framing is consistent with destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the decision condition, then mechanics, then constraints, then the alternative — a sensible order with little waste. Slightly long; the 'Like the other draft tools...' clause and repeated 'NEVER re-selects tickers' restate points made earlier, costing some density.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does the heavy lifting: it names the `unresolved` field, the 'Pending AI drafts' destination, and the accept/discard outcome. It stops short of describing the rest of the response (e.g. draft identifier, resolved weight summary), which is the only remaining gap for a write tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already spells out weight-vs-amount sizing, the remainder-as-cash rule, normalisation, and the 1-30 item bound. The description only restates sizing modes ('by weight (percent) or by explicit USD amount') and verbatim tickers, adding no syntax or edge-case detail the schema lacks. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Persists a REVIEWABLE paper-portfolio draft built from the tickers you supply') and immediately pins the scope: exact holdings, used verbatim, no re-selection. It explicitly contrasts with create_portfolio_draft, so an agent can separate the two without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives the positive trigger ('YOU or the user have ALREADY decided the exact holdings'), the negative trigger and named alternative ('For a vague brief where the model should pick, use create_portfolio_draft instead'), plus prerequisite tooling (search_etfs / get_etf_snapshot / screen_stocks / get_stock_metrics) to confirm tickers before calling.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

create_position_draftCreate a position draftAInspect

Use when the user asks what to BUY or ADD to an EXISTING portfolio — e.g. "what should I buy next", "suggest a stock or ETF for my portfolio", "what should I add", "recommend a position", "any ideas to round out my holdings". Generates REVIEWABLE suggested additions for one existing Bullrun portfolio. Requires OAuth with the write:drafts scope. Available to signed-in free accounts; daily usage limits and portfolio capacity still apply. This is DRAFT-ONLY: the suggested position(s) are saved to the user's account and appear in the Bullrun Portfolio tab under Pending AI drafts, where the user reviews and accepts them into the target portfolio or discards them. It never changes live holdings by itself. To draft a whole new portfolio from scratch use create_portfolio_draft; to test whether a specific named ticker fits, use get_portfolio_analytics with candidateTicker. Pass instrumentUniverse for stocks only, ETFs only, or a mix. If it is unclear, first confirm which portfolio (use list_portfolios when the user has more than one) and how many ideas (a single best idea or a few) in ONE quick step; otherwise just build.

NameRequiredDescriptionDefault
portfolioIdYesThe Bullrun portfolio id to propose additions for. Use list_portfolios first if unsure.
maxPositionsNoHow many suggested additions to save, 1-5. Use 1 for a single-position idea; default 3.
instrumentUniverseNoCandidate universe: stocks only, ETFs only, or a mix. Default mix.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses the required write:drafts OAuth scope, free-account availability, daily usage limits and portfolio capacity constraints, and most importantly spells out the DRAFT-ONLY contract — where the output lands (Pending AI drafts in the Portfolio tab), that the user must accept or discard, and that live holdings are never changed. This is exactly the missing context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the trigger condition, then scope, limits, draft behavior, and alternatives in a logical order; nearly every sentence carries decision-relevant information. The quoted user-phrase list is slightly long but each entry is a distinct disambiguation signal, so the length is largely earned.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description supplies the full picture an agent needs: preconditions (OAuth scope, one portfolio must exist, limits), what the call produces, where it appears, and that it is non-destructive to live holdings. Nothing material is left to inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so parameter mechanics are already documented. The description still adds useful semantics by mapping user intent ('how many ideas, a single best idea or a few') onto maxPositions and restating the stocks/ETFs/mix choice for instrumentUniverse, which helps translate a natural-language request into arguments.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific action (generate reviewable suggested additions) against a specific resource (one existing Bullrun portfolio), and explicitly excludes sibling behavior by naming create_portfolio_draft for new portfolios and get_portfolio_analytics with candidateTicker for single-ticker checks. An agent can route correctly from the description alone.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit trigger phrasings ('what should I buy next', 'recommend a position'), names the alternative tools and the conditions that select them, and prescribes a fallback (confirm portfolio and idea count in ONE step, use list_portfolios when the user has multiple). Both when-to-use and when-to-use-something-else are covered.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

find_stock_peersDiscover comparable stock candidatesA
Read-only
Inspect

Discover stock comparison candidates for one exact Bullrun ticker using stored industry or sector classification. Discloses the chosen classification, country preference, deterministic selection order, scan cap and issuer/listing exclusions. Excludes the subject, secondary listings and identifiable duplicate issuers/share classes. Returns compact stored multiples/growth plus ready-to-use compare_stocks arguments. Classification peers are not verified competitors or a financial-similarity ranking; no generated peers or paid graph discovery. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum peers. compare_stocks supports the subject plus at most four selected peers.
tickerYesBullrun equity ticker, e.g. AAPL, BMW or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
matchByNoauto uses exact stored industry when present, otherwise sector. It does not silently widen an empty industry result to the entire sector.auto
sameCountryOnlyNoRestrict to the subject's exact stored country. Otherwise same-country candidates are shown first, followed by other countries.

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, closed-world, non-destructive, so the bar is low — yet the description adds real behavioral context: scan cap, deterministic selection order, disclosed classification and country preference, and explicit exclusions (subject, secondary listings, duplicate issuers/share classes). This tells the agent exactly what it will and will not get back, and the 'Read-only.' line is consistent with rather than contradictory to the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose, then behavior, then exclusions; each clause carries distinct information. It is dense with packed lists ('classification, country preference, deterministic selection order, scan cap and issuer/listing exclusions') but no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully sketches the return payload (compact multiples/growth plus compare_stocks arguments) and the exclusion rules. What is missing is failure/edge behavior when no peer set exists or when an industry match is empty — a minor gap for a read-only discovery tool backed by annotations.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the schema already explains ticker formats, matchBy's auto behavior, sameCountryOnly ordering, and the limit rationale, so the baseline applies. The description adds only the framing detail that the ticker is resolved to 'one exact Bullrun ticker' and that classification/country choices are disclosed — nothing about parameter interaction beyond what the schema states.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Discover stock comparison candidates for one exact Bullrun ticker') plus the mechanism used (stored industry or sector classification). It also carves out what it is not ('not verified competitors or a financial-similarity ranking; no generated peers or paid graph discovery'), which separates it from screen_stocks and compare_stocks without needing the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The workflow is clear from 'Returns ... ready-to-use compare_stocks arguments', positioning this as the discovery step before compare_stocks. It also rules out adjacent interpretations (no generated peers, no similarity ranking). It stops short of an explicit when-to-use/alternative statement naming screen_stocks or search_stocks as the fallback path.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_capabilitiesGet account capabilitiesA
Read-only
Inspect

Discover what the connected Bullrun account can do BEFORE attempting an action, so you can plan instead of learning by hitting a 403. Reports whether you are authenticated and as WHICH identity (email + userId), the account's Pro/trial status and why (subscription / trial / admin), the granted OAuth scopes, portfolio usage vs the free/max limits, and a per-tool entitlement map: create_portfolio_from_positions, create_portfolio_draft and create_position_draft (all available to signed-in free accounts, subject to usage limits), and whether another portfolio can be created now. Call this first when a draft/write tool might be gated, or to confirm which account a request will act on. Read-only.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations only declare read-only/non-destructive/openWorld=false, but the description adds the real behavioral value: this is a pre-flight gate check that prevents 403s and disambiguates which identity a subsequent request will act on. It also discloses the entitlement semantics of the gated write tools (available to signed-in free accounts subject to usage limits), plus free/max portfolio limits — context an agent cannot get from the annotations.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the purpose and the 'BEFORE' urgency, then the return contents, then the call condition. The middle entitlement enumeration is dense but each item carries information. Slightly long for a zero-param tool, but nothing is padding.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description must describe return values — and it does, itemizing identity, plan status and reason, scopes, usage-vs-limits, and per-tool entitlements. Combined with the explicit call condition and the read-only confirmation, an agent has everything needed to invoke it correctly in one shot.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so there is nothing for the description to compensate for; baseline applies. The description correctly implies the call is unconditional and account-scoped rather than parameter-driven.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Discover what the connected Bullrun account can do') and then enumerates exactly what it reports: auth identity, Pro/trial status, OAuth scopes, portfolio usage limits, and a per-tool entitlement map. This is unmistakably distinct from every sibling tool, which are all market/portfolio data reads.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives explicit timing ('BEFORE attempting an action'), an explicit motivation ('plan instead of learning by hitting a 403'), and a concrete trigger ('Call this first when a draft/write tool might be gated, or to confirm which account a request will act on'). The gated tools are named directly, so an agent knows precisely when this pre-flight call is warranted.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_company_data_coverageGet company data availability and freshnessA
Read-only
Inspect

A cheap stored-data manifest for one exact company: available datasets, latest reporting periods, actual ingestion/computation timestamps where stored, and cached relationship graph status. Call before deeper research when coverage or freshness is uncertain. This reads indexed metadata, not every research endpoint, and never starts enrichment. Availability is not completeness or accuracy. A null stored timestamp means freshness is unknown; a reporting period is not an ingestion date. Read-only.

NameRequiredDescriptionDefault
tickerYesBullrun company ticker, e.g. AAPL, SAP or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/safety, and the description adds real behavioral context beyond them: it is 'cheap' (cost signal), reads only indexed metadata rather than live research endpoints, never triggers enrichment, and explicitly warns that availability != completeness/accuracy and that a null timestamp means unknown freshness. These are caveats an agent could not infer from the schema.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense but front-loaded: the manifest contents lead, then usage guidance, then caveats. Almost every sentence carries distinct information; 'Read-only' merely restates the annotation and 'cheap' is an unquantified adjective, minor waste.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description successfully doubles as a return-value specification by enumerating the fields the manifest exposes. Combined with the freshness caveats and the single well-documented parameter, an agent has everything needed to call it and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the ticker parameter already documents formats and the search_stocks fallback. The description only reinforces the 'one exact company' scope, adding no syntax or constraint detail beyond the schema, so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific resource ('stored-data manifest for one exact company') and enumerates exactly what it contains: available datasets, latest reporting periods, ingestion/computation timestamps, and cached relationship graph status. The line 'This reads indexed metadata, not every research endpoint' cleanly separates it from sibling data tools like get_financial_history or get_company_relationships.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

'Call before deeper research when coverage or freshness is uncertain' gives a concrete trigger condition, and 'never starts enrichment' bounds the action. It stops short of naming a specific alternative tool to use instead when coverage IS known, so routing is implied rather than explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_company_newsGet company news with sources and freshnessAInspect

Get cached company news for one exact Bullrun ticker, newest publication first, with publisher, source URL, publication date and stored-fetch freshness when recorded. Optional since cutoff and limit up to 50; only the newest 50 stored articles are searched. Useful for company headlines and article sources; use get_corporate_calendar for scheduled earnings/dividends and get_earnings_call_transcript for call text. Reading news also registers demand and requests a best-effort background cache refresh; this response does not wait for or confirm a refresh. Cached/empty/stale results do not establish that no new events exist. Does not change portfolios or place trades.

NameRequiredDescriptionDefault
limitNoMaximum returned articles, newest publication first. Up to 50 cached source articles are read before cutoff filtering.
sinceNoInclusive publication-time cutoff. YYYY-MM-DD means midnight UTC; timestamps need an explicit Z or UTC offset. Applied to the newest 50 stored articles, not a full historical news archive.
tickerYesBullrun company ticker, e.g. AAPL, SAP, ABBN or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint=false, the description carries the key burden of explaining the side effect: reading registers demand and triggers a best-effort background cache refresh that the response does not wait for or confirm. It also discloses the 50-article search window, staleness caveat, and explicitly states it does not change portfolios or place trades.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with purpose, then alternatives, then behavioral caveats, with no filler sentences. It is dense and slightly long, but each clause (refresh side effect, staleness, no trade placement) contributes new information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description enumerates the returned fields (publisher, source URL, publication date, stored-fetch freshness). Combined with the coverage limits and side-effect disclosure, an agent has everything needed to call it correctly and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so ticker format, since cutoff semantics, and limit bounds are already fully documented. The description restates the cutoff and the 50 cap without adding syntax or edge-case detail beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Get cached company news') plus scope constraints: one exact Bullrun ticker, newest publication first, and the returned fields. It explicitly contrasts itself with get_corporate_calendar and get_earnings_call_transcript, so an agent can tell it apart from siblings without opening their schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Names the two most confusable alternatives and the condition that selects each (scheduled earnings/dividends vs. call text). It also warns that cached/empty/stale results do not prove no new events exist, which is a clear usage caveat.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_company_relationshipsGet company relationship networkA
Read-only
Inspect

Bullrun's company relationship graph for one stock: named competitors, suppliers, customers and partners, each with its Bullrun ticker when the counterparty is listed, verification status (VERIFIED against a primary filing/source vs search-SUGGESTED), confidence, sole-source flag, quantified dependence where disclosed (e.g. "Cirrus Logic gets 91% of revenue from Apple") and the evidence behind it. Use for supply-chain and second-order risk questions ("who supplies X", "who depends on X", "who competes with X", "which listed companies are exposed if X stumbles"), then call get_company_risk or get_stock_metrics on the counterparties' tickers. Returns only the cached graph and never starts a paid discovery run; a company with no graph yet reports status "none". A missing edge is not proof of no relationship. Read-only.

NameRequiredDescriptionDefault
rolesNoWhich relationships to return, from this company's point of view. Default: all four.
tickerYesBullrun ticker, e.g. "AAPL", "SAP", "ASML". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
evidenceNonone = counts only; sources = source title/URL/type per edge; excerpts = also the quoted evidence text.sources
limitPerRoleNoMax counterparties per role, verified and highest-confidence first.
verifiedOnlyNotrue = only edges confirmed against a primary source (filing, company release). false also returns search-suggested edges, each labelled with its status and confidence.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, it discloses that the tool returns only the cached graph, never starts a paid discovery run, reports status 'none' when no graph exists, labels verification and confidence, and warns that a missing edge is not proof of no relationship. These are meaningful behavioral constraints and caveats that an agent needs before calling it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a dense but front-loaded paragraph that starts with what the tool returns and then moves to usage, caveats and follow-ups. It is appropriately sized for a complex graph tool, though the long field list makes it slightly heavy rather than maximally concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of explaining return contents and does so thoroughly: it describes counterparties, tickers, verification status, confidence, sole-source flags, quantified dependence and evidence. It also explains the 'none' status and the missing-edge caveat, leaving no significant gap for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all five parameters, including roles, evidence levels, limit ordering and verifiedOnly behavior. The description adds some interpretive meaning around verification status and counterparty tickers, but most parameter semantics are already supplied by the schema, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific resource and verb: Bullrun's company relationship graph for one stock, covering competitors, suppliers, customers and partners with ticker, verification status, confidence and evidence. It clearly distinguishes this from sibling tools by naming the follow-up tools and use cases, so an agent can identify the tool without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit use cases such as supply-chain and second-order risk questions and recommends following up with get_company_risk or get_stock_metrics. However, it does not explicitly state when not to use it versus siblings like find_stock_peers or compare_company_exposures, so it is clear context without full exclusions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_company_riskGet company risk profileA
Read-only
Inspect

Bullrun's company risk read for one stock: a 0-100 composite risk score and six mechanism dials (market expectation, operating pressure, cash conversion, leverage & coverage, competitive position, concentration) with band (Contained/Normal/Elevated/Stretched/Acute), direction vs the prior reading, the driving input and a plain-English explanation; plus filing-derived risk factors (severity, mechanism, source filing), identified supplier concentration (share of cost base covered, HHI, sole-source count, top supplier share) and recent material events. Use for "how risky is X", "what are the main risks for X", "is X's supply chain concentrated", or before adding a stock to a portfolio. Pair with get_company_relationships for the named competitors/suppliers/customers behind the concentration dial. Bands describe measured strain, never a buy/sell view. Read-only.

NameRequiredDescriptionDefault
detailNosummary = scores, bands, drivers and explanations; full = also every per-input term behind each category score.summary
tickerYesBullrun ticker, e.g. "AAPL", "ASML", "NESN", "6324.T" or "0700.HK". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
includeNoModules to return. dials = composite + six mechanism dials (market expectation, operating pressure, cash conversion, leverage, competitive position, concentration); risk_factors = filing-derived risk factors (10-K/annual report) with severity and mechanism; supplier_exposure = identified supplier spend concentration; events = recent restructuring/legal/supply/recall events; headline = latest news headline beside the dials. Default: dials, risk_factors, supplier_exposure.
maxEventsNoMax recent company events to return, most severe first.
maxRiskFactorsNoMax filing risk factors to return, most severe first.

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, closed-world, non-destructive behavior, so the bar is lower. The description still adds meaningful context: the scores are filing-derived and measured-strain based, with an explicit guardrail that bands are never a buy/sell view, and it discloses the data sources behind each module. No latency or freshness notes, but it exceeds what the annotations cover.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

It is front-loaded with the primary output, which is good, but the output inventory is delivered as one very long semicolon-chained sentence that duplicates the include/module list already present in the schema. Every clause is informative but the density makes it harder to scan than necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and five parameters, the description carries the full burden of explaining return contents, and it does so thoroughly — value ranges, band labels, direction, drivers, explanations, and per-module payloads. Combined with usage cues and the interpretive guardrail, nothing an agent needs to call or interpret it is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3 despite the schema already documenting ticker formats, include enums, and max caps in detail. The description restates the module names that map to the include enum but adds no syntax or default guidance beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (a per-stock company risk read), enumerates the exact outputs (0-100 composite, six named dials, risk factors, supplier concentration, events) and clearly separates it from adjacent siblings like get_company_risk_history and screen_risk_board. An agent can identify what this returns without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete trigger phrases ("how risky is X", "is X's supply chain concentrated") and a workflow position (before adding a stock to a portfolio), plus an explicit pairing with get_company_relationships. It stops short of stating when NOT to use it versus get_company_risk_history or screen_risk_board.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_company_risk_historyGet company risk history and changesA
Read-only
Inspect

Stored historical company risk category readings and their observed input changes. Shows dates, computation times, formula versions, score changes, changing input coverage and measurement bases. Use for 'how has X's risk changed?' and 'which inputs changed?'. These are retained category scores, not a complete daily series or proof of causation. Missing history is unknown, never a zero risk score. Read-only; does not run risk computation or paid discovery.

NameRequiredDescriptionDefault
limitNoLatest stored run dates to return, oldest first; each date carries its change from the previous stored date. Retention and gaps vary. Full detail supports at most six dates.
detailNoSummary keeps scores, explanations and up to three changed inputs per category; full includes stored input terms and all returned term changes.summary
tickerYesBullrun company ticker, e.g. AAPL, SAP or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already establish that this is a read-only, non-destructive, closed-world tool. The description adds substantial context beyond that: it discloses retained category scores, computation times, formula versions, changing input coverage, missing-history semantics, and that it does not run risk computation or paid discovery.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with what the tool returns, followed by use cases, caveats, and boundary conditions. Each sentence has a distinct purpose and there is no filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still enumerates the key returned elements: dates, computation times, formula versions, score changes, input coverage, and measurement bases. Combined with the rich parameter schema and read-only annotations, it gives enough context to call the tool correctly and interpret the results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the ticker, limit, and detail parameters are thoroughly documented in the schema itself. The description does not add parameter-specific syntax or guidance beyond that, so the schema does the heavy lifting.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: stored historical company risk category readings and observed input changes. It also clarifies that these are retained category scores, not a complete daily series, which distinguishes this tool from likely current-risk siblings such as get_company_risk.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives explicit use cases ('how has X's risk changed?' and 'which inputs changed?') and negative constraints ('not a complete daily series or proof of causation'; 'does not run risk computation or paid discovery'). However, it does not explicitly name the sibling to use for current risk or broader risk movers, so alternative routing is only implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_corporate_calendarGet corporate calendarA
Read-only
Inspect

Read stored upcoming earnings and ex-dividend dates, plus recent equity listings. Supports ticker/company search and explicit effective windows, market-cap filters, native listing quote currencies, available source metadata and partial coverage. Recent first-trade dates are not confirmed IPOs or an upcoming IPO schedule. Calendar dates and estimates can change; missing events mean unknown coverage, never proof that no event exists. Read-only; at most three calendar requests, plus a ticker lookup when q carries a Yahoo exchange suffix.

NameRequiredDescriptionDefault
qNoOptional case-insensitive ticker or company-name contains search, also matched with spaces removed. This is not an exact ticker filter. A Yahoo-style symbol whose listing Bullrun stores in another form (BMW.DE as BMW, 7203.T as 7203) is searched under the stored ticker. A nonblank search widens earnings/ex-dividend to 120 days and listings to 60 months. % and _ act as search wildcards.
daysNoForward days for earnings and ex-dividend, inclusive of the API server's current date. A nonblank q makes the backend use 120 days regardless of this value.
limitNoMaximum rows per selected calendar, not an overall result count. A full page may omit other matching events.
includeNoSelected stored calendars: upcoming earnings, upcoming ex-dividend dates, and recent listings (not an upcoming IPO schedule).
minCapUsdNoOptional minimum market capitalization in USD. Omit to retain API defaults: 50 million for earnings/ex-dividend and zero for listings. Listings with unknown market cap are retained even with a positive floor.
listingMonthsNoTrailing months for recent listings. A nonblank q makes the backend search 60 months regardless of this value.

Output Schema

NameRequiredDescription
queryYes
webPageNo
warningsYes
calendarsYes
methodologyYes
retrievedAtYes
platformLinkNo
requestedTypesYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds real context beyond the readOnly/openWorld annotations: a request budget (three calendar requests plus a ticker lookup), coverage caveats (partial coverage, missing events mean unknown coverage), and volatility of dates/estimates. It does not mention auth or pagination/ordering behavior, so it stops short of fully informative.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Purpose is front-loaded in the first clause, and the later sentences all carry operational warnings rather than filler. It is dense and caveat-heavy in a single paragraph, which slightly hurts scanability but wastes no sentences.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema and full annotation coverage, the description only needs to supply coverage and override semantics, which it does, including the important warning that absent events are not proof of absence. Minor gap: it never states ordering or how the three included calendars combine into one response.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents q's wildcard/suffix semantics and the q-overrides-days rule, so the description is mostly restating it. The one addition, native listing quote currencies and source metadata, is not tied to any specific parameter, so it does not meaningfully extend parameter understanding.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with a specific verb and three named resources (upcoming earnings, ex-dividend dates, recent equity listings), which no sibling tool covers. It also pre-empts a likely confusion by saying recent first-trade dates are not an IPO schedule, drawing a clean line against screen_stocks/search_stocks territory.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It implies the usage pattern (ticker/company search, explicit effective windows, market-cap filtering) and notes when a nonblank q overrides days/listingMonths, which is genuinely useful. However, no sibling alternative is named and there is no explicit when-not-to-use guidance, leaving routing to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_country_macroGet country macro profileA
Read-only
Inspect

One country's macro dashboard from Bullrun's Global Markets warehouse: a 0-100 macro stress score (higher = more stress) built from six pillars - labour (unemployment, its change, youth unemployment), housing (real house prices, price-to-income and price-to-rent vs history), credit (BIS credit-to-GDP gap, household debt service, household credit), fiscal (government debt, fiscal balance), external (current account) and cycle (GDP growth, inflation) - with every input's latest value, period, source (OECD, IMF, BIS, World Bank, Eurostat), its stress contribution and a historyCode for get_macro_history. Use for "how is the German economy doing", "is there a housing bubble in Canada", "macro risks in Italy", or to judge the backdrop for a country's stocks. A thinly covered country returns state "insufficient", never a falsely calm score. Read-only.

NameRequiredDescriptionDefault
countryYesCountry name, e.g. "Germany", "United States" (aliases like US, UK, Korea, Eurozone are understood). Also "Euro Area".

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false, and openWorldHint=false, but the description adds material behavioral context beyond them: thinly covered countries return state "insufficient" rather than a falsely calm score, and every input includes latest value, period, source, and stress contribution. That coverage-state behavior is exactly the kind of edge case an agent needs to know before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core purpose and output are front-loaded, and the use-case examples follow efficiently. The middle pillar enumeration is dense and long, but it is informative rather than repetitive; the description is appropriately sized for a complex composite dashboard, though not maximally concise.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, so the description carries the burden of explaining return content, and it does: the stress score, six pillars, per-input latest values, periods, sources, contributions, historyCode, and the "insufficient" state. For a one-parameter read-only tool, this is complete enough to call correctly and interpret results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100% and the single country parameter is already documented with examples and accepted aliases. The description does not add meaningful parameter-level detail beyond the schema, so the baseline of 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific resource (a single country's macro dashboard) and defines its central output (a 0-100 macro stress score built from six named pillars). It clearly distinguishes this from get_macro_history by noting that inputs include a historyCode for that sibling, and from broad macro indicators by focusing on a country-level stress score and pillar inputs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete usage examples ("how is the German economy doing", "housing bubble in Canada", "macro risks in Italy", and judging the backdrop for a country's stocks), which tells the agent when this tool fits. It also routes historical follow-up to get_macro_history, though it does not explicitly state when not to use this tool versus siblings like get_macro_indicators.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_earnings_call_transcriptGet earnings call transcriptAInspect

Read cached earnings-call paragraphs for one exact Bullrun ticker, optionally filtered by fiscal period or search text. A best-effort free background import collects at most the two latest retained calls from DefeatBeta for supported US listings, with a 24-hour stored-data cooldown; the first read may be empty. Coverage and source publication lag vary. Speaker names and paragraph order are retained; roles and prepared/Q&A section labels may be unavailable. Does not change portfolios or user data.

NameRequiredDescriptionDefault
searchNoOptional case-insensitive text/speaker search across transcript chunks.
tickerYesBullrun ticker, e.g. "CRWD", "SPGI", "V". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
maxChunksNoMaximum speaker-tagged transcript chunks to return.
fiscalYearNoOptional fiscal year filter.
fiscalQuarterNoOptional fiscal quarter filter.
maxCharsPerChunkNoMaximum characters per transcript chunk in the MCP response.

TDQS

A4.2/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the annotations: discloses the best-effort background import, the two-most-recent-calls cap, DefeatBeta as source, US-listing-only support, a 24-hour stored-data cooldown, possible empty first read, variable coverage and publication lag, and that roles/section labels may be missing. Crucially it explains why readOnlyHint=false is set (a background import runs) while assuring portfolios/user data are untouched, resolving what would otherwise look inconsistent.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four sentences, front-loaded with the what/scope before the caveats, and each caveat is substantive rather than filler. Slightly dense in the middle sentence, but no sentence is redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the return-shape burden and does so: speaker-tagged paragraphs, preserved speaker names and paragraph order, missing role/section labels, and the empty-first-read case. Combined with the ticker-resolution note in the schema, an agent has enough to call this correctly and set expectations for the user.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline of 3 applies; the schema already documents ticker format, search, fiscal period, and both chunk caps. The description adds only 'one exact Bullrun ticker' emphasis and reiterates the fiscal-period/search filters. It says nothing about how maxChunks and maxCharsPerChunk interact or which should be tuned for long calls.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb plus resource plus scope: 'Read cached earnings-call paragraphs for one exact Bullrun ticker, optionally filtered by fiscal period or search text.' No sibling tool exposes transcripts, so the resource alone distinguishes it from the price, news, financial-history and ETF families.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied ('read cached ... paragraphs') and a boundary is drawn against mutation tools ('Does not change portfolios or user data'), but there is no explicit when-to-use/when-not guidance and no pointer to an alternative source for transcript-like content. The real operational guidance present is about expectations (first read may be empty, cooldown), not about tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_etf_exposuresGet ETF exposuresA
Read-only
Inspect

Calculate sector, country, currency, and broad asset exposure from the latest stored ETF holdings. Sector and country come from the fund provider's own holdings file where it states them (normalized to Bullrun's sector and country names), otherwise from the Bullrun instrument the holding resolves to by ISIN or by symbol with a matching company name. Currency uses the reported holding currency, else an explicitly disclosed estimate from the company's home-market listing or usual country currency. This is a holding quote/listing-currency proxy, not revenue FX exposure, economic currency risk or hedge-adjusted fund exposure. Positions without a classification or currency basis are Unclassified / Not reported. Sector and currency cover all stored rows; country covers securities and excludes cash and derivatives. Coverage states complete bucket weights and any buckets omitted by limitPerType. Broad asset class comes from the normalized fund profile. Factor and thematic look-through are unavailable until dedicated source data exists. Coverage states how much fund weight was classified and how, so partial top-holdings data is never presented as full exposure. Read-only.

NameRequiredDescriptionDefault
typesNo
tickerYesExact Bullrun ETF listing ticker.
limitPerTypeNo

Output Schema

NameRequiredDescription
tickerYes
webPageNo
coverageYes
warningsYes
exposuresYes
platformLinkNo
availableTypesYes
notLoadedTypesNo
requestedTypesYes
unavailableTypesYes

TDQS

A4.3/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only safety profile, and the description adds substantial behavior beyond them: resolution fallbacks (provider file, then ISIN, then symbol with matching company name), what is excluded per dimension (country excludes cash and derivatives while sector and currency cover all rows), how unclassified positions are labeled, and how coverage/limitPerType truncation is reported. It also discloses a genuine limitation (no factor/thematic look-through) rather than leaving the agent to discover it.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and dimensions in the first sentence, then methodology and caveats in descending importance. Some redundancy: two separate sentences are spent on coverage reporting, and the trailing 'Read-only.' duplicates readOnlyHint=true.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value structure need not be explained; the description instead covers what the agent cannot get from schema or annotations — data provenance, fallback chain, per-dimension exclusions, and partial-coverage honesty. Nothing material for correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is only 33% (only ticker is documented), so the description must compensate and largely does: it enumerates the four exposure dimensions the types enum can request and flags that factor/thematic will not return data. It also explains that limitPerType causes bucket omission and that coverage reports those omissions. It does not document the types default list or per-enum behavior beyond the four named buckets, so it is not fully compensating.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: 'Calculate sector, country, currency, and broad asset exposure from the latest stored ETF holdings.' An agent can tell this is a derived-exposure tool rather than a raw holdings dump. It does not explicitly name the sibling it differs from (e.g. get_etf_holdings or compare_etf_exposures), so it stops short of full sibling differentiation.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives clear usage context: exposure is computed only from stored holdings, and 'Factor and thematic look-through are unavailable until dedicated source data exists' — which matters because factor and thematic are valid values in the types enum. It also warns the currency output 'is a holding quote/listing-currency proxy, not revenue FX exposure, economic currency risk or hedge-adjusted fund exposure,' steering the agent away from misuse. It never explicitly names an alternative sibling tool to use instead.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_etf_filter_optionsList ETF filter valuesA
Read-only
Inspect

List the exact values accepted by the categorical filters on search_etfs and screen_etfs — asset classes, categories, index keys, product/wrapper types, regions, domiciles, currencies, exchanges, and (on request) issuers and focus strings. Those filters match exactly, so a guessed string returns zero rows and looks like "no such ETF exists"; call this first whenever a filter value is not already known to be valid. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum values per facet, 1-1000. Each facet reports its untruncated total.
facetsNoWhich facets to return. Defaults to everything except the long tails fundFamilies (~890 issuers) and industries (~650 focus strings) — request those explicitly, ideally with search.
searchNoCase-insensitive substring filter applied to every requested facet, e.g. "ishares" against fundFamilies or "world" against categories.

Output Schema

NameRequiredDescription
notesYes
facetsYes
searchYes
totalsYes
webPageNo
platformLinkNo
truncatedFacetsYes

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered and the description's closing 'Read-only' largely repeats it. What it adds beyond the annotations is valuable: exact-match semantics that silently yield zero rows, plus the default exclusion of the long-tail facets unless explicitly requested.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and the call-first instruction are front-loaded in the first sentence. The second sentence is dense but every clause carries operational meaning; only the trailing 'Read-only' is redundant with the annotations.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return-value detail is unnecessary, and annotations cover the safety profile. For a read-only lookup with three optional params, the description supplies everything an agent needs to call it correctly and know why.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3, but the description adds rationale the schema only implies: that issuers and focus strings ('on request') are omitted by default because they are long tails. This helps an agent understand why an unfiltered call may not show those facet families.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (list) and resource (exact values accepted by categorical filters on search_etfs and screen_etfs), then enumerates the facet families returned. An agent can immediately distinguish this lookup tool from the sibling search_etfs and screen_etfs it feeds.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly says when to call it ('call this first whenever a filter value is not already known to be valid') and supplies the consequence of skipping it ('a guessed string returns zero rows and looks like no such ETF exists'). It also names the specific downstream tools whose filters it serves.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_etf_fundGet ETF fund by ISINA
Read-only
Inspect

Resolve one FUND rather than one listing. Given an ISIN (or any venue ticker of the fund) it returns the fund's identity, costs, index, distribution policy, wrapper type and every venue it is listed on with exchange and trading currency. Use this when the user quotes an ISIN, asks "which ticker do I buy on my exchange?", or when several tickers may be the same underlying fund. Ratios are percentage points. Read-only.

NameRequiredDescriptionDefault
isinNoFund ISIN, e.g. IE00B4L5Y983. The identifier European factsheets and brokers quote.
tickerNoAny venue listing ticker of the fund, e.g. EUNL.DE or IWDA.L. Resolved to its fund ISIN first. Provide this or isin.

Output Schema

NameRequiredDescription
fundYes
foundYes
queryYes
webPageNo
listingsYes
warningsYes
platformLinkNo

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, destructiveHint=false and openWorldHint=false, so the closing 'Read-only' adds nothing. The description does add real context beyond annotations: it enumerates the returned categories and specifies that ratios are in percentage points, which prevents unit misinterpretation.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the fund-vs-listing distinction and then the return shape, then use cases, then the unit caveat. The final 'Read-only' sentence is redundant with annotations and could be dropped.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists so return values needn't be detailed, yet the description usefully sketches the result categories and unit convention. With annotations covering safety and a zero-required-param schema, an agent has everything needed to call it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so both params (isin, ticker) are already fully documented with examples, and the description's '(or any venue ticker of the fund)' largely repeats the ticker schema text. It adds only the implicit either/or framing, which the schema already conveys with 'Provide this or isin'.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource: given an ISIN or venue ticker it returns the fund's identity, costs, index, distribution policy, wrapper and all listings. The opening line 'Resolve one FUND rather than one listing' explicitly separates it from listing-level siblings like get_etf_snapshot or the ticker-oriented tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives three concrete triggering situations (user quotes an ISIN, asks which ticker to buy on their exchange, several tickers may be the same fund), which is stronger than typical. It doesn't name a specific alternative for those cases (e.g. search_etfs for discovery), so routing coverage is clear but not exhaustive.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_etf_holdingsGet ETF holdingsA
Read-only
Inspect

Return the latest stored ETF holdings snapshot with opaque cursor pagination. The response reports the provider's stated holdings count, stored row count, covered weight, and whether the stored rows appear complete. Treat isComplete=false or null as partial look-through data. Historical as-of selection will be added when the upstream API exposes it. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum holdings to return on this page, 1-100.
cursorNoOpaque nextCursor returned by a previous get_etf_holdings call for the same ticker.
tickerYesExact Bullrun ETF listing ticker, including its exchange suffix when present.

Output Schema

NameRequiredDescription
tickerYes
webPageNo
asOfDateYes
coverageYes
holdingsYes
returnedYes
nextCursorYes
platformLinkNo
totalRowsAvailableYes

TDQS

A3.7/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only/non-destructive profile, yet the description adds real context beyond them: the data is a stored snapshot, pagination is cursor-based, completeness may be partial, and historical as-of selection is not yet available. That last point usefully tells the agent a capability it might otherwise assume exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four tight sentences, front-loaded with what is returned and followed by the important completeness caveat. The trailing 'Read-only.' is redundant with readOnlyHint=true and is the only sentence that does not earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need not be spelled out, and the description correctly focuses on the interpretability caveat (isComplete) that an agent needs. Coverage of pagination and data staleness is adequate for a 3-parameter read tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so ticker, limit, and cursor are already fully documented. The description adds the notion of opaque cursor paging but no ticker format or exchange-suffix detail beyond what the schema states. Baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Return the latest stored ETF holdings snapshot') and qualifies the data as stored/latest rather than live. It does not, however, distinguish itself from adjacent siblings such as get_etf_exposures or get_etf_fund, so an agent must infer the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description gives interpretation guidance ('Treat isComplete=false or null as partial look-through data') which is genuinely useful, but it never says when to choose this tool over get_etf_exposures or get_etf_fund, and no exclusions are stated. Usage is implied by the holdings framing only.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_etf_index_groupCompare funds tracking one indexA
Read-only
Inspect

Answer "what is the cheapest way to track ?". Returns every fund tracking one index ordered cheapest fee first, deduplicated to one row per FUND rather than per venue listing (a five-venue UCITS fund is one choice, not five) with its listingCount and venues. Defaults to UCITS-buyable domiciles. Omit indexKey to list the available index families. Fees are percentage points and the response states how many funds publish no fee at all, so a "cheapest" claim is never made over silently omitted funds. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum funds (or index families) to return, 1-100.
scopeNoucits (default) restricts to domiciles a European retail investor can actually buy. all adds US-domiciled trackers, which look cheaper but are not purchasable by EU retail.ucits
currencyNoKeep only funds with a listing trading in this currency (e.g. CHF, EUR, USD, GBP) and name that line.
exchangeNoKeep only funds listed on this venue and name each one's ticker there, e.g. SW (SIX Swiss Exchange), XETRA, LSE, AS, MI. A Swiss investor wanting the SIX line passes SW.
indexKeyNoNormalized index key, e.g. SP500, MSCI_WORLD, NASDAQ100, MSCI_EM, EURO_STOXX_50, TOPIX, FTSE100. Omit to list every index family that has at least one fund.
distributionPolicyNoOptionally keep only accumulating or only distributing share classes.

Output Schema

NameRequiredDescription
modeYes
foundYes
fundsYes
scopeYes
webPageNo
coverageYes
indexKeyYes
warningsYes
platformLinkNo
indexFamiliesYes

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnly/non-destructive annotations, it discloses ordering, the fund-vs-venue dedup behavior, listingCount/venues in the result, the domicile default, and that the response reports how many funds publish no fee so 'cheapest' claims aren't made over silent omissions. That is exactly the kind of context annotations cannot carry.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the user question and mostly waste-free, but the single dense run-on sentence packs several ideas (dedup, defaults, fee disclosure) and could be broken for scanability.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a read-only screening tool with 6 optional params, an output schema, and full annotation coverage, the description supplies ordering, dedup semantics, default scope, and data-quality caveats. Nothing an agent needs to call it correctly is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3; the description earns extra by explaining indexKey omission as a mode switch and by surfacing listingCount/venues as output concepts tied to the filtering parameters. Currency/exchange semantics are left largely to the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Opens with the exact question it answers and states a specific resource (every fund tracking one index, ordered cheapest fee first). The dedup rule ('one row per FUND rather than per venue listing') sharply distinguishes it from raw listing/search tools like search_etfs.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete routing guidance: omit indexKey to enumerate index families, and scope defaults to UCITS-buyable domiciles with 'all' adding US trackers. It does not explicitly name alternatives such as compare_etfs or simulate_etf_cost, so the when-not case must be inferred.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_etf_riskGet ETF riskA
Read-only
Inspect

Calculate drawdown, annualized volatility, downside volatility, historical VaR, Sharpe, Sortino and Calmar ratios from stored daily close prices. With benchmarkTicker, also calculates beta, correlation, tracking error, active return and information ratio on aligned dates. Results are price-return risk, not distribution-adjusted total-return risk. Read-only.

NameRequiredDescriptionDefault
daysNoCalendar-day lookback for daily close-price risk calculations.
tickerYesExact Bullrun ETF listing ticker.
benchmarkTickerNoOptional exact priced benchmark/proxy ticker for beta, correlation, tracking error, active return, and information ratio.
riskFreeRatePctNoAnnual risk-free rate in percentage points for Sharpe, Sortino, and Calmar ratios.

Output Schema

NameRequiredDescription
riskYes
tickerYes
webPageNo
coverageYes
warningsYes
methodologyYes
lookbackDaysYes
platformLinkNo
benchmarkRelativeYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so the safety profile is covered (the trailing 'Read-only' is redundant). The description adds real, non-annotation context: the calculations run off stored daily close prices, benchmark metrics only on aligned dates, and critically that results are price-return risk, not distribution-adjusted total-return risk — a caveat that changes how an agent should interpret and report the numbers.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three dense sentences, front-loaded with the computed metrics, then the conditional benchmark behavior, then the interpretive caveat. Nothing is padding and the ordering matches how an agent would reason about the call.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With a full schema, complete annotations, and an output schema (so return shapes needn't be described), the description covers method and interpretation well. The only real gap is behavior on thin history (e.g., days=30 with annualized volatility or required benchmark overlap), which would help an agent avoid misleading output.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every parameter is already documented, and the description's benchmarkTicker explanation largely restates the schema. It does implicitly convey that riskFreeRatePct drives only the ratio-based metrics, but adds no syntax, alignment, or edge-case detail beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb ('Calculate') and enumerates the exact metric set (drawdown, volatility, VaR, Sharpe, Sortino, Calmar), plus the benchmark-relative additions. That enumeration makes it unmistakable against siblings like get_etf_timeseries (raw series) or get_company_risk (equities), so the agent can pick it without opening the schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It states the conditional behavior clearly ('With benchmarkTicker, also calculates beta, correlation...'), which tells the agent how to unlock the relative-risk metrics. But it never says when to prefer this over get_etf_timeseries/get_etf_snapshot, nor any when-not conditions such as insufficient history.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_etf_snapshotGet ETF snapshotA
Read-only
Inspect

Fetch a modular snapshot for one exact ETF listing. The include array controls which of identity, classification, market, fund_data (NAV/AUM), costs, income, and benchmark are fetched and returned. Unrequested modules are omitted; requested-but-unavailable modules are named explicitly. Ratios use percentage points. Read-only.

NameRequiredDescriptionDefault
tickerYesExact Bullrun ETF listing ticker, including its exchange suffix when present, e.g. SPY, VWRL.L, or EUNL.DE.
includeNoOnly these snapshot modules are fetched and returned. Default: identity, classification, market, costs.

Output Schema

NameRequiredDescription
asOfYes
foundYes
tickerYes
modulesYes
webPageNo
dataQualityYes
platformLinkNo
missingModulesYes
availableModulesYes
requestedModulesYes

TDQS

A3.9/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the readOnlyHint/destructiveHint annotations it adds genuinely useful behavior: unrequested modules are omitted, requested-but-unavailable modules are named explicitly (partial-result semantics), and ratios are returned in percentage points. The trailing 'Read-only' merely restates annotations, but the rest is substantive disclosure.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Four short sentences, front-loaded with the core action and scope, then the parameter contract and the output-unit note. Only the closing 'Read-only' is wasted space since annotations already assert it.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema present and annotations covering the safety profile, the description supplies exactly what remains: module selection semantics, defaulted omission behavior, handling of unavailable modules, and unit conventions. An agent could call this correctly without further inference.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the enum and default are already documented, but the description still adds meaning not in the schema — notably that fund_data carries NAV/AUM and that include drives both fetching and return shape. It does not explain cost of requesting all modules or how module ordering affects output.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Fetch a modular snapshot') and narrows scope to 'one exact ETF listing', which separates it from list-style siblings like search_etfs and screen_etfs. It does not name the adjacent per-fund siblings (get_etf_fund, get_etf_holdings, get_etf_exposures), so differentiation is good but not fully explicit.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied by 'one exact ETF listing' and by the include array controlling breadth, suggesting a one-call multi-module lookup. However, there is no explicit when-to-use/when-not statement and no named alternative for the narrower sibling tools such as get_etf_holdings or get_etf_risk.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_etf_timeseriesGet ETF time seriesA
Read-only
Inspect

Fetch ETF price or price-return history at daily, weekly, or monthly intervals. NAV, true total-return, benchmark, and premium/discount series are returned only when their required source data or an explicit benchmark ticker exists; unavailable requested series are named explicitly and never approximated with price returns. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum recent daily source bars to load before date filtering and interval aggregation.
seriesNoRequested series. Unsupported stored series are reported in unavailableSeries rather than synthesized.
tickerYesExact Bullrun ETF listing ticker.
endDateNo
intervalNodaily
startDateNo
benchmarkTickerNoExact priced ticker to use when benchmark is requested. A benchmark name alone cannot resolve a price series safely.

Output Schema

NameRequiredDescription
seriesYes
tickerYes
webPageNo
intervalYes
metadataYes
warningsYes
platformLinkNo
availableSeriesYes
requestedSeriesYes
unavailableSeriesYes

TDQS

A3.8/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true and destructiveHint=false, so 'Read-only' adds little. The real value is the disclosure that unavailable series are surfaced as named gaps and never approximated with price returns — a non-obvious behavioral contract an agent could otherwise get wrong.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Two tight sentences: the primary capability is front-loaded and the availability caveat follows immediately. No filler, and 'Read-only' is the only arguable redundancy.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return shape needs no explanation, and the description covers the subtle part — partial series availability. For a 7-parameter tool it omits any note on how `limit` interacts with date filtering and interval aggregation, which is a modest but real gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 57%, so the schema carries much of the burden. The description adds meaning for `series` (unsupported stored series -> unavailableSeries) and for `benchmarkTicker` (an explicit ticker is required because a benchmark name cannot resolve a price series safely), but says nothing about `limit`, `startDate`, or `endDate` beyond what the schema shows.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Fetch ETF price or price-return history') plus the interval granularity, so an agent knows exactly what it retrieves. It does not name a sibling to distinguish itself from, e.g., get_stock_price_history or get_etf_snapshot, leaving that separation implicit in the 'ETF' qualifier.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Conveys conditional availability ('returned only when their required source data ... exists') and the fallback policy, which is genuine usage context. However, it never says when to prefer this over get_stock_price_history, get_etf_snapshot, or get_etf_fund, and gives no guidance on choosing intervals or date windows.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_financial_historyGet financial historyA
Read-only
Inspect

Fetch 1-15 years of historical financial statements for one exact Bullrun ticker. Returns annual and/or quarterly rows grouped into income statement, balance sheet, cash flow, per-share metrics, margins, source currency, and annual growth/CAGR consistency checks. Use this when evaluating multi-year revenue/net-income growth, margin trajectories, leverage, cash flow quality, or whether a stock passed a rule such as 10% revenue and net-income growth every year.

NameRequiredDescriptionDefault
yearsNoHow many fiscal years of history to return, counting backward from the latest fiscal year available.
tickerYesThe Bullrun ticker. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
periodTypeNoReturn annual rows, quarterly rows, or both. Annual rows use fiscalQuarter=0.both
includeEmptyRowsNoInclude sparse rows that have no major income statement, balance sheet, cash-flow, or EPS values.

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly=true, destructive=false, openWorld=false, so the safety profile is covered. The description adds real value beyond that: it discloses the 1-15 year range, the annual/quarterly row grouping, the specific statement sections returned, and that growth/CAGR consistency checks are included. It stops short of noting data-availability caveats, coercion of ambiguous tickers, or volume/pagination characteristics.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three sentences, front-loaded with the action and scope, then the return shape, then the use cases. No redundant or filler language; each sentence carries distinct information.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does the heavy lifting by enumerating the returned row groups and the growth/CAGR checks, which is sufficient for an agent to know what comes back. Minor gaps remain around failure modes for an unresolved ticker and how sparse/empty rows behave, though the latter is partially covered by the schema's includeEmptyRows parameter.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3. The description reinforces the year range and 'one exact Bullrun ticker' but adds no syntax or behavioral detail beyond what the schema already documents for years, periodType, and includeEmptyRows.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource with scope: 'Fetch 1-15 years of historical financial statements for one exact Bullrun ticker,' and enumerates the returned groups. It implicitly separates itself from snapshot tools like get_stock_metrics via 'multi-year' but never names a sibling to contrast with.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The final sentence gives concrete triggering situations — multi-year revenue/net-income growth, margin trajectories, leverage, cash flow quality, and rule checks like 10% growth every year. No explicit when-not or named alternative (e.g., get_stock_metrics for a current snapshot) is provided, so routing is clear but not fully closed.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_forward_estimatesGet forward estimatesAInspect

Read cached Yahoo analyst consensus revenue/EPS estimates and available EPS revision percentages for one exact Bullrun ticker. A free background refresh checks supported symbols on demand, storing at most one snapshot per day; the first read may be empty. Fiscal periods and source currency are preserved. The configured feed does not provide EBITDA estimates, management guidance or revenue revisions. Forward P/E/PEG context uses the latest annual consensus snapshot only when quote and EPS currency units match. Does not change portfolios or user data.

NameRequiredDescriptionDefault
limitNoMaximum estimate rows to return.
tickerYesBullrun ticker, e.g. "AAPL", "CRWD", "SPGI". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
periodTypeNoReturn annual estimates, quarterly estimates, or both.both

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds substantial context beyond the annotations: on-demand background refresh writes a snapshot at most once per day, first read may be empty, and the data has known gaps (no EBITDA estimates, management guidance, or revenue revisions). It also discloses the currency-unit matching condition for forward P/E/PEG and clarifies it does not mutate portfolios or user data, which is consistent with destructiveHint=false.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core purpose, and each subsequent sentence carries distinct information about caching, coverage limits, or currency handling. It is dense and slightly longer than needed, but there is little wasted text.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does well to state what is returned (consensus revenue/EPS estimates, EPS revisions) and what is not available. It doesn't describe row shape or pagination behavior for the limit parameter, which is a minor remaining gap.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so ticker, periodType, and limit are already fully documented, including examples and enum values. The description adds only modest context (fiscal periods and source currency preserved, exact ticker required), so the baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The first sentence names a specific verb (read cached Yahoo analyst consensus revenue/EPS estimates plus EPS revision percentages) and a precise resource scope (one exact Bullrun ticker). It is clearly distinguishable from sibling tools like get_financial_history or get_stock_metrics, which cover reported history and metrics rather than forward consensus.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Usage is implied through the caching note ('the first read may be empty') and the single-ticker constraint, which hints at how to call it. However, there is no explicit when-to-use/when-not guidance and no named alternative for consensus estimates, so routing is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_global_markets_overviewGet global markets overviewA
Read-only
Inspect

Bullrun's Global Markets dashboard in one call: world equity indices (S&P 500, Nasdaq-100, MSCI World, DAX, FTSE 100, Nikkei, Hang Seng, Nifty...), central-bank policy rates and next rate decisions (Fed, ECB, BoE, BoJ, SNB, BoC), 16 sovereign 10-year yields, 20 FX pairs, oil/gas/gold/copper, headline macro tiles (global GDP growth, inflation, debt/GDP, VIX, DXY, 2s10s curve, US jobless claims), the upcoming economic calendar, market news and the US housing balance. Each row carries a historyCode for get_macro_history. Use for "how are markets doing today", "what's the macro backdrop", "where are rates/yields", "what's on the calendar this week" or a morning briefing. Daily closes, with live intraday index levels while markets are open. Read-only.

NameRequiredDescriptionDefault
sectionsNoSections to return. headline = global GDP/inflation/debt, oil, gold, DXY, US 10Y, 2s10s curve, VIX, EUR/USD, Bitcoin, policy-rate average, OECD unemployment, US jobless claims; indices = 19 world equity indices (live intraday level when a market is open); rates = six major central-bank policy rates + upcoming rate decisions; yields = 16 sovereign 10Y yields; currencies = 20 FX pairs; commodities = Brent, WTI, natural gas, gold, copper; calendar = upcoming high-impact economic releases; news = market headlines; us_housing = US housing-market balance (months' supply, inventory, price cuts). Default: everything except news and us_housing.
newsLimitNoHeadlines to return when the news section is requested.

TDQS

A4.2/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint and non-destructive, so the 'Read-only' line is redundant, but the description adds real behavioral context the annotations cannot: daily closes with live intraday index levels while markets are open, which tells the agent about data freshness. It does not cover payload size or latency for a dashboard-sized response.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core claim, then content coverage, then usage triggers and the freshness caveat. Dense but purposeful; the long parenthetical ticker lists (S&P 500, Nasdaq-100, MSCI World, DAX...) are mildly padded given the schema already enumerates section contents.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-parameter, read-only dashboard tool with no output schema, the description gives enough to call it correctly: scope, freshness semantics, default behavior referenced via the schema, and the downstream historyCode hook. Nothing essential for a correct invocation is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the sections enum plus per-value descriptions already document the parameters, including the default (everything except news and us_housing). The description's section inventory largely restates the schema, adding no syntax or format detail beyond it — baseline 3.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb+resource ('Bullrun's Global Markets dashboard in one call') followed by an explicit inventory of what is returned: indices, policy rates, 16 sovereign 10Y yields, FX, commodities, macro tiles, calendar and news. It also distinguishes itself from get_macro_history by noting each row carries a historyCode, so an agent can tell which tool to reach for without opening either schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete trigger phrasings ('how are markets doing today', 'what's the macro backdrop', 'what's on the calendar this week', morning briefing) and routes history lookups to get_macro_history. It lacks explicit exclusions against other macro siblings such as get_macro_indicators or get_country_macro, so the boundary there is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_macro_historyGet macro / market historyA
Read-only
Inspect

Historical time series behind the Global Markets dashboard, often decades long: equity indices, central-bank policy rates, 10-year government bond yields, FX rates, oil/gas/gold/copper, VIX, DXY, the US 2s10s curve, and per-country macro indicators (GDP growth, inflation, unemployment, house prices, credit gap, debt, confidence, macro stress). Address a series by historyCode (from get_global_markets_overview, get_country_macro or get_macro_indicators), by instrument name ("Fed", "Brent", "Germany 10Y", "S&P 500"), or by indicator + country. Returns summary statistics (latest, change over 1M/3M/1Y/5Y, range, where the latest sits in the window) plus resampled points. Use for "how have rates moved since 2022", "plot Brent over 10 years", "is German unemployment rising". Read-only.

NameRequiredDescriptionDefault
toNoEnd date YYYY-MM-DD (inclusive).
codeNoExact series code from another tool's historyCode field (e.g. "CNBC_US10Y", "BIS_CBPOL_US", "UNEMPLOYMENT:Germany", "YAHOO_GSPC").
fromNoStart date YYYY-MM-DD (inclusive).
countryNoCountry for indicator, e.g. "Japan".
intervalNoResample to end-of-period values. auto = the finest interval that fits maxPoints.auto
indicatorNoOr a per-country macro indicator, together with country (same keys as get_macro_indicators).
maxPointsNoUpper bound on returned points (auto interval only; an explicit interval is truncated to the most recent maxPoints).
instrumentNoOr a market name: an index ("S&P 500", "DAX", "Nikkei 225"), commodity ("Brent", "Gold"), FX pair ("EUR/USD"), central bank ("Fed", "ECB", "BoE"), 10Y yield ("Germany 10Y", "US 10Y"), or headline series ("VIX", "DXY", "2s10s", "global inflation").

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With readOnlyHint/destructiveHint already covering safety, the description goes further by disclosing what comes back — summary statistics (latest, change over 1M/3M/1Y/5Y, range, position in window) plus resampled points — and that series are often decades long. That return-value disclosure is genuinely additive since no output schema exists.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the resource and scope, then addressing modes, then return shape — a sensible order. The long enumeration of series families is the bulkiest part but it is doing selection work; only marginally overlong.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Eight optional parameters with no output schema and no required args demand a lot from the description, and it delivers on addressing modes and return content. The remaining gap is the all-optional behavior: it never says what happens if no parameter is supplied, or how conflicting addressing modes are resolved.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the baseline is 3; the description adds real value by framing the parameters as mutually alternative addressing modes (code vs. instrument vs. indicator+country) and giving instrument-name examples ("Fed", "Brent", "Germany 10Y", "S&P 500"). It does not specify precedence when multiple modes are supplied together, so it isn't a 5.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: retrieves historical time series behind the Global Markets dashboard, and enumerates the concrete series families (equity indices, policy rates, 10Y yields, FX, commodities, VIX, DXY, 2s10s, per-country macro indicators). It also names the sibling tools that supply historyCode, so an agent can distinguish it from the snapshot/overview tools without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly gives the three ways to address a series (historyCode, instrument name, or indicator+country) and supplies three natural-language example queries ("how have rates moved since 2022", "plot Brent over 10 years"). It stops short of stating when to prefer a sibling snapshot tool (get_global_markets_overview / get_country_macro) instead, which keeps it off a 5.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_macro_indicatorsRank countries by macro indicatorA
Read-only
Inspect

Cross-country macro comparison from Bullrun's Global Markets warehouse: rank up to ~200 countries on one indicator (GDP growth annual or quarterly, CPI inflation, government debt/GDP, unemployment, youth unemployment, real house-price growth, house price-to-income and price-to-rent vs history, BIS credit-to-GDP gap, household debt service, household credit/GDP, business and consumer confidence, or Bullrun's macro stress score), or compare a named set of countries. Every row has value, period, source and a historyCode for get_macro_history. Use for "fastest growing economies", "highest inflation in Europe", "most indebted G7 government", "where is housing most overvalued", "compare unemployment in Spain, Italy and Greece". Read-only.

NameRequiredDescriptionDefault
limitNo
orderNodesc = highest value first, asc = lowest first.desc
countriesNoOnly these countries (e.g. ["Germany","France","Italy"]); aliases like US/UK understood. Omit for every covered country.
indicatorYesWhich cross-country indicator: gdp_growth (annual), gdp_growth_quarterly, inflation, government_debt, unemployment, youth_unemployment, real_house_prices, house_price_to_income, house_price_to_rent, credit_gap, household_debt_service, household_credit, business_confidence, consumer_confidence, macro_stress (Bullrun composite).

TDQS

A4.1/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnly/openWorld=false, so the 'Read-only' line is redundant. What earns credit is the added context: coverage of roughly 200 countries, and that every row carries value, period, source and a historyCode — return-shape information the annotations cannot convey and no output schema exists to supply.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The lead clause front-loads the verb, resource and source, and the example queries earn their place by disambiguating the two usage modes. Some length is wasted re-enumerating all 15 indicator values that the enum already lists verbatim.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description usefully states row fields (value, period, source, historyCode) and the country universe. Remaining gaps are minor but real: it doesn't say whether the latest available period is used or how to interpret 'vs history' comparators.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 75% and the enum glosses already explain each indicator; only 'limit' is undocumented. The description adds modest value by expanding friendly names ('government debt/GDP', 'price-to-rent vs history', 'BIS credit-to-GDP gap'), but it never clarifies how 'countries' interacts with ranking or whether the latest period is returned — so it roughly matches the schema baseline.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

Names a specific verb (rank/compare) and resource (countries on a macro indicator) plus the source warehouse. It is clearly separable from siblings: get_macro_history is the time-series companion and get_country_macro is the single-country view, so an agent can route without opening any schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete example questions ('fastest growing economies', 'highest inflation in Europe', 'compare unemployment in Spain, Italy and Greece') that map directly onto the two supported modes: rank-all vs. named-country comparison. It also routes to get_macro_history via historyCode. It stops short of explicitly stating when NOT to use it (e.g. single-country profile → get_country_macro).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_operating_kpisGet operating KPIsA
Read-only
Inspect

Read curated, source-linked operating KPI observations for one exact Bullrun ticker. Coverage is sparse and no automatic KPI feed is configured: do not assume ARR, retention, customer counts or payments metrics are available. Check get_company_data_coverage first. Returns stored fiscal periods, units and source links; company-economics observations are a separate dataset. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum KPI rows to return.
tickerYesBullrun ticker, e.g. "CRWD", "SNOW", "V". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
categoryNoOptional category filter such as SaaS, payments, marketplace, banking, or other domain labels.
metricKeyNoOptional metric key present in stored coverage. No particular business KPI is guaranteed to be available.

TDQS

A4.4/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds substantial behavioral context beyond the annotations: coverage is sparse, no automatic KPI feed is configured, specific metrics should not be assumed available, and the return shape includes stored fiscal periods, units and source links. These details directly affect whether and how an agent invokes the tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with purpose, then coverage caveats, then return details. It is efficient, though the final 'Read-only' repeats the annotation and the coverage warnings are slightly redundant with the 'do not assume' sentence.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the absence of an output schema, the description supplies the key return-context details (fiscal periods, units, source links). It also covers the main risk — sparse coverage — and tells the agent to check coverage first, which is exactly what is needed for correct use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so all four parameters are fully documented in the input schema. The description only broadly mentions 'one exact Bullrun ticker' and does not add syntax or filtering guidance beyond what the schema already provides, making the baseline 3 appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a precise verb and resource — 'Read curated, source-linked operating KPI observations for one exact Bullrun ticker' — and distinguishes the dataset from company-economics observations. An agent can immediately tell what this tool returns and how it differs from related data tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives a clear prerequisite ('Check get_company_data_coverage first') and explicit warnings about what not to expect ('do not assume ARR, retention, customer counts or payments metrics are available'). It does not name a specific alternative tool for company-economics observations, but the routing guidance is strong.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_portfolio_analyticsGet portfolio analyticsA
Read-only
Inspect

Use when the user asks about THEIR portfolio's risk, diversification, or concentration, or whether to add a stock or ETF — e.g. "is my portfolio diversified", "how risky is my portfolio", "am I too concentrated", "what's my exposure to X", "should I add NVDA", "would AAPL improve my diversification". Fetches portfolio-level relationship analytics for one signed-in user's portfolio: correlation and annualized covariance matrices across holdings, contribution-to-risk, concentration by weight and risk, currency/sector/country exposures, value/growth/momentum/quality/size proxy factor scores, scenario/stress tests (rates +100bp, oil -20%, USD +10%), and optional candidateTicker fit analysis showing correlation to the current portfolio plus pro-forma volatility (set candidateTicker when the user asks whether to add a specific stock or ETF). Set includeLookThrough=true with candidateTicker to add duplicate direct/ETF-contained underlying securities in separate lookThroughFit, lookThroughCoverage and lookThroughWarnings fields; this is opt-in and uses a priced-position denominator independent of the risk-history subset. Partial ETF snapshots make duplicate exposure a lower bound. Pass a portfolioId from list_portfolios. The risk math only covers holdings with enough price history, dropping unpriced/unmatched ones (ETFs, funds, untracked tickers) and renormalizing all percentages over what remains; the response leads with a coverage banner (first text block) stating how many holdings were excluded, so never read these figures as the whole portfolio. For a plain holdings/value snapshot and the full matched/unmatched breakdown use get_portfolio_context instead. Requires OAuth (read:portfolios) and returns the caller's own data only. privacyMode defaults to "full"; "weights_only" hides absolute USD amounts while keeping weights, percentages, correlations and scores.

NameRequiredDescriptionDefault
daysNoCalendar-day lookback for daily USD return analytics. Default 370.
portfolioIdYesThe portfolio id, as returned by list_portfolios.
privacyModeNo"full" (default) includes absolute USD amounts; "weights_only" returns only relative figures.
candidateTickerNoOptional exact Bullrun stock or ETF listing ticker to test as a candidate diversifier, e.g. AAPL, BMW, ABBN, NESN or SPY. Use the stored listing ticker; do not infer exchange suffixes.
candidateWeightPctNoOptional hypothetical candidate allocation for pro-forma volatility. Default 5 (%).
includeLookThroughNoAlso compare an exact stock or ETF candidate against direct holdings and stored ETF constituents. Requires candidateTicker. Default false: no underlying holdings requests. Look-through has separate priced-position coverage from price-history risk analytics.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover the read-only/non-destructive safety profile, and the description adds substantial context beyond them: the coverage banner, exclusion and renormalization of unpriced/unmatched holdings, the requirement to never read figures as whole-portfolio, OAuth scope (read:portfolios), caller-only data, and privacyMode default behavior. The only gap is that it doesn't state latency/cost of the heavier analytics or includeLookThrough path.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the when-to-use clause before the mechanics, which is the right order. It is dense and long with some run-on sentences (the look-through sentence packs four concepts), but nearly every clause carries actionable information about coverage caveats or parameter behavior, so little is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a complex six-parameter read tool with no output schema, the description covers inputs, the analytical outputs, the coverage/exclusion caveat, privacy behavior, auth requirements, and the correct sibling for a plain snapshot. An agent has everything needed to call it correctly and interpret the results.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds real semantics beyond the schema: candidateTicker triggers pro-forma fit analysis, includeLookThrough requires candidateTicker and produces separate lookThroughFit/lookThroughCoverage/lookThroughWarnings with an independent priced-position denominator, and privacyMode's 'weights_only' effects are spelled out. It goes beyond restating the fields.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource (fetches portfolio-level relationship analytics) and enumerates exactly what is returned: correlation/covariance matrices, contribution-to-risk, concentration, exposures, factor scores, stress tests, candidate fit. It explicitly contrasts with the sibling get_portfolio_context, so an agent can route between them without opening schemas.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Opens with an explicit trigger ('Use when the user asks about THEIR portfolio's risk, diversification, or concentration, or whether to add a stock or ETF') backed by concrete example utterances, including the exact phrasing for candidateTicker activation. It also names the alternative (get_portfolio_context) and the condition that selects it, and scopes includeLookThrough as opt-in.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_portfolio_contextGet portfolio contextA
Read-only
Inspect

Use when the user asks to look at, review, or analyze THEIR portfolio / holdings / positions — e.g. "analyze my portfolio", "how is my portfolio doing", "what's in my portfolio", "review my holdings", "how am I invested", "what should I improve". Fetches a deep snapshot of ONE of the signed-in user's portfolios: the summary (value, day change, total return), every holding (with position weight %, sector and return) and Bullrun's computed insights (benchmark comparison, concentration, diversification, dividend income). Pass a portfolioId from list_portfolios (call that first if the user hasn't named a portfolio). The response ALWAYS returns the complete holdings list with each position flagged matched/unmatched, plus a coverage summary: holdings that Bullrun can't link to its universe (ETFs, funds, untracked tickers) carry no weight, sector, insight or ML score, so weights/insights/ML below describe ONLY the matched subset. Read the coverage banner (the first text block) and never present matched-only figures as the whole portfolio. For risk/diversification math, correlations, factor exposure, or whether to add a specific stock, use get_portfolio_analytics instead. Requires OAuth (read:portfolios) and returns the caller's own data only. privacyMode defaults to "full" (absolute $ included); "weights_only" returns only relative figures. Read-only.

NameRequiredDescriptionDefault
daysNoInsights look-back window in days (default 30).
portfolioIdYesThe portfolio id, as returned by list_portfolios.
privacyModeNo"full" (default) includes absolute $; "weights_only" returns only relative figures.

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only safety, but the description adds substantial context beyond them: OAuth scope required (read:portfolios), caller's-own-data restriction, the privacyMode default and its effect, and most importantly that unmatched holdings (ETFs, funds, untracked tickers) carry no weight/sector/insight/ML — with an instruction to read the coverage banner and never present matched-only figures as the whole portfolio.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the use case and examples before mechanics, and the coverage caveat is well placed. It is long and slightly repetitive (portfolioId sourcing and privacyMode appear in both prose and schema), but nearly every clause carries load-bearing information for correct interpretation.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the description takes on return-value disclosure — and it does: summary fields, holding fields, insight categories, matched/unmatched flags, and the coverage summary block. Combined with the auth requirement and the analytics alternative, an agent has everything needed to call and interpret this tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and already documents all three params, including the days look-back range and the privacyMode enum, so the description can't add much. It restates privacyMode behavior and the portfolioId source, and it never explicitly mentions the `days` insights window, so it roughly matches rather than exceeds the schema; baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — 'Fetches a deep snapshot of ONE of the signed-in user's portfolios' — and enumerates the payload (summary, holdings with weight/sector/return, computed insights). It also explicitly separates itself from list_portfolios and get_portfolio_analytics, so an agent can route without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Opens with an explicit trigger condition plus five quoted user phrasings, then gives the counter-case: risk/diversification math, correlations, factor exposure, or add-a-stock questions go to get_portfolio_analytics. It also states the prerequisite sequencing ('Pass a portfolioId from list_portfolios (call that first...)').

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_quality_moat_metricsGet quality and moat metricsA
Read-only
Inspect

Compute annual quality, moat, earnings-quality, and capital-allocation metrics for one exact Bullrun ticker from existing financial statements: ROIC, ROE/ROA, ROIC-vs-supplied-WACC, accruals, cash conversion, capex intensity, dividend payout/growth, diluted share-count changes, and a buyback proxy. Read-only.

NameRequiredDescriptionDefault
yearsNoHow many fiscal years of annual history to evaluate.
tickerYesThe Bullrun ticker. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
estimatedWaccPctNoOptional user-supplied WACC assumption, in percent. When omitted, ROIC-vs-WACC spread is returned as null.
taxRateFallbackPctNoFallback tax rate used for NOPAT only when reported tax/pretax data is missing or unusable.

TDQS

A3.5/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=false, destructiveHint=false, so the trailing 'Read-only' earns no credit. The description does add that all outputs are derived from existing statements (no data mutation, no external fetch) and that ROIC-vs-WACC is conditional on a supplied assumption, but says nothing about behavior on missing/unusable statement data, ambiguity resolution, or result shape.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the verb and the domain (quality/moat/earnings-quality/capital-allocation), then a compact metric list. The long enumeration is justified because each item is a distinct output; only the redundant 'Read-only' sentence is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, so the metric enumeration effectively serves as the return-value contract, which is the main completeness requirement here. Minor gaps remain: no statement of the minimum years/history requirement, no mention of null/degraded outputs when inputs are missing (beyond WACC), and no guidance on ambiguous ticker resolution.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already carries parameter meaning and the baseline of 3 applies. The description adds one useful semantic link — 'ROIC-vs-supplied-WACC' ties estimatedWaccPct to a specific output field — but says nothing about years, taxRateFallbackPct, or the ticker-resolution behavior beyond the schema text.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

Specific verb ('Compute') plus a concrete enumeration of derived metrics (ROIC, ROE/ROA, accruals, cash conversion, capex intensity, payout/growth, share-count changes, buyback proxy) on annual data for one ticker. The derived-metric framing distinguishes it in substance from raw-data siblings like get_financial_history and get_stock_metrics, though no sibling is named.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The phrase 'from existing financial statements' and 'annual' implies the context (per-ticker fundamental analysis rather than screening or valuation modeling), and 'one exact Bullrun ticker' hints at the ticker-resolution precondition. But there is no explicit when-to-use/when-not guidance and no pointer to alternatives such as get_valuation_model or get_financial_history.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_revenue_breakdownGet revenue breakdownA
Read-only
Inspect

Fetch segment, geography, product, customer, or other revenue breakdown rows for one exact Bullrun ticker. Use this to separate cyclical businesses from recurring segments or inspect geographic exposure instead of relying on blended revenue. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum breakdown rows to return.
tickerYesThe Bullrun ticker, e.g. "SPGI", "MSFT", "V". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
dimensionNoBreakdown dimension to return, or all dimensions.all

TDQS

A3.8/5.0
Behavior3/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint=true, openWorldHint=false and destructiveHint=false, so the trailing 'Read-only.' adds nothing. The description does not say how rows are returned (flat rows with dimension labels?), whether all dimensions come back at once under 'all', or what happens when the ticker resolves ambiguously — those gaps matter more than the safety profile here.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and scope lead, with the analytical rationale second — good front-loading and no fluff. The final 'Read-only.' clause is pure duplication of the annotations and is the one part that does not earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness3/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description carries the burden of telling the agent what comes back — row shape, whether values are absolute or percentages, and how dimension='all' behaves. None of that is covered, though the input side is fully handled by the schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and both non-trivial parameters (ticker format rules, dimension enum, limit bounds) are already fully documented in the schema, so the description cannot add much. Its mention of the five dimension values merely echoes the enum. Baseline 3 is appropriate.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Fetch ... revenue breakdown rows') and enumerates the dimensions covered (segment, geography, product, customer, other), which separates it from the blended-revenue siblings like get_financial_history or get_stock_metrics.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a concrete use case: separate cyclical from recurring segments, or inspect geographic exposure 'instead of relying on blended revenue'. That implies when to prefer it, but it never names the sibling tool an agent should use for blended revenue, so routing is only half-explicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_risk_moversGet risk moversA
Read-only
Inspect

Companies whose Bullrun composite risk score crossed into a different band (e.g. Elevated -> Stretched, or Acute -> Stretched) within the last N days, with prior and current score, the move in points, and the input driving the reading. Use for "what got riskier this week", "any risk deteriorations I should know about", or to monitor a watchlist (pass the tickers to get_company_risk afterwards). Band changes, not small score drift, so every row changed a word on the page. Read-only.

NameRequiredDescriptionDefault
daysNoLook-back window in days for band changes.
limitNo
directionNoKeep only companies whose composite got worse, got better, or both.all
minMarketCapUsdNoOnly companies with at least this market capitalisation in USD, e.g. 1e9 for $1B+. Without it the list is dominated by micro-caps, whose scores move most.
stableBasisOnlyNotrue (default) = only real movements. false also includes band changes caused purely by a category starting or stopping scoring (coverage changes, flagged basisChanged).

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already cover read-only/no-destruction, so the description correctly focuses on semantics: it explains that rows represent band crossings rather than drift, and that default behavior suppresses movements caused purely by coverage changes (stableBasisOnly). It omits pagination/limit behavior and what happens when more movers exist than the limit allows, which is the main remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The core definition and returned fields come first, followed by usage triggers and the band-vs-drift caveat. It is somewhat long with a parenthetical example and a quoted-phrase list, but each clause carries real routing value rather than filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description does the necessary work by naming the returned fields (prior/current score, point move, driving input). It does not cover result-set size limits or ordering, which matters for a ranked list tool with a limit parameter, so it falls just short of complete.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 80%, so days, direction, minMarketCapUsd and stableBasisOnly are already documented with rationale in the schema. The description adds little parameter-specific detail beyond restating the N-day window; the micro-cap and coverage-change caveats live in the schema, not the description, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names a specific resource (companies whose Bullrun composite risk score crossed a band) and a specific scope (last N days), then enumerates exactly what each row contains. It is clearly separable from siblings: get_company_risk is single-name, screen_risk_board is a filter board, and the description explicitly routes to get_company_risk as the follow-up step.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives concrete user-intent triggers ("what got riskier this week", "risk deteriorations", watchlist monitoring) plus the downstream pattern of passing tickers to get_company_risk. It also states the rejection criterion — band changes only, not small score drift — which tells the agent when this tool is the wrong choice.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_stock_metricsGet stock metricsA
Read-only
Inspect

Fetch a consolidated metrics snapshot for a single stock by ticker: identity (company, exchange, currency, sector, industry, country, ISIN), latest daily price (OHLCV), latest valuation (market cap, P/E, dividend yield, annual dividend per share), the most recent reported financials (revenue, gross/operating income, EBITDA, net income, diluted EPS, free & operating cash flow, total debt, cash, total assets, equity) and a short company description. Prices are in the listing's trading currency; financials in their own sourceCurrency. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN. Read-only.

NameRequiredDescriptionDefault
tickerYesThe stock ticker as Bullrun lists it, e.g. "AAPL", "BMW", "NESN", "6324.T", "0700.HK" or "005930". A bare numeric code is resolved when exactly one listing matches.

TDQS

A4.5/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The annotations already establish readOnlyHint, destructiveHint, and openWorldHint, so the description does not need to re-state safety. It adds useful behavioral context by specifying currency semantics: prices are in the listing's trading currency and financials are in sourceCurrency, plus automatic ticker resolution when one listing matches.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The purpose and return fields are front-loaded, so an agent can quickly identify the tool. The description is dense and the field enumeration is long, but most of it earns its place by disambiguating the consolidated snapshot from sibling tools and clarifying ticker formats.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, but the description enumerates the returned sections and fields in enough detail for an agent to know what to expect: identity, latest OHLCV, valuation, recent financials, and company description. It also covers the important currency caveat and ticker resolution behavior, leaving little material ambiguity for this read-only tool.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the schema has 100% coverage for the single ticker parameter, the description adds substantial meaning beyond it. It explains regional ticker conventions, suffix usage across Asian and Indian exchanges, plain-code exceptions for some Japanese and Korean large caps, and the automatic resolution rule.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description uses a specific verb and resource: "Fetch a consolidated metrics snapshot for a single stock by ticker." It then enumerates the exact contents (identity, latest price, valuation, financials, company description), which clearly distinguishes it from sibling tools focused on histories, valuations, or comparisons.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly tells the agent to use search_stocks when it only has a company name or ISIN, and it explains ticker resolution behavior when exactly one listing matches. However, it does not explicitly contrast this snapshot tool with siblings like get_financial_history or get_stock_price_history, so the when-to-use guidance is clear but not fully comparative.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_stock_price_historyGet stock price history and technical indicatorsA
Read-onlyIdempotent
Inspect

Read bounded stored stock OHLCV history, ascending by trade date, as daily, weekly or monthly bars, with close-based price returns/drawdown and optional deterministic SMA, EMA, Wilder RSI and MACD. Useful for price trends, volatility context and technical analysis; use get_stock_metrics for a latest company snapshot. Up to 2600 recent daily source rows; dates filter that bounded window. Provider split/dividend adjustment is unknown: returns are not verified total returns. Missing OHLCV/indicator warm-up remains null; no synthetic sessions, intraday data or live quote claims. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum most-recent DAILY source bars to load before date filtering and aggregation (hard cap 2600). Increase for indicator warm-up or longer history.
tickerYesBullrun stock ticker, e.g. AAPL, SAP, ABBN, 6324.T or 7203. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.
endDateNoInclusive last trade date; the API still loads the most recent source bars before this filter.
intervalNoAggregate stored daily bars. Weekly buckets start Monday; monthly buckets use the calendar month. No intraday or live quotes.daily
rsiPeriodNoNumber of close-to-close changes for Wilder RSI. MACD uses fixed EMA periods 12/26 and signal 9.
startDateNoInclusive trade-date cutoff, applied after loading the latest source bars. Cannot page into history older than the source limit.
indicatorsNoOptional indicators computed on the selected interval's closes after date filtering. Insufficient warm-up yields null, never a fabricated value.
movingAveragePeriodNoObservation count for SMA and EMA, in the selected interval.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Beyond the annotations, the description discloses the 2600-row bounded source window, the fact that date filters apply after loading recent bars, unknown provider split/dividend adjustment, null warm-up behavior, and the absence of synthetic sessions, intraday data, or live quotes. This is materially useful behavioral context for a read-only historical data tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is dense but front-loaded and appropriate for an 8-parameter analytical tool. It is slightly repetitive in places, such as restating read-only and no-intraday constraints, but each sentence generally adds operational value.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema and a relatively complex parameter set, the description provides the necessary context: bounded history limits, aggregation behavior, indicator warm-up nulls, adjustment caveats, and exclusions. An agent can invoke and interpret this tool correctly without additional documentation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so parameter details are already well documented. The description nevertheless adds useful semantics: the limit is a bounded daily-source-row cap applied before date filtering and aggregation, dates filter that bounded window, and indicators are computed after date filtering with nulls for insufficient warm-up.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description names the specific resource (stored stock OHLCV history), the supported intervals, returns/drawdown, and optional technical indicators. It also explicitly distinguishes itself from get_stock_metrics, which is for a latest company snapshot.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear use cases (price trends, volatility context, technical analysis) and names the alternative tool for a latest company snapshot. The bounded-window and date-filter caveats further clarify when this tool is appropriate.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_valuation_modelGet Bullrun valuation modelA
Read-only
Inspect

Bullrun's proprietary machine-learning valuation and forecast scores for 1-10 stocks, recomputed nightly. Valuation: a LightGBM model predicts the P/E (or price/sales for loss-makers) that companies with similar fundamentals typically command a year out; the gap = typical / current multiple - 1 (positive = trades below its typical multiple), with the implied model-typical P/E, percentile and rank in the scored universe. Forecast: a relative 1-year return-rank signal with percentile. Both on quarterly and on annual financials (annual covers most non-US companies). Use for "is X cheap or expensive", "what's X's fair P/E", "compare valuations of X, Y, Z", or a valuation sanity check before buying. Descriptive context, not a price target or recommendation. Read-only.

NameRequiredDescriptionDefault
tickersYes1-10 Bullrun tickers, e.g. ["AAPL","MSFT"] or ["ASML","SAP","NESN"]. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN.

TDQS

A4.1/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Going well beyond the readOnlyHint/destructiveHint=false annotations, it discloses that scores are recomputed nightly, the model family, the sign convention of the gap, that percentiles/ranks are relative to the scored universe, and that annual-financials coverage extends to most non-US companies. These are exactly the interpretive facts an agent needs to report the numbers without misreading them.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads the core claim and the 1-10 limit, then methodology, then usage examples — a logical order. It is long and methodology-dense, but nearly every clause (sign convention, percentile basis, annual-coverage caveat) earns its place; the methodology could be tightened without losing meaning.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter, read-only, fully-described-schema tool with no output schema, the description supplies the missing interpretive layer — what the two score families measure, how to read the sign, and what the rankings are relative to. Nothing an agent needs to call and correctly communicate results is absent.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the ticker parameter already documents suffix conventions, 1-10 bounds, and resolution behavior. The description only echoes the 1-10 cap; it adds no syntax or edge-case detail (e.g., partial-resolution failures) beyond the schema, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb+resource: fetches Bullrun's LightGBM valuation-gap scores and relative-return forecast rankings for a ticker set, and explains what each output means (gap = typical/current multiple - 1). It differentiates itself functionally from metric/history siblings, but never names the closest sibling screen_valuation_model, so an agent must infer retrieval-vs-screening from context.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete triggering questions ("is X cheap or expensive", "what's X's fair P/E", "compare valuations of X, Y, Z") and a pre-buy sanity-check scenario, plus a clear boundary ("descriptive context, not a price target or recommendation"). It does not state when NOT to use it or point to screen_valuation_model for universe-wide valuation screening.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_portfoliosList my portfoliosA
Read-only
Inspect

Use when the user refers to THEIR portfolio(s) or holdings — e.g. "my portfolios", "what portfolios do I have", "how are my investments doing", "show my holdings", "my account". Lists the signed-in Bullrun user's virtual portfolios with computed summaries: name, base currency, total value (USD), day change, cost basis and total return, plus position counts. Start here when a portfolio question doesn't name a specific portfolio, then pass a portfolioId to get_portfolio_context or get_portfolio_analytics. Requires connecting this server to a Bullrun account (OAuth, read:portfolios scope) — it returns that user's own data only. privacyMode defaults to "full" (includes absolute $ amounts); pass "weights_only" to hide absolute money and return only relative figures (returns %, counts). Read-only.

NameRequiredDescriptionDefault
privacyModeNo"full" (default) includes absolute $; "weights_only" hides cash/value/cost-basis and keeps only %.

TDQS

A4.8/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnly annotation by disclosing the OAuth requirement, the read:portfolios scope, that only the user's own data is returned, and the default behavior of privacyMode with its effect on the response. These are exactly the operational facts an agent needs before calling.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the trigger condition and entry-point rule, then prerequisites and the parameter default. The run of example phrasings is slightly long but each maps to a real disambiguation case, so little is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a zero-required-param, read-only list tool with no output schema, the description supplies triggers, next-step routing, auth prerequisites, and return-value expectations, leaving no material gap for correct invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the enum is documented in the schema, so the baseline is 3. The description adds value by stating the default ('privacyMode defaults to full') and explaining the user-facing intent of 'weights_only' (hide absolute money, return relative figures), which clarifies when to switch modes.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Lists the signed-in Bullrun user's virtual portfolios') and explicitly differentiates from siblings by naming get_portfolio_context and get_portfolio_analytics as the next step.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides explicit trigger phrases ('my portfolios', 'show my holdings', 'my account'), a clear entry-point rule ('Start here when a portfolio question doesn't name a specific portfolio'), and the handoff condition ('then pass a portfolioId to...').

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

list_research_shortlistRead my research shortlistA
Read-onlyIdempotent
Inspect

Read the signed-in user's saved Research Shortlist of stock and ETF listing tickers, with dated stored prices. Requires OAuth read:shortlist. Use after the user asks for their saved research queue. Read-only; does not evaluate a screen, schedule monitoring or send notifications.

NameRequiredDescriptionDefault

No parameters

TDQS

A4.4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint, idempotentHint and destructiveHint=false, so the 'Read-only' sentence largely restates them; however, the description adds non-trivial behavioral facts the annotations do not contain: the OAuth scope read:shortlist and the fact that results are scoped to the signed-in user. It does not mention ordering, pagination or limits on the returned list, which is the remaining gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three short sentences, each carrying distinct information: what is returned, what is required to call it, and when to call it. The auth requirement is placed before the usage guidance, which is the right front-loading for a tool that will fail without a scope.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no input schema, no output schema and only read annotations, the description covers everything an agent needs to decide and call: data returned, user scoping, required scope, and the boundaries of the operation. Only the shape/ordering of the returned shortlist is unstated, which is minor for a zero-argument read.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The tool takes zero parameters, so the baseline is 4; the description correctly adds no parameter prose and instead spends its words on scope and auth. Nothing about arguments is missing because there are none.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Read the signed-in user's saved Research Shortlist of stock and ETF listing tickers') and even names the payload contents ('with dated stored prices'). It is clearly distinguishable from save_research_shortlist, which is its only near-twin among the siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit trigger ('Use after the user asks for their saved research queue') and three named exclusions (evaluating a screen, scheduling monitoring, sending notifications) that keep the agent from overreaching. It stops short of explicitly naming save_research_shortlist as the write counterpart, so the read/write pairing is left implicit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

save_research_shortlistSave research to my shortlistA
Idempotent
Inspect

Add 1-20 exact Bullrun stock or ETF listing tickers to the signed-in user's Research Shortlist when the user asks to save them. Requires OAuth write:shortlist; reconnect if this scope was not granted. Resolve ambiguous names with search_stocks/search_etfs first. Existing entries are retained; repeated saves are idempotent. Each ticker is saved independently and failures are reported alongside successful saves, so retry only failed tickers. Does not create a portfolio, schedule monitoring or send notifications.

NameRequiredDescriptionDefault
tickersYesExact listing tickers chosen by the user, e.g. AAPL or EUNL.DE.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare the safety profile (idempotent, non-destructive, not read-only), but the description adds context annotations cannot: the OAuth scope requirement (write:shortlist) and reconnection remedy, the fact that existing entries are retained, and the partial-batch failure model with retry guidance. That is exactly the kind of behavioral detail an agent needs before invoking a write tool.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The verb and resource are front-loaded in the first clause, and each subsequent sentence contributes a distinct operational fact (auth, resolution, retention, partial failure, exclusions). There is no filler or repetition of schema-level detail.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a single-parameter mutation with no output schema, the description covers everything an agent needs: trigger condition, auth prerequisite, input resolution, idempotency/retention semantics, and how failures are surfaced. Nothing material is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100% and the schema already documents the tickers array, pattern, and bounds, so the baseline is 3. The description adds real meaning by stressing 'exact Bullrun stock or ETF listing tickers' and by directing the agent to resolve ambiguous names via search_stocks/search_etfs before calling, which prevents the most likely misuse.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (Add), resource (exact Bullrun stock or ETF listing tickers), and destination (the signed-in user's Research Shortlist), with the quantity bound (1-20). It also distinguishes itself from siblings by name (search_stocks/search_etfs for resolution, list_research_shortlist implicitly as the read counterpart) and by explicit exclusions (does not create a portfolio, schedule monitoring, or send notifications).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives a clear trigger ('when the user asks to save them'), an alternative routing rule ('Resolve ambiguous names with search_stocks/search_etfs first'), and explicit exclusions ('Does not create a portfolio, schedule monitoring or send notifications'). Nothing about when to use this versus alternatives is left to inference.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

screen_etfsScreen ETFsA
Read-only
Inspect

Screen the WHOLE ETF universe by numeric rules and fund attributes in one pass — expense ratio, AUM, yield, trailing returns, volatility, liquidity, top-10 concentration, fund age and holdings count — combined with issuer, index, domicile, UCITS status, distribution policy, currency hedging and constituent look-through (holdingSearch finds funds by what they hold). Prefer this over search_etfs for any "cheapest / largest / best performing / most liquid" question: search_etfs only filters a bounded candidate scan, while this evaluates the full universe and reports evaluatedCount and matchCount. Percentages are percentage points. This full-universe screen is an expensive read, and request limits depend on your connection and plan. Build one precise screen to conserve your allowance. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum ETFs to return, 1-100.
orderNoSort direction. Nulls always sort last regardless of direction.desc
rulesNoNumeric rules. A fund with no value for a ruled metric never matches that rule.
issuerNoSubstring match on the fund family/issuer, e.g. "iShares", "Amundi", "Vanguard".
regionNoExact investment-region string.
searchNoFree-text match on ticker, fund name or ISIN. Omit to screen the whole universe.
sortByNoSort field applied to the returned rows.totalAssets
categoryNoExact category string. Call get_etf_filter_options for the valid values; a wrong guess silently returns zero rows.
currencyNoExact trading currency, e.g. EUR, USD, GBX.
domicileNoExact fund domicile, e.g. "Ireland", "Luxembourg", "United States".
exchangeNoExact listing exchange, e.g. XETRA, LSE, "NYSE ARCA".
indexKeyNoExact tracked-index key, e.g. SP500, MSCI_WORLD, NASDAQ100. Use get_etf_index_group to compare every fund on one index instead.
strategyNoExact strategy classification string.
assetClassNoExact asset-class group: EQUITY, FIXED_INCOME, COMMODITY, REAL_ESTATE, MULTI_ASSET, CASH, CURRENCY, DIGITAL_ASSETS, ALTERNATIVES or OTHER.
holdingModeNoINCLUDES keeps funds holding the constituent. EXCLUDES keeps only funds with a holdings snapshot that confirms absence — funds with no snapshot are dropped, never assumed clean.INCLUDES
productTypeNoExact wrapper type, e.g. UCITS_FUND.
ucitsStatusNoUCITS restricts to wrappers a European retail investor can actually buy.
holdingSearchNoLook-through filter: find funds by a CONSTITUENT ticker or company name, e.g. "NVDA" or "NVIDIA". Only funds with a stored holdings snapshot can match.
currencyHedgedNoHEDGED selects funds labelled currency-hedged. NOT_LABELLED_HEDGED selects funds not so labelled — absence of a label is not proof a fund is unhedged.
benchmarkSearchNoSubstring match on the stated benchmark name.
includeSecondaryNoReturn every venue listing as its own row. Default false: one row per FUND (by fund ISIN), showing its most liquid listing with the others under otherListings. Use exchange/currency to choose the venue, e.g. exchange "SW" for the SIX line.
marketDevelopmentNoExact market-development classification, e.g. developed vs emerging.
distributionPolicyNoAccumulating (reinvests income) or distributing (pays it out) — the usual first cut for a European investor.
holdingMinWeightPctNoMinimum constituent weight in percentage points for holdingSearch to count as a match.

Output Schema

NameRequiredDescription
queryYes
resultsYes
webPageNo
coverageYes
returnedYes
warningsYes
matchCountYes
platformLinkNo

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already mark read-only, non-destructive, closed-world, so the safety profile is covered. The description adds value beyond them: it warns this is an expensive full-universe read, notes request limits depend on connection/plan, advises building one precise screen to conserve allowance, reports evaluatedCount/matchCount, and states percentages are percentage points. That is substantial extra behavioral context, though it doesn't discuss latency or failure modes.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and the sibling comparison, and each sentence conveys actionable information (routing rule, unit convention, cost warning). The long attribute enumeration is dense but purposeful; the only mild bloat is the full metric list repeating enum values.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given 24 optional parameters, a rich schema and an output schema, the description covers the essentials an agent needs: when to pick this tool, cost constraints, unit conventions, and the evaluatedCount/matchCount return signal. Remaining gaps (pagination, output field shapes) are handled by the output schema, so it is nearly complete for a tool of this complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so every one of the 24 parameters is already documented in structured fields, which sets the baseline at 3. The description adds the percentage-point unit convention and a couple of example values, but most semantic weight is carried by the schema's own per-parameter descriptions (groupId AND/OR grouping, EXCLUDES semantics, includeSecondary venue handling).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Screen the WHOLE ETF universe") and enumerates the metric families it can filter on, so the tool's scope is unmistakable. It explicitly distinguishes itself from search_etfs (full-universe evaluation vs. bounded candidate scan), letting an agent tell the two apart without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives an explicit routing rule: prefer this over search_etfs for "cheapest / largest / best performing / most liquid" questions, with the reason stated. The schema and description also point to get_etf_index_group and get_etf_filter_options for adjacent needs, covering the when-to-use and when-to-use-else paths.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

screen_risk_boardScreen the risk boardA
Read-only
Inspect

Rank Bullrun's scored stock universe (~9,000 companies) by company risk: the composite risk score or any one mechanism dial (market expectation, operating pressure, cash conversion, leverage, competitive position, concentration), filtered by band, sector, country and dial coverage. Returns ticker, score, band and its meaning, direction and move since the prior reading, and the driving input per row, plus the universe band distribution and how many companies changed band at the last recompute. Use for "which large caps have stretched leverage", "most concentrated supply chains in semiconductors", "calmest German industrials", or "how risky is tech vs utilities" (includeSlices). Drill into a row with get_company_risk. A ranking of readings, not of companies to avoid. Read-only.

NameRequiredDescriptionDefault
bandsNoKeep only these bands, e.g. ["STRETCHED","ACUTE"] for the most strained readings or ["CONTAINED"] for the calmest.
limitNo
offsetNo
sectorNoExact sector, case-insensitive (e.g. "Technology", "Industrials"). Set includeSlices=true to list the sectors the board covers.
sortByNomarket_cap = largest companies first (default; a pure score sort surfaces micro-caps); score_desc = most strained first; score_asc = calmest first; worsened / improved = biggest move since the prior reading; coverage = most dials lit; name.market_cap
countryNoExact country, case-insensitive (e.g. "United States", "Germany").
mechanismNoRank by the composite (OVERALL) or by one mechanism dial: MARKET (drawdown, volatility, liquidity), OPERATING (margin/cost pressure), CASH_CONVERSION (cash vs earnings, capex), LEVERAGE (debt, interest cover, liquidity; CET1 for banks), COMPETITIVE (R&D, margins vs peers, technology transition), CONCENTRATION (supplier, customer, geographic).OVERALL
minDialsLitNoCoverage floor: only companies with at least this many of the six dials measured. 4+ avoids thinly-measured composites.
includeSlicesNoAlso return mean composite risk by sector and by country across the scored universe.

TDQS

A4.6/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/destructiveHint=false, and the description adds real value beyond that: it states what each row returns (ticker, score, band and meaning, direction, move since prior reading, driving input) plus universe-level band distribution and band-change counts. It does not discuss pagination caps or rate limits, so it stops short of fully exhaustive.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core action and universe, then filters, then return shape and use cases. Dense but nearly every clause earns its place; the single long paragraph is slightly run-on compared with a bulleted structure.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

No output schema exists, yet the description fully covers the return payload (per-row fields, band distribution, band-change count) and supplies the interpretive caveat. For a 9-parameter, all-optional screening tool, an agent has everything needed to call and read it correctly.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 78%, so the schema carries most parameter docs, but the description still adds meaning: it groups the filter dimensions (band, sector, country, dial coverage) and explains the purpose of includeSlices for sector/country comparison. The mechanism dials are expanded with business meaning that reinforces the enum.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource — rank the ~9,000-company scored universe by composite risk or a single mechanism dial — and enumerates the filters. It is clearly distinct from sibling screen_stocks (equity screening) and get_company_risk (single-row drill-down).

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Provides four concrete example queries mapping to real use cases, explains when to use includeSlices ("how risky is tech vs utilities"), and explicitly routes row-level inspection to get_company_risk. It also bounds interpretation: "A ranking of readings, not of companies to avoid."

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

screen_stocksScreen stocksA
Read-only
Inspect

Screen the global Bullrun stock universe with the app rule engine using custom fundamental rules or named presets: profitable value, dividend income, growth and cash flow, cash generators, dividend growth. action=list_presets discloses exact thresholds, units, annual lookback and sorting without any backend request. action=run (default) executes one preset or custom rules; running uses the API's metered screening budget. Custom screens support sector/industry/country, listing controls, annual/quarterly lookback, AND/OR rule groups and money units. Presets are mechanical starting points, not recommendations or famous-investor strategies. Read-only.

NameRequiredDescriptionDefault
modeNoDeprecated alias for lookbackMode; kept for compatibility.
limitNoMaximum stocks to return: custom default 25 (1-100), preset default 20 (1-50).
orderNoSort direction. Custom default desc; presets use their disclosed order. Nulls always sort last regardless of direction.
rulesNoFundamental rules. Same groupId means AND; different groupIds mean OR.
actionNolist_presets discloses named screens without any backend request; run executes a preset or custom rules and uses the metered screening budget.run
presetNoOptional named screen. Presets use disclosed fixed rules/sorting, annual lookback (2-10 years), primary active listings and a default limit of 20 (maximum 50). Omit for custom rules; do not combine with rules or minMarketCap.
sectorNoExact sector name to filter by, e.g. "Technology", "Healthcare". Omit for all sectors.
sortByNoMetric to sort by. Custom default marketCap; presets use their disclosed sorting. revenueGrowth is accepted as an alias for revenueGrowthPct.
countryNoExact country name to filter by, e.g. "United States", "Germany". Omit for all countries.
periodsNoDeprecated alias for lookback; kept for compatibility.
industryNoExact industry name to filter by, e.g. "Software - Infrastructure". Omit for all industries.
lookbackNoHow many reporting periods to evaluate (default 3). Growth rules need at least 2 comparable periods; presets require 2-10 annual observations.
countriesNoExact country names to include. Use this for multi-country screens; it overrides country when provided.
lookbackModeNoWhether rule evaluation uses annual or quarterly reporting periods. Default annual; presets require annual.
minMarketCapNoCompatibility shortcut: adds marketCap >= this absolute value to every rule group.
includeInactiveNoInclude delisted/inactive tickers with no recent price bar. Default false.
includeSecondaryNoInclude secondary cross-listings of the same security. Default false (primary listings only).

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Adds context beyond the annotations: list_presets performs no backend request, while run consumes the API's metered screening budget — a genuine cost/rate consideration an agent needs. It also discloses the 'not a recommendation' framing and restates read-only. It does not describe the response shape or what a screened result set looks like.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded with the core verb and the preset list, then the mode semantics, then the caveats. Some clauses are dense ('Custom screens support sector/industry/country, listing controls...') and could read as a feature dump, but no sentence is filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For a 17-parameter, zero-required screening tool with no output schema, the description covers the decision-relevant surface well: mode selection, budget cost, preset semantics, and scope of custom rules. The notable gap is that it says nothing about what a returned result contains or how many rows are ranked, which the agent must infer from the limit schema.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description goes further by naming the capability surface an agent would otherwise have to reconstruct from 17 properties — sector/industry/country filters, listing controls, annual vs quarterly lookback, AND/OR rule groups, and money units. It stops short of explaining parameter interactions (e.g. that presets cannot be combined with rules or minMarketCap, which only appears in the schema).

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ('Screen the global Bullrun stock universe with the app rule engine') and enumerates the two operating modes (custom rules vs named presets, with the five preset names). It implicitly separates itself from screen_etfs via 'stock universe' but never names a sibling explicitly to sharpen the boundary.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Clearly explains when to use action=list_presets (discloses thresholds without a backend request) versus action=run (executes and consumes the metered budget), and warns that presets are mechanical starting points, not recommendations. It does not tell the agent when a different sibling tool (e.g. search_stocks, screen_etfs) is the better fit.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

screen_valuation_modelScreen by Bullrun valuation modelA
Read-only
Inspect

Rank the whole scored stock universe (market cap >= $100M) by Bullrun's proprietary ML models: the stocks trading furthest below (or above) the P/E or price/sales multiple their fundamentals typically command, or the strongest/weakest relative 1-year forecast signals. Filter by sector, country, exchange and financial-history coverage. Each row has the valuation gap or forecast edge, the model-typical vs current P/E, percentile, rank and data quality. Use for "cheapest stocks vs fundamentals in Europe", "most expensive tech names by the model", "best forecast scores in Japan". The valuation gap is descriptive context, not a return prediction; follow up with get_stock_metrics, get_company_risk and get_quality_moat_metrics before drawing conclusions. Read-only.

NameRequiredDescriptionDefault
endNotop = highest percentile first (valuation: furthest BELOW typical multiple, i.e. cheapest vs fundamentals; forecast: strongest signal). bottom = lowest first (richest vs fundamentals / weakest signal).top
limitNo
modelNovaluation = P/E gap on quarterly financials (profitable companies); valuation_ps = price/sales gap (covers loss-makers); valuation_annual_1y = P/E gap on annual financials (broader non-US coverage); forecast / forecast_annual_1y = relative 1-year return-rank signal.valuation
sectorNoExact sector, case-insensitive, e.g. "Technology", "Healthcare", "Financial Services".
countryNoExact country, case-insensitive, e.g. "United States", "Germany", "Japan".
coverageNofull = only stocks whose model window (8 quarters / 4 years) is fully populated; limited = the rest.all
exchangeNoExact exchange code, case-insensitive, e.g. "NASDAQ", "XETRA", "LSE".

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare read-only, non-destructive, closed-world, so the description's additions are the real value: the universe constraint, the per-row payload (valuation gap, model-typical vs current P/E, percentile, rank, data quality), and the important caveat that the gap is descriptive context rather than a return prediction. No pagination or rate-limit detail, which caps it at 4.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loads what is ranked and by which models, then filters, then row contents, then example queries, then the interpretive caveat. Dense but every sentence carries information; no filler or restatement of the title.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With no output schema, the description still enumerates the returned fields and data-quality signal, defines the universe, and warns about interpretation. An agent can call this and correctly frame the result without further context.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 86% and the enum descriptions already explain the model variants and top/bottom ordering in detail. The description reinforces the model family in prose (P/E gap, price/sales gap, forecast signal) and names the filter dimensions, but adds no syntax or format detail beyond what the schema carries, so the baseline 3 applies.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb and resource ("Rank the whole scored stock universe... by Bullrun's proprietary ML models") and pins down the universe scope (market cap >= $100M), which distinguishes it from the generic screen_stocks and the single-name get_valuation_model siblings.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Gives concrete selection context ("Use for 'cheapest stocks vs fundamentals in Europe', 'most expensive tech names by the model'...") plus explicit follow-up tools (get_stock_metrics, get_company_risk, get_quality_moat_metrics). It does not explicitly contrast itself with screen_stocks or get_valuation_model, so no true when-not guidance.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_etfsSearch ETFsA
Read-only
Inspect

Look up ETFs by name, ticker or ISIN, with classification, listing, index, distribution-policy, AUM, expense-ratio and yield filters. Best for finding a known fund. For ranking questions ("cheapest", "largest", "best performing", "most liquid") prefer screen_etfs, which evaluates the whole universe: here minAum and minYieldTtmPct are applied only to a bounded profile-enriched candidate scan, so do not describe the result as exhaustive when candidateCapReached is true. Use get_etf_snapshot for one listing, get_etf_fund to resolve an ISIN across venues, and get_etf_holdings for constituents. Read-only.

NameRequiredDescriptionDefault
focusNoExact ETF focus/exposure filter, e.g. Japan, TOPIX, or Equity - Australia.
limitNoMaximum matching ETFs to return, 1-100.
minAumNoMinimum assets under management in the profile's reported currency units.
regionNoExact portfolio or investment-region filter.
searchNoFree-text ETF search by ticker, fund name, or ISIN (e.g. IE00B4L5Y983). Omit for a broad screen.
sortByNoSort field. Relevance preserves Bullrun search ordering.relevance
categoryNoExact broad ETF category/asset-class filter, e.g. Equity, Fixed Income, Commodity, Crypto, or Real Estate. Call get_etf_filter_options for valid values.
currencyNoExact trading-currency filter.
domicileNoExact fund domicile filter.
exchangeNoExact listing exchange filter.
indexKeyNoExact tracked-index key, e.g. SP500 or MSCI_WORLD. Use get_etf_index_group to rank every fund on one index by cost.
scanLimitNoMaximum coarse-search candidates to enrich before applying quantitative filters/sorts, 25-500.
sortDirectionNodesc
minYieldTtmPctNoMinimum trailing yield in percentage points, e.g. 2 means 2%.
includeInactiveNo
includeSecondaryNo
distributionPolicyNoAccumulating (reinvests income) or distributing (pays it out).
maxExpenseRatioPctNoMaximum annual expense ratio in percentage points, e.g. 0.25 means 0.25%.

Output Schema

NameRequiredDescription
queryYes
resultsYes
webPageNo
coverageYes
returnedYes
warningsYes
platformLinkNo
matchesInScannedCandidatesYes

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Although annotations already declare read-only/non-destructive behavior, the description adds a material behavioral caveat: minAum and minYieldTtmPct apply only to a bounded profile-enriched candidate scan, and the result should not be described as exhaustive when candidateCapReached is true. That is exactly the kind of operational disclosure annotations cannot provide.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is front-loaded with the lookup behavior, then immediately gives ranking alternatives, sibling routing, and the bounded-scan caveat. It is dense but every sentence carries a distinct operational instruction; nothing is wasted.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

With an output schema, clear annotations, 18 documented parameters at 83% coverage, and explicit sibling routing, the definition gives the agent everything needed to choose and invoke this tool correctly. The candidateCapReached caveat closes the main remaining ambiguity about result completeness.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is already high at 83%, so the baseline is 3. The description adds meaningful semantics for the quantitative filters by explaining that they are applied only after a bounded candidate-enrichment scan, which is not fully apparent from the individual parameter descriptions.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: look up ETFs by name, ticker or ISIN, with a long list of filter dimensions. It immediately distinguishes the tool from screen_etfs by positioning it as best for finding a known fund rather than ranking the whole universe.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It explicitly says when to use this tool versus screen_etfs for ranking questions, and it routes the agent to get_etf_snapshot, get_etf_fund, and get_etf_holdings for adjacent needs. The alternatives and selection conditions are named, not implied.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

search_stocksFind stock tickers and company listingsA
Read-only
Inspect

Resolve a company name, native ticker, ISIN or exchange-qualified symbol to Bullrun listings before calling exact-ticker research tools. Supports exchange/MIC, country, currency and instrument-type filters. Recognized Yahoo suffixes are checked against compatible stored venues; dots in native share-class tickers are preserved. Returns explicit ambiguous candidates and never picks a listing when alternatives remain. No enrichment or market-data refresh. Read-only.

NameRequiredDescriptionDefault
limitNoMaximum output candidates. A backend scan is capped at 500 candidates per search.
queryYesCompany/name phrase, exact native ticker (AAPL, BMW, BRK.B), ISIN, EXCHANGE:TICKER, or Yahoo symbol (BMW.DE, NESN.SW).
countryNoExact stored country name, e.g. Germany or Switzerland.
currencyNoListing quote currency, e.g. USD, CHF or GBX. GBX and GBP are different quote units.
exchangeNoStored exchange code or supported MIC, e.g. XETRA/XETR, NASDAQ/XNAS, SW/XSWX. A conflicting prefix is rejected.
quoteTypeNoDefault stocks, including unclassified equities. ETF/ALL allow other instrument lookup; this does not make stock-only research tools valid for funds.EQUITY
includeInactiveNoInclude inactive/retired listings. Returned lifecycle/successor fields must be checked.
includeSecondaryNoInclude alternative venue listings. ISIN/name matches across venues require an explicit listing choice.

TDQS

A4.3/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Goes well beyond the readOnly/openWorld annotations by disclosing disambiguation behavior ('explicit ambiguous candidates', 'never picks a listing when alternatives remain'), suffix-to-venue validation, and share-class dot preservation. The trailing 'Read-only' is redundant with the annotations, and nothing is said about result shape or candidate ordering.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Dense and front-loaded: the resolution purpose and the sequencing constraint come first, followed by scope limits. Nearly every clause carries information, though the final 'Read-only' restates the annotation and is the one piece that does not earn its place.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

For an 8-parameter resolution tool with no output schema, the description covers purpose, symbol normalization, ambiguity handling, and scope exclusions, which is close to sufficient. What is missing is any indication of what a candidate record looks like or how limit interacts with the 500-candidate backend cap beyond the schema note.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters4/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so the baseline is 3; the description earns above that by explaining cross-parameter behavior the schema alone cannot convey — that Yahoo suffixes are validated against compatible stored venues and that native share-class dots survive resolution. The filter list (exchange/MIC, country, currency, instrument type) is named but not elaborated per-parameter.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (resolve) and resource (Bullrun listings) and enumerates the accepted identifier forms (company name, native ticker, ISIN, exchange-qualified symbol). It also positions itself relative to a whole class of sibling tools ('exact-ticker research tools'), so an agent can distinguish it from screen_stocks, find_stock_peers and the get_stock_* family without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines4/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

Explicitly frames the call as a prerequisite ('before calling exact-ticker research tools') and rules out one misuse case ('No enrichment or market-data refresh'). It does not name a specific alternative sibling or state when to prefer screening tools over this resolver, so it falls short of full when/when-not coverage.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

simulate_etf_costSimulate ETF costA
Read-only
Inspect

Simulate expense-ratio, assumed bid/ask spread, commissions, and recurring contributions over a holding period. Compares the same gross-return path with and without costs and reports direct charges plus ending-value drag. Taxes, FX, market impact and brokerage-specific fees are excluded unless represented by the inputs. Read-only.

NameRequiredDescriptionDefault
yearsNo
tickerYesExact Bullrun ETF listing ticker.
spreadPctNoAssumed full bid/ask spread in percentage points; each purchase pays half the spread.
expenseRatioPctNoOptional expense-ratio override in percentage points. Otherwise uses the stored ETF profile value.
initialInvestmentNo
commissionPerTradeNo
contributionAmountNo
grossAnnualReturnPctNoAssumed annual return before ETF and trading costs, in percentage points. Default 0 isolates direct costs.
contributionFrequencyNomonthly

Output Schema

NameRequiredDescription
tickerYes
resultsYes
webPageNo
warningsYes
assumptionsYes
platformLinkNo
costBreakdownYes

TDQS

A4/5.0
Behavior4/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations already declare readOnlyHint/non-destructive, and the description adds real behavioral context: it compares identical gross-return paths with and without costs and reports direct charges plus ending-value drag, and it discloses the tax/FX/market-impact exclusions. The closing 'Read-only' merely repeats the annotation, but the modeling mechanics are genuine added value.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Three tight sentences, front-loaded with the modeling scope before the exclusion caveat. The only wasted content is the redundant 'Read-only' trailing clause that the annotations already cover.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

An output schema exists, so return values need no explanation. For a 9-parameter simulation tool the description supplies the modeling mechanics, the cost-isolation default behavior, and the explicit exclusion list — everything an agent needs to decide it is the right tool and interpret the result.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 44%, so the description must partly compensate. It does name each modeled input conceptually (expense-ratio override, spread, commissions, recurring contributions, holding period, gross return) but adds no format or interaction detail beyond what the schema already states, and leaves initialInvestment undocumented in both places.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

States a specific verb (simulate) plus the exact cost components modeled (expense ratio, bid/ask spread, commissions, recurring contributions) and the holding-period horizon. No sibling tool does cost simulation, so the agent can distinguish it immediately from the surrounding get_/screen_/compare_ tools.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines3/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description establishes scope boundaries by listing what is excluded (taxes, FX, market impact, brokerage-specific fees), which implicitly tells the agent when the tool is appropriate. However, it never names an alternative or states conditions for choosing this tool over compare_etfs or get_etf_fund for cost-related questions.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Tool Schema Changelog

Recent tool additions, removals, and schema changes observed during successful MCP inspections.

  1. 21 tool updatesv0.8.1
    • Removedanalyze_etf_overlap
    • Removedanalyze_portfolio_fit
    • Changedcompare_company_exposures1 field changed
      • changedInput schema / properties / tickers / description
        Previous value: -"Two to five distinct exact Bullrun listing tickers. Names and inferred exchange suffixes are not accepted."New value: +"Two to five distinct Bullrun listing tickers, e.g. AAPL, BMW or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN. Company names are not accepted here."
    • Changedcompare_etfs6 fields changed
      • addedInput schema / properties / include / description
        Added value: +"Selected comparison modules. overlap is opt-in and returns pairwise shared holdings and weighted overlap from each fund's latest stored snapshot."
      • changedInput schema / properties / include / items / enum
        Previous value: -[
        -  "classification",
        -  "market",
        -  "fund_data",
        -  "costs",
        -  "income",
        -  "benchmark",
        -  "performance",
        -  "risk",
        -  "holdings"
        -]New value: +[
        +  "classification",
        +  "market",
        +  "fund_data",
        +  "costs",
        +  "income",
        +  "benchmark",
        +  "performance",
        +  "risk",
        +  "holdings",
        +  "overlap"
        +]
      • changedInput schema / properties / include / maxItems
        Previous value: -9New value: +10
      • addedInput schema / properties / topSharedLimit
        Added value: +{
        +  "default": 20,
        +  "description": "Maximum shared holdings per ETF pair when overlap is requested; does not limit the snapshots used in overlap calculations.",
        +  "maximum": 100,
        +  "minimum": 1,
        +  "type": "integer"
        +}
      • addedOutput schema / properties / overlap
        Added value: +{
        +  "additionalProperties": false,
        +  "properties": {
        +    "coverage": {
        +      "items": {
        +        "additionalProperties": {},
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "methodology": {
        +      "additionalProperties": {},
        +      "type": "object"
        +    },
        +    "pairs": {
        +      "items": {
        +        "additionalProperties": {},
        +        "type": "object"
        +      },
        +      "type": "array"
        +    },
        +    "warnings": {
        +      "items": {
        +        "type": "string"
        +      },
        +      "type": "array"
        +    }
        +  },
        +  "required": [
        +    "methodology",
        +    "coverage",
        +    "pairs",
        +    "warnings"
        +  ],
        +  "type": "object"
        +}
      • changedOutput schema / properties / requestedModules / items / enum
        Previous value: -[
        -  "classification",
        -  "market",
        -  "fund_data",
        -  "costs",
        -  "income",
        -  "benchmark",
        -  "performance",
        -  "risk",
        -  "holdings"
        -]New value: +[
        +  "classification",
        +  "market",
        +  "fund_data",
        +  "costs",
        +  "income",
        +  "benchmark",
        +  "performance",
        +  "risk",
        +  "holdings",
        +  "overlap"
        +]
    • Changedcompare_stocks1 field changed
      • changedInput schema / properties / tickers / description
        Previous value: -"Two to five distinct exact Bullrun stock listing tickers, e.g. AAPL, BMW, NESN or 005930. No fuzzy company names or inferred ticker suffixes."New value: +"Two to five distinct Bullrun stock tickers, e.g. AAPL, BMW, NESN, 6324.T or 7203. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN. Company names are not accepted here."
    • Changedfind_stock_peers1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Exact native Bullrun equity ticker. Use search_stocks first for a company name, ISIN or Yahoo-format symbol."New value: +"Bullrun equity ticker, e.g. AAPL, BMW or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Changedget_company_data_coverage1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Exact native Bullrun company ticker, e.g. AAPL or SAP."New value: +"Bullrun company ticker, e.g. AAPL, SAP or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Changedget_company_news1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Exact native Bullrun company ticker, e.g. AAPL, SAP or ABBN. Resolve the symbol with search_stocks first if uncertain."New value: +"Bullrun company ticker, e.g. AAPL, SAP, ABBN or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Changedget_company_risk_history3 fields changed
      • changedInput schema / properties / limit / default
        Previous value: -6New value: +3
      • changedInput schema / properties / limit / description
        Previous value: -"Latest stored run dates to return, oldest first. Retention and gaps vary. Full detail supports at most six dates."New value: +"Latest stored run dates to return, oldest first; each date carries its change from the previous stored date. Retention and gaps vary. Full detail supports at most six dates."
      • changedInput schema / properties / ticker / description
        Previous value: -"Exact native Bullrun company ticker, e.g. AAPL or SAP."New value: +"Bullrun company ticker, e.g. AAPL, SAP or 6324.T. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Changedget_corporate_calendar1 field changed
      • changedInput schema / properties / q / description
        Previous value: -"Optional case-insensitive ticker or company-name contains search, also matched with spaces removed. This is not an exact ticker filter. A nonblank search widens earnings/ex-dividend to 120 days and listings to 60 months. % and _ act as search wildcards."New value: +"Optional case-insensitive ticker or company-name contains search, also matched with spaces removed. This is not an exact ticker filter. A Yahoo-style symbol whose listing Bullrun stores in another form (BMW.DE as BMW, 7203.T as 7203) is searched under the stored ticker. A nonblank search widens earnings/ex-dividend to 120 days and listings to 60 months. % and _ act as search wildcards."
    • Changedget_earnings_call_transcript2 fields changed
      • changedInput schema / properties / maxChunks / default
        Previous value: -80New value: +40
      • changedInput schema / properties / ticker / description
        Previous value: -"The ticker exactly as listed on Bullrun, e.g. \"CRWD\", \"SPGI\", \"V\"."New value: +"Bullrun ticker, e.g. \"CRWD\", \"SPGI\", \"V\". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Changedget_etf_exposures1 field changed
      • addedOutput schema / properties / notLoadedTypes
        Added value: +{
        +  "items": {
        +    "$ref": "#/properties/requestedTypes/items"
        +  },
        +  "type": "array"
        +}
    • Changedget_forward_estimates1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"The ticker exactly as listed on Bullrun, e.g. \"AAPL\", \"CRWD\", \"SPGI\"."New value: +"Bullrun ticker, e.g. \"AAPL\", \"CRWD\", \"SPGI\". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Changedget_operating_kpis1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"The ticker exactly as listed on Bullrun, e.g. \"CRWD\", \"SNOW\", \"V\"."New value: +"Bullrun ticker, e.g. \"CRWD\", \"SNOW\", \"V\". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Changedget_portfolio_analytics2 fields changed
      • changedInput schema / properties / candidateTicker / description
        Previous value: -"Optional exact Bullrun ticker to test as a candidate diversifier - the native local-exchange symbol, e.g. AAPL, BMW, ABBN, NESN (not Yahoo-style suffixes like BMW.DE)."New value: +"Optional exact Bullrun stock or ETF listing ticker to test as a candidate diversifier, e.g. AAPL, BMW, ABBN, NESN or SPY. Use the stored listing ticker; do not infer exchange suffixes."
      • addedInput schema / properties / includeLookThrough
        Added value: +{
        +  "default": false,
        +  "description": "Also compare an exact stock or ETF candidate against direct holdings and stored ETF constituents. Requires candidateTicker. Default false: no underlying holdings requests. Look-through has separate priced-position coverage from price-history risk analytics.",
        +  "type": "boolean"
        +}
    • Changedget_stock_price_history1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"Exact native Bullrun stock ticker, e.g. AAPL, SAP or ABBN; find it with search_stocks. Do not append Yahoo exchange suffixes."New value: +"Bullrun stock ticker, e.g. AAPL, SAP, ABBN, 6324.T or 7203. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Addedlist_research_shortlist
    • Removedquery_etfs
    • Addedsave_research_shortlist
    • Removedscreen_stock_presets
    • Changedscreen_stocks13 fields changed
      • addedInput schema / properties / action
        Added value: +{
        +  "default": "run",
        +  "description": "list_presets discloses named screens without any backend request; run executes a preset or custom rules and uses the metered screening budget.",
        +  "enum": [
        +    "list_presets",
        +    "run"
        +  ],
        +  "type": "string"
        +}
      • removedInput schema / properties / limit / default
        Removed value: -25
      • changedInput schema / properties / limit / description
        Previous value: -"Maximum number of stocks to return (1-100)."New value: +"Maximum stocks to return: custom default 25 (1-100), preset default 20 (1-50)."
      • removedInput schema / properties / lookback / default
        Removed value: -3
      • changedInput schema / properties / lookback / description
        Previous value: -"How many reporting periods to evaluate. Growth rules need at least 2 comparable periods."New value: +"How many reporting periods to evaluate (default 3). Growth rules need at least 2 comparable periods; presets require 2-10 annual observations."
      • removedInput schema / properties / lookbackMode / default
        Removed value: -"annual"
      • changedInput schema / properties / lookbackMode / description
        Previous value: -"Whether rule evaluation uses annual or quarterly reporting periods."New value: +"Whether rule evaluation uses annual or quarterly reporting periods. Default annual; presets require annual."
      • removedInput schema / properties / order / default
        Removed value: -"desc"
      • changedInput schema / properties / order / description
        Previous value: -"Sort direction. Nulls always sort last regardless of direction."New value: +"Sort direction. Custom default desc; presets use their disclosed order. Nulls always sort last regardless of direction."
      • addedInput schema / properties / preset
        Added value: +{
        +  "description": "Optional named screen. Presets use disclosed fixed rules/sorting, annual lookback (2-10 years), primary active listings and a default limit of 20 (maximum 50). Omit for custom rules; do not combine with rules or minMarketCap.",
        +  "enum": [
        +    "profitable_value",
        +    "dividend_income",
        +    "growth_and_cashflow",
        +    "cash_generators",
        +    "dividend_growth"
        +  ],
        +  "type": "string"
        +}
      • removedInput schema / properties / rules / default
        Removed value: -[]
      • removedInput schema / properties / sortBy / default
        Removed value: -"marketCap"
      • changedInput schema / properties / sortBy / description
        Previous value: -"Metric to sort by. revenueGrowth is accepted as an alias for revenueGrowthPct."New value: +"Metric to sort by. Custom default marketCap; presets use their disclosed sorting. revenueGrowth is accepted as an alias for revenueGrowthPct."
  2. 45 tool updatesv0.7.0
    • Addedanalyze_etf_overlap
    • Addedanalyze_portfolio_fit
    • Addedcompare_company_exposures
    • Addedcompare_etfs
    • Addedcompare_stocks
    • Changedcreate_portfolio_draft1 field changed
      • addedInput schema / properties / instrumentUniverse
        Added value: +{
        +  "description": "Candidate universe: stocks only, ETFs only, or a mix. Default mix unless the prompt says otherwise.",
        +  "enum": [
        +    "stocks",
        +    "etfs",
        +    "mix"
        +  ],
        +  "type": "string"
        +}
    • Addedcreate_portfolio_from_positions
    • Changedcreate_position_draft1 field changed
      • addedInput schema / properties / instrumentUniverse
        Added value: +{
        +  "description": "Candidate universe: stocks only, ETFs only, or a mix. Default mix.",
        +  "enum": [
        +    "stocks",
        +    "etfs",
        +    "mix"
        +  ],
        +  "type": "string"
        +}
    • Addedfind_stock_peers
    • Addedget_capabilities
    • Addedget_company_data_coverage
    • Addedget_company_news
    • Addedget_company_relationships
    • Addedget_company_risk
    • Addedget_company_risk_history
    • Addedget_corporate_calendar
    • Addedget_country_macro
    • Addedget_etf_exposures
    • Addedget_etf_filter_options
    • Addedget_etf_fund
    • Addedget_etf_holdings
    • Addedget_etf_index_group
    • Addedget_etf_risk
    • Addedget_etf_snapshot
    • Addedget_etf_timeseries
    • Changedget_financial_history1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"The ticker exactly as listed on Bullrun, e.g. \"AAPL\", \"ABBN.SW\", \"BMW.DE\"."New value: +"The Bullrun ticker. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Addedget_global_markets_overview
    • Addedget_macro_history
    • Addedget_macro_indicators
    • Changedget_operating_kpis1 field changed
      • changedInput schema / properties / metricKey / description
        Previous value: -"Optional exact metric key to filter, e.g. ARR, NRR, RPO, BILLINGS, PAYMENT_VOLUME."New value: +"Optional metric key present in stored coverage. No particular business KPI is guaranteed to be available."
    • Changedget_portfolio_analytics1 field changed
      • changedInput schema / properties / candidateTicker / description
        Previous value: -"Optional exact Bullrun ticker to test as a candidate diversifier, e.g. AAPL, NESN.SW, BMW.DE."New value: +"Optional exact Bullrun ticker to test as a candidate diversifier - the native local-exchange symbol, e.g. AAPL, BMW, ABBN, NESN (not Yahoo-style suffixes like BMW.DE)."
    • Changedget_quality_moat_metrics1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"The ticker exactly as listed on Bullrun, e.g. \"AAPL\", \"ABBN.SW\", \"BMW.DE\"."New value: +"The Bullrun ticker. Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Changedget_revenue_breakdown1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"The ticker exactly as listed on Bullrun, e.g. \"SPGI\", \"MSFT\", \"V\"."New value: +"The Bullrun ticker, e.g. \"SPGI\", \"MSFT\", \"V\". Bullrun tickers: US and most European listings use the plain local symbol (AAPL, BMW, NESN, ABBN); most Asian and Indian listings keep their exchange suffix (Tokyo 6324.T, Hong Kong 0700.HK, Shanghai 600519.SS, Shenzhen 000001.SZ, Taiwan 2330.TW, Korea 000100.KS, Singapore D05.SI, India RELIANCE.NS), but some Japanese and Korean large caps are plain codes (Toyota 7203, Samsung 005930). Either form is resolved automatically when exactly one listing matches; use search_stocks to find a ticker by company name or ISIN."
    • Addedget_risk_movers
    • Changedget_stock_metrics1 field changed
      • changedInput schema / properties / ticker / description
        Previous value: -"The stock ticker exactly as listed on Bullrun, e.g. \"AAPL\", \"ABBN.SW\", \"BMW.DE\"."New value: +"The stock ticker as Bullrun lists it, e.g. \"AAPL\", \"BMW\", \"NESN\", \"6324.T\", \"0700.HK\" or \"005930\". A bare numeric code is resolved when exactly one listing matches."
    • Addedget_stock_price_history
    • Addedget_valuation_model
    • Changedquery_etfs2 fields changed
      • changedInput schema / properties / category / description
        Previous value: -"Exact ETF category filter. This maps to Bullrun's ETF category column."New value: +"Exact broad ETF asset-class filter, such as Equity, Fixed Income, Commodity, Crypto, or Real Estate. Kept as category for API compatibility."
      • changedInput schema / properties / focus / description
        Previous value: -"Exact ETF focus filter. This maps to Bullrun's ETF focus / asset-class column."New value: +"Exact ETF exposure filter, such as Japan, Equity - Australia, TOPIX, or an exchange/source exposure label. Kept as focus for API compatibility."
    • Addedscreen_etfs
    • Addedscreen_risk_board
    • Addedscreen_stock_presets
    • Addedscreen_valuation_model
    • Addedsearch_etfs
    • Addedsearch_stocks
    • Addedsimulate_etf_cost
  3. 14 tool updatesv0.1.0
    • First observedcreate_portfolio_draft
    • First observedcreate_position_draft
    • First observedget_earnings_call_transcript
    • First observedget_financial_history
    • First observedget_forward_estimates
    • First observedget_operating_kpis
    • First observedget_portfolio_analytics
    • First observedget_portfolio_context
    • First observedget_quality_moat_metrics
    • First observedget_revenue_breakdown
    • First observedget_stock_metrics
    • First observedlist_portfolios
    • First observedquery_etfs
    • First observedscreen_stocks

TDQS

A3.9/5.0

Scored across 48 tools

Disambiguation4/5

Tool purposes are mostly distinct, and descriptions explicitly route between similar pairs such as search_etfs vs screen_etfs, get_etf_snapshot vs get_etf_fund, and get_company_risk vs screen_risk_board. Still, with 48 tools across stock, ETF, macro, and portfolio domains, a few adjacent pairs require careful reading to avoid misselection.

Naming Consistency5/5

All tool names use snake_case and begin with a predictable action verb such as get_, list_, search_, screen_, create_, compare_, save_, find_, or simulate_. Minor variations like find_stock_peers and compare_company_exposures remain readable and consistent.

Tool Count2/5

48 tools is well beyond the 3-15 sweet spot and exceeds the 25+ heavy threshold, even for a broad investment research platform. The wide scope justifies some expansion, but the surface is large enough to impose meaningful selection and navigation cost.

Completeness4/5

Coverage is extensive across macro data, stock fundamentals and risk, ETF research, and portfolio drafts/shortlists, with clear lifecycle support for saved items and drafts. Minor gaps remain around live trading, alerting/monitoring, and direct portfolio mutation, but those appear outside the research-oriented purpose.

Maintenance

ActivityMaintained
ResponsivenessNo issues

Related MCP Connectors

Related MCP Servers

  • A
    license
    B
    quality
    C
    maintenance
    MCP server that provides AI assistants access to stock market data including financial statements, stock prices, and market news through a Model Context Protocol interface.
    11
    2,314
    MIT
  • A
    license
    A
    quality
    A
    maintenance
    A simple MCP server for Yahoo Finance using yfinance. This server provides a set of tools to fetch stock data, news, and other financial information.
    15
    204
    MIT
  • F
    license
    Not graded
    quality
    D
    maintenance
    A Python-based FastMCP server that provides financial tools for securities analysis, including market data, news, fundamental/technical analysis, and visualization capabilities that can be consumed by any MCP-aware client.
    8
    -
  • -
    license
    Not graded
    quality
    Not graded
    maintenance
    An MCP server that enables Amazon Q CLI users to create, query, and manage Maverick sites through natural language commands.
    -