# Stocklake - full agent reference > Stock market data for AI agents, served as a remote MCP server. Prices, fundamentals, technical indicators and daily price history for 3,500+ US, European and Asian stocks and ETFs, plus AI research, signals, insider activity, financial statements and macro/sector intelligence. No account needed to start. This is the complete reference. The short version is https://www.stocklake.dev/llms.txt. Contents: 1. Rules for agents 2. Connecting 3. Tiers, pricing and limits 4. Errors 5. Data coverage, symbols and freshness 6. Conventions (units, scores, directions) 7. Picking the right tool 8. Free tools 9. Pro tools 10. Other surfaces and links --- ## 1. Rules for agents - Use Stocklake's numbers for prices, indicators and fundamentals. Do not fill gaps from memory. - Prefer OAuth. Ask the user for an API key only if your client cannot do OAuth. - Watch the call budget (section 3). Batch-style tools cost 1 call per stock. On guest or free, keep `limit` small and pass a single `category` to `get_market_movers`. - On HTTP 429, stop. Tell the user the limit resets at 00:00 UTC and how to get more (sign in, or Pro). Retrying cannot succeed before the reset. - On `pro_required`, tell the user once that the feature is part of the Pro plan; the `upgrade` field links to the plan overview. Do not call other Pro tools hoping for a different answer. - Check timestamps (`updated_at`, `generated_at`, `flagged_at`, `regime_stale`) before presenting data as current. - Stocklake is informational. Never present its output as personal financial advice or as a recommendation to trade. - Data is for the account holder's own use. Do not build a tool that resells or redistributes Stocklake data, bulk-exports it, or mirrors it as a downstream feed (section 3, Data usage). --- ## 2. Connecting Endpoint: https://api.stocklake.dev/mcp Transport: Streamable HTTP Protocol: MCP 2025-11-25 Discovery: `initialize` and `tools/list` work without authentication and never count against a limit. ### 2.1 OAuth (preferred) Add https://api.stocklake.dev/mcp as a connector or remote MCP server. The client runs OAuth; the user signs in with a magic link sent to their email. No password, no key to copy. - claude.ai and Claude Desktop: Settings → Connectors → search "Stocklake" (listed in the Claude Connectors Directory) or add the URL. - Claude Code: `claude mcp add stocklake --transport http --url https://api.stocklake.dev/mcp`, then run `/mcp`, select stocklake, choose Authenticate. Adding the server does not start sign-in by itself. Until you authenticate, every call runs as guest. - ChatGPT: Settings → Connectors → Developer Mode → add a custom connector with the URL. - Perplexity (Pro/Max/Enterprise): Developer Mode → add a remote connector with the URL. - Cursor, VS Code, Windsurf, Zed, Codex and other local clients: add the URL as a remote MCP server; they complete OAuth through a local callback. - Also listed on Smithery, Glama and LobeHub. OAuth details, for client builders: - Protected resource metadata: https://api.stocklake.dev/.well-known/oauth-protected-resource (RFC 9728) - Authorization server metadata: https://api.stocklake.dev/.well-known/oauth-authorization-server (RFC 8414) - Dynamic client registration: POST https://api.stocklake.dev/oauth/register (RFC 7591) - Authorization code flow with PKCE (S256). Endpoints: /oauth/authorize, /oauth/token, /oauth/revoke. - Access tokens last 1 hour. Refresh tokens last 30 days and rotate on each use. - Claude, ChatGPT, Perplexity, loopback (localhost) callbacks and the cursor/vscode/windsurf/zed app schemes sign in without a consent screen. Any other callback shows a one-time consent page. - An unauthenticated call to a Pro-only tool returns HTTP 401 with `WWW-Authenticate: Bearer ... resource_metadata="https://api.stocklake.dev/.well-known/oauth-protected-resource"`. OAuth-capable clients use this to start sign-in. - Users can see and revoke connections at https://www.stocklake.dev/account under "Active connections". ### 2.2 API key (only when OAuth is not possible) 1. The user signs in at https://www.stocklake.dev/login (email, magic link; no password, no card). 2. The key (starts with `sl_`) is on the account page. It does not expire. 3. Send it on every request as `Authorization: Bearer sl_...` or `X-API-Key: sl_...`. Python example (fastmcp): from fastmcp import Client from fastmcp.client.transports import StreamableHttpTransport transport = StreamableHttpTransport( url="https://api.stocklake.dev/mcp", headers={"Authorization": "Bearer sl_your_key"}, ) async with Client(transport) as client: result = await client.call_tool("get_stock", {"symbol": "AAPL"}) ### 2.3 Guest (no account) Send no Authorization or X-API-Key header. You get the 11 free tools with the guest limit (section 3). Pro-only tools return HTTP 401 as described above. ### 2.4 Raw JSON-RPC Any HTTP client can call tools directly. Send `Content-Type: application/json` and `Accept: application/json, text/event-stream`. POST https://api.stocklake.dev/mcp {"jsonrpc":"2.0","id":1,"method":"tools/call", "params":{"name":"get_stock","arguments":{"symbol":"AAPL"}}} Tool results come back as JSON text in `result.content[0].text`. --- ## 3. Tiers, pricing and limits | Tier | Calls/day | Tools | Cost | |-------|-----------|--------------------------------------------------------|----------------------------------------| | guest | 25 per IP | 11 free tools, base fields | none, no account | | free | 200 | 11 free tools, base fields | free account, no card | | pro | 5,000 | all 20 tools, plus Pro fields inside the 11 free tools | $20/month | - Free tools: get_stock, get_stocks, get_stock_history, get_stock_news, get_screener, get_market_movers, get_market_pulse, get_earnings_calendar, get_insider_activity, get_stock_financials, get_economic_calendar. - Pro-only tools: get_stock_research, get_signals, get_news_feed, get_market_assessment, get_sector_intelligence, get_earnings_intelligence, get_indicator_history, get_analyst_trend, get_watchlist. - Pro: the first upgrade on an account includes a 7-day free trial. Checkout runs on Stripe; cancel any time from the account page. Upgrade at https://www.stocklake.dev/account. - Data is free, AI analysis is Pro: prices, fundamentals, core indicators, history, plain headlines, screening, movers, market pulse, the earnings and economic calendars, the latest fiscal year of statements and recent insider filings are available to everyone. AI research, AI scores, signals, specialized indicators, ratings, multi-year and quarterly statements, the full filing window and macro/sector intelligence are Pro. ### 3.1 How calls are counted - The counter resets at 00:00 UTC. - Guest is counted per IP address (per /64 for IPv6). - A free or pro account has a single counter, shared by its API key and all OAuth sessions. Rotating the key does not reset it. - `initialize` and `tools/list` are free. - A `tools/call` costs 1, also when it returns `symbol_not_found` or `pro_required`. A call rejected for its arguments before any lookup (wrong type, unknown parameter, unknown preset or category) costs nothing. Exceptions: | Tool | Cost | |-----------------------------|-----------------------------------------------------------------------| | get_stocks | 1 per requested symbol, including symbols not found (a malformed symbol, e.g. one with an underscore, is listed in `missing` and not billed); the request is admitted only if symbols + 5 fit in the remaining budget | | get_screener | 1 per result row (limit 1-25, default 20) | | get_market_movers | 1 per row in every category returned (limit is per category, max 20; category="all" returns 3 categories) | | get_signals (Pro) | 1 per signal returned (default 25, max 50) | | get_earnings_intelligence (Pro) | 1 per result row (max 25) | - `get_market_movers()` with no arguments returns up to 30 rows. That is more than a guest's whole day. Pass `category="gainers"`, `"losers"` or `"most_active"` and a small `limit`. - Budget example for guest: get_market_pulse (1) + get_market_movers(category="losers", limit=5) (5) + get_stocks with 10 symbols (10) = 16 of 25. ### 3.2 Rate-limit headers Tool-call responses carry: - `x-ratelimit-limit`: daily limit for this caller - `x-ratelimit-remaining`: calls left before this request - `x-ratelimit-reset`: next reset as Unix time (00:00 UTC) 429 responses also carry `retry-after` in seconds. On a 429, `x-ratelimit-remaining` is what is still left: a batch can be refused while a smaller request still fits. ### Data usage Stocklake data is for the account holder's own use: research, analysis, and your own agents and tools. Personal and internal use is fine. Not allowed: reselling or redistributing API data or access to third parties, bulk-exporting data beyond normal API usage, or building a mirror, downstream feed, or competing data product on top of the API. Accounts that appear to do this can be suspended. Full terms: https://www.stocklake.dev/legal#acceptable-use --- ## 4. Errors ### 4.1 HTTP-level | Status | When | Body | |--------|----------------------------------------------------------|----------------------------------------------------------------------| | 401 | Pro-only tool called with no credentials | JSON-RPC error, code -32001, `data.reason: "pro_tool_unauthenticated"`, plus `WWW-Authenticate` header | | 401 | Invalid or deactivated API key or token | `{"error": "Invalid or inactive API key", "oauth": ..., "guest_access": ..., ...}` | | 429 | Guest daily limit reached | `{"error": "guest_limit_reached", "message": ..., "action_for_agent": ..., "pro_upgrade": ...}` | | 429 | Free or pro daily limit reached (or request cost exceeds what is left) | `{"error": "Daily limit reached (N calls/day for tier 'free') ..."}` | | 403 | Blocked IP | `{"error": "Access blocked."}` | ### 4.2 Pro feature on a free account A free account calling a Pro-only tool (or the `high_conviction` screener preset) gets a normal result containing: { "error": "pro_required", "your_tier": "free", "message": "...", "tell_your_user": "...", "upgrade": "https://www.stocklake.dev/#pricing", "preview": { plain facts only: what exists and how fresh it is. Never AI output }, "preview_note": "what Pro unlocks for this tool" } ### 4.3 Tool errors Other errors come back inside the tool result as: {"error": {"code": "", "message": "", "type": "error" | "not_found"}} | Code | Meaning | |----------------------|--------------------------------------------------------------| | symbol_not_found | No data for this symbol. Check the suffix (section 5). | | symbol_invalid | Malformed symbol | | symbols_required / symbols_invalid | get_stocks called without a usable symbol list | | batch_too_large | get_stocks with more than 25 symbols. Split the list. | | history_not_found | No price history for this symbol | | invalid_preset / invalid_sort_by / invalid_sma_trend / invalid_macd_signal / invalid_min_volume / invalid_sector / invalid_country | Bad get_screener parameter | | invalid_period / invalid_statement | Bad get_stock_financials parameter | | invalid_category | Bad get_market_movers category | | invalid_direction / invalid_source | Bad get_signals parameter | | no_data | The pipeline has not produced this data yet | | no_account | get_watchlist called with a credential that has no account | | internal_error | Server-side failure. Safe to retry once later. | The message text always names the accepted values. --- ## 5. Data coverage, symbols and freshness ### 5.1 Coverage - 3,500+ symbols: about 3,200 stocks and 320 ETFs. Indices, futures and currency pairs cannot be looked up by symbol; `get_market_pulse` carries the index and volatility readings. - Stocks: about 2,000 US-listed companies and 1,200 outside the US - Germany, Canada, Switzerland, France, China, Japan, the UK, Italy, Hong Kong, the Netherlands, Spain, Singapore, Brazil, Australia, South Korea, Taiwan, India and more. - Sectors (11, as used by `sector` parameters): Basic Materials, Communication Services, Consumer Cyclical, Consumer Defensive, Energy, Financial Services, Healthcare, Industrials, Real Estate, Technology, Utilities. - Insider transactions: regulatory insider filings for the US, Germany, the Netherlands and Spain. Market data fills gaps where no filing is on record. - Not provided: intraday bars, tick data, options, order books, order execution. ### 5.2 Symbols - Exchange-suffix format. US: AAPL, NVDA. Share classes use a dash: BRK-B (BRK.B and BF.B are also accepted). Non-US listings need the exchange suffix: SAP.DE, MC.PA, 2318.HK, 4528.T, RELIANCE.NS, 005930.KS. - Many non-US companies also trade in the US as ADRs under a plain ticker (for example SAP, TM). Both may exist as separate symbols with different prices and currencies. - Single-symbol tools (get_stock, get_stocks, get_stock_history, get_stock_news, get_stock_research, get_insider_activity, get_indicator_history, get_stock_financials) accept a company name such as "GOLDMAN SACHS" when it matches exactly one company. The response then includes `resolved_from`. Names that match several companies return `symbol_not_found`; use the ticker. ### 5.3 Freshness | Data | Refresh | |-------------------------------------------|-------------------------------------------------------------------| | Prices, change, volume | every few minutes on trading days; less often on weekends. See `updated_at`. | | Technical indicators | several times per trading day | | Daily OHLCV history | daily | | News headlines and AI news reads | continuously through the day | | AI stock summaries (ai_verdict, ai_score) | rolling; each stock is regenerated every few days. See `generated_at`. | | Signals | throughout the day as screeners and news run. See `flagged_at`. | | Market assessment, sector intelligence | about 4 times per weekday during market hours; not overnight or on weekends. See `regime_stale`, `updated_at`. | | Insider and institutional data | daily scan; each stock refreshes when new filings appear | | Financial statements, forensic scores | when a company files new statements | All AI output is produced by scheduled pipelines. No AI runs on your request, so responses are fast and the same for every caller. --- ## 6. Conventions ### 6.0 Parameter ranges A numeric parameter outside its range is moved to the nearest allowed value, not rejected: a `limit` or `days` below 1 is treated as 1, a value above the maximum as the maximum. A batch tool then bills for the rows it returns. ### 6.1 Units - Timestamps: ISO 8601, UTC. - `price`, `prev_close`, `week52_high/low`, `analyst_target`: listing currency (see `currency`). - `market_cap`, `enterprise_value`, `revenue_ttm`, `free_cashflow`: listing currency, not converted to USD. `revenue_ttm`, `gross_profit_ttm` and `free_cashflow` come from the company's filings; when it files in another currency (`financial_currency`, e.g. CNY for BABA) they are converted to the listing currency, or null with a `financials_note` when no rate is available. `market_cap_usd` is the same market cap converted to US dollars (null when no FX rate exists for the currency). Market-cap filters (`min_market_cap_b`, `max_market_cap_b`) and the `market_cap` sort use `market_cap_usd`. - Percent values (e.g. 0.32 means 0.32%): `change_pct`, `dividend_yield`, `atr_pct`, `perf_*`, `*_pct` breadth fields, `inst_ownership`, `institutional_pct`. - Fractions (e.g. 0.276 means 27.6%): `profit_margins`, `operating_margins`, `return_on_equity`, `revenue_growth`, `earnings_growth`. - `debt_to_equity`: ratio × 100 (78.4 means 0.784). - `analyst_rating_score`: 1.0 (strong buy) to 5.0 (strong sell). ### 6.2 Direction vocabulary - `POSITIVE` / `NEGATIVE` / `NEUTRAL` everywhere a direction or stance is reported. Insider/institutional signals may also be `STRONG_POSITIVE` / `STRONG_NEGATIVE`. - On a signal, `NEUTRAL` also covers a two-sided idea (real arguments both ways). Its `rationale` explains both sides. - Analyst ratings keep their own vocabulary: strong_buy, buy, hold, sell, strong_sell. ### 6.3 Scores | Score | Scale | Meaning | Where | |----------------|-------|----------------------------------------------------------------------|-------| | signal_score | 0-100 | Strength of an idea or notable news: AI read, source track record and technical factors combined. For a two-sided signal it is the stronger side. | get_signals, get_news_feed, get_stock_news (Pro), get_stock_research, get_insider_activity | | ai_score | 0-100 | Strength of the AI stock summary's overall read | get_stock/get_stocks (Pro), get_screener (Pro), get_market_movers (Pro), get_earnings_intelligence, get_watchlist, get_stock_research | | rating.score | 0-10 | Technical-only composite from RSI, MACD, Bollinger Bands, SMA trend, Williams %R and Ultimate Oscillator | get_stock/get_stocks (Pro), get_screener (Pro) | | macro_score | 0-100 | How much risk the macro environment supports (0 = risk-off, 100 = risk-on) | get_market_assessment | | sector_score | 0-100 | Sector relative strength (0 = lagging, 100 = leading); comparable across sectors | get_sector_intelligence | | risk_appetite_score | 0-100 | Coarse restatement of the 4 regime buckets | get_market_assessment | `signal_score` and `ai_score` share the same bands, reported in `*_band` fields: | Band | Range | |-------------|--------| | Weak | 0-49 | | Moderate | 50-64 | | Strong | 65-79 | | Very Strong | 80-100 | A score and its band are `null` when there is not enough data, never 0. --- ## 7. Picking the right tool | You need | Call | |-------------------------------------------------|----------------------------------------------------| | Current price and fundamentals for one stock | get_stock | | The same for several stocks | get_stocks (one call, up to 25) | | Past prices for charting or returns | get_stock_history | | Everything about one stock, including AI analysis | get_stock_research (Pro) - replaces get_stock + get_stock_news + get_insider_activity + per-symbol signals | | News for one stock | get_stock_news | | The most important news across the market | get_news_feed (Pro) | | Stocks matching criteria | get_screener | | What moved today | get_market_movers | | The market's mood right now | get_market_pulse | | Macro regime and sector preferences | get_market_assessment (Pro) | | Which sectors lead or lag | get_sector_intelligence with no sector, sort_by_strength=true (Pro) | | Fresh trade ideas | get_signals (Pro) | | Who reports earnings soon | get_earnings_calendar; with AI context: get_earnings_intelligence (Pro) | | Macro releases (CPI, rates, payrolls) | get_economic_calendar (7-day window free, 14 on Pro) | | Indicator trends over time | get_indicator_history (Pro) | | Are analysts getting more or less bullish | get_analyst_trend (Pro) | | Balance sheet, income statement, cash flow | get_stock_financials (latest year free, history Pro) | | The user's own starred symbols | get_watchlist (Pro) | Efficient patterns: - Overview → detail: get_market_pulse, then get_screener or get_market_movers with a small limit, then get_stock_research on the one or two most relevant symbols. - Several stocks: always get_stocks, never a loop of get_stock. - Idea check: get_signals, then get_stock_research on the symbols you will actually discuss. --- ## 8. Free tools Available to guest, free and pro. "Pro adds" lists fields that only Pro callers receive; they are absent (not null) for guest and free. ### get_stock(symbol) Price, fundamentals, company profile, analyst consensus and indicators for one symbol. Returns: - Identity: symbol, name, exchange, currency, country, sector, industry, website, employees, description, officers[] (name, title, total_pay) - Price: price, change_pct, prev_close, volume, avg_volume, week52_high, week52_low, updated_at - Valuation and fundamentals: market_cap, market_cap_usd, enterprise_value, beta, pe_trailing, pe_forward, price_to_book, dividend_rate, dividend_yield, ex_dividend_date, debt_to_equity, profit_margins, operating_margins, gross_margins, return_on_equity, revenue_growth, earnings_growth, revenue_ttm, gross_profit_ttm, free_cashflow - Earnings: earnings_date (next report; null when no date has been announced), earnings_is_estimate (applies to that next date), last_earnings_date (most recent report) - Analysts: analyst_rating, analyst_rating_score, analyst_target, analyst_count - indicators: rsi, macd {macd_line, signal_line, histogram}, bollinger_bands {upper_band, middle_band, lower_band}, sma20, sma50, sma200, ema20, ema200, atr_20 Pro adds: - More indicators inside `indicators`: williams_r, ultimate_osc, vix_fix {value, percentile, spike}, williams_ad {trend, divergence}, td_sequential {setup_direction, setup_count, setup_complete, countdown_count, countdown_complete, countdown_direction, signal, phase, ...} (setup_direction / countdown_direction are downtrend_exhaustion = counting falling closes, a decline that may be running out, or uptrend_exhaustion = counting rising closes; signal is the most recent COMPLETED setup or countdown, DOWNTREND_EXHAUSTION_SETUP / UPTREND_EXHAUSTION_SETUP / DOWNTREND_EXHAUSTION_COUNTDOWN / UPTREND_EXHAUSTION_COUNTDOWN, and can be weeks old; for the count running now read setup_direction with setup_count, or countdown_direction with countdown_count), elliott_wave, adx {adx, plus_di, minus_di}, ichimoku {tenkan, kijun, cloud_top, cloud_bot, above_cloud, below_cloud}, squeeze {squeeze_on, hist}, rs_rank (relative-strength rank 1-99, stocks only: past-year return with the latest quarter counted double, ranked against every tracked stock; 99 = strongest; absent with under a year of history) - rating: {score 0-10, direction, signals: per-indicator {text, value, strength, verdict}} - signals: plain-English label per indicator (rsi, macd, bollinger, sma200, sma50, williams_r, ultimate_osc, vix_fix, williams_ad, td_sequential, elliott_wave) plus `overall` - stance_signals[]: one entry per source that has a current view - technical rating, AI summary near/longer term, insider/institutional, analyst consensus, recent signals. Each: {stance, conviction 0-10, horizon INTRADAY|SWING|POSITION|LONG_TERM, edge_quality PROVEN|OBSERVATION|UNKNOWN, source, raw_label, as_of}. Sources without current data are left out. - relative_strength: {windows: {5d, 20d, 60d, 120d, 12m: {stock_return_pct, rs_vs_spy, rs_vs_qqq, rs_vs_sector}}, verdict}. Values are percentage-point differences. Windows without enough history are left out. - market_risk: {beta_spy_1y, corr_spy_1y} - forensic_scores: {altman_z {score, zone safe|grey|distress, note}, piotroski_f {score 0-9, strength strong|moderate|weak, note}, beneish_m {score, likely_manipulator, note}, computed_at}. Read each `note`: Altman Z is not meaningful for banks and insurers and can flag REITs as distress; Beneish M is a screening heuristic, not proof of manipulation. `score: null` means not computable for this company. - sector_context: where this stock's revenue_growth, gross_margin and operating_margin sit versus the other tracked equities in its own sector: {sector, : {value, sector_median, percentile 0-100, n}, as_of, trend}. `trend` is {period: "quarterly", points: [{period_end, : {value, sector_median, n}}]}, oldest first, the last few quarters (revenue_growth is year-over-year) beside the sector median for that quarter. Descriptive positioning only, no rating or direction. A metric is left out when the stock has no value or its sector has fewer than 15 peers with data; the block is left out when nothing is computable. Sectors are pooled globally across all tracked equities; refreshed daily. - ai_verdict (POSITIVE|NEUTRAL|NEGATIVE), ai_headline (one sentence), ai_score, ai_score_band ### get_stocks(symbols) `get_stock` for up to 25 symbols in one call. - symbols: list of up to 25 symbols. More than 25 returns `batch_too_large`. - Returns: {count, requested, symbols: {SYMBOL: }, missing: [...], duplicates_collapsed} - Pro adds, per symbol, the same fields as get_stock (specialized indicators, rating, signals, relative_strength, market_risk, forensic_scores, sector_context without its `trend`, ai_verdict, ai_headline, ai_score, ai_score_band) except `stance_signals`. - Cost: 1 per requested symbol, including symbols not found. ### get_stock_history(symbol, days=90) Daily OHLCV bars, oldest first. - days: trading days to return. Guest and free: 1-365 (larger values are capped at 365 and the response carries a `pro_unlocks` note). Pro: full history, up to 20,000 trading days. A full-history call can be 10,000+ bars - request only the window you need. - Returns: {symbol, days_requested, days_returned, count, history: [{date, open, high, low, close, volume}], history_available: {bars, earliest_date}, pro_unlocks (guest/free only, when capped)} ### get_stock_news(symbol, limit=10, days=30) Recent AI-processed news for one symbol, newest first. - Guest and free: at most 5 articles and 30 days (larger values are reduced). Each article: title, published_at. - Pro: at most 50 articles and 90 days. Each article adds ai_sentiment, ai_summary, signal_score, signal_score_band. - signal_score on news: if the symbol has a news signal from the last 90 days, every article shows that signal's current score. Otherwise each article gets its own score from its AI read. - Returns: {symbol, articles[], count, status "ok"|"empty", days} (plus `message` when empty, `pro_unlocks` for guest and free; `tier_note` carries the same text under its older name) ### get_screener(...) Filter and rank stocks. Parameters (all optional): - sector: one of the 11 sectors in section 5.1 - country: e.g. "United States", "Germany" - min_rsi, max_rsi: RSI bounds - sma_trend: "above_200" | "below_200" - macd_signal: "positive" | "negative" - min_perf_1d, max_perf_1d: 1-day change in percent - min_volume: minimum daily volume - min_market_cap_b, max_market_cap_b: market cap in billions of US dollars (compared against market_cap_usd) - max_pe_forward - analyst_rating: "strong_buy" | "buy" | "hold" | "sell" | "strong_sell" - min_ai_score (Pro): 0-100; ignored for guest and free - preset: "oversold" (RSI ≤ 35 and above SMA200) | "overbought" (RSI ≥ 65) | "momentum" (RSI 50-70, above SMA200, up ≥ 0.5% today) | "high_conviction" (Pro: ai_score ≥ 70). A preset overrides the matching individual filters. - sort_by: "market_cap" (default) | "rsi" | "perf_1d" | "volume" | "analyst_rating" | "rating" (Pro) | "ai_score" (Pro; default for high_conviction). Pro sorts fall back to market_cap for guest and free. - sort_dir: "desc" (default) | "asc" - limit: 1-25, default 20 Returns: {count, preset, filters, results: [{symbol, name, sector, industry, country, price, change_pct, volume, market_cap, market_cap_usd, currency, pe_forward, rsi, macd_signal, sma200_trend, analyst_rating}]} Pro adds per result: rating, ai_verdict, ai_headline, ai_score, ai_score_band. ### get_market_movers(category="all", limit=10, min_market_cap_b) Top gainers, losers and most active stocks. - category: "gainers" | "losers" | "most_active" | "all" - limit: rows per category, 1-20 - min_market_cap_b: minimum market cap in billions of US dollars (compared against market_cap_usd) - Returns: {category, limit_per_category, gainers[], losers[], most_active[]} (only the requested categories). Each row: symbol, name, sector, price, change_pct, volume, rsi, market_cap (listing currency), market_cap_usd, currency, analyst_rating, atr_pct (left out when unreliable). - Pro adds per row: ai_verdict, ai_headline, ai_score, ai_score_band. - Cost: 1 per row in every category. A symbol listed in two categories counts twice. ### get_market_pulse() Market overview in one call. Returns: {vix, fear_greed {value 0-100, description, last_update}, breadth {universe_size, has_rsi, oversold_count, oversold_pct, overbought_count, overbought_pct, neutral_count, neutral_pct}, indices {spy, qqq, iwm: {price, change_pct, rsi}}, bonds_commodities {tlt, gld: {price, change_pct, rsi}}, updated_at} Breadth counts RSI < 30 as oversold and RSI > 70 as overbought across the whole universe. ### get_earnings_calendar(days=7) Upcoming earnings, soonest first. - days: 1-30 - Returns: {window_days, from_date, to_date, count, results: [{symbol, name, sector, market_cap, price, rsi, earnings_date, is_estimate, eps_trailing, eps_forward}]} - Treat dates with `is_estimate: true` as approximate. --- ### get_insider_activity(symbol, days=90) Insider transactions from regulatory insider filings for the US, Germany, the Netherlands and Spain; market data is used only where no regulatory filing is on record. The filing facts are free on every tier. Pro adds the AI read and institutional holders. - Every tier: insider_buys, insider_sells, insider_buy_value, insider_sell_value (total value of those filings, listing currency), transactions [{date, name, role, type, shares, price, value}] (newest first), summary (a one-line factual readout computed from those same rows -- counts, dollar totals, insiders, date range -- so it can never disagree with them), window_days, source (regulatory_filing|market_data, null when nothing is on record), source_name, updated_at (when the filings were last fetched). The counts, rows and summary all come from the same merge and window, so they always agree. - Free/guest: `days` 1-90, default 90; a larger value is capped at 90 and `days_note` says so (`days_requested` echoes what you asked for). Up to 5 transactions; `transactions_note` says how many more are in the window. `pro_unlocks` lists what Pro adds. No AI fields and no institutional holders. - Pro: `days` 1-365, up to 50 transactions, plus signal, signal_score, signal_score_band, insider_signal, inst_signal, ai_commentary (a separately-generated AI narrative on its own refresh cadence, with ai_commentary_as_of -- it can lag the transactions; trust `summary`/the rows if they disagree), top_holders [{name, shares, pct_held, sources, share_counts_by_source}] (up to 15), holder_count_divergence, inst_ownership, total_holders. - `note` appears when no insider buys or sells are on record in the window. - `holder_count_divergence` is non-null when the two holder feeds (filings, market_data) disagree on share counts by the same factor, which means holder share counts for this symbol may be unreliable. ### get_stock_financials(symbol, period="annual", statement="all") Reported financial statements across periods. Free and guest get the latest fiscal year; Pro gets the history. - period: "annual" (Pro: up to 5 fiscal years; free: the latest fiscal year) | "quarterly" (Pro: up to ~8 quarters) | "both" (Pro) - statement: "all" | "balance_sheet" | "income_stmt" | "cash_flow" - Returns: {symbol, period, statement, period_end, financial_currency, annual: {periods[], balance_sheet, income_stmt, cash_flow}, quarterly: {...}} - `financial_currency` is the currency the company files in (can differ from the listing currency, e.g. CNY for BABA). Statement values are NOT converted. - Free/guest: `annual` holds only the latest fiscal year (one date in `periods`, one entry per line item). All three statements and the `statement` filter work. period="quarterly" or "both" is not an error: it returns that latest annual year with `quarterly: null`. Free responses add `annual_periods_available` (years on file, what Pro returns) and a `pro_unlocks` note. - Each statement is {line item name: {period end date: value}}, e.g. income_stmt["Total Revenue"]["2025-09-30"]. - About 50-60 line items per statement. A missing line item means the company does not report it. - Values are in the company's reporting currency, which can differ from the trading currency. - ETFs have no statements. A block may be null with a `*_note` explaining why. ### get_economic_calendar(days=3, lookback_days=2, limit=20, major_only=false, key_events_only=false) Macro events: rate decisions, CPI, GDP, PMI, unemployment, payrolls, retail sales and more. Callable on every tier. Guest and free get the same tool, filters and response shape with a smaller window; Pro gets the wider one. - days: days ahead. Guest/free 1-7, Pro 1-14. - lookback_days: days back. Guest/free 1-2, Pro 1-7. Keep at 2 or more; values can arrive about a day after release. - limit: results per bucket. Guest/free 1-20, Pro 1-50. - major_only: only United States, Euro Area, United Kingdom, Japan, China, Germany, France, Canada - key_events_only: only rate decisions, CPI, GDP and headline non-farm payrolls - Returns: {window_days, lookback_days, today, released_recent[], upcoming[], released_total, upcoming_total}. When the row limit cuts a list, `truncated_note` says so (lists are major-economy-first, so a cut list can end before the window does; use key_events_only or major_only). Each event: {country, event, date, time, previous, consensus, actual, key_event}; released events add `diff` (actual minus previous). - `consensus` is often null. `diff` is plain arithmetic, not a beat or miss. - Both lists put major economies first. - Guest/free above a cap: the value is served at the cap (no error) and the response adds `capped`, e.g. `{"days": {"requested": 14, "served": 7}}`, plus `pro_unlocks`, a one-line note on the Pro window. Neither key appears when nothing was capped, or on Pro. ## 9. Pro tools Guest callers get HTTP 401 (section 4.1). Free accounts get `pro_required` with a preview (section 4.2). ### get_stock_research(symbol) Everything about one stock in one call. Returns: - stock: symbol, name, sector, industry, price, change_pct, market_cap, pe_forward, pe_trailing, beta, dividend_yield, week52_high, week52_low, analyst_rating, analyst_target, rsi, sma200_trend - ai_summary: verdict, ai_score, ai_score_band, headline, summary, key_points[], risks[], near_term {stance, confidence} (next ~4 weeks, weighted to technicals and momentum), longer_term {stance, confidence} (multi-month, weighted to fundamentals, analysts and institutional flows), price_at_generation, generated_at. headline, near_term and longer_term can be null on older summaries; use verdict and ai_score then. - news[]: up to 3 recent notable articles with title, published_at, ai_sentiment, ai_summary, signal_score, signal_score_band - sentiment: signal, signal_score, signal_score_band, insider_trend (buying|selling|neutral|null), institutional_pct, updated_at - signals[]: up to 5 signals on this symbol from the last 90 days, newest first, with direction, signal_score, signal_score_band, source, rationale, expires, flagged_at. Includes signals that have since expired. - forensic_scores: as in get_stock; left out if not computed for this symbol ### get_signals(direction, min_signal_score=60, source, limit=25) Stock ideas the AI pipeline surfaced recently. - direction: "POSITIVE" | "NEGATIVE" | "NEUTRAL" (default: all) - min_signal_score: 0-100, default 60 - source: "news" | "screener" | "sentiment" (default: all) - limit: 1-50, default 25 - Shows the last 24 hours. If nothing qualified in that window, it returns the most recent signals instead and says so in `window`. - Returns: {count, filters, window, signals: [{symbol, direction, signal_score, signal_score_band, source, sources[], rationale, expires, flagged_at}]} - Cost: 1 per signal returned. ### get_news_feed(min_signal_score=60, days=3, limit=10) The most notable news across all tracked stocks, highest signal_score first. For one symbol, use get_stock_news. - min_signal_score: 0-100 - days: 1-10 - limit: 1-25 - Returns: {count, days, min_signal_score, articles: [{symbol, title, published_at, ai_sentiment, ai_summary, signal_score, signal_score_band}]} - Articles about the same stock with a live news signal show the same signal_score. ### get_market_assessment(history_count=0) Macro regime and market outlook from the same pipeline run. - history_count: 0-3 previous assessments to include - Regime (how much risk to take): regime (RISK_OFF|CAUTIOUS|NEUTRAL|AGGRESSIVE), risk_appetite_score, macro_score 0-100, regime_strength 1-10, macro_score_trend {change_7d, change_30d, direction}, regime_bias, regime_bias_note, regime_confidence, regime_rationale, key_risks[], watch_for[], vix_at_assessment, regime_updated_at, regime_stale - Outlook (which direction and sectors): outlook (POSITIVE|NEUTRAL|NEGATIVE), outlook_conviction, equity_view, preferred_sectors[], avoided_sectors[], catalyst, outlook_key_risk, outlook_rationale, outlook_updated_at, outlook_stale - indicators: macro_data (yield_spread_10y2y, fed_funds_rate, unemployment, breakeven_10y, usd_index, m2, cpi_index - each {value, date, delta_3m}; cpi_index is the index level, not a percent), volatility_term_structure (VIX, VIX3M, VIX6M, signal), market_sentiment (Fear & Greed), breadth - market_context: prices, RSI, SMA200 and 1-week/1-month performance for SPY, QQQ, IWM, TLT, GLD, VIX, TNX, MOVE, SKEW and more, as recorded when the assessment ran. For live prices use get_market_pulse. - With history_count > 0: regime_history[], outlook_history[] - `*_stale` is true when that assessment is more than 72 hours old. The normal weekend gap does not trigger it. ### get_sector_intelligence(sector=None, sort_by_strength=false, history_count=0) AI sector assessment with computed statistics. - sector: one sector name (section 5.1), or omit for all 11 - sort_by_strength: all-sectors call only; orders LEADING first - history_count: all-sectors call only; 0-3 previous states per sector - Per sector: sector, signal (LEADING|STRONG|NEUTRAL|WEAK|LAGGING), cycle_stage, rotation_signal, drivers, alert, confidence, strength_score 1-10, sector_score 0-100, updated_at, stats {stocks, avg_rsi, oversold_pct, overbought_pct, sma200_breadth_pct, avg_perf_1w_pct, avg_perf_1m_pct, cap_weighted_1m_pct, top5_concentration_pct, rsi_distribution, median_market_cap_B, perf_1m_percentile, rsi_percentile, overbought_percentile, top_movers[], bottom_movers[]} - Single sector: returns that sector's object plus sector_score_trend {change_7d, change_30d, direction}. - All sectors: {sectors[], count}, each with `history[]` when history_count > 0. ### get_earnings_intelligence(days_ahead=14, sector, min_ai_score, limit=25) Upcoming earnings with the AI view of each company. - days_ahead: 1-30 - sector: optional sector filter - min_ai_score: optional 0-100, applied before limit - limit: 1-25 - Returns: {count, days_ahead, from_date, to_date, results: [{symbol, name, sector, price, rsi, market_cap, earnings_date, is_estimate, eps_trailing, eps_forward, ai_verdict, ai_score, ai_score_band, ai_risks[] (top 2), analyst_rating, analyst_target}]} - Cost: 1 per result. ### get_indicator_history(symbol, days=90, full=false) Daily indicator snapshots for trend analysis. - days: 1-730 - Returns: {symbol, days, full, count, snapshots: [{recorded_at, price, rsi, macd_histogram, bb_pct, sma20, sma200}]} - bb_pct: position in the Bollinger Bands, 0 = lower band, 100 = upper band; can go below 0 or above 100. - full=true adds per snapshot: williams_r, ultimate_osc, vix_fix_value, williams_ad_trend, td_signal (DOWNTREND_EXHAUSTION_SETUP / UPTREND_EXHAUSTION_SETUP / DOWNTREND_EXHAUSTION_COUNTDOWN / UPTREND_EXHAUSTION_COUNTDOWN or null), td_phase, analyst_rating, analyst_target. - When fewer than 3 snapshots exist: `count` 0, an empty `snapshots` list and a `note`. ### get_analyst_trend(symbol, days=90) Daily analyst consensus history: how the rating and price targets have moved, not just today's value. - days: 1-365 - Returns: {symbol, days, count, snapshots: [{date, analyst_rating, analyst_rating_score, analyst_count, analyst_target, analyst_target_high, analyst_target_low, analyst_target_median, price}]}, oldest first. - analyst_rating_score: 1.0 = strong buy, 5.0 = strong sell (lower is more bullish), same scale as get_stock. analyst_rating is derived from it on days the source gives no label. - One snapshot per weekday, history starting July 2026. `price` is the stock's price that day, for reading a target against where the stock traded. - analyst_rating can be null on a given day even when the price targets are present (the source occasionally drops the label). A weekday can be absent entirely if the daily snapshot did not run; those days are not reconstructed. - Fewer than 2 snapshots returns an empty `snapshots` list with a `note`. ETFs and other symbols with no analyst coverage have none. - For price and indicator history use get_indicator_history; this tool is analyst consensus only. ### get_watchlist() The signed-in user's starred symbols. - No parameters. Symbols are starred on https://www.stocklake.dev/dashboard; the API cannot add or remove them. - Returns: {count, items: [{symbol, name, sector, price, change_pct, rsi, market_cap, analyst_rating, atr_pct, ai_verdict, ai_headline, ai_score, ai_score_band, added_at, price_at_add}]} - An empty watchlist returns count 0. --- ## 10. Other surfaces and links - Setup guide: https://www.stocklake.dev/docs - Tool reference with examples: https://www.stocklake.dev/docs/tools - Pricing: https://www.stocklake.dev/#pricing - Account, key, usage, billing: https://www.stocklake.dev/account - Web dashboard: https://www.stocklake.dev/dashboard - Public stock pages: https://www.stocklake.dev/stock/{SYMBOL} - n8n: use n8n's built-in MCP Client node with the endpoint, or the self-hosted community node `n8n-nodes-stocklake` - https://www.stocklake.dev/blog/stocklake-mcp-with-n8n - Changelog: https://www.stocklake.dev/changelog - Support: api@stocklake.dev For informational purposes only. Not financial advice.