A stateless MCP server that gathers and structures financial data for AI trading agents (snapshots, fundamentals, dividends, crypto data, and more). Pairs with agentic-trading-mcp.
Scout demonstrates solid tool design with clear, domain-specific naming (company_dossier, search_symbols, market_movers) and comprehensive descriptions (avg 180 chars, well above 34-char baseline). All 10 tools have explicit descriptions and input schemas with types. However, output schemas are not formally documented in the code, responses are returned as Pydantic model_dump() without inline schema declarations. Parameter descriptions are present but inconsistent in depth; some lack format/constraint details (e.g., 'as_of' accepts YYYY-MM-DD but this is only documented in the description text, not as a regex pattern). Error handling returns structured {ok, error} envelopes but lacks recovery guidance (e.g., 'symbol not found, try search_symbols()'). No tool annotations (readOnlyHint, destructiveHint) despite all tools being read-only. Composition is strong: tools chain well (search_symbols → company_dossier), batch operations reduce call count (compare, classify, news_digest accept symbol arrays), and responses include necessary IDs for downstream calls.
Upcoming earnings and ex-dividend dates across several symbols, sorted by date. Answers "what's coming up for my positions this week?" in one call. Pass `as_of` (YYYY-MM-DD) to treat that date as "now". Returns events (symbol, type, date) only.
Sector, industry and market cap for several symbols in one call. The building block for "how much of my book is tech?": this returns the classification per symbol so the agent can aggregate exposure (the agent owns the position sizes; Scout just labels the names). A symbol whose data is missing gets a `note`.
Consolidated one-call research dossier for a US stock/ETF — the flagship tool. Fans several reads out in parallel and returns them together: a `snapshot`, plus (when `depth="full"`, the default) `fundamentals` and `dividends`. Use `depth="summary"` for a quick snapshot-only read. Pass `as_of` (YYYY-MM-DD) for a point-in-time view. If one source is momentarily unavailable the dossier still returns, with the gap recorded in `notes` — prefer this over calling the individual tools when you want the full picture at once.
Light single-call portrait of a US stock/ETF: price, day move and key multiples. Returns name, currency, price, previous_close, change/percent, market cap, trailing & forward P/E, dividend yield, 52-week high/low, sector and industry. Also `recent_splits` (newest first) — so a split-adjusted price (e.g. NFLX post-10:1) isn't read as "wrong" against pre-split memory; price and the 52-week range are already split-adjusted. Pass `as_of` (YYYY-MM-DD) to read a past date — historical reads return price/move (plus splits up to that date) only (point-in-time multiples are not available yet). `data` is null if the symbol can't be resolved.
Output schemas not formally documented. Responses are Pydantic model_dump() calls without inline schema declarations or return type annotations in docstrings. LLMs cannot plan downstream tool calls without knowing response structure.
Error responses lack recovery guidance. Errors return {ok: false, error: str(exc)} with no actionable next steps. E.g., 'symbol not found' should suggest 'Try search_symbols() with a partial name.'
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 62 | 2026-07-28+ | v2 |
Compare several US stocks/ETFs side by side in one call. For each symbol, gathers price, market cap, trailing & forward P/E, dividend yield, revenue, net margin and sector (snapshot + fundamentals, in parallel). Pass `as_of` (YYYY-MM-DD) for a point-in-time view. A symbol whose data is unavailable still appears, with a `note`.
Pairwise return correlation between symbols — to see real diversification. Fetches each symbol's daily prices over `period`, aligns them on common trading days and returns the Pearson correlation of daily returns for every pair (1.0 = move together, -1.0 = move opposite, ~0 = unrelated). Needs at least two symbols with overlapping history.
Market-wide top movers today — discovery WITHOUT a symbol in hand. `category` is "gainers", "losers" or "most_active". Returns the names moving most today (symbol, name, price, % change, volume) so you can ask "what's moving right now?" before you have a ticker. Raw market data, not a pick.
Recent headlines across several symbols in one call, newest first. For "any news that affects what I hold?" over a whole watchlist/portfolio — each item is tagged with its symbol and carries a link you can pass to `extract`. Headlines only.
Derived quality & return ratios for a US company. Returns ROE, ROA, gross/operating/net margins, year-over-year revenue & earnings growth, and multi-year revenue & net-income CAGR (computed from the income statements). Raw numbers — it does not score "quality" or "moat"; you read ROE/margins/CAGR and judge. NOTE on basis: ROE, ROA and the margins here are the provider's trailing-twelve-month (TTM) figures — they will NOT reconcile with a single fiscal-year statement (e.g. ROE here ≠ that year's net income / equity from `sec_financials`), since the numerator is TTM, not the fiscal year. Only the CAGR fields are derived from the annual statements.
Resolve a company name or partial ticker to matching symbols. The starting point when you have a name but not the ticker (e.g. "nvidia", "coca cola"). Returns candidates with symbol, name, exchange and instrument type — pick the right ticker, then feed it to the other tools.
No tool annotations despite all tools being read-only. FastMCP supports readOnlyHint annotation; adding it would signal to agents that these tools are safe to call speculatively without side effects.
Parameter constraints not formalized. 'as_of' accepts YYYY-MM-DD but is documented only in description text, not as a JSON Schema format or pattern. Numeric limits (limit_per_symbol, period) lack min/max bounds.
Partial failure handling not documented. Tools like company_dossier note 'If one source is momentarily unavailable the dossier still returns, with the gap recorded in notes' but the notes field structure is not formally specified.