{"schema_version":"verify.compare.v1","generated_at":"2026-09-10T06:06:50.521779+00:00","count":1,"missing_servers":[],"results":[{"server_id":"ferinator/bullrun-mcp","display_name":"BullRun","profile_url":"https://verify.sentinelsignal.io/servers/ferinator/bullrun-mcp","compare_url":"https://verify.sentinelsignal.io/compare?server=ferinator%2Fbullrun-mcp","trust_summary_url":"https://verify.sentinelsignal.io/v1/servers/ferinator/bullrun-mcp/trust-summary","claimed":false,"verified_publisher":false,"claim_status":"unclaimed","badge_url":"https://verify.sentinelsignal.io/badge/ferinator/bullrun-mcp.svg","report_url":"https://verify.sentinelsignal.io/v1/servers/ferinator/bullrun-mcp/report","policy_url":"https://verify.sentinelsignal.io/v1/servers/ferinator/bullrun-mcp/policy","evidence_url":"https://verify.sentinelsignal.io/api/v1/servers/ferinator/bullrun-mcp/evidence","commerce_signal":null,"payment_capable":null,"delegation_level":null,"risk_flags":[],"strengths":["report_available","policy_available","badge_available"],"limitations":["unclaimed_profile","publisher_not_verified"],"last_seen":null,"last_scored":"2026-09-10T04:17:01.186046+00:00","recommended_agent_action":"unknown","observed_attention":{"schema":"verify.observed_attention.v1","window_days":30,"level":"none","label":"No observed attention","summary":"No recent machine-readable trust or discovery activity observed for this server.","segments":{"useful_ai_user":{"level":"none","observed":false,"description":"AI-assisted user sessions such as ChatGPT/User or Claude/User."},"machine_trust_evaluator":{"level":"none","observed":false,"description":"Synthetic sessions inspecting multiple trust surfaces such as report, policy, ledger, badge, trust-summary, or compare."},"possible_agent_or_script":{"level":"none","observed":false,"description":"Structured direct sessions with rapid profile, compare, report, policy, badge, or trust-surface fan-out."},"isolated_machine_surface":{"level":"none","observed":false,"description":"Aged-out direct synthetic singleton sessions that touched a machine-readable trust surface without becoming a broader evaluator."},"ai_crawler":{"level":"none","observed":false,"description":"Known AI crawler activity such as ClaudeBot, GPTBot, or similar crawlers."},"search_crawler":{"level":"none","observed":false,"description":"Search and SEO crawler activity."},"browser_like_automation":{"level":"none","observed":false,"description":"Browser-like synthetic sessions with rapid structured endpoint activity."},"confirmed_human":{"level":"none","observed":false,"description":"Confirmed browser-session human activity."}},"surfaces_observed":{"server_profile":false,"compare":false,"compare_json":false,"compare_api":false,"report_json":false,"policy":false,"ledger":false,"badge_metadata":false,"badge_svg":false,"trust_summary":false,"mcp_tool":false},"claim_prompt":{"recommended":false,"reason":"No claim prompt is recommended from observed attention in the current window."},"notes":["Observed attention is based on segmented first-party telemetry.","Crawler and evaluator activity is not treated as confirmed human demand.","Public levels are bucketed to avoid exposing raw traffic counts."]},"owner_activation":{"claim_recommended":false,"reason":"no_observed_attention"}}],"servers":[{"namespace":"ferinator","name":"bullrun-mcp","title":"BullRun","description":"Stock screening, company financials, ETF search, and personal portfolio analysis over a remote OAuth-protected MCP server\n\nhttps://mcp.bull-run.org/mcp","homepage_url":"https://glama.ai/mcp/servers/qumdedbzj7","docs_url":null,"icon_url":null,"support_url":"https://github.com/ferinator/bullrun-mcp","remote_url":"https://mcp.bull-run.org/mcp","server_card_url":null,"latest_version":null,"current_status":"failing","current_score":null,"transport_type":"streamable-http","has_oauth":true,"has_dcr":false,"has_prompts":false,"tool_count":0,"current_validation_schema_version":"8058defc70ca932c","last_validated_at":"2026-09-10T04:17:01.186046+00:00","registry_source":"glama_registry","registry_identifier":"glama_registry:qumdedbzj7","canonical_identifier":null,"current_score_components":{"auth_operability_score":3.0,"error_contract_score":0.0,"rate_limit_semantics_score":2.0,"schema_completeness_score":0.0,"backward_compatibility_score":4.0,"slo_health_score":0.0,"security_hygiene_score":0.0,"task_success_score":0.0,"trust_confidence_score":1.0,"prompt_contract_score":0.0,"resource_contract_score":0.0,"discovery_metadata_score":2.0,"registry_consistency_score":2.0,"installability_score":1.0,"session_semantics_score":1.0,"tool_surface_design_score":0.0,"result_shape_stability_score":0.0,"oauth_interop_score":3.0,"recovery_semantics_score":0.0,"maintenance_signal_score":2.0,"adoption_signal_score":1.0,"freshness_confidence_score":1.0,"transport_fidelity_score":4.0,"spec_recency_score":2.0,"session_resume_score":4.0,"step_up_auth_score":3.0,"transport_compliance_score":2.0,"utility_coverage_score":0.0,"advanced_capability_coverage_score":0.0,"connector_publishability_score":0.0,"tool_snapshot_churn_score":0.0,"connector_replay_score":0.0,"request_association_score":0.0,"interactive_flow_safety_score":3.0,"official_registry_presence_score":2.0,"safety_transparency_score":2.0,"tool_capability_clarity_score":0.0,"data_exfiltration_resilience_score":0.0,"dependency_supply_chain_signal_score":0.0,"input_sanitization_safety_score":0.0,"tool_namespace_clarity_score":0.0},"capability_taxonomy":[],"machine_summary":{},"taxonomy_tags":[],"score_decomposition":[],"validation_diff":null,"tool_snapshot_diff":null,"connector_replay":{},"request_association":{},"production_readiness":{"code":"failing","label":"Failing","reason":"The latest validation run was attempted but did not complete successfully.","badge":"score-low"},"recommended_for":[],"history_summary":{},"validation_timeline":[],"evidence_confidence":{"score":null,"label":"not_assessed","reason":"No evidence-bearing validation runs exist yet (8 captured checks, validation age 1.8 hours). Confidence cannot be computed.","live_check_count":8,"validation_age_hours":1.83,"basis":{"evidence_bearing_validations":0,"affirmative_live_check_count":8,"validation_age_hours":1.83,"freshness_threshold_hours":24}},"incident_feed":[],"disputes":[],"remediations":[],"client_remediation_modes":[],"client_profiles":[],"client_readiness_verdicts":[],"publishability_policy_profiles":[],"compatibility_fixtures":[],"install_snippets":{},"aliases":[],"raw_evidence":{"checks":{"probe_noise_resilience":{"status":"ok","latency_ms":486.4,"details":{"url":"https://mcp.bull-run.org/robots.txt","http_status":200,"headers":{"content-type":"text/plain; charset=utf-8"},"validation_disallowed":false,"consent_error":null}},"server_card":{"status":"error","latency_ms":394.4,"details":{"url":"https://mcp.bull-run.org/.well-known/mcp/server-card.json","error":"Client error '404 Not Found' for url 'https://mcp.bull-run.org/.well-known/mcp/server-card.json'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404"}},"oauth_protected_resource":{"status":"ok","latency_ms":411.66,"details":{"url":"https://mcp.bull-run.org/.well-known/oauth-protected-resource","payload":{"resource":"https://mcp.bull-run.org","authorization_servers":["https://bull-run.org"],"scopes_supported":["read:market","read:portfolios","write:drafts"],"bearer_methods_supported":["header"],"resource_name":"Bullrun MCP","resource_documentation":"https://mcp.bull-run.org"},"http_status":200,"headers":{"content-type":"application/json; charset=utf-8"}}},"oauth_authorization_server":{"status":"ok","latency_ms":415.74,"details":{"url":"https://bull-run.org/.well-known/oauth-authorization-server","payload":{"issuer":"https://bull-run.org","authorization_endpoint":"https://bull-run.org/oauth2/authorize","pushed_authorization_request_endpoint":"https://bull-run.org/oauth2/par","device_authorization_endpoint":"https://bull-run.org/oauth2/device_authorization","token_endpoint":"https://bull-run.org/oauth2/token","token_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post","client_secret_jwt","private_key_jwt","tls_client_auth","self_signed_tls_client_auth","none"],"jwks_uri":"https://bull-run.org/oauth2/jwks","response_types_supported":["code"],"grant_types_supported":["authorization_code","client_credentials","refresh_token","urn:ietf:params:oauth:grant-type:device_code","urn:ietf:params:oauth:grant-type:token-exchange"],"revocation_endpoint":"https://bull-run.org/oauth2/revoke","revocation_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post","client_secret_jwt","private_key_jwt","tls_client_auth","self_signed_tls_client_auth"],"introspection_endpoint":"https://bull-run.org/oauth2/introspect","introspection_endpoint_auth_methods_supported":["client_secret_basic","client_secret_post","client_secret_jwt","private_key_jwt","tls_client_auth","self_signed_tls_client_auth"],"code_challenge_methods_supported":["S256"],"tls_client_certificate_bound_access_tokens":true,"dpop_signing_alg_values_supported":["RS256","RS384","RS512","PS256","PS384","PS512","ES256","ES384","ES512"],"client_id_metadata_document_supported":true},"http_status":200,"headers":{"content-type":"application/json"}}},"openid_configuration":{"status":"error","latency_ms":281.45,"details":{"url":"https://bull-run.org/.well-known/openid-configuration","error":"Client error '404 Not Found' for url 'https://bull-run.org/.well-known/openid-configuration'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/404"}},"initialize":{"status":"ok","latency_ms":145.25,"details":{"url":"https://mcp.bull-run.org/mcp","payload":{"result":{"protocolVersion":"2025-03-26","capabilities":{"tools":{"listChanged":true},"prompts":{"listChanged":true}},"serverInfo":{"name":"bullrun-mcp","version":"0.3.0"},"instructions":"For ETFs: screen_etfs is the whole-universe screen and the right default for any ranking question (cheapest, largest, best performing, most liquid, or \"which funds hold X\" via its holdingSearch look-through); search_etfs looks up a known fund by name, ticker or ISIN; get_etf_filter_options lists the exact strings the categorical filters accept, so call it before guessing a category, region, index key or issuer; get_etf_index_group answers \"cheapest way to track <index>\" with one row per FUND rather than per venue listing; get_etf_fund resolves an ISIN (or any venue ticker) to the fund and all the venues it trades on — reach for it whenever the user quotes an ISIN or asks which line to buy; get_etf_snapshot for requested snapshot modules; get_etf_timeseries for price/history coverage; get_etf_holdings and get_etf_exposures for explicit partial/full look-through; get_etf_risk for price risk; compare_etfs and analyze_etf_overlap for fund comparisons; analyze_portfolio_fit for a signed-in portfolio; and simulate_etf_cost for deterministic cost scenarios. Expense ratios and yields are always percentage points in tool inputs and outputs, never fractions. The same UCITS fund is listed on several venues under different tickers: treat those as ONE holding, never as diversification. Read every coverage/warnings field: unavailable NAV, total-return, factor, thematic, benchmark, spread, fee, or holdings data is never synthesized, and a fund missing a metric is excluded by any rule on it. query_etfs remains available for compatibility. Bullrun market-data and portfolio tools. Use screen_stocks to find stocks across the global universe by fundamentals (sector/industry/country, market cap, P/E, dividend yield, revenue growth), query_etfs to search ETFs by ticker/fund name, category, focus, domicile, exchange and currency with profile, price and holdings detail for exact tickers, get_stock_metrics to pull a consolidated snapshot for one exact stock ticker, get_financial_history for multi-year annual/quarterly statements, CAGRs, margins, and growth consistency checks, and get_quality_moat_metrics for annual ROIC, ROIC-vs-supplied-WACC, accruals, cash conversion, capex intensity, dividends, share-count changes, and capital-allocation caveats. Use get_forward_estimates for consensus revenue/EPS/EBITDA, guidance, estimate revisions, and derived forward P/E/PEG context; get_operating_kpis for domain KPIs such as ARR, NRR, RPO, billings, customer counts, payment volume, cross-border volume, and processed transactions; get_revenue_breakdown for segment/geography/product revenue splits; and get_earnings_call_transcript for speaker-tagged management commentary and analyst Q&A. Whenever the user talks about THEIR OWN portfolio, holdings, positions, or investments (\"my portfolio\", \"how am I doing\", \"what should I improve/buy/add\", \"is my portfolio diversified\", \"how risky am I\"), reach for the per-user portfolio tools rather than answering from general knowledge. When the user has connected their Bullrun account, list_portfolios lists their own virtual portfolios (start here when no specific portfolio is named), get_portfolio_context returns a deep snapshot of one (holdings, weights, value, insights — use for \"analyze/review my portfolio\"), and get_portfolio_analytics returns portfolio-level relationship analytics: correlation/covariance matrices, contribution-to-risk, factor proxy exposure, sector/currency/country concentration, stress scenarios, and optional candidateTicker fit analysis (use for diversification/risk/concentration questions and \"should I add <ticker>\"). create_portfolio_draft builds a new paper portfolio saved as a draft for GUI review (\"build me a portfolio\"); create_position_draft proposes additions to an existing portfolio saved as a draft for GUI review (\"what should I buy next\"). Draft tools never change live holdings by themselves. create_portfolio_from_positions saves a portfolio you have ALREADY designed from an explicit {ticker, weight|amountUsd} basket (used verbatim, never re-picked) and is free (no Pro needed) — prefer it over create_portfolio_draft whenever the exact holdings are already decided. get_capabilities reports the connected identity, Bullrun Pro status, granted scopes, and which tools are gated — call it first when a draft tool might return subscriber_required or to confirm which account you are acting on. Before calling either draft tool, scope the request in ONE short step: if the user has already been specific (style, region, size, or which portfolio), go straight to the tool; if the request is vague (e.g. just \"build me a portfolio\" or \"what should I buy\"), ask a single round of at most three multiple-choice questions first. For a NEW portfolio ask investing style (income/dividends, growth, defensive, broad-market, or a named theme), region focus (US, Europe, or global), and size (starting cash and/or number of holdings). For additions to an EXISTING portfolio ask which portfolio (call list_portfolios first when the user has more than one) and how many ideas (a single best idea or a few). Give a sensible default with every question so the user can reply \"just pick for me\", then call the tool immediately with those defaults. Keep it to that one step — do not interrogate across multiple turns or re-ask anything the user already stated. The per-user tools accept a privacyMode (\"full\" default, or \"weights_only\" to hide absolute money). All read tools are sourced from the Bullrun database."},"jsonrpc":"2.0","id":1},"http_status":200,"headers":{"content-type":"text/event-stream","mcp-session-id":"57fa5335-f9a2-44b6-ac98-f9a0f08155d5"}}},"protocol_version_probe":{"status":"warning","latency_ms":null,"details":{"claimed_version":"2025-03-26","validator_protocol_version":"2025-03-26","latest_known_version":"2025-11-25","releases_behind":2,"lag_days":244}},"tools_list":{"status":"error","latency_ms":438.3,"details":{"url":"https://mcp.bull-run.org/mcp","error":"Client error '400 Bad Request' for url 'https://mcp.bull-run.org/mcp'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400","http_status":400,"payload":{},"headers":{"content-type":"application/json; charset=utf-8"}}},"prompts_list":{"status":"missing","latency_ms":294.61,"details":{"url":"https://mcp.bull-run.org/mcp","error":"Client error '400 Bad Request' for url 'https://mcp.bull-run.org/mcp'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400","http_status":400,"payload":{},"headers":{"content-type":"application/json; charset=utf-8"},"reason":"not_advertised"}},"prompt_get":{"status":"missing","latency_ms":null,"details":{"reason":"not_advertised"}},"resources_list":{"status":"missing","latency_ms":462.36,"details":{"url":"https://mcp.bull-run.org/mcp","error":"Client error '400 Bad Request' for url 'https://mcp.bull-run.org/mcp'\nFor more information check: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/400","http_status":400,"payload":{},"headers":{"content-type":"application/json; charset=utf-8"},"reason":"not_advertised"}},"resource_read":{"status":"missing","latency_ms":null,"details":{"reason":"not_advertised"}},"determinism_probe":{"status":"missing","latency_ms":null,"details":{"reason":"tools_list_unavailable"}},"instruction_tool_reference_probe":{"status":"not_assessed","latency_ms":null,"details":{"reason":"initialize_or_tools_unavailable"}},"session_resume_probe":{"status":"ok","latency_ms":331.85,"details":{"url":"https://mcp.bull-run.org/mcp","payload":{"result":{"tools":[{"name":"screen_stocks","title":"Screen stocks","description":"Screen the global Bullrun stock universe with the same rule engine as the app screener. Filter by sector, industry, country/countries, primary vs secondary listings, active vs inactive listings, lookback mode, AND/OR rule groups, comparison operators, money units, growth metrics and latest-value metrics. Returns a compact table of matching stocks. Read-only.","inputSchema":{"type":"object","properties":{"sector":{"type":"string","description":"Exact sector name to filter by, e.g. \"Technology\", \"Healthcare\". Omit for all sectors."},"industry":{"type":"string","description":"Exact industry name to filter by, e.g. \"Software - Infrastructure\". Omit for all industries."},"country":{"type":"string","description":"Exact country name to filter by, e.g. \"United States\", \"Germany\". Omit for all countries."},"countries":{"type":"array","items":{"type":"string"},"description":"Exact country names to include. Use this for multi-country screens; it overrides country when provided."},"lookbackMode":{"type":"string","enum":["annual","quarterly"],"default":"annual","description":"Whether rule evaluation uses annual or quarterly reporting periods."},"lookback":{"type":"integer","minimum":1,"maximum":40,"default":3,"description":"How many reporting periods to evaluate. Growth rules need at least 2 comparable periods."},"mode":{"type":"string","enum":["annual","quarterly"],"description":"Deprecated alias for lookbackMode; kept for compatibility."},"periods":{"type":"integer","minimum":1,"maximum":40,"description":"Deprecated alias for lookback; kept for compatibility."},"rules":{"type":"array","items":{"type":"object","properties":{"metric":{"type":"string","enum":["revenueGrowthPct","netIncomeGrowthPct","grossProfitGrowthPct","operatingIncomeGrowthPct","ebitdaGrowthPct","freeCashflowGrowthPct","epsGrowthPct","operatingCashflowGrowthPct","dividendGrowthPct","latestRevenue","latestNetIncome","latestGrossProfit","latestOperatingIncome","latestEbitda","latestDilutedEps","latestDividendsPerShare","latestFreeCashflow","latestOperatingCashflow","latestCash","latestTotalAssets","latestTotalDebt","latestStockholdersEquity","marketCap","peRatio","dividendYield"],"description":"Metric to filter on."},"operator":{"type":"string","enum":[">=","<=",">","<","=",".."],"default":">=","description":"Comparison operator. Use '..' for an inclusive between range."},"value":{"type":["string","number"],"description":"Threshold value. For money metrics, combine with unit for K/M/B/T scaling."},"valueMax":{"type":["string","number"],"description":"Upper bound for '..' range rules. Ignored for other operators."},"unit":{"type":"string","enum":["","K","M","B","T"],"default":"","description":"Optional money unit for money metrics: '', K, M, B or T."},"groupId":{"type":"integer","minimum":1,"default":1,"description":"Rules with the same groupId are ANDed; different groups are ORed."}},"required":["metric"],"additionalProperties":false},"default":[],"description":"Fundamental rules. Same groupId means AND; different groupIds mean OR."},"minMarketCap":{"type":"number","minimum":0,"description":"Compatibility shortcut: adds marketCap >= this absolute value to every rule group."},"includeSecondary":{"type":"boolean","default":false,"description":"Include secondary cross-listings of the same security. Default false (primary listings only)."},"includeInactive":{"type":"boolean","default":false,"description":"Include delisted/inactive tickers with no recent price bar. Default false."},"sortBy":{"type":"string","enum":["revenueGrowthPct","netIncomeGrowthPct","grossProfitGrowthPct","operatingIncomeGrowthPct","ebitdaGrowthPct","freeCashflowGrowthPct","epsGrowthPct","operatingCashflowGrowthPct","dividendGrowthPct","latestRevenue","latestNetIncome","latestGrossProfit","latestOperatingIncome","latestEbitda","latestDilutedEps","latestDividendsPerShare","latestFreeCashflow","latestOperatingCashflow","latestCash","latestTotalAssets","latestTotalDebt","latestStockholdersEquity","marketCap","peRatio","dividendYield","revenueGrowth"],"default":"marketCap","description":"Metric to sort by. revenueGrowth is accepted as an alias for revenueGrowthPct."},"order":{"type":"string","enum":["desc","asc"],"default":"desc","description":"Sort direction. Nulls always sort last regardless of direction."},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Maximum number of stocks to return (1-100)."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"search_etfs","title":"Search ETFs","description":"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.","inputSchema":{"type":"object","properties":{"search":{"type":"string","description":"Free-text ETF search by ticker, fund name, or ISIN (e.g. IE00B4L5Y983). Omit for a broad screen."},"category":{"type":"string","description":"Exact broad ETF category/asset-class filter, e.g. Equity, Fixed Income, Commodity, Crypto, or Real Estate. Call get_etf_filter_options for valid values."},"focus":{"type":"string","description":"Exact ETF focus/exposure filter, e.g. Japan, TOPIX, or Equity - Australia."},"region":{"type":"string","description":"Exact portfolio or investment-region filter."},"domicile":{"type":"string","description":"Exact fund domicile filter."},"exchange":{"type":"string","description":"Exact listing exchange filter."},"currency":{"type":"string","description":"Exact trading-currency filter."},"indexKey":{"type":"string","description":"Exact tracked-index key, e.g. SP500 or MSCI_WORLD. Use get_etf_index_group to rank every fund on one index by cost."},"distributionPolicy":{"type":"string","enum":["ACCUMULATING","DISTRIBUTING"],"description":"Accumulating (reinvests income) or distributing (pays it out)."},"minAum":{"type":"number","minimum":0,"description":"Minimum assets under management in the profile's reported currency units."},"maxExpenseRatioPct":{"type":"number","minimum":0,"description":"Maximum annual expense ratio in percentage points, e.g. 0.25 means 0.25%."},"minYieldTtmPct":{"type":"number","minimum":0,"description":"Minimum trailing yield in percentage points, e.g. 2 means 2%."},"sortBy":{"type":"string","enum":["relevance","ticker","name","aum","expense_ratio","yield"],"default":"relevance","description":"Sort field. Relevance preserves Bullrun search ordering."},"sortDirection":{"type":"string","enum":["asc","desc"],"default":"desc"},"includeSecondary":{"type":"boolean","default":false},"includeInactive":{"type":"boolean","default":false},"scanLimit":{"type":"integer","minimum":25,"maximum":500,"default":100,"description":"Maximum coarse-search candidates to enrich before applying quantitative filters/sorts, 25-500."},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Maximum matching ETFs to return, 1-100."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"query":{"type":"object","additionalProperties":{}},"coverage":{"type":"object","additionalProperties":{}},"matchesInScannedCandidates":{"type":"integer","minimum":0},"returned":{"type":"integer","minimum":0},"results":{"type":"array","items":{"type":"object","additionalProperties":{}}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["query","coverage","matchesInScannedCandidates","returned","results","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"screen_etfs","title":"Screen ETFs","description":"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 is the heaviest read in the API and is metered against a small per-day action budget, so build one well-specified screen rather than probing repeatedly. Read-only.","inputSchema":{"type":"object","properties":{"search":{"type":"string","description":"Free-text match on ticker, fund name or ISIN. Omit to screen the whole universe."},"assetClass":{"type":"string","description":"Exact asset-class group: EQUITY, FIXED_INCOME, COMMODITY, REAL_ESTATE, MULTI_ASSET, CASH, CURRENCY, DIGITAL_ASSETS, ALTERNATIVES or OTHER."},"category":{"type":"string","description":"Exact category string. Call get_etf_filter_options for the valid values; a wrong guess silently returns zero rows."},"domicile":{"type":"string","description":"Exact fund domicile, e.g. \"Ireland\", \"Luxembourg\", \"United States\"."},"region":{"type":"string","description":"Exact investment-region string."},"exchange":{"type":"string","description":"Exact listing exchange, e.g. XETRA, LSE, \"NYSE ARCA\"."},"currency":{"type":"string","description":"Exact trading currency, e.g. EUR, USD, GBX."},"indexKey":{"type":"string","description":"Exact tracked-index key, e.g. SP500, MSCI_WORLD, NASDAQ100. Use get_etf_index_group to compare every fund on one index instead."},"distributionPolicy":{"type":"string","enum":["ACCUMULATING","DISTRIBUTING"],"description":"Accumulating (reinvests income) or distributing (pays it out) — the usual first cut for a European investor."},"productType":{"type":"string","description":"Exact wrapper type, e.g. UCITS_FUND."},"ucitsStatus":{"type":"string","enum":["UCITS","NON_UCITS"],"description":"UCITS restricts to wrappers a European retail investor can actually buy."},"issuer":{"type":"string","description":"Substring match on the fund family/issuer, e.g. \"iShares\", \"Amundi\", \"Vanguard\"."},"strategy":{"type":"string","description":"Exact strategy classification string."},"benchmarkSearch":{"type":"string","description":"Substring match on the stated benchmark name."},"marketDevelopment":{"type":"string","description":"Exact market-development classification, e.g. developed vs emerging."},"currencyHedged":{"type":"string","enum":["HEDGED","NOT_LABELLED_HEDGED"],"description":"HEDGED selects funds labelled currency-hedged. NOT_LABELLED_HEDGED selects funds not so labelled — absence of a label is not proof a fund is unhedged."},"holdingSearch":{"type":"string","description":"Look-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."},"holdingMode":{"type":"string","enum":["INCLUDES","EXCLUDES"],"default":"INCLUDES","description":"INCLUDES 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."},"holdingMinWeightPct":{"type":"number","minimum":0,"maximum":100,"description":"Minimum constituent weight in percentage points for holdingSearch to count as a match."},"rules":{"type":"array","items":{"type":"object","properties":{"metric":{"type":"string","enum":["expenseRatioPct","totalAssets","yieldTtmPct","holdingsCount","fundAgeYears","inceptionYear","nav","return1mPct","return3mPct","return6mPct","return1yPct","returnYtdPct","volatility1yPct","avgVolume90d","avgTurnover90d","top10ConcentrationPct"],"description":"Numeric metric to filter on."},"operator":{"type":"string","enum":[">=","<=",">","<","=",".."],"default":">=","description":"Comparison operator. Use '..' for an inclusive between range with valueMax."},"value":{"type":["string","number"],"description":"Threshold. For money metrics combine with unit for K/M/B/T scaling."},"valueMax":{"type":["string","number"],"description":"Upper bound for '..' range rules. Ignored for other operators."},"unit":{"type":"string","enum":["","K","M","B","T"],"default":"","description":"Optional money unit for money metrics: '', K, M, B or T."},"groupId":{"type":"integer","minimum":1,"default":1,"description":"Rules with the same groupId are ANDed; different groups are ORed."}},"required":["metric"],"additionalProperties":false},"default":[],"description":"Numeric rules. A fund with no value for a ruled metric never matches that rule."},"includeSecondary":{"type":"boolean","default":false,"description":"Include secondary venue listings of the same fund. Default false — one row per fund's primary listing."},"sortBy":{"type":"string","enum":["expenseRatioPct","totalAssets","yieldTtmPct","return1mPct","return3mPct","return6mPct","return1yPct","returnYtdPct","volatility1yPct","avgVolume90d","avgTurnover90d","top10ConcentrationPct","holdingsCount","nav","ticker","name"],"default":"totalAssets","description":"Sort field applied to the returned rows."},"order":{"type":"string","enum":["desc","asc"],"default":"desc","description":"Sort direction. Nulls always sort last regardless of direction."},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Maximum ETFs to return, 1-100."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"query":{"type":"object","additionalProperties":{}},"coverage":{"type":"object","additionalProperties":{}},"matchCount":{"type":"integer","minimum":0},"returned":{"type":"integer","minimum":0},"results":{"type":"array","items":{"type":"object","additionalProperties":{}}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["query","coverage","matchCount","returned","results","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"get_etf_index_group","title":"Compare funds tracking one index","description":"Answer \"what is the cheapest way to track <index>?\". 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.","inputSchema":{"type":"object","properties":{"indexKey":{"type":"string","description":"Normalized 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."},"scope":{"type":"string","enum":["ucits","all"],"default":"ucits","description":"ucits (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."},"distributionPolicy":{"type":"string","enum":["ACCUMULATING","DISTRIBUTING"],"description":"Optionally keep only accumulating or only distributing share classes."},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Maximum funds (or index families) to return, 1-100."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"mode":{"type":"string","enum":["index_group","index_list"]},"indexKey":{"type":["string","null"]},"scope":{"type":"string"},"found":{"type":"boolean"},"coverage":{"type":"object","additionalProperties":{}},"funds":{"type":"array","items":{"type":"object","additionalProperties":{}}},"indexFamilies":{"type":"array","items":{"type":"object","additionalProperties":{}}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["mode","indexKey","scope","found","coverage","funds","indexFamilies","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"get_etf_fund","title":"Get ETF fund by ISIN","description":"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.","inputSchema":{"type":"object","properties":{"isin":{"type":"string","description":"Fund ISIN, e.g. IE00B4L5Y983. The identifier European factsheets and brokers quote."},"ticker":{"type":"string","description":"Any venue listing ticker of the fund, e.g. EUNL.DE or IWDA.L. Resolved to its fund ISIN first. Provide this or isin."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"query":{"type":"object","additionalProperties":{}},"found":{"type":"boolean"},"fund":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"listings":{"type":"array","items":{"type":"object","additionalProperties":{}}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["query","found","fund","listings","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"get_etf_filter_options","title":"List ETF filter values","description":"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.","inputSchema":{"type":"object","properties":{"facets":{"type":"array","items":{"type":"string","enum":["assetClasses","categories","indexKeys","productTypes","regions","domiciles","currencies","exchanges","sectors","fundFamilies","industries"]},"minItems":1,"description":"Which facets to return. Defaults to everything except the long tails fundFamilies (~890 issuers) and industries (~650 focus strings) — request those explicitly, ideally with search."},"search":{"type":"string","description":"Case-insensitive substring filter applied to every requested facet, e.g. \"ishares\" against fundFamilies or \"world\" against categories."},"limit":{"type":"integer","minimum":1,"maximum":1000,"default":100,"description":"Maximum values per facet, 1-1000. Each facet reports its untruncated total."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"facets":{"type":"object","additionalProperties":{}},"totals":{"type":"object","additionalProperties":{"type":"number"}},"truncatedFacets":{"type":"array","items":{"type":"string"}},"search":{"type":["string","null"]},"notes":{"type":"array","items":{"type":"string"}}},"required":["facets","totals","truncatedFacets","search","notes"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"get_etf_snapshot","title":"Get ETF snapshot","description":"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.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"Exact Bullrun ETF listing ticker, including its exchange suffix when present, e.g. SPY, VWRL.L, or EUNL.DE."},"include":{"type":"array","items":{"type":"string","enum":["identity","classification","market","fund_data","costs","income","benchmark"]},"minItems":1,"maxItems":7,"default":["identity","classification","market","costs"],"description":"Only these snapshot modules are fetched and returned. Default: identity, classification, market, costs."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"ticker":{"type":"string"},"found":{"type":"boolean"},"requestedModules":{"type":"array","items":{"type":"string","enum":["identity","classification","market","fund_data","costs","income","benchmark"]}},"availableModules":{"type":"array","items":{"$ref":"#/properties/requestedModules/items"}},"missingModules":{"type":"array","items":{"$ref":"#/properties/requestedModules/items"}},"modules":{"type":"object","additionalProperties":{}},"asOf":{"type":"object","additionalProperties":{}},"dataQuality":{"type":"object","additionalProperties":{}}},"required":["ticker","found","requestedModules","availableModules","missingModules","modules","asOf","dataQuality"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"get_etf_holdings","title":"Get ETF holdings","description":"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.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"Exact Bullrun ETF listing ticker, including its exchange suffix when present."},"cursor":{"type":"string","description":"Opaque nextCursor returned by a previous get_etf_holdings call for the same ticker."},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Maximum holdings to return on this page, 1-100."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"ticker":{"type":"string"},"asOfDate":{"type":["string","null"]},"returned":{"type":"integer","minimum":0},"totalRowsAvailable":{"type":"integer","minimum":0},"nextCursor":{"type":["string","null"]},"coverage":{"type":"object","additionalProperties":{}},"holdings":{"type":"array","items":{"type":"object","additionalProperties":{}}}},"required":["ticker","asOfDate","returned","totalRowsAvailable","nextCursor","coverage","holdings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"get_etf_timeseries","title":"Get ETF time series","description":"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.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"Exact Bullrun ETF listing ticker."},"series":{"type":"array","items":{"type":"string","enum":["price","price_return","nav","total_return","benchmark","premium_discount"]},"minItems":1,"maxItems":6,"default":["price"],"description":"Requested series. Unsupported stored series are reported in unavailableSeries rather than synthesized."},"benchmarkTicker":{"type":"string","minLength":1,"description":"Exact priced ticker to use when benchmark is requested. A benchmark name alone cannot resolve a price series safely."},"interval":{"type":"string","enum":["daily","weekly","monthly"],"default":"daily"},"startDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"endDate":{"type":"string","pattern":"^\\d{4}-\\d{2}-\\d{2}$"},"limit":{"type":"integer","minimum":1,"maximum":1300,"default":260,"description":"Maximum recent daily source bars to load before date filtering and interval aggregation."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"ticker":{"type":"string"},"requestedSeries":{"type":"array","items":{"type":"string","enum":["price","price_return","nav","total_return","benchmark","premium_discount"]}},"availableSeries":{"type":"array","items":{"$ref":"#/properties/requestedSeries/items"}},"unavailableSeries":{"type":"array","items":{"$ref":"#/properties/requestedSeries/items"}},"interval":{"type":"string","enum":["daily","weekly","monthly"]},"series":{"type":"object","additionalProperties":{}},"metadata":{"type":"object","additionalProperties":{}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["ticker","requestedSeries","availableSeries","unavailableSeries","interval","series","metadata","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"get_etf_exposures","title":"Get ETF exposures","description":"Calculate sector, country, currency, and broad asset exposure from the latest stored ETF holdings and Bullrun instrument mappings. Factor and thematic look-through are reported unavailable until dedicated source data exists. Coverage states how much fund weight and how many holding symbols were resolved, so partial top-holdings data is never presented as full exposure. Read-only.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"Exact Bullrun ETF listing ticker."},"types":{"type":"array","items":{"type":"string","enum":["sector","country","currency","asset","factor","thematic"]},"minItems":1,"maxItems":6,"default":["sector","country","currency","asset"]},"limitPerType":{"type":"integer","minimum":1,"maximum":100,"default":25}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"ticker":{"type":"string"},"requestedTypes":{"type":"array","items":{"type":"string","enum":["sector","country","currency","asset","factor","thematic"]}},"availableTypes":{"type":"array","items":{"$ref":"#/properties/requestedTypes/items"}},"unavailableTypes":{"type":"array","items":{"$ref":"#/properties/requestedTypes/items"}},"exposures":{"type":"object","additionalProperties":{}},"coverage":{"type":"object","additionalProperties":{}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["ticker","requestedTypes","availableTypes","unavailableTypes","exposures","coverage","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"get_etf_risk","title":"Get ETF risk","description":"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.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"Exact Bullrun ETF listing ticker."},"days":{"type":"integer","minimum":30,"maximum":1825,"default":370,"description":"Calendar-day lookback for daily close-price risk calculations."},"benchmarkTicker":{"type":"string","minLength":1,"description":"Optional exact priced benchmark/proxy ticker for beta, correlation, tracking error, active return, and information ratio."},"riskFreeRatePct":{"type":"number","minimum":-10,"maximum":30,"default":0,"description":"Annual risk-free rate in percentage points for Sharpe, Sortino, and Calmar ratios."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"ticker":{"type":"string"},"lookbackDays":{"type":"integer"},"methodology":{"type":"object","additionalProperties":{}},"coverage":{"type":"object","additionalProperties":{}},"risk":{"type":"object","additionalProperties":{}},"benchmarkRelative":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"warnings":{"type":"array","items":{"type":"string"}}},"required":["ticker","lookbackDays","methodology","coverage","risk","benchmarkRelative","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"compare_etfs","title":"Compare ETFs","description":"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, and holdings modules. Leaders are mechanical extrema, not recommendations. Currency and partial-holdings caveats are explicit. Read-only.","inputSchema":{"type":"object","properties":{"tickers":{"type":"array","items":{"type":"string","minLength":1},"minItems":2,"maxItems":10,"description":"Two to ten exact Bullrun ETF listing tickers."},"include":{"type":"array","items":{"type":"string","enum":["classification","market","fund_data","costs","income","benchmark","performance","risk","holdings"]},"minItems":1,"maxItems":9,"default":["classification","market","fund_data","costs","income","benchmark"]},"performanceDays":{"type":"integer","minimum":30,"maximum":1825,"default":370}},"required":["tickers"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"tickers":{"type":"array","items":{"type":"string"}},"requestedModules":{"type":"array","items":{"type":"string","enum":["classification","market","fund_data","costs","income","benchmark","performance","risk","holdings"]}},"rows":{"type":"array","items":{"type":"object","additionalProperties":{}}},"leaders":{"type":"object","additionalProperties":{}},"coverage":{"type":"array","items":{"type":"object","additionalProperties":{}}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["tickers","requestedModules","rows","leaders","coverage","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"analyze_etf_overlap","title":"Analyze ETF overlap","description":"Compare two to ten ETFs using their latest stored holdings. Returns pairwise shared holdings, weighted overlap (sum of the smaller weight for each shared holding), each fund's weight in shared names, and the largest duplicate exposures. Coverage is explicit because provider holdings may be partial top-holdings samples. Read-only.","inputSchema":{"type":"object","properties":{"tickers":{"type":"array","items":{"type":"string","minLength":1},"minItems":2,"maxItems":10,"description":"Two to ten exact Bullrun ETF listing tickers."},"topSharedLimit":{"type":"integer","minimum":1,"maximum":100,"default":20}},"required":["tickers"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"tickers":{"type":"array","items":{"type":"string"}},"methodology":{"type":"object","additionalProperties":{}},"coverage":{"type":"array","items":{"type":"object","additionalProperties":{}}},"pairs":{"type":"array","items":{"type":"object","additionalProperties":{}}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["tickers","methodology","coverage","pairs","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"analyze_portfolio_fit","title":"Analyze ETF portfolio fit","description":"Analyze an ETF candidate against one signed-in user's portfolio. Combines Bullrun's price-history candidate fit (correlation, beta and pro-forma volatility) with latest-holdings look-through that identifies direct and ETF-contained duplicate underlying positions. Coverage is explicit and partial provider holdings make duplicate exposure a lower bound. Requires OAuth read:portfolios. Read-only.","inputSchema":{"type":"object","properties":{"portfolioId":{"type":"integer","exclusiveMinimum":0,"description":"Portfolio id returned by list_portfolios."},"candidateTicker":{"type":"string","minLength":1,"description":"Exact Bullrun ETF listing ticker to test."},"candidateWeightPct":{"type":"number","minimum":0.1,"maximum":50,"default":5},"days":{"type":"integer","minimum":30,"maximum":1825,"default":370},"includeLookThrough":{"type":"boolean","default":true}},"required":["portfolioId","candidateTicker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"portfolioId":{"type":"integer"},"candidateTicker":{"type":"string"},"candidateWeightPct":{"type":"number"},"priceRiskFit":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"lookThroughFit":{"anyOf":[{"type":"object","additionalProperties":{}},{"type":"null"}]},"coverage":{"type":"object","additionalProperties":{}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["portfolioId","candidateTicker","candidateWeightPct","priceRiskFit","lookThroughFit","coverage","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"simulate_etf_cost","title":"Simulate ETF cost","description":"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.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"Exact Bullrun ETF listing ticker."},"initialInvestment":{"type":"number","minimum":0,"default":10000},"contributionAmount":{"type":"number","minimum":0,"default":0},"contributionFrequency":{"type":"string","enum":["none","monthly","quarterly","annual"],"default":"monthly"},"years":{"type":"number","minimum":0.25,"maximum":50,"default":10},"grossAnnualReturnPct":{"type":"number","minimum":-99,"maximum":100,"default":0,"description":"Assumed annual return before ETF and trading costs, in percentage points. Default 0 isolates direct costs."},"expenseRatioPct":{"type":"number","minimum":0,"maximum":20,"description":"Optional expense-ratio override in percentage points. Otherwise uses the stored ETF profile value."},"spreadPct":{"type":"number","minimum":0,"maximum":20,"default":0,"description":"Assumed full bid/ask spread in percentage points; each purchase pays half the spread."},"commissionPerTrade":{"type":"number","minimum":0,"default":0}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"},"outputSchema":{"type":"object","properties":{"ticker":{"type":"string"},"assumptions":{"type":"object","additionalProperties":{}},"results":{"type":"object","additionalProperties":{}},"costBreakdown":{"type":"object","additionalProperties":{}},"warnings":{"type":"array","items":{"type":"string"}}},"required":["ticker","assumptions","results","costBreakdown","warnings"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"}},{"name":"query_etfs","title":"Query ETFs","description":"Compatibility tool for older clients: search the Bullrun ETF universe and optionally bundle profile, recent prices, and latest holdings for an exact ticker. New clients should use search_etfs, get_etf_snapshot, and get_etf_holdings for smaller responses, structured output, quantitative filters, and explicit coverage metadata. Read-only.","inputSchema":{"type":"object","properties":{"search":{"type":"string","description":"Free-text ETF search by ticker or fund name. Omit to list the first ETFs."},"ticker":{"type":"string","description":"Exact ETF ticker for profile, prices, and optional holdings, e.g. SPY, VWRL.L, EUNL.DE."},"category":{"type":"string","description":"Exact broad ETF asset-class filter, such as Equity, Fixed Income, Commodity, Crypto, or Real Estate. Kept as category for API compatibility."},"focus":{"type":"string","description":"Exact ETF exposure filter, such as Japan, Equity - Australia, TOPIX, or an exchange/source exposure label. Kept as focus for API compatibility."},"domicile":{"type":"string","description":"Exact ETF domicile filter."},"exchange":{"type":"string","description":"Exact exchange filter, e.g. NYSE ARCA, LSE, XETRA."},"currency":{"type":"string","description":"Exact trading currency filter, e.g. USD, EUR, CHF."},"includeSecondary":{"type":"boolean","default":false,"description":"Include secondary/cross-listed ETF tickers. Default false."},"includeInactive":{"type":"boolean","default":false,"description":"Include ETFs with no recent price bar. Default false."},"includeHoldings":{"type":"boolean","default":true,"description":"When ticker is supplied, include latest holdings. Ignored for broad searches."},"holdingsLimit":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Maximum holdings to return for an exact ticker, 1-100."},"priceLimit":{"type":"integer","minimum":0,"maximum":250,"default":1,"description":"Recent daily price rows to return for an exact ticker. Use 0 to skip prices."},"limit":{"type":"integer","minimum":1,"maximum":100,"default":25,"description":"Maximum ETF search rows to return, 1-100."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"get_stock_metrics","title":"Get stock metrics","description":"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. Use the exact ticker as listed on Bullrun - the native local-exchange symbol (e.g. AAPL, BMW, ABBN, NESN, or a numeric code like 005930), NOT Yahoo-style country suffixes like BMW.DE or ABBN.SW. If a ticker returns no data, use screen_stocks (by sector/country) to find the exact symbol. Read-only.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"The stock ticker exactly as listed on Bullrun - the native local-exchange symbol, e.g. \"AAPL\", \"BMW\" (not \"BMW.DE\"), \"ABBN\" (not \"ABBN.SW\"), \"NESN\", or a numeric code like \"005930\". Do not append Yahoo-style country suffixes."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"get_financial_history","title":"Get financial history","description":"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.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"The ticker exactly as listed on Bullrun - the native local-exchange symbol, e.g. \"AAPL\", \"BMW\" (not \"BMW.DE\"), \"ABBN\" (not \"ABBN.SW\"), \"NESN\", or a numeric code like \"005930\". Do not append Yahoo-style country suffixes; if a lookup returns nothing, use screen_stocks to find the exact symbol."},"periodType":{"type":"string","enum":["annual","quarterly","both"],"default":"both","description":"Return annual rows, quarterly rows, or both. Annual rows use fiscalQuarter=0."},"years":{"type":"integer","minimum":1,"maximum":15,"default":10,"description":"How many fiscal years of history to return, counting backward from the latest fiscal year available."},"includeEmptyRows":{"type":"boolean","default":false,"description":"Include sparse rows that have no major income statement, balance sheet, cash-flow, or EPS values."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"get_quality_moat_metrics","title":"Get quality and moat metrics","description":"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.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"The ticker exactly as listed on Bullrun - the native local-exchange symbol, e.g. \"AAPL\", \"BMW\" (not \"BMW.DE\"), \"ABBN\" (not \"ABBN.SW\"), \"NESN\", or a numeric code like \"005930\". Do not append Yahoo-style country suffixes; if a lookup returns nothing, use screen_stocks to find the exact symbol."},"years":{"type":"integer","minimum":2,"maximum":15,"default":10,"description":"How many fiscal years of annual history to evaluate."},"estimatedWaccPct":{"type":"number","minimum":0,"maximum":50,"description":"Optional user-supplied WACC assumption, in percent. When omitted, ROIC-vs-WACC spread is returned as null."},"taxRateFallbackPct":{"type":"number","minimum":0,"maximum":50,"default":21,"description":"Fallback tax rate used for NOPAT only when reported tax/pretax data is missing or unusable."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"get_forward_estimates","title":"Get forward estimates","description":"Fetch forward consensus revenue/EPS/EBITDA estimates, management guidance ranges, and estimate-revision percentages for one exact Bullrun ticker. Also derives simple forward P/E and PEG-style context from the latest close when EPS estimates are available. Read-only.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"The ticker exactly as listed on Bullrun, e.g. \"AAPL\", \"CRWD\", \"SPGI\"."},"periodType":{"type":"string","enum":["annual","quarterly","both"],"default":"both","description":"Return annual estimates, quarterly estimates, or both."},"limit":{"type":"integer","minimum":1,"maximum":200,"default":80,"description":"Maximum estimate rows to return."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"get_operating_kpis","title":"Get operating KPIs","description":"Fetch period-specific operating KPIs and unit-economics metrics for one exact Bullrun ticker: ARR, net revenue retention, RPO, billings, customer counts, payments volume, cross-border volume, processed transactions, or other domain-specific metrics when populated. Read-only.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"The ticker exactly as listed on Bullrun, e.g. \"CRWD\", \"SNOW\", \"V\"."},"metricKey":{"type":"string","description":"Optional exact metric key to filter, e.g. ARR, NRR, RPO, BILLINGS, PAYMENT_VOLUME."},"category":{"type":"string","description":"Optional category filter such as SaaS, payments, marketplace, banking, or other domain labels."},"limit":{"type":"integer","minimum":1,"maximum":300,"default":120,"description":"Maximum KPI rows to return."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"get_revenue_breakdown","title":"Get revenue breakdown","description":"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.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"The ticker exactly as listed on Bullrun, e.g. \"SPGI\", \"MSFT\", \"V\"."},"dimension":{"type":"string","enum":["segment","geography","product","customer","other","all"],"default":"all","description":"Breakdown dimension to return, or all dimensions."},"limit":{"type":"integer","minimum":1,"maximum":300,"default":160,"description":"Maximum breakdown rows to return."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"get_earnings_call_transcript","title":"Get earnings call transcript","description":"Fetch speaker-tagged earnings-call transcript chunks for one exact Bullrun ticker, optionally filtered by fiscal period or search text. Use this for management guidance language, analyst Q&A, and qualitative judgment that is not visible in financial statements. Read-only.","inputSchema":{"type":"object","properties":{"ticker":{"type":"string","minLength":1,"description":"The ticker exactly as listed on Bullrun, e.g. \"CRWD\", \"SPGI\", \"V\"."},"fiscalYear":{"type":"integer","minimum":1900,"maximum":2200,"description":"Optional fiscal year filter."},"fiscalQuarter":{"type":"integer","minimum":1,"maximum":4,"description":"Optional fiscal quarter filter."},"search":{"type":"string","description":"Optional case-insensitive text/speaker search across transcript chunks."},"maxChunks":{"type":"integer","minimum":1,"maximum":200,"default":80,"description":"Maximum speaker-tagged transcript chunks to return."},"maxCharsPerChunk":{"type":"integer","minimum":200,"maximum":4000,"default":1600,"description":"Maximum characters per transcript chunk in the MCP response."}},"required":["ticker"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"list_portfolios","title":"List my portfolios","description":"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.","inputSchema":{"type":"object","properties":{"privacyMode":{"type":"string","enum":["full","weights_only"],"description":"\"full\" (default) includes absolute $; \"weights_only\" hides cash/value/cost-basis and keeps only %."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"get_portfolio_context","title":"Get portfolio context","description":"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.","inputSchema":{"type":"object","properties":{"portfolioId":{"type":"integer","exclusiveMinimum":0,"description":"The portfolio id, as returned by list_portfolios."},"days":{"type":"integer","minimum":7,"maximum":3700,"description":"Insights look-back window in days (default 30)."},"privacyMode":{"type":"string","enum":["full","weights_only"],"description":"\"full\" (default) includes absolute $; \"weights_only\" returns only relative figures."}},"required":["portfolioId"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"get_portfolio_analytics","title":"Get portfolio analytics","description":"Use when the user asks about THEIR portfolio's risk, diversification, or concentration, or whether to add a stock — 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). 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.","inputSchema":{"type":"object","properties":{"portfolioId":{"type":"integer","exclusiveMinimum":0,"description":"The portfolio id, as returned by list_portfolios."},"days":{"type":"integer","minimum":30,"maximum":1825,"description":"Calendar-day lookback for daily USD return analytics. Default 370."},"candidateTicker":{"type":"string","minLength":1,"description":"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)."},"candidateWeightPct":{"type":"number","minimum":0,"maximum":50,"description":"Optional hypothetical candidate allocation for pro-forma volatility. Default 5 (%)."},"privacyMode":{"type":"string","enum":["full","weights_only"],"description":"\"full\" (default) includes absolute USD amounts; \"weights_only\" returns only relative figures."}},"required":["portfolioId"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}},{"name":"create_portfolio_draft","title":"Create a portfolio draft","description":"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 and a Bullrun Pro account. 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.","inputSchema":{"type":"object","properties":{"prompt":{"type":"string","maxLength":600,"description":"What 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)."},"startingCash":{"type":"number","minimum":100,"maximum":100000000,"description":"Starting cash in USD (default 10000)."},"maxPositions":{"type":"integer","minimum":3,"maximum":20,"description":"Maximum number of holdings (3-20, default 10)."},"instrumentUniverse":{"type":"string","enum":["stocks","etfs","mix"],"description":"Candidate universe: stocks only, ETFs only, or a mix. Default mix unless the prompt says otherwise."}},"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":false,"destructiveHint":false},"execution":{"taskSupport":"forbidden"}},{"name":"create_position_draft","title":"Create a position draft","description":"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 and a Bullrun Pro account. 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.","inputSchema":{"type":"object","properties":{"portfolioId":{"type":"integer","exclusiveMinimum":0,"description":"The Bullrun portfolio id to propose additions for. Use list_portfolios first if unsure."},"maxPositions":{"type":"integer","minimum":1,"maximum":5,"description":"How many suggested additions to save, 1-5. Use 1 for a single-position idea; default 3."},"instrumentUniverse":{"type":"string","enum":["stocks","etfs","mix"],"description":"Candidate universe: stocks only, ETFs only, or a mix. Default mix."}},"required":["portfolioId"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":false,"destructiveHint":false},"execution":{"taskSupport":"forbidden"}},{"name":"create_portfolio_from_positions","title":"Save a portfolio from explicit holdings","description":"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. It is NOT Pro-gated (it mirrors manual position entry, which is free) and needs only 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.","inputSchema":{"type":"object","properties":{"positions":{"type":"array","items":{"type":"object","properties":{"ticker":{"type":"string","description":"Exact Bullrun ticker, used verbatim (never re-picked), e.g. VWCE.DE, SMH, ROG.SW."},"weight":{"type":"number","exclusiveMinimum":0,"description":"Target weight as a PERCENT (e.g. 46 for 46%). If the weights across positions sum to <=100 the remainder is held as cash; any other sum is normalised to fully invested. Use weight OR amountUsd across the basket, not both."},"amountUsd":{"type":"number","exclusiveMinimum":0,"description":"Explicit USD amount to allocate to this holding. If ANY position uses amountUsd, sizing is by amount for all."}},"required":["ticker"],"additionalProperties":false},"minItems":1,"maxItems":30,"description":"The exact holdings to persist (1-30). Tickers are used verbatim, never re-selected."},"name":{"type":"string","maxLength":72,"description":"Portfolio name. Default \"Custom Portfolio Draft\"."},"startingCash":{"type":"number","minimum":100,"maximum":100000000,"description":"Total portfolio cash in USD. Default 10000 in weight mode; the sum of amounts in amount mode."},"cashPct":{"type":"number","minimum":0,"maximum":95,"description":"Explicit cash percentage to hold back. Overrides the weight-remainder rule."}},"required":["positions"],"additionalProperties":false,"$schema":"http://json-schema.org/draft-07/schema#"},"annotations":{"readOnlyHint":false,"destructiveHint":false},"execution":{"taskSupport":"forbidden"}},{"name":"get_capabilities","title":"Get account capabilities","description":"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), whether the account has Bullrun Pro 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 (free), create_portfolio_draft and create_position_draft (Pro-only), 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.","inputSchema":{"$schema":"http://json-schema.org/draft-07/schema#","type":"object","properties":{}},"annotations":{"readOnlyHint":true},"execution":{"taskSupport":"forbidden"}}]},"jsonrpc":"2.0","id":301},"http_status":200,"headers":{"content-type":"text/event-stream","mcp-session-id":"57fa5335-f9a2-44b6-ac98-f9a0f08155d5"},"session_id_present":true,"transport":"streamable-http","requested_protocol_version":"2025-03-26","resumed":true}},"step_up_auth_probe":{"status":"warning","latency_ms":null,"details":{"oauth_present":true,"auth_required_checks":[],"supported_scopes":[],"scope_specificity_ratio":0.0,"broad_scopes":[],"challenge_headers":[],"step_up_signals":[],"minimal_scope_documented":false}},"transport_compliance_probe":{"status":"error","latency_ms":385.02,"details":{"transport":"streamable-http","session_id_present":true,"protocol_header_present":false,"last_event_id_visible":false,"requested_protocol_version":"2025-03-26","bad_protocol_status_code":400,"bad_protocol_payload":{"jsonrpc":"2.0","error":{"code":-32000,"message":"Bad Request: Unsupported protocol version: 1999-99-99 (supported versions: 2025-11-25, 2025-06-18, 2025-03-26, 2024-11-05, 2024-10-07)"},"id":null},"bad_protocol_headers":{"content-type":"application/json"},"bad_protocol_error":null,"delete_status_code":200,"delete_error":null,"expired_session_status_code":400,"expired_session_error":null,"issues":["missing_protocol_header","expired_session_not_404"]}},"utility_coverage_probe":{"status":"missing","latency_ms":102.24,"details":{"completions":{"advertised":false,"sample_target":null,"live_probe":"not_executed"},"pagination":{"supported":false,"next_cursor_methods":[],"metadata_signal":false},"tasks":{"advertised":false,"probe_status":"missing","http_status":400},"initialize_capability_keys":["prompts","tools"]}},"advanced_capabilities_probe":{"status":"missing","latency_ms":null,"details":{"capabilities":{"prompts":false,"resources":false,"completions":false,"roots":false,"sampling":false,"elicitation":false,"structured_outputs":false,"resource_links":false},"enabled_count":0,"enabled":[],"initialize_capability_keys":["prompts","tools"]}},"tool_snapshot_probe":{"status":"missing","latency_ms":null,"details":{"reason":"no_tools"}},"connector_replay_probe":{"status":"missing","latency_ms":null,"details":{"reason":"no_tools"}},"request_association_probe":{"status":"missing","latency_ms":null,"details":{"reason":"no_request_association_capabilities_advertised"}},"interactive_flow_probe":{"status":"ok","latency_ms":null,"details":{"risk_hits":[],"safe_hits":[],"oauth_supported":true,"prompt_available":false}},"action_safety_probe":{"status":"not_assessed","latency_ms":null,"details":{"summary":{"tool_count":0,"high_risk_tools":0,"destructive_tools":0,"exec_tools":0,"egress_tools":0,"secret_tools":0,"bulk_access_tools":0,"declared_non_read_only_tools":0,"annotation_conflict_tools":0,"risk_distribution":{"low":0,"medium":0,"high":0,"critical":0},"capability_distribution":{},"has_mutating_capability":false,"has_non_read_capability":false},"auth_present":true,"safeguard_count":0,"confirmation_signals":[],"reason":"empty_observation_set"}},"official_registry_probe":{"status":"missing","latency_ms":null,"details":{"registry_source":"glama_registry","direct_match":false,"official_peer_count":0}},"provenance_divergence_probe":{"status":"not_assessed","latency_ms":null,"details":{"direct_official_match":false,"registry_title":null,"server_card_title":null,"registry_version":null,"server_card_version":null,"registry_homepage":null,"server_card_homepage":null,"registry_repository":null,"server_card_repository":null,"drift_fields":[],"metadata_document_count":1,"compared_fields":["title","version","homepage","repository"],"readable_sources":[],"comparable_field_count":0}},"schema_divergence_probe":{"status":"missing","latency_ms":null,"details":{"reason":"no_server_card_tools","compared_tool_count":0,"compared_dimensions":["server_name","server_version","declared_vs_observed_auth","tool_membership","parameter_names","required_parameters","parameter_types","output_schema_presence"],"server_name_mismatch":false,"card_server_name":null,"live_server_name":"bullrun-mcp","server_version_mismatch":false,"card_server_version":null,"live_server_version":"0.3.0","auth_scheme_mismatch":false}},"connector_publishability_probe":{"status":"error","latency_ms":null,"details":{"transport":"streamable-http","tool_count":0,"high_risk_tools":0,"blockers":["tools_list","protocol_version","step_up_auth","transport_compliance","connector_replay","request_association","action_safety","server_card","tool_surface"],"criteria":{"remote_transport":true,"initialize":true,"tools_list":false,"protocol_version":false,"session_resume":true,"step_up_auth":false,"transport_compliance":false,"connector_replay":false,"request_association":false,"action_safety":false,"server_card":false,"tool_surface":false,"auth_flow":true}}}}},"active_alerts":[{"code":"server_failing","severity":"critical","title":"Latest validation is failing","message":"Core MCP flows did not validate successfully on the latest run.","addressee":"publisher"}],"maintainer_analytics":{},"public_server_reputation":{},"maintainer_response_quality":{},"maintainer_annotations":[],"maintainer_rebuttals":[],"security_posture_summary":{},"tool_security_inventory":[],"transport_compliance":{},"utility_coverage":{},"write_action_governance":{},"provenance_divergence":{},"alias_consolidation":{},"alert_routing":{},"authenticated_validation":{},"hosted_runtime":{},"action_controls_diff":null,"benchmark_tasks":[],"latest_capability_counts":{},"point_loss_breakdown":[],"verdict_traces":{},"current_snapshot":{"schema_version":"verify.trust_snapshot.v1","snapshot_id":"trustsnap_593807c14b334998","generated_at":"2026-09-10T06:06:50.554339+00:00","trust_evaluated_at":"2026-09-10T06:06:50.554339+00:00","evidence_revision":"574db1f83e6a1a0c709a7bf9","source":"current_snapshot","server":"ferinator/bullrun-mcp","last_validated_at":"2026-09-10T04:17:01.186046+00:00","validation_age_hours":1.83,"freshness":{"schema_version":"verify.freshness_profile.v1","last_validated_at":"2026-09-10T04:17:01.186046+00:00","age_hours":1.83,"bucket":"verified_last_24h","label":"Verified in last 24h","badges":["verified_last_24h"],"freshness_sla_hours":720.0,"freshness_sla_status":"met","stale_score_suppressed":false,"display_score":null,"raw_score":null,"confidence_score":null,"confidence_weighted_score":null,"tier_status":[{"tier":"community","label":"Community","freshness_sla_hours":720,"met":true,"priority_revalidation":false},{"tier":"pro","label":"Pro","freshness_sla_hours":168,"met":true,"priority_revalidation":true},{"tier":"enterprise","label":"Enterprise","freshness_sla_hours":24,"met":true,"priority_revalidation":true}]},"current_status":"failing","current_score":null,"display_score":null,"stale_score_suppressed":false,"production_trust_decision":{"schema_version":"verify.executive_verdict.v1","decision":"Not assessed","why":"tool surface has not been observed by any completed validation run","next_action":"revalidate so the tool surface can be inspected before a production decision is made","reason_count":0},"production_readiness_class":{"code":"failing","label":"Failing","reason":"The latest validation run was attempted but did not complete successfully."},"evidence_confidence":{"score":null,"label":"not_assessed","validation_age_hours":1.83,"live_check_count":8,"basis":{"evidence_bearing_validations":0,"affirmative_live_check_count":8,"validation_age_hours":1.83,"freshness_threshold_hours":24}},"active_alerts":[{"code":"server_failing","severity":"critical","title":"Latest validation is failing"}],"active_alert_summary":{"critical":1,"high":0,"medium":0,"low":0,"high_or_critical":1,"total":1},"materialization":{"state":"partial","trust_core_complete":true,"fields_unavailable":["tool_security_inventory","security_posture_summary","write_action_governance","capability_taxonomy","remediations"],"materialized_at":"2026-09-10T06:06:50.554339+00:00"}},"trust_snapshot":{"schema_version":"verify.trust_snapshot.v1","snapshot_id":"trustsnap_593807c14b334998","generated_at":"2026-09-10T06:06:50.554339+00:00","trust_evaluated_at":"2026-09-10T06:06:50.554339+00:00","evidence_revision":"574db1f83e6a1a0c709a7bf9","source":"current_snapshot","server":"ferinator/bullrun-mcp","last_validated_at":"2026-09-10T04:17:01.186046+00:00","validation_age_hours":1.83,"freshness":{"schema_version":"verify.freshness_profile.v1","last_validated_at":"2026-09-10T04:17:01.186046+00:00","age_hours":1.83,"bucket":"verified_last_24h","label":"Verified in last 24h","badges":["verified_last_24h"],"freshness_sla_hours":720.0,"freshness_sla_status":"met","stale_score_suppressed":false,"display_score":null,"raw_score":null,"confidence_score":null,"confidence_weighted_score":null,"tier_status":[{"tier":"community","label":"Community","freshness_sla_hours":720,"met":true,"priority_revalidation":false},{"tier":"pro","label":"Pro","freshness_sla_hours":168,"met":true,"priority_revalidation":true},{"tier":"enterprise","label":"Enterprise","freshness_sla_hours":24,"met":true,"priority_revalidation":true}]},"current_status":"failing","current_score":null,"display_score":null,"stale_score_suppressed":false,"production_trust_decision":{"schema_version":"verify.executive_verdict.v1","decision":"Not assessed","why":"tool surface has not been observed by any completed validation run","next_action":"revalidate so the tool surface can be inspected before a production decision is made","reason_count":0},"production_readiness_class":{"code":"failing","label":"Failing","reason":"The latest validation run was attempted but did not complete successfully."},"evidence_confidence":{"score":null,"label":"not_assessed","validation_age_hours":1.83,"live_check_count":8,"basis":{"evidence_bearing_validations":0,"affirmative_live_check_count":8,"validation_age_hours":1.83,"freshness_threshold_hours":24}},"active_alerts":[{"code":"server_failing","severity":"critical","title":"Latest validation is failing"}],"active_alert_summary":{"critical":1,"high":0,"medium":0,"low":0,"high_or_critical":1,"total":1},"materialization":{"state":"partial","trust_core_complete":true,"fields_unavailable":["tool_security_inventory","security_posture_summary","write_action_governance","capability_taxonomy","remediations"],"materialized_at":"2026-09-10T06:06:50.554339+00:00"}},"agent_commerce":{},"latest_claim":null,"maintainer_profile_slug":null,"watch_summary":{},"partial":true,"fields_unavailable":["tool_security_inventory","security_posture_summary","write_action_governance","capability_taxonomy","remediations"],"trust_evaluated_at":"2026-09-10T06:06:50.554339+00:00","evidence_revision":"574db1f83e6a1a0c709a7bf9","active_alert_summary":{"critical":1,"high":0,"medium":0,"low":0,"high_or_critical":1,"total":1},"materialization":{"state":"partial","trust_core_complete":true,"fields_unavailable":["tool_security_inventory","security_posture_summary","write_action_governance","capability_taxonomy","remediations"],"materialized_at":"2026-09-10T06:06:50.554339+00:00"},"owner_opted_out":false,"observed_attention":{"schema":"verify.observed_attention.v1","window_days":30,"level":"none","label":"No observed attention","summary":"No recent machine-readable trust or discovery activity observed for this server.","segments":{"useful_ai_user":{"level":"none","observed":false,"description":"AI-assisted user sessions such as ChatGPT/User or Claude/User."},"machine_trust_evaluator":{"level":"none","observed":false,"description":"Synthetic sessions inspecting multiple trust surfaces such as report, policy, ledger, badge, trust-summary, or compare."},"possible_agent_or_script":{"level":"none","observed":false,"description":"Structured direct sessions with rapid profile, compare, report, policy, badge, or trust-surface fan-out."},"isolated_machine_surface":{"level":"none","observed":false,"description":"Aged-out direct synthetic singleton sessions that touched a machine-readable trust surface without becoming a broader evaluator."},"ai_crawler":{"level":"none","observed":false,"description":"Known AI crawler activity such as ClaudeBot, GPTBot, or similar crawlers."},"search_crawler":{"level":"none","observed":false,"description":"Search and SEO crawler activity."},"browser_like_automation":{"level":"none","observed":false,"description":"Browser-like synthetic sessions with rapid structured endpoint activity."},"confirmed_human":{"level":"none","observed":false,"description":"Confirmed browser-session human activity."}},"surfaces_observed":{"server_profile":false,"compare":false,"compare_json":false,"compare_api":false,"report_json":false,"policy":false,"ledger":false,"badge_metadata":false,"badge_svg":false,"trust_summary":false,"mcp_tool":false},"claim_prompt":{"recommended":false,"reason":"No claim prompt is recommended from observed attention in the current window."},"notes":["Observed attention is based on segmented first-party telemetry.","Crawler and evaluator activity is not treated as confirmed human demand.","Public levels are bucketed to avoid exposing raw traffic counts."]},"owner_activation":{"claim_recommended":false,"reason":"no_observed_attention"},"snapshot_id":"trustsnap_593807c14b334998"}],"rows":[{"label":"Snapshot ID","values":["trustsnap_593807c14b334998"]},{"label":"Status","values":["failing"]},{"label":"Score","values":[null]},{"label":"Production readiness","values":["Failing"]},{"label":"Production trust decision","values":["Not assessed"]},{"label":"Recommended policy","values":["Not assessed"]},{"label":"Observed Attention","values":["No observed attention"]},{"label":"Evidence confidence","values":[null]},{"label":"Freshness","values":["n/a"]},{"label":"Latency","values":["n/a"]},{"label":"Spec recency","values":[2.0]},{"label":"Session resume","values":[4.0]},{"label":"Step-up auth","values":[3.0]},{"label":"Transport compliance","values":[2.0]},{"label":"Utility coverage","values":[0.0]},{"label":"Publishability","values":[0.0]},{"label":"Connector replay","values":[0.0]},{"label":"Request association","values":[0.0]},{"label":"Action safety","values":[null]},{"label":"Registry presence","values":[2.0]},{"label":"Provenance divergence","values":[null]},{"label":"Client compatibility: ChatGPT","values":["unknown"]},{"label":"Client compatibility: Claude","values":["unknown"]},{"label":"Write-action publishing","values":["unknown"]},{"label":"Snapshot churn risk","values":["unknown"]},{"label":"Transport","values":["streamable-http"]},{"label":"Auth","values":["OAuth"]},{"label":"Tools","values":[0]},{"label":"Prompts","values":[0]},{"label":"Resources","values":[0]},{"label":"OAuth","values":[true]},{"label":"DCR","values":[false]},{"label":"Taxonomy","values":[""]},{"label":"Recommended for","values":["none"]},{"label":"Top alerts","values":["Latest validation is failing"]}],"partial":true,"fields_unavailable":["tool_security_inventory","security_posture_summary","write_action_governance","capability_taxonomy","remediations"],"cache_note":"Compact compare fallback response; deep compare evidence is deferred to protect web capacity.","trust_evaluated_at":"2026-09-10T06:06:50.554339+00:00","materialization":{"state":"partial","trust_core_complete":true,"fields_unavailable":["tool_security_inventory","security_posture_summary","write_action_governance","capability_taxonomy","remediations"],"materialized_at":"2026-09-10T06:06:50.558343+00:00"}}