Skip to content
verify mcp Beta VerifyMCP is currently in beta. If you notice any issues, email [email protected] and we’ll put it right.

Bullrun

REMOTE · MCP.BULL-RUN.ORG · SCANNED AUG 3

Global stock research, ML forecasts, valuation signals, screeners & portfolio tracking in Claude

Available components

+2 this week 62 Trust /100
Trust breakdown (6 categories)

How this component scores in each security and reliability category. Every signal is checked automatically against the live server, and we only credit what we can confirm. How we score →

Endpoint Security46
Transport & Reachability100
Schema Quality & AI Usability73
  • 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).Pass
  • AI-judged instruction clarity (excellent).Pass
  • Context-footprint check failed: tool/resource definitions use about 5212 tokens (~325/item across 16 items; 16 tools + 0 resources), over budget; trim descriptions and params. See how to fix → Fail
  • Usage-examples check failed: none of the tools include examples. See how to fix → Fail
Stability & Change Management27
  • Stability observed for 8 of 30 days with no destabilising changes; credit accrues until the full window elapses.Partial
Tool Coverage100
  • 100% of tools have a non-trivial description (not blank, and not just the tool's name).Pass
  • 100% of tool parameters carry a description.Pass
Capabilities100
  • Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.Pass
Install

Add this component to your MCP client. Where a client-specific snippet is available, pick your client below and copy it straight into your config; otherwise use the connection detail shown.

remote · mcp.bull-run.org

# add to Claude Code
claude mcp add --transport http org-bull-run-bullrun https://mcp.bull-run.org/mcp
# ~/.codex/config.toml
[mcp_servers.org-bull-run-bullrun]
url = "https://mcp.bull-run.org/mcp"
// opencode.json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "org-bull-run-bullrun": {
      "type": "remote",
      "url": "https://mcp.bull-run.org/mcp",
      "enabled": true
    }
  }
}
# add to OpenClaw
openclaw mcp add org-bull-run-bullrun --url https://mcp.bull-run.org/mcp --transport streamable-http
# ~/.hermes/config.yaml
mcp_servers:
  org-bull-run-bullrun:
    url: "https://mcp.bull-run.org/mcp"
// mcp.json
{
  "mcpServers": {
    "org-bull-run-bullrun": {
      "type": "http",
      "url": "https://mcp.bull-run.org/mcp"
    }
  }
}

The mcpServers block is a cross-client convention. Remote transports vary, so check your client's docs.

Changelog

Every change we have recorded for this component, newest first. Security-relevant changes are always shown. ▲ marks a change for the better, ▼ a change for the worse; unmarked changes are neutral.

  • 3 Aug 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 23 to 27. That category is still filling its 30-day observation window: 7 days of observed history at the previous scan, 8 at this one. The score rises as the window fills, whether or not the server changes.

  • 31 Jul 26 −1
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 29 Jul 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 7 to 10. That category is still filling its 30-day observation window: 2 days of observed history at the previous scan, 3 at this one. The score rises as the window fills, whether or not the server changes.

  • 28 Jul 26 +1

    No change was recorded against any check on this day. Stability & Change Management went from 3 to 7. That category is still filling its 30-day observation window: 1 days of observed history at the previous scan, 2 at this one. The score rises as the window fills, whether or not the server changes.

  • 27 Jul 26 0
    • We updated how we score, so this day's move reflects our rubric, not a change to the server See what changed → functional
  • 26 Jul 26 60

    First indexed and scored.

Diagnostics

Diagnostic detail from the automated scan of this channel: what the scanner observed at each step, so you can see exactly where a check passed or failed. It is informational only and never changes the trust score.

Captured 3 Aug 2026 · Probed https://mcp.bull-run.org/mcp

TLS valid

Negotiated TLS 1.3 with TLS_AES_128_GCM_SHA256 .

Subject Issuer Valid from Valid until Key Signature Serial
CN=bull-run.org CN=YE1,O=Let's Encrypt,C=US 20 Jun 2026 18 Sept 2026 ECDSA 256 ECDSA-SHA384 5d52df1b938473303dc7b8299937c474611
SANs: *.bull-run.org, bull-run.org
CN=YE1,O=Let's Encrypt,C=US (CA) CN=Root YE,O=ISRG,C=US 3 Sept 2025 2 Sept 2028 ECDSA 384 ECDSA-SHA384 5ddd70dd31f801c85c186a7a04b80afe
CN=Root YE,O=ISRG,C=US (CA) CN=ISRG Root X2,O=Internet Security Research Group,C=US 13 May 2026 2 Sept 2032 ECDSA 384 ECDSA-SHA384 872165fc34b6e5fba8add5b3705fb53a
CN=ISRG Root X2,O=Internet Security Research Group,C=US (CA) CN=ISRG Root X1,O=Internet Security Research Group,C=US 13 May 2026 2 Sept 2032 ECDSA 384 SHA256-RSA 6c8f1dc727c7117f7baf853ac980f9cd
DNSSEC insecure

Validation of mcp.bull-run.org. Not signed

Zone DS Keys Algorithms Outcome
. trust_anchor 20326, 38696 8, 8 Verified
org. present 26974 8 Verified
bull-run.org. absent Unsigned (proven) parent-signed NSEC/NSEC3 proves an unsigned delegation
Authentication No authorisation required

The endpoint answered without asking for a token. Anyone who knows the URL can reach it.

Result No authorisation required
HTTP status 200
Transports 2 probes
Transport URL Outcome Status Location
streamable-http https://mcp.bull-run.org/mcp Verified 200
http (plaintext) http://mcp.bull-run.org/mcp Inconclusive 400
MCP tools — 16 exposed · ~4,378 tokens

The tools this component advertises to a client, with an estimated token cost for each. Expand a tool to see its parameters and schema. The per-tool counts are indicative and are not scored directly; the schema's total context footprint is one signal in Schema Quality & AI Usability.

Tool Tokens
create_portfolio_draft ~405

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.

NameTypeReqDescription
instrumentUniversestringCandidate universe: stocks only, ETFs only, or a mix. Default mix unless the prompt says otherwise.
maxPositionsintegerMaximum number of holdings (3-20, default 10).
promptstringWhat 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 nati…
startingCashnumberStarting cash in USD (default 10000).

No output schema declared.

No examples provided.

create_portfolio_from_positions ~345

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 query_etfs / screen_stocks / get_stock_metrics to confirm exact tickers first). For a vague brief where the model should pick, use create_portfolio_draft instead.

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

No output schema declared.

No examples provided.

create_position_draft ~320

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.

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

No output schema declared.

No examples provided.

get_capabilities ~144

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.

Input schema present but exposes no named parameters.

No output schema declared.

No examples provided.

get_earnings_call_transcript ~168

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.

NameTypeReqDescription
fiscalQuarterintegerOptional fiscal quarter filter.
fiscalYearintegerOptional fiscal year filter.
maxCharsPerChunkintegerMaximum characters per transcript chunk in the MCP response.
maxChunksintegerMaximum speaker-tagged transcript chunks to return.
searchstringOptional case-insensitive text/speaker search across transcript chunks.
tickerstringyesThe ticker exactly as listed on Bullrun, e.g. "CRWD", "SPGI", "V".

No output schema declared.

No examples provided.

get_financial_history ~266

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.

NameTypeReqDescription
includeEmptyRowsbooleanInclude sparse rows that have no major income statement, balance sheet, cash-flow, or EPS values.
periodTypestringReturn annual rows, quarterly rows, or both. Annual rows use fiscalQuarter=0.
tickerstringyesThe 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-sty…
yearsintegerHow many fiscal years of history to return, counting backward from the latest fiscal year available.

No output schema declared.

No examples provided.

get_forward_estimates ~120

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.

NameTypeReqDescription
limitintegerMaximum estimate rows to return.
periodTypestringReturn annual estimates, quarterly estimates, or both.
tickerstringyesThe ticker exactly as listed on Bullrun, e.g. "AAPL", "CRWD", "SPGI".

No output schema declared.

No examples provided.

get_operating_kpis ~163

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.

NameTypeReqDescription
categorystringOptional category filter such as SaaS, payments, marketplace, banking, or other domain labels.
limitintegerMaximum KPI rows to return.
metricKeystringOptional exact metric key to filter, e.g. ARR, NRR, RPO, BILLINGS, PAYMENT_VOLUME.
tickerstringyesThe ticker exactly as listed on Bullrun, e.g. "CRWD", "SNOW", "V".

No output schema declared.

No examples provided.

get_portfolio_analytics ~459

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.

NameTypeReqDescription
candidateTickerstringOptional 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).
candidateWeightPctnumberOptional hypothetical candidate allocation for pro-forma volatility. Default 5 (%).
daysintegerCalendar-day lookback for daily USD return analytics. Default 370.
portfolioIdintegeryesThe portfolio id, as returned by list_portfolios.
privacyModestring"full" (default) includes absolute USD amounts; "weights_only" returns only relative figures.

No output schema declared.

No examples provided.

get_portfolio_context ~362

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.

NameTypeReqDescription
daysintegerInsights look-back window in days (default 30).
portfolioIdintegeryesThe portfolio id, as returned by list_portfolios.
privacyModestring"full" (default) includes absolute $; "weights_only" returns only relative figures.

No output schema declared.

No examples provided.

get_quality_moat_metrics ~258

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.

NameTypeReqDescription
estimatedWaccPctnumberOptional user-supplied WACC assumption, in percent. When omitted, ROIC-vs-WACC spread is returned as null.
taxRateFallbackPctnumberFallback tax rate used for NOPAT only when reported tax/pretax data is missing or unusable.
tickerstringyesThe 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-sty…
yearsintegerHow many fiscal years of annual history to evaluate.

No output schema declared.

No examples provided.

get_revenue_breakdown ~112

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.

NameTypeReqDescription
dimensionstringBreakdown dimension to return, or all dimensions.
limitintegerMaximum breakdown rows to return.
tickerstringyesThe ticker exactly as listed on Bullrun, e.g. "SPGI", "MSFT", "V".

No output schema declared.

No examples provided.

get_stock_metrics ~263

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.

NameTypeReqDescription
tickerstringyesThe 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 Yah…

No output schema declared.

No examples provided.

list_portfolios ~212

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.

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

No output schema declared.

No examples provided.

query_etfs ~366

Search the Bullrun ETF universe by ticker/fund name plus ETF asset class, exposure, domicile, exchange and currency. For an exact ticker, returns ETF profile details, recent historical price rows, and latest holdings. Read-only.

NameTypeReqDescription
categorystringExact broad ETF asset-class filter, such as Equity, Fixed Income, Commodity, Crypto, or Real Estate. Kept as category for API compatibility.
currencystringExact trading currency filter, e.g. USD, EUR, CHF.
domicilestringExact ETF domicile filter.
exchangestringExact exchange filter, e.g. NYSE ARCA, LSE, XETRA.
focusstringExact ETF exposure filter, such as Japan, Equity - Australia, TOPIX, or an exchange/source exposure label. Kept as focus for API compatibility.
holdingsLimitintegerMaximum holdings to return for an exact ticker, 1-100.
includeHoldingsbooleanWhen ticker is supplied, include latest holdings. Ignored for broad searches.
includeInactivebooleanInclude ETFs with no recent price bar. Default false.
includeSecondarybooleanInclude secondary/cross-listed ETF tickers. Default false.
limitintegerMaximum ETF search rows to return, 1-100.
priceLimitintegerRecent daily price rows to return for an exact ticker. Use 0 to skip prices.
searchstringFree-text ETF search by ticker or fund name. Omit to list the first ETFs.
tickerstringExact ETF ticker for profile, prices, and optional holdings, e.g. SPY, VWRL.L, EUNL.DE.

No output schema declared.

No examples provided.

screen_stocks ~415

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.

NameTypeReqDescription
countriesarrayExact country names to include. Use this for multi-country screens; it overrides country when provided.
countrystringExact country name to filter by, e.g. "United States", "Germany". Omit for all countries.
includeInactivebooleanInclude delisted/inactive tickers with no recent price bar. Default false.
includeSecondarybooleanInclude secondary cross-listings of the same security. Default false (primary listings only).
industrystringExact industry name to filter by, e.g. "Software - Infrastructure". Omit for all industries.
limitintegerMaximum number of stocks to return (1-100).
lookbackintegerHow many reporting periods to evaluate. Growth rules need at least 2 comparable periods.
lookbackModestringWhether rule evaluation uses annual or quarterly reporting periods.
minMarketCapnumberCompatibility shortcut: adds marketCap >= this absolute value to every rule group.
modestringDeprecated alias for lookbackMode; kept for compatibility.
orderstringSort direction. Nulls always sort last regardless of direction.
periodsintegerDeprecated alias for lookback; kept for compatibility.
rulesarrayFundamental rules. Same groupId means AND; different groupIds mean OR.
sectorstringExact sector name to filter by, e.g. "Technology", "Healthcare". Omit for all sectors.
sortBystringMetric to sort by. revenueGrowth is accepted as an alias for revenueGrowthPct.

No output schema declared.

No examples provided.