novada-mcp
One MCP server for all web data. Search, scrape, crawl, proxy, and AI research in one install.
npm · fingerprint 93060c752344f63dc9d15e99 · repository · RSS
38tools
2recorded versions
45dtracked
unchanged 8d
What changed
Changed between 4 September 2026 and 5 October 2026 (first seen 2026-10-05 14:40 UTC)
38 descriptions rewritten.
--- pinned/novada_account +++ observed/novada_account { "annotations": { "destructiveHint": false, - "description": "Single-call account & billing dashboard. Composes wallet balance, plan balances, capture logs, and health entitlements based on the `section` param.\n\n**Best for:** \"What's my Novada account status?\" / \"How much do I have left?\" / one-shot health snapshot.\n**section=\"summary\" (default):** Full dashboard — wallet balance + plan quotas + recent capture logs + product entitlements (proxy/browser/wallet-funded services). This is what novada_account_summary + novada_health combined.\n**section=\"balance\":** Master wallet currency balance.\n**section=\"usage\":** Paginated wallet transaction / usage history. Pass start_time/end_time/page/page_size.\n**section=\"plans\":** Per-product plan balances (residential/isp/mobile/datacenter/static/capture). Pass products[] to filter.\n**section=\"traffic\":** Daily proxy traffic consumption across products. Pass start_time/end_time/products[].\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).\n**Aliases (backward compat):** novada_wallet_balance, novada_wallet_usage_record, novada_plan_balance_all, novada_traffic_daily, novada_capture_logs, novada_account_summary, novada_health, novada_health_all — all route here.", + "description": "Single-call account & billing dashboard. Composes wallet balance, plan balances, capture logs, and health entitlements via the `section` param.\n\n**Best for:** \"what's my account status / balance\" one-shot checks.\n**section=\"summary\" (default):** wallet balance + plan quotas + recent capture logs + product entitlements.\n**section=\"balance\":** master wallet currency balance.\n**section=\"usage\":** paginated transaction history (start_time/end_time/page/page_size).\n**section=\"plans\":** per-product plan balances (residential/isp/mobile/datacenter/static/capture); filter with products[].\n**section=\"traffic\":** daily proxy traffic consumption; filter with start_time/end_time/products[].\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).\n**Aliases:** novada_wallet_balance, novada_wallet_usage_record, novada_plan_balance_all, novada_traffic_daily, novada_capture_logs, novada_account_summary, novada_health, novada_health_all all route here.", "inputSchema": { "properties": { "end_time": { - "name": "novada_account" + "name": "novada_account", + "title": "Account & Billing" }
--- pinned/novada_ai_monitor +++ observed/novada_ai_monitor { "annotations": { "destructiveHint": false, - "description": "Search PUBLIC indexed pages on AI-company domains for brand mentions and sentiment — this is NOT page-change monitoring (that's novada_monitor) and does NOT query live AI models.\n\nSearches indexed pages on chatgpt.com/openai.com, perplexity.ai, anthropic.com, and similar domains for public mentions of a brand or product. Returns per-source mention counts, sentiment signals, and competitor mentions. A brand not discussed on those indexed domains will show few/zero mentions — that reflects indexed-page coverage, not the models' actual behavior.\n\n**How it works:** For each selected domain group, executes a Google search scoped to that domain (e.g. site:openai.com \"brandname\") and analyzes the returned page snippets for sentiment, claims, and competitor co-mentions.\n**Best for:** Checking whether a brand appears on AI-company public docs/blogs/changelogs; competitive presence on indexed pages of AI platforms.\n**Not for:** Finding out how ChatGPT/Perplexity/Claude actually answer questions about your brand (those are live model responses, not indexed pages); general web search (use novada_search); real-time social monitoring (use novada_scrape with twitter/reddit).\n**Output:** Per-domain sentiment (positive/neutral/negative), key claims from indexed snippets, competitor mentions, source URLs.\n**Domains searched:** chatgpt.com+openai.com, perplexity.ai, grok.com+x.com/i/grok, claude.ai+anthropic.com, gemini.google.com. Default: chatgpt, perplexity, grok.", + "description": "Search PUBLIC indexed pages on AI-company domains (chatgpt.com/openai.com, perplexity.ai, anthropic.com, etc.) for brand mentions and sentiment. NOT page-change monitoring (novada_monitor) and does NOT query live AI models — a brand absent from indexed pages may still be discussed live; this only reflects indexed-page coverage.\n\n**How it works:** for each selected domain group, runs a Google search scoped to that domain (e.g. site:openai.com \"brandname\") and analyzes snippets for sentiment, claims, and competitor co-mentions.\n**Best for:** checking brand presence on AI-company public docs/blogs/changelogs.\n**Not for:** live model answers about your brand (query the model directly), general web search (novada_search), real-time social monitoring (novada_scrape with twitter/instagram).\n**Output:** per-domain sentiment (positive/neutral/negative), key claims from indexed snippets, competitor mentions, mention counts, source URLs.\n**Domains:** chatgpt.com+openai.com, perplexity.ai, grok.com+x.com/i/grok, claude.ai+anthropic.com, gemini.google.com. Default: chatgpt, perplexity, grok.", "inputSchema": { "properties": { "brand": { - "name": "novada_ai_monitor" + "name": "novada_ai_monitor", + "title": "AI Brand Monitor" }
--- pinned/novada_browser +++ observed/novada_browser { "annotations": { "destructiveHint": false, - "description": "Use when you need to interact with a web page — click buttons, fill forms, scroll, take screenshots, or execute JavaScript. Chain multiple actions in one call for efficiency.\n\n**Best for:** Login flows, paginated content, interactive SPAs, form submission, visual verification, scraping behind user interactions.\n**Not for:** Simple page reading (use novada_extract), structured data (use novada_scrape), raw HTML (use novada_extract with format=\"html\").\n**Actions:** navigate, click, type, screenshot, snapshot, aria_snapshot, evaluate, wait, scroll, hover, press_key, select — up to 20 per call. snapshot = full DOM text; aria_snapshot = smaller semantic tree (prefer aria_snapshot for most extraction tasks).\n**Sessions:** Pass session_id to reuse the same browser page (cookies, login) across calls. Persistent cross-call sessions are reliable only on the local/long-lived server; on the hosted serverless endpoint treat each call as one-shot (a session_id may not survive between calls). Use close_session to release early.\n**Auth:** NOVADA_API_KEY (auto-provisions Browser API credentials). NOVADA_BROWSER_WS is optional — set it to override auto-provision.\n**Platform note:** Use wait with domcontentloaded (never networkidle) for SPAs. (The `country` param is accepted but NOT yet applied to the browser exit node — do not rely on it for geo-routing.)\n**Constraint:** close_session and list_sessions must be the only action in the call — they cannot be combined with other actions.", + "description": "Interact with a web page — click, fill forms, scroll, screenshot, or run JavaScript. Chain multiple actions in one call.\n\n**Best for:** login flows, paginated content, SPAs, form submission, visual verification, scraping behind interactions.\n**Not for:** simple page reads (novada_extract), structured data (novada_scrape), raw HTML (novada_extract format=\"html\").\n**Actions:** navigate, click, type, screenshot, snapshot, aria_snapshot, evaluate, wait, scroll, hover, press_key, select — up to 20/call. snapshot = full DOM text; aria_snapshot = smaller semantic tree (prefer it for extraction).\n**Sessions:** session_id reuses the same page (cookies, login) across calls — reliable only on the local/long-lived server; on hosted serverless, treat each call as one-shot. close_session releases early.\n**Auth:** NOVADA_API_KEY auto-provisions Browser API credentials; NOVADA_BROWSER_WS optionally overrides.\n**SPAs:** wait with domcontentloaded, never networkidle. `country` is accepted but not yet applied to the browser exit node — don't rely on it for geo-routing.\n**Constraint:** close_session/list_sessions must be the ONLY action in the call.", "inputSchema": { "properties": { "actions": { - "description": "Array of browser actions to execute sequentially. Max 20 per call. Each action MUST use the discriminated union format: {action: \"<type>\", ...fields}. Examples: {action: \"navigate\", url: \"https://example.com\"} | {action: \"click\", selector: \"#btn\"} | {action: \"type\", selector: \"#input\", text: \"hello\"} | {action: \"wait\", ms: 2000} | {action: \"screenshot\"} | {action: \"aria_snapshot\"}. Do NOT use string format (\"navigate\") or object-key format ({navigate: \"url\"}) — both are invalid.", + "description": "Array of browser actions to execute sequentially (max 20/call). Each action MUST use the discriminated union format {action: \"<type>\", ...fields}, e.g. {action:\"navigate\",url:\"https://example.com\"} | {action:\"click\",selector:\"#btn\"} | {action:\"wait\",ms:2000} | {action:\"screenshot\"}. Do NOT use a bare string (\"navigate\") or object-key format ({navigate:\"url\"}) — both are invalid.", "items": { "oneOf": [ { - "description": "Page load event to wait for. Default 'domcontentloaded' works for most sites including SPAs (X, TikTok). Avoid 'networkidle' for SPAs — they continuously poll and never reach networkidle, causing a 30s timeout.", + "description": "Page load event. Default 'domcontentloaded' works for SPAs (X, TikTok). Avoid 'networkidle' for SPAs — they poll continuously and never idle, causing a 30s timeout.", "enum": [ "load", "domcontentloaded", - "name": "novada_browser" + "name": "novada_browser", + "title": "Browser Automation" }
--- pinned/novada_browser_flow +++ observed/novada_browser_flow { "annotations": { "destructiveHint": false, - "description": "Simplified browser automation with a 5-action flow API (click, scroll, wait, type, screenshot). Use only if you specifically need this simplified flow interface or novada_browser is unavailable.\n\n**novada_browser is the primary, more capable tool** — it provides full CDP access with 12 automation action types (navigate, click, type, screenshot, snapshot, aria_snapshot, evaluate, wait, scroll, hover, press_key, select) plus 2 session-management actions (close_session, list_sessions). Prefer novada_browser for all new browser automation.\n**Use novada_browser_flow when:** you specifically need the simplified flow API, or you have an existing workflow built around it.\n**Actions:** click, scroll, wait, type, screenshot — up to 20 per call.\n**Sessions:** Pass session_id to reuse the same browser instance across calls (preserves cookies, login state). Sessions expire after 10 minutes of inactivity.\n**Not for:** Single URL reading without interaction (use novada_extract), structured platform data (use novada_scrape).", + "description": "Simplified browser automation — 5 actions (click, scroll, wait, type, screenshot). Use only if you need this simpler interface or novada_browser is unavailable.\n\n**novada_browser is primary/more capable** — full CDP access, 12 action types + 2 session-management actions. Prefer it for new automation.\n**Use this when:** you need the simplified flow API or have an existing workflow built on it.\n**Actions:** click, scroll, wait, type, screenshot — up to 20/call.\n**Sessions:** session_id reuses the browser instance (cookies, login) across calls; expires after 10 min idle.\n**Not for:** reading one URL without interaction (novada_extract) or structured platform data (novada_scrape).", "inputSchema": { "properties": { "actions": { - "name": "novada_browser_flow" + "name": "novada_browser_flow", + "title": "Browser Flow Automation" }
--- pinned/novada_capture_apikey +++ observed/novada_capture_apikey { "annotations": { "destructiveHint": true, - "description": "Get or reset the Capture API key for the account. Wraps POST /v1/capture/get_apikey and /v1/capture/reset_apikey.\n\n**Actions:** \"get\" = retrieve the current capture/scraper API key (read-only). \"reset\" = regenerate the key — DESTRUCTIVE, invalidates the old key, requires confirm:true.\n**Behavior:** Without confirm:true on \"reset\", returns a warning preview and does NOT call the API.\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", + "description": "Get or reset the Capture API key (wraps POST /v1/capture/get_apikey and /v1/capture/reset_apikey).\n\n**Actions:** \"get\" = retrieve the current key (read-only). \"reset\" = regenerate it — DESTRUCTIVE, invalidates the old key, gated by a two-step approval_token.\n**Behavior:** call \"reset\" once WITHOUT `approval_token` to get a warning preview plus a fresh token (valid 10 minutes) — this does NOT call the API. Re-call with the EXACT SAME parameters plus that token to execute. `confirm: true` is a deprecated no-op.\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", "inputSchema": { "properties": { "action": { + "approval_token": { + "description": "Two-step approval token, required to execute 'reset'. Omit on the first call to receive a preview + a fresh approval_token (valid 10 minutes). Re-call with the EXACT SAME parameters plus this field set to that token to execute. Never invent a value — an invented or stale token is rejected. Ignored for 'get' action.", + "minLength": 1, + "type": "string" + }, "confirm": { "const": true, - "description": "Required for 'reset' action. Pass `true` ONLY after the human user has confirmed they want to invalidate the current API key. Ignored for 'get' action.", + "description": "DEPRECATED — ignored for both actions. Setting this alone no longer authorizes 'reset' (closed 2026-09, finding F2-2: an agent could self-supply confirm:true with no prior human-reviewed preview). Use approval_token instead: call once WITHOUT approval_token to receive a preview and a token, then call again with the identical parameters plus approval_token.", "type": "boolean" } }, - "name": "novada_capture_apikey" + "name": "novada_capture_apikey", + "title": "Capture API Key" }
--- pinned/novada_crawl +++ observed/novada_crawl { "annotations": { "destructiveHint": false, - "description": "Use when you need content from a bounded set of pages (up to 20) and don't have the URLs yet. Crawls BFS or DFS, extracts content from each page inline. Use select_paths globs to target specific sections (e.g. \"/docs/api/**\").\n\n**IMPORTANT — wrong tool for whole-site jobs:** If you need to copy more than ~20 pages or want an entire docs site / knowledge base on disk, use `novada_site_copy` instead (up to 1000 pages, manifest output, streams files to disk). novada_crawl hard-caps at 20 pages and returns bodies inline — it will silently hit that cap on large sites.\n\n**Best for:** Competitive content analysis, extracting a handful of related pages inline (returns page bodies directly).\n**Not for:** A single page (use novada_extract), URL discovery without content extraction (use novada_map — much faster), copying an entire site to disk (use novada_site_copy — it handles hundreds of pages and writes files).\n\nCommon mistakes:\n- Do NOT set max_pages > 10 for large sites — crawl time scales linearly (~1.4s/page). At max_pages=20, expect 28s minimum.\n- Do NOT use novada_crawl to fetch one page — use novada_extract which is faster and simpler.\n- Use select_paths to restrict to relevant URL patterns before setting max_pages high.\n\nWhen to use:\n- You need content from a small set of related pages on one domain (e.g., all /docs/* pages, up to 20).\n- You need BFS discovery of related content under a path prefix and want bodies inline.\n\nNot for:\n- Single-URL extraction — use novada_extract.\n- Finding all URLs on a site without downloading content — use novada_map.\n- Copying a whole docs site or knowledge base to disk — use novada_site_copy (handles hundreds of pages, returns a manifest).\n\n**Rendering:** The `render` param defaults to \"auto\" (tries static first, escalates to JS rendering on detection) — it is not static-only.", + "description": "Use when you need content from a bounded set of pages (up to 20) and don't have the URLs yet. Crawls BFS/DFS, extracts each page inline. Use select_paths globs to target sections (e.g. \"/docs/api/**\").\n\n**Wrong tool for whole-site jobs:** for >20 pages or a full docs site on disk, use `novada_site_copy` instead (up to 1000 pages, streams to disk, returns a manifest). novada_crawl hard-caps at 20 pages and returns bodies inline.\n\n**Best for:** competitive content analysis, a handful of related pages inline (returns bodies directly).\n**Not for:** a single page (novada_extract), URL discovery only (novada_map — much faster), a whole site to disk (novada_site_copy).\n**Performance:** avoid max_pages > 10 on large sites — crawl time scales ~1.4s/page (max_pages=20 ≈ 28s minimum). Use select_paths to narrow scope before raising max_pages.\n**Rendering:** `render` defaults to \"auto\" (static first, escalates to JS on detection) — not static-only.", "inputSchema": { "properties": { "exclude_paths": { - "description": "Natural language hint for which pages to prioritize. E.g. 'only API reference pages', 'skip blog and changelog'. Applied as path-level filtering; semantic filtering is agent-side.", + "description": "Natural language hint for which pages to prioritize, e.g. 'only API reference pages', 'skip blog and changelog'. Echoed back in the output as a hint — it does NOT filter which pages get crawled; use select_paths/exclude_paths for actual filtering, or act on this hint yourself when choosing follow-up calls.", "type": "string" }, "max_pages": { - "name": "novada_crawl" + "name": "novada_crawl", + "title": "Site Crawler" }
--- pinned/novada_discover +++ observed/novada_discover { "annotations": { "destructiveHint": false, - "description": "List all available Novada tools with name, description, category, and status.\n\n**agent_instruction:** Call this first to see all available Novada tools and capabilities — especially useful when starting a new task and you need to find the right tool.\n**Returns:** Markdown table grouped by category — Content Retrieval, Scraping & Verification, Proxy, Browser & Rendering, Account & Billing, Health & Discovery.\n**Filter:** Pass category to narrow to a specific group (e.g. category=\"Proxy\" to see all proxy tools).\n**Status legend:** active = available now. Output also includes server_version (the running package version).\n\n**KEY FACT: ONE API KEY COVERS ALL PRODUCTS.** NOVADA_API_KEY authenticates search, extract, research, crawl, scrape, unblock, and proxy auto-provisioning. No separate keys needed for any product. NOVADA_BROWSER_WS and NOVADA_PROXY_ENDPOINT unlock additional capabilities but require no extra API key. If a tool fails, call novada_account (section=\"summary\") to check your balance, plans, and entitlements.", + "description": "List all available Novada tools — name, description, category, group, and status.\n\n**agent_instruction:** call this first when starting a task to find the right tool.\n**Returns:** a markdown table grouped by category, plus a Tool Groups reference (core/scrapers/account/meta).\n**Filter:** category narrows the catalog (e.g. category=\"Proxy\"); NOVADA_GROUPS/NOVADA_TOOLS (local) or ?groups=/?tools= (hosted) narrow the actual tool set exposed on this connection.\n**Status:** active = available now. Output includes server_version.\n\n**ONE API KEY COVERS ALL PRODUCTS.** NOVADA_API_KEY authenticates search/extract/research/crawl/scrape/unblock/proxy auto-provisioning — no separate keys needed. NOVADA_BROWSER_WS/NOVADA_PROXY_ENDPOINT unlock extras, no extra key. On tool failure, call novada_account (section=\"summary\") for balance/plans/entitlements.", "inputSchema": { "properties": { "category": { - "name": "novada_discover" + "name": "novada_discover", + "title": "Tool Discovery" }
--- pinned/novada_extract +++ observed/novada_extract { "annotations": { "destructiveHint": false, - "description": "Extract content from any URL. Handles Cloudflare, DataDome, Kasada automatically via auto-escalation (static → JS render → Browser CDP). Batch mode: pass url as array for up to 10 pages in parallel.\n\n**CRITICAL — Format Selection:**\n- `format=\"markdown\"` (default): full-page content for reading/analysis. Best for articles, docs.\n- `format=\"json\"`: structured object. Key fields: url, title, content, quality, links, structured_data, fields, hints, mode, fetched_at. Use `fields=[\"price\",\"title\"]` to populate the `fields` key — this is the primary reason to choose format=\"json\".\n- `format=\"html\"`: raw HTML source (truncated at 100K chars by default; pass max_chars to adjust). Best for debugging or custom DOM parsing.\n- `clean=true`: strip nav/sidebar, return main content only (~15K chars vs ~100K full page).\n\nCommon mistake: using markdown when you need specific data — use `format=\"json\"` + `fields=[\"price\",\"title\"]` instead.\n\n**Use for:** Reading pages, batch-extracting search results, pulling structured fields (price, author, date). Works on anti-bot pages automatically.\n**Not for:** URL discovery (novada_map), multi-page crawl (novada_crawl), platform data like Amazon/LinkedIn (novada_scrape is richer).\n**Key rule:** Leave render=\"auto\" (default). Only set render=\"render\" for known JS-heavy SPAs. Auto mode is 15-100x faster on static sites.\nBy default returns full page content for maximum information. Add clean=true to extract only the main article body (strips nav/footer/ads).\n\n**Geo-routing:** Pass `country=\"de\"` (ISO 2-letter) to route render fetches through an exit IP in that country — useful for localized pricing, geo-restricted content, or comparing the same page across countries.\n**Results auto-saved:** Every extraction saves to `~/Downloads/novada-mcp/YYYY-MM-DD/` automatically. File path shown at the top of each response.\n**Project grouping:** Pass `project=\"my-project\"` to group all outputs in a subfolder (e.g. ~/Downloads/novada-mcp/2026-06-26/my-project/). Useful for multi-step research tasks.", + "description": "Extract content from any URL. Auto-handles Cloudflare/DataDome/Kasada via escalation (static → JS render → Browser CDP). Batch mode: pass url as an array for up to 10 pages in parallel.\n\n**Format selection:**\n- `format=\"markdown\"` (default): full-page content for reading/analysis.\n- `format=\"json\"`: structured object (url, title, content, quality, links, structured_data, fields, hints, mode, fetched_at). Use with `fields=[\"price\",\"title\"]` to populate `fields`. Common mistake: using markdown when you need specific fields — use format=\"json\"+fields instead.\n- `format=\"html\"`: raw HTML (truncated at 100K chars by default; adjust via max_chars).\n- `clean=true`: strip nav/sidebar, main content only (~15K chars vs ~100K full page).\n\n**Use for:** reading pages, batch-extracting search results, structured fields (price, author, date) — works on anti-bot pages automatically.\n**Not for:** URL discovery (novada_map), multi-page crawl (novada_crawl), rich platform data like Amazon/LinkedIn (novada_scrape).\n**Key rule:** leave render=\"auto\" (default) — 15-100x faster on static sites; only set render=\"render\" for known JS-heavy SPAs.\n**Geo-routing:** `country=\"de\"` (ISO 2-letter) routes render fetches through that country's exit IP — for localized pricing or geo-restricted content.\n**Auto-saved:** every extraction is written to `~/Downloads/novada-mcp/YYYY-MM-DD/` (path shown in the response).\n**Project grouping:** `project=\"my-project\"` groups outputs under a subfolder.", "inputSchema": { "properties": { "clean": { - "description": "ISO 3166-1 alpha-2 country code (e.g. 'de', 'us', 'gb') to route the fetch through an exit IP in that country. Useful for localized pricing, geo-restricted content, and per-country monitoring (e.g. comparing a product price across European countries). Only applies to render/unblocker fetches (render=\"render\"|\"js\" or auto-escalation to render); no effect on a pure static fetch. In batch mode (url array), the same country is applied to all URLs in the call.", + "description": "ISO 3166-1 alpha-2 country code (e.g. 'de','us','gb') to route the fetch through an exit IP there — for localized pricing, geo-restricted content, or per-country comparisons. Only applies to render/unblocker fetches (render=\"render\"|\"js\" or auto-escalation to render); no effect on a pure static fetch. Batch mode (url array) applies the same country to all URLs.", "maxLength": 2, "minLength": 2, "type": "string" - "description": "Specific fields to extract (e.g. ['price', 'author', 'availability', 'rating']). ADVISORY / confidence-gated: each field returns {value, source, confidence}. Source priority is structured-first — JSON-LD → infobox/table/microdata → anchored pattern → loose scan LAST. A match below the confidence floor (loose proximity scan) is SUPPRESSED: value=null with low_confidence:true + the rejected candidate in low_confidence_value, rather than emitting a confidently-wrong guess. Treat a resolved value as a strong hint, not ground truth — check the source/confidence, and re-read the content or retry with render='render' when a field is null/low_confidence.", + "description": "Specific fields to extract (e.g. ['price','author','availability','rating']). ADVISORY/confidence-gated: each returns {value, source, confidence}. Source priority: JSON-LD → infobox/table/microdata → anchored pattern → loose scan (last resort). Below the confidence floor, the match is SUPPRESSED (value=null, low_confidence:true, raw candidate in low_confidence_value) instead of a confidently-wrong guess. Treat a resolved value as a hint, not ground truth — check source/confidence and retry with render='render' when null/low_confidence.", "items": { "minLength": 1, "type": "string" - "description": "Maximum characters to return (default: 25000, max: 100000). When content exceeds this limit, it is truncated and content_truncated:true plus total_chars are emitted. Raise up to 100000 only when you need the full page — do not set 100000 by default.", + "description": "Maximum characters to return (default 25000, max 100000). Truncated content emits content_truncated:true + total_chars. Raise only when you need the full page.", "maximum": 100000, "minimum": 1000, "type": "integer" - "description": "Optional project name to group related outputs in a subfolder. E.g. 'france-vs-norway'. (local stdio only; no effect on the hosted endpoint)", + "description": "Group outputs in a subfolder, e.g. 'france-vs-norway'. Local stdio only — no effect on hosted.", "maxLength": 30, "type": "string" }, - "description": "CSS selector to wait for before capturing content (browser mode only). E.g. '.price', '#product-title', '[data-testid=price]'. Delays capture until the element appears in the DOM. Max wait: 15s.", + "description": "CSS selector to wait for before capturing content (browser mode only). E.g. '.price', '#product-title'. Delays capture until the element appears in the DOM. Max wait: 15s.", "type": "string" }, "wait_ms": { - "description": "Fixed milliseconds to wait after page load before capturing content. Use wait_for (CSS selector) instead when possible — it is more reliable. wait_ms is a fallback for pages with no stable selector. Max: 30000ms.", + "description": "Fixed ms to wait after page load before capturing (browser mode only). Prefer wait_for (CSS selector) when possible — more reliable. Fallback for pages with no stable selector. Max 30000ms.", "maximum": 30000, "minimum": 0, "type": "integer" - "name": "novada_extract" + "name": "novada_extract", + "title": "Content Extractor" }
--- pinned/novada_ip_whitelist +++ observed/novada_ip_whitelist { "annotations": { "destructiveHint": true, - "description": "Manage IP whitelist for proxy products. Supports add/list/delete/remark for Residential (1), Unlimited (4), and Static ISP (5) products.\n\n**Actions:** \"add\" (WRITE — requires confirm), \"list\" (read-only), \"del\" (WRITE — requires confirm), \"remark\" (update note on entry).\n**Required:** action, product (1=Residential, 4=Unlimited, 5=Static ISP).\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", + "description": "Manage the proxy IP whitelist — add/list/delete/remark — for Residential (1), Unlimited (4), and Static ISP (5).\n\n**Actions:** \"add\" (WRITE, gated by approval_token), \"list\" (read-only), \"del\" (WRITE, gated by approval_token), \"remark\" (WRITE, gated by approval_token).\n**Behavior for \"add\"/\"del\"/\"remark\":** call once WITHOUT `approval_token` to get a preview plus a fresh token (valid 10 minutes) — this does NOT hit the API. Re-call with the EXACT SAME parameters plus that token to execute. `confirm: true` is a deprecated no-op.\n**Required:** action, product (1=Residential, 4=Unlimited, 5=Static ISP).\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", "inputSchema": { "properties": { "action": { - "description": "Action to perform. \"add\": add IP to whitelist (WRITE — requires confirm). \"list\": list whitelisted IPs. \"del\": delete whitelisted IPs (WRITE — requires confirm). \"remark\": update remark on a whitelist entry.", + "description": "Action to perform. \"add\": add IP to whitelist (WRITE — requires approval_token). \"list\": list whitelisted IPs. \"del\": delete whitelisted IPs (WRITE — requires approval_token). \"remark\": update remark on a whitelist entry (WRITE — requires approval_token).", "enum": [ "add", "list", + "approval_token": { + "description": "Two-step approval token, required to execute \"add\"/\"del\"/\"remark\". Omit on the first call to receive a preview + a fresh approval_token (valid 10 minutes). Re-call with the EXACT SAME parameters plus this field set to that token to execute. Never invent a value — an invented or stale token is rejected.", + "minLength": 1, + "type": "string" + }, "confirm": { "const": true, - "description": "REQUIRED for WRITE actions (\"add\" and \"del\"). Pass `true` ONLY after the human user has approved. If omitted on a write action, the tool returns a dry-run preview instead of calling the API.", + "description": "DEPRECATED — ignored. Setting this alone no longer authorizes WRITE actions (\"add\"/\"del\"/\"remark\") (closed 2026-09, finding F2-2: an agent could self-supply confirm:true with no prior human-reviewed preview). Use approval_token instead: call once WITHOUT approval_token to receive a preview and a token, then call again with the identical parameters plus approval_token.", "type": "boolean" }, "end_time": { - "name": "novada_ip_whitelist" + "name": "novada_ip_whitelist", + "title": "IP Whitelist Manager" }
--- pinned/novada_map +++ observed/novada_map { "annotations": { "destructiveHint": false, - "description": "Use when you need to know what URLs exist on a site before deciding what to read. Tries sitemap.xml first (fast), falls back to BFS crawl. Returns URL list only — no content. Hard cap: 100 URLs.\n\n**Best for:** Site structure discovery, finding the correct subpage URL when you extracted the wrong page, pre-flight before novada_crawl or novada_extract.\n**Not for:** Reading page content (follow with novada_extract or novada_crawl). Copying an entire site to disk (use novada_site_copy — it handles hundreds of pages).\n**Note:** Limited results on JavaScript SPAs — will flag this in output.", + "description": "Discover URLs on a site before deciding what to read. Tries sitemap.xml first (fast), falls back to BFS crawl. Returns URLs only — no content. Hard cap: 100 URLs.\n\n**Best for:** site structure discovery, finding the right subpage, pre-flight before novada_crawl/novada_extract.\n**Not for:** reading content (use novada_crawl/novada_extract) or copying a whole site to disk (novada_site_copy).\n**Note:** limited results on JS SPAs — flagged in the output.", "inputSchema": { "properties": { "include_subdomains": { - "name": "novada_map" + "name": "novada_map", + "title": "URL Mapper" }
--- pinned/novada_monitor +++ observed/novada_monitor { "annotations": { "destructiveHint": false, - "description": "Detect changes on a web page over time. Extracts content, computes a hash, compares with previous check. Returns changed/unchanged + field-level diffs.\n\n**Use for:** E-commerce price monitoring, stock availability tracking, content change detection, competitive pricing alerts.\n**How:** First call = baseline. Subsequent calls compare against baseline and report changes. Pass fields=[\"price\",\"availability\"] for field-level diffs with % change.\n**Not for:** One-time extraction (novada_extract), full crawl (novada_crawl).\n\n⚠️ **Hosted endpoint (mcp.novada.com) limitation:** Baselines do NOT survive between calls on the hosted serverless endpoint — each invocation lands on a cold function with no prior state, so change detection will always return baseline_recorded. For real change detection you must run the local server (`npx novada-mcp`, a long-lived process) or schedule calls from your own job runner and diff externally. This is a known interim limitation until persistent KV storage ships.", + "description": "Detect changes on a web page over time. Extracts content, computes a hash, and compares it with the previous check. Returns changed/unchanged plus field-level diffs.\n\n**Use for:** e-commerce price monitoring, stock tracking, content-change detection, competitive pricing alerts.\n**How:** the first call sets a baseline; later calls compare against it and report changes. Pass fields=[\"price\",\"availability\"] for field-level % diffs.\n**Not for:** one-time extraction (novada_extract) or a full crawl (novada_crawl).\n\n⚠️ **Hosted endpoint (mcp.novada.com) limitation:** baselines do NOT survive between calls on hosted's serverless runtime — every call is a cold function with no prior state, so change detection always returns baseline_recorded. Use the local server (`npx novada-mcp`) or diff externally for real change detection.", "inputSchema": { "properties": { "fields": { - "name": "novada_monitor" + "name": "novada_monitor", + "title": "Page Change Monitor" }
--- pinned/novada_proxy +++ observed/novada_proxy { "annotations": { "destructiveHint": false, - "description": "Use when you need to route your own HTTP requests through residential or mobile IPs — for geo-targeting, IP rotation, or bypassing IP-based rate limits. Returns proxy URL, shell export commands, or curl --proxy flag.\n\n**Best for:** When you need a specific country/city IP, sticky sessions for multi-step workflows, or testing geo-restricted content.\n**Not for:** Web page extraction (use novada_extract — proxy is automatic), web search (use novada_search).\n**Formats:** \"url\" for Node.js/Python, \"env\" for shell variables, \"curl\" for CLI requests.\n**Requires:** NOVADA_PROXY_ENDPOINT env var. NOVADA_PROXY_USER/PASS are auto-fetched from your account using NOVADA_API_KEY if not explicitly set.\n\n**Proxy type guide (pass as `type` param):**\n- `residential` — strongest anti-bot bypass, real home ISP IPs, best for geo-restricted / protected pages; escalate HERE when blocked\n- `isp` — looks like a home user (ISP-assigned), best for social media / ecommerce; note: ignores country param\n- `datacenter` — fastest and cheapest, best for non-anti-bot targets and high-volume scraping\n- `mobile` — 4G/5G device IPs, best for mobile-targeted content and app APIs\n- `static` — same dedicated ISP IP every request (requires session_id + country), best for account-management workflows\n- `dedicated` — exclusive clean datacenter IP not shared with others (requires session_id), best for high-trust platforms\n\n**Escalation path when blocked:** datacenter → isp → residential", + "description": "Route your own HTTP requests through residential or mobile IPs — geo-targeting, IP rotation, bypassing IP-based rate limits. Returns a proxy URL, shell exports, or a curl --proxy flag.\n\n**Best for:** a specific country/city IP, sticky multi-step sessions, testing geo-restricted content.\n**Not for:** page extraction (novada_extract — proxy is automatic) or web search (novada_search).\n**Formats:** \"url\" (Node.js/Python), \"env\" (shell vars), \"curl\" (CLI).\n**Requires:** NOVADA_PROXY_ENDPOINT env var; NOVADA_PROXY_USER/PASS auto-fetch from your account via NOVADA_API_KEY if unset.\n\n**`type` guide:**\n- `residential` — strongest anti-bot bypass, real home ISP IPs; escalate here when blocked\n- `isp` — looks like a home user; best for social/ecommerce; ignores country param\n- `datacenter` — fastest/cheapest; non-anti-bot, high-volume targets\n- `mobile` — 4G/5G device IPs; mobile-targeted content and app APIs\n- `static` — same dedicated ISP IP every request; set session_id + country explicitly for account-management workflows — omitting either silently falls back to a SHARED \"default\"/\"us\" identity, not an error\n- `dedicated` — exclusive datacenter IP; set session_id explicitly for high-trust platforms — omitting it silently falls back to a SHARED \"default\" identity, not an error\n\n**Escalation when blocked:** datacenter → isp → residential.", "inputSchema": { "properties": { "city": { - "description": "ISO 2-letter country code (e.g. 'us', 'gb', 'de'). Omit for any country. NOTE: country targeting is NOT applied when type='isp' — it is silently ignored for that proxy type.", + "description": "ISO 2-letter country code (e.g. 'us','gb','de'). Omit for any country. NOTE: silently ignored when type='isp'.", "pattern": "^[a-zA-Z]{2}$", "type": "string" }, - "description": "Proxy type. 'residential' for most anti-bot scenarios, 'mobile' for app automation, 'isp' for sticky sessions, 'datacenter' for high-volume/low-cost, 'static' for a dedicated ISP IP (same IP every request, requires session_id), 'dedicated' for an exclusive datacenter IP (not shared, requires session_id).", + "description": "Proxy type. 'residential' for most anti-bot scenarios, 'mobile' for app automation, 'isp' for sticky sessions, 'datacenter' for high-volume/low-cost, 'static'/'dedicated' for a fixed IP — set session_id explicitly, or it silently falls back to a SHARED \"default\" identity (not an error).", "enum": [ "residential", "isp", + }, + "verify": { + "description": "Verify the issued config with ONE live IP-echo request routed through the proxy (default true). Appends evidence — exit IP, org/ASN, country, latency — to the response; failures are classified (402 payment / 407 auth / timeout) WITHOUT withholding the config. Costs ~1 KB of metered proxy traffic and ~1s of latency per call — set false to skip. Local/stdio runtimes only; skipped automatically (and disclosed) on hosted runtimes.", + "type": "boolean" } }, "required": [], - "name": "novada_proxy" + "name": "novada_proxy", + "title": "Proxy Credentials" }
--- pinned/novada_proxy_account_create +++ observed/novada_proxy_account_create { "annotations": { "destructiveHint": false, - "description": "⚠️ WRITE — Create a proxy sub-account. Two-step confirm gate.\n\n**Behavior:** Without `confirm: true` the tool returns a `confirmation_required` JSON preview (password masked) and DOES NOT hit the API. Show preview to the human user; only re-call with `confirm: true` after explicit human approval.\n\n**Best for:** Provisioning a team-member or per-project sub-account against your master plan.\n**Params:** product (\"1\"=Residential, \"2\"=Rotating ISP, \"3\"=Rotating Datacenter, \"4\"=Unlimited, \"7\"=Unblocker, \"9\"=Mobile), account (3-64, [a-zA-Z0-9_-]), password (8-64), status (\"1\" active default | \"-3\" disabled), remark?, limit_flow? (GB cap as string), confirm.\n**Wire format:** multipart/form-data (per developer-api spec).\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", + "description": "⚠️ WRITE — Create a proxy sub-account. Two-step approval-token gate.\n\n**Behavior:** call once WITHOUT `approval_token` to get a `confirmation_required` JSON preview (password masked) plus a fresh `approval_token` valid for 10 minutes — this does NOT hit the API. Show the preview to the human, then re-call with the EXACT SAME parameters plus that `approval_token` after explicit approval. `confirm: true` is a deprecated no-op and does NOT substitute for the token.\n\n**Best for:** provisioning a team-member or per-project sub-account against your master plan.\n**Params:** product (\"1\"=Residential, \"2\"=Rotating ISP, \"3\"=Rotating Datacenter, \"4\"=Unlimited, \"7\"=Unblocker, \"9\"=Mobile), account (3-64, [a-zA-Z0-9_-]), password (8-64), status (\"1\" active default | \"-3\" disabled), remark?, limit_flow? (GB cap), approval_token.\n**Wire format:** multipart/form-data.\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", "inputSchema": { "properties": { "account": { + "approval_token": { + "description": "Two-step approval token. Omit on the first call to receive a preview + a fresh approval_token (valid 10 minutes). Re-call with the EXACT SAME parameters plus this field set to that token to execute. Never invent a value — an invented or stale token is rejected.", + "minLength": 1, + "type": "string" + }, "confirm": { "const": true, - "description": "REQUIRED for execution. Pass `true` ONLY after the human user has approved this account creation. If omitted, the tool returns a dry-run preview instead of calling the API.", + "description": "DEPRECATED — ignored. Setting this alone no longer authorizes execution (closed 2026-09, finding F2-2: an agent could self-supply confirm:true with no prior human-reviewed preview). Use approval_token instead: call once WITHOUT approval_token to receive a preview and a token, then call again with the identical parameters plus approval_token.", "type": "boolean" }, "limit_flow": { - "name": "novada_proxy_account_create" + "name": "novada_proxy_account_create", + "title": "Proxy Account Create" }
--- pinned/novada_proxy_account_list +++ observed/novada_proxy_account_list { "annotations": { "destructiveHint": false, - "description": "List proxy sub-accounts. Wraps developer-api POST /v1/proxy_account/list.\n\n**Best for:** Auditing sub-accounts, finding account names before rotating credentials.\n**Params:** product (REQUIRED — same codes as create), page, limit (max 200), status? (\"1\"|\"-3\"), account? (exact-match filter).\n**Wire format:** multipart/form-data.\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", + "description": "List proxy sub-accounts (wraps developer-api POST /v1/proxy_account/list).\n\n**Best for:** auditing sub-accounts, finding account names before rotating credentials.\n**Params:** product (REQUIRED — same codes as create), page, limit (max 200), status? (\"1\"|\"-3\"), account? (exact-match filter).\n**Wire format:** multipart/form-data.\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", "inputSchema": { "properties": { "account": { - "name": "novada_proxy_account_list" + "name": "novada_proxy_account_list", + "title": "Proxy Account List" }
--- pinned/novada_research +++ observed/novada_research { "annotations": { "destructiveHint": false, - "description": "One call → 3-10 parallel searches across Google/Bing/DuckDuckGo → dedup → extract full content from top sources → returns CITED SOURCE MATERIAL (numbered source sections), not a written answer. Extractive, not generative: it gathers and ranks the most relevant passages; YOU compose the final answer from them.\n\n**Use for:** Any complex question where you want relevant passages from ≥3 independent sources gathered in one call. Comparative analysis, market research, technical deep dives, competitive intelligence. Replaces 5-10 manual search+extract calls.\n**Not for:** Single fact lookup or finding one URL — use novada_search for that (faster, cheaper). Reading a known URL — use novada_extract. A finished prose report — this returns source material, you write the answer.\n**Rule of thumb:** If the answer could fit in one search result snippet, use novada_search. If you need source material pulled from multiple pages to reason over, use novada_research.\n**Depth:** \"quick\" (3 queries), \"deep\" (6), \"comprehensive\" (8-9), \"auto\" (default: picks quick or deep by question length — never comprehensive).\n**Key advantage:** Agents call this ONCE instead of orchestrating search→extract manually. Saves tokens, time, and complexity.\n**Project grouping:** Pass `project=\"my-project\"` to group all outputs in a subfolder (e.g. ~/Downloads/novada-mcp/2026-06-26/my-project/). Useful for multi-step research tasks.\n**Recency:** Supports `time_range` (\"day\"|\"week\"|\"month\"|\"year\"), `start_date`, and `end_date` (ISO YYYY-MM-DD) for recency-constrained research — all are propagated to every internal search call.", + "description": "One call → 3-10 parallel searches across Google/Bing/DuckDuckGo → dedup → extracts full content from top sources → returns CITED SOURCE MATERIAL (numbered passages), not a written answer. Extractive, not generative — you compose the final answer from the gathered passages.\n\n**Use for:** complex questions needing passages from ≥3 independent sources in one call — comparative analysis, market research, technical deep dives, competitive intelligence. Replaces 5-10 manual search+extract calls.\n**Not for:** a single fact or one URL (novada_search — faster/cheaper), a known URL (novada_extract), or a finished prose report (this returns source material, not an answer).\n**Depth:** \"quick\" (3 queries), \"deep\" (6), \"comprehensive\" (8-9), \"auto\" (default — quick or deep by question length, never comprehensive).\n**Project grouping:** `project=\"my-project\"` groups outputs under a subfolder.\n**Recency:** `time_range` (\"day\"|\"week\"|\"month\"|\"year\"), `start_date`/`end_date` (ISO YYYY-MM-DD) propagate to every internal search call.", "inputSchema": { "properties": { "depth": { - "description": "Optional project name to group related outputs in a subfolder. E.g. 'france-vs-norway'. (local stdio only; no effect on the hosted endpoint)", + "description": "Group outputs in a subfolder, e.g. 'france-vs-norway'. Local stdio only — no effect on hosted.", "maxLength": 30, "type": "string" }, - "name": "novada_research" + "name": "novada_research", + "title": "Deep Research" }
--- pinned/novada_scrape +++ observed/novada_scrape { "annotations": { "destructiveHint": false, - "description": "Use when you need structured data from a specific platform — not raw HTML, but clean tabular records. Supports 16 platforms (~87 operations): Amazon, Walmart, SHEIN, Google (incl. Shopping), Bing, DuckDuckGo, Yandex, X/Twitter, TikTok, Instagram, Facebook, YouTube, LinkedIn, GitHub, ChatGPT, Perplexity.\n\n**Best for:** E-commerce product data, social posts/comments, job listings, reviews, real estate, market data.\n**Not for:** General web pages not in the platform list — use novada_extract for arbitrary URLs instead.\n**Output formats:** \"markdown\" (default, agent-optimized table), \"json\" (structured records array returned inside a \"## Scrape Results\" wrapper — a fenced json block, not a bare object), \"toon\" (token-optimized pipe-separated format — 40-65% smaller than JSON/markdown, best for large result sets in context-constrained situations), \"csv\" (inline CSV text), \"excel\" (inline .xlsx base64), \"html\" (inline HTML table).\n**Example:** platform=\"amazon.com\", operation=\"amazon_product_keywords\", params={keyword:\"iphone 16\", num:5}\n**Amazon price fields:** trust `final_price`/`price` (check `_price_source`); `initial_price` and `buybox_prices.final_price` are frequently 0 by design, not a bug; `buybox_prices.unit_price` is raw upstream per-unit data and may be empty/inconsistent — never treat it as the listing price.\n**Discover platforms:** Read the `novada://scraper-platforms` MCP resource for the complete platform list with operation IDs and required params.\n**Resume slow-platform scrapes:** Pass `task_id` from a previous call that returned status:processing to fetch its result without submitting a new billable task. platform and operation are still required (display only when resuming).\n**Project grouping:** Pass `project=\"my-project\"` to group all outputs in a subfolder (e.g. ~/Downloads/novada-mcp/2026-06-26/my-project/). Useful for multi-step research tasks.", + "description": "Use for structured data from a specific platform — clean tabular records, not raw HTML. Supports 16 platforms (~87 operations): Amazon, Walmart, SHEIN, Google (incl. Shopping), Bing, DuckDuckGo, Yandex, X/Twitter, TikTok, Instagram, Facebook, YouTube, LinkedIn, GitHub, ChatGPT, Perplexity.\n\n**Best for:** e-commerce product data, social posts/comments, job listings, reviews, real estate, market data.\n**Not for:** general web pages outside this platform list — use novada_extract instead.\n**Prefer the dedicated tool when one exists:** for amazon/google/bing/duckduckgo/yandex/youtube/instagram/facebook/tiktok/x/walmart/shein/linkedin/github/perplexity, call novada_scrape_<platform> instead — same engine, but its `operation` enum uses typed friendly names and is rejected client-side before any network call if wrong. Use THIS generic tool for platforms with no dedicated sibling (e.g. ChatGPT) or when resuming by task_id.\n**Output formats:** markdown (default table), json (records array inside a fenced \"## Scrape Results\" block), toon (pipe-separated, 40-65% smaller — best for large result sets), csv, excel (base64), html.\n**Example:** platform=\"amazon.com\", operation=\"amazon_product_keywords\", params={keyword:\"iphone 16\", num:5}.\n**Amazon price fields:** trust `final_price`/`price` (check `_price_source`) — `initial_price` and `buybox_prices.final_price` are often 0 by design, not a bug; `buybox_prices.unit_price` is raw per-unit data, never the listing price.\n**Discover platforms:** read the `novada://scraper-platforms` resource for the full operation list.\n**Resume:** pass `task_id` from a prior status:processing call to fetch the result without a new billable task (platform/operation still required, display-only).\n**Project grouping:** `project=\"my-project\"` groups outputs under a subfolder.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table, easy to read and reason over. 'json': structured records array — key fields (title/price/rating/url) surfaced, noise trimmed — returned inside a \"## Scrape Results\" wrapper as a fenced json block (not a bare object). 'csv': inline CSV text, header row + one row per record, copy-paste into any spreadsheet. 'excel': real .xlsx returned as inline base64 — paste the base64 block into a decoder or use the provided download hint. 'html': inline HTML <table> (header row + one row per record) ready to drop into a page or open in a browser. 'toon': token-optimized pipe-separated format (40-65% smaller than JSON/markdown).", + "description": "'markdown' (default): structured table. 'json': records array with key fields surfaced — returned inside a \"## Scrape Results\" wrapper as a fenced json block, NOT a bare object. 'csv': inline CSV, header + one row/record. 'excel': real .xlsx as inline base64 — decode or use the download hint. 'html': inline HTML <table>. 'toon': token-optimized pipe-separated (40-65% smaller than json/markdown).", "enum": [ "json", "csv", - "description": "Platform domain to scrape. E.g. 'amazon.com', 'reddit.com', 'tiktok.com', 'linkedin.com', 'google.com'.", + "description": "Platform domain to scrape. E.g. 'amazon.com', 'walmart.com', 'tiktok.com', 'linkedin.com', 'google.com'.", "maxLength": 100, "minLength": 1, "pattern": "^[a-zA-Z0-9._\\-]+$", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'france-vs-norway'. (local stdio only; no effect on the hosted endpoint)", + "description": "Group outputs in a subfolder, e.g. 'france-vs-norway'. Local stdio only — no effect on hosted.", "maxLength": 30, "type": "string" }, - "name": "novada_scrape" + "name": "novada_scrape", + "title": "Platform Scraper" }
--- pinned/novada_scrape_amazon +++ observed/novada_scrape_amazon { "annotations": { "destructiveHint": false, - "description": "Extract structured Amazon data — product details, reviews, seller info, bestseller lists, and category/brand listings — through an Amazon-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"amazon.com\".\n\n**Use when:** \"get the price/rating/title for Amazon ASIN B0...\", \"pull the reviews for this Amazon product URL\", \"search Amazon for <keyword> with price and rating\", \"who is this Amazon seller\", \"what's in this Amazon Best Sellers list\".\n**Not for:** Any other platform — use novada_scrape with the target platform's domain instead (e.g. platform=\"walmart.com\"). A general Google/web search — use novada_search. Reading one arbitrary URL's raw content — use novada_extract.\n**Returns:** Structured product/review/seller records (title, price, rating, asin, availability, etc.) in the chosen format — same rendering as novada_scrape (markdown/json/csv/excel/html/toon).\n**Operations:** 10 verified-working Amazon operations (see the `operation` param's description for the exact `params` keys each needs). 3 known backend-broken Amazon operations are intentionally NOT in this enum — this tool rejects them before any backend call, unlike novada_scrape(platform=\"amazon.com\", ...), which still forwards them with a warning.", + "description": "Extract structured Amazon data — product details, reviews, seller info, bestseller lists, category/brand listings — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"amazon.com\").\n\n**Use when:** \"get the price/rating/title for Amazon ASIN B0...\", \"pull the reviews for this Amazon product URL\", \"search Amazon for <keyword> with price and rating\", \"who is this Amazon seller\", \"what's in this Amazon Best Sellers list\".\n**Not for:** Any other platform — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\"). A general Google/web search — use novada_search. Reading one arbitrary URL's raw content — use novada_extract.\n**Returns:** Structured product/review/seller records (title, price, rating, asin, availability, etc.) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 10 verified-working Amazon operations. 3 known backend-broken ones are excluded from this enum (rejected client-side before any backend call) — unlike novada_scrape(platform=\"amazon.com\", ...), which still forwards them with a warning.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which Amazon operation to run. Each requires specific keys in `params`:\n- product_by_asin: params.asin (e.g. \"B0BWBK8F37\")\n- product_by_url: params.url (product page URL); optional params.zip_code\n- products_by_keywords: params.keyword; optional params.max_pages, params.min_price, params.max_price\n- bestsellers: params.url (a Best Sellers list page URL); optional params.max_pages\n- reviews_by_url: params.url (product page URL)\n- seller_by_url: params.url (seller page URL)\n- listings_by_keyword: params.keyword and params.domain (e.g. \"https://www.amazon.com\"); optional params.max_pages\n- global_product_by_url: params.url\n- global_product_by_category_url: params.url (category/search URL) and params.maximum; optional params.sort_by, params.get_sponsored\n- global_product_by_keyword_and_brand: params.keyword, params.brands, params.max_pages", + "description": "Amazon operation to run (params keys per entry):\n- product_by_asin: params.asin (e.g. \"B0BWBK8F37\")\n- product_by_url: params.url (product page URL); optional params.zip_code\n- products_by_keywords: params.keyword; optional params.max_pages, params.min_price, params.max_price\n- bestsellers: params.url (a Best Sellers list page URL); optional params.max_pages\n- reviews_by_url: params.url (product page URL)\n- seller_by_url: params.url (seller page URL)\n- listings_by_keyword: params.keyword and params.domain (e.g. \"https://www.amazon.com\"); optional params.max_pages\n- global_product_by_url: params.url\n- global_product_by_category_url: params.url (category/search URL) and params.maximum; optional params.sort_by, params.get_sponsored\n- global_product_by_keyword_and_brand: params.keyword, params.brands, params.max_pages", "enum": [ "product_by_asin", "product_by_url", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_amazon" + "name": "novada_scrape_amazon", + "title": "Scrape Amazon" }
--- pinned/novada_scrape_bing +++ observed/novada_scrape_bing { "annotations": { "destructiveHint": false, - "description": "Extract structured Bing SERP data — organic web search results, video results, news results, and shopping listings — through a Bing-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"bing.com\". Bing is NOT a selectable engine on novada_search — this is the only intentional way to query Bing specifically.\n\n**Use when:** \"get the raw Bing search results (titles, links, ranks) for <query>\", \"find Bing video results for <query>\", \"find Bing news results for <query>, sorted by date\", \"search Bing Shopping for <keyword>\".\n**Not for:** A general question that just needs an answer or a few good links — use novada_search — google/duckduckgo/yandex only (Bing is not selectable there); ranked, reranked, answer-oriented, and cheaper than a raw-SERP scrape. A complex question needing cited multi-source synthesis — use novada_research. Reading one already-known URL's page content (not a search results page) — use novada_extract. A different platform's structured data (Amazon, LinkedIn, TikTok, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured SERP records per operation — organic results (title/url/snippet/rank), video results, news results (with date), and shopping listings (price/rating) — in the chosen format (markdown/json/csv/excel/html/toon), same rendering as novada_scrape.\n**Operations:** 4 verified-working Bing operations: web search, videos, news, and shopping (see the `operation` param's description for the exact `params` keys each needs). Every bing.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured Bing SERP data — organic web search, video results, news results, shopping listings — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"bing.com\"). Bing is NOT a selectable engine on novada_search — this is the only intentional way to query Bing specifically.\n\n**Use when:** \"get the raw Bing search results (titles, links, ranks) for <query>\", \"find Bing video results for <query>\", \"find Bing news results for <query>, sorted by date\", \"search Bing Shopping for <keyword>\".\n**Not for:** A general question needing just an answer or a few good links — use novada_search — google/duckduckgo/yandex only (Bing is not selectable there); ranked, cheaper than a raw-SERP scrape. A complex question needing cited multi-source synthesis — use novada_research. Reading one already-known URL's page content — use novada_extract. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured SERP records per operation — organic results (title/url/snippet/rank), video results, news results (with date), shopping listings (price/rating) — in the chosen output format, same rendering as novada_scrape.\n**Ops:** 4 verified-working Bing operations: web search, videos, news, and shopping. Every bing.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which Bing operation to run. Each requires specific keys in `params`:\n- web_search: params.q (search query); optional params.device, params.country, params.lg (language), params.location, params.start, params.num, params.safe, params.filters\n- videos: params.q (search query); optional params.device, params.country, params.lg, params.length (short/medium/long), params.date, params.resolution, params.source_site, params.price\n- news: params.q (search query — required by the engine's preflight even though the catalog's own params list omits it); optional params.country, params.language, params.start, params.num, params.qft (sort order, e.g. \"sortbydate\")\n- shopping: params.q (search query); optional params.country, params.lg, params.start, params.filters", + "description": "Bing operation to run (params keys per entry):\n- web_search: params.q (search query); optional params.device, params.country, params.lg (language), params.location, params.start, params.num, params.safe, params.filters\n- videos: params.q (search query); optional params.device, params.country, params.lg, params.length (short/medium/long), params.date, params.resolution, params.source_site, params.price\n- news: params.q (search query — required by the engine's preflight even though the catalog's own params list omits it); optional params.country, params.language, params.start, params.num, params.qft (sort order, e.g. \"sortbydate\")\n- shopping: params.q (search query); optional params.country, params.lg, params.start, params.filters", "enum": [ "web_search", "videos", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_bing" + "name": "novada_scrape_bing", + "title": "Scrape Bing" }
--- pinned/novada_scrape_duckduckgo +++ observed/novada_scrape_duckduckgo { "annotations": { "destructiveHint": false, - "description": "Extract structured DuckDuckGo web search SERP data through a DuckDuckGo-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"duckduckgo.com\". Returns the raw organic-results SERP, with region/time/adult-content filters novada_search does not expose, not a generated answer.\n\n**Use when:** \"get the raw DuckDuckGo search results (titles, links, ranks) for <query>\", \"search DuckDuckGo restricted to a specific region (params.kl) or time range (params.df)\", \"compare DuckDuckGo's ranking for <query> against another engine's raw SERP\".\n**Not for:** A general question that just needs an answer or a few good links — use novada_search with engine=\"duckduckgo\" — same engine, but ranked/reranked and answer-oriented instead of a raw SERP dump. A complex question needing cited multi-source synthesis — use novada_research. Reading one already-known URL's page content (not a search results page) — use novada_extract. A different platform's structured data (Amazon, LinkedIn, TikTok, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured organic-result SERP records (title/url/snippet/rank) in the chosen format (markdown/json/csv/excel/html/toon), same rendering as novada_scrape.\n**Operations:** 1 verified-working DuckDuckGo operation (web search — see the `operation` param's description for the exact `params` keys it needs). The single duckduckgo.com catalog operation is currently status:\"ok\".", + "description": "Extract structured DuckDuckGo web search SERP data via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"duckduckgo.com\"). Returns the raw organic-results SERP, with region/time/adult-content filters novada_search does not expose, not a generated answer.\n\n**Use when:** \"get the raw DuckDuckGo search results (titles, links, ranks) for <query>\", \"search DuckDuckGo restricted to a specific region (params.kl) or time range (params.df)\", \"compare DuckDuckGo's ranking for <query> against another engine's raw SERP\".\n**Not for:** A general question needing just an answer or a few good links — use novada_search with engine=\"duckduckgo\" (ranked/reranked instead of a raw SERP dump). A complex question needing cited multi-source synthesis — use novada_research. Reading one already-known URL's page content — use novada_extract. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured organic-result SERP records (title/url/snippet/rank) in the chosen output format, same rendering as novada_scrape.\n**Ops:** 1 verified-working DuckDuckGo operation (web search). The single duckduckgo.com catalog operation is currently status:\"ok\".", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which DuckDuckGo operation to run. Each requires specific keys in `params`:\n- web_search: params.q (search query); optional params.kl (region), params.start (results offset), params.df (time range: d/w/m/y), params.kp (adult content filter)", + "description": "DuckDuckGo operation to run (params keys per entry):\n- web_search: params.q (search query); optional params.kl (region), params.start (results offset), params.df (time range: d/w/m/y), params.kp (adult content filter)", "enum": [ "web_search" ], - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_duckduckgo" + "name": "novada_scrape_duckduckgo", + "title": "Scrape DuckDuckGo" }
--- pinned/novada_scrape_facebook +++ observed/novada_scrape_facebook { "annotations": { "destructiveHint": false, - "description": "Extract structured Facebook data — public profile pages, posts, comments, and events — through a Facebook-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"facebook.com\".\n\n**Use when:** \"get this public Facebook page's profile info\", \"pull the comments on this Facebook post\", \"get details for this Facebook event\", \"find events matching <query> on Facebook\", \"list the upcoming events on this Facebook page\".\n**Not for:** A single Facebook URL you just want read as plain text — use novada_extract. A general web search not scoped to Facebook — use novada_search. A different platform's structured data (Instagram, X, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured profile/post/comment/event records (page name, post text, comment author/text, event name/date/location, etc.) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 6 verified-working Facebook operations spanning public profile pages, posts, comments, and events (search / single event / event list) (see the `operation` param's description for the exact `params` keys each needs). Every facebook.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured Facebook data — public profile pages, posts, comments, and events — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"facebook.com\").\n\n**Use when:** \"get this public Facebook page's profile info\", \"pull the comments on this Facebook post\", \"get details for this Facebook event\", \"find events matching <query> on Facebook\", \"list the upcoming events on this Facebook page\".\n**Not for:** A single Facebook URL to read as plain text — use novada_extract. A general web search not scoped to Facebook — use novada_search. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured profile/post/comment/event records (page name, post text, comment author/text, event name/date/location, etc.) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 6 verified-working Facebook operations spanning public profile pages, posts, comments, and events (search / single event / event list). Every facebook.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which Facebook operation to run. Each requires specific keys in `params`:\n- profile_by_url: params.url (personal/page homepage URL); optional params.file_name\n- events_by_search_url: params.url (an activity/events search URL); optional params.file_name\n- event_by_url: params.url (a single event URL); optional params.file_name\n- events_by_list_url: params.url (a page's /events list URL); optional params.upcoming_events, params.file_name\n- post_by_url: params.url (post URL); optional params.file_name\n- comments_by_post_url: params.url (post URL); optional params.get_all_replies, params.limit_records, params.file_name", + "description": "Facebook operation to run (params keys per entry):\n- profile_by_url: params.url (personal/page homepage URL); optional params.file_name\n- events_by_search_url: params.url (an activity/events search URL); optional params.file_name\n- event_by_url: params.url (a single event URL); optional params.file_name\n- events_by_list_url: params.url (a page's /events list URL); optional params.upcoming_events, params.file_name\n- post_by_url: params.url (post URL); optional params.file_name\n- comments_by_post_url: params.url (post URL); optional params.get_all_replies, params.limit_records, params.file_name", "enum": [ "profile_by_url", "events_by_search_url", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_facebook" + "name": "novada_scrape_facebook", + "title": "Scrape Facebook" }
--- pinned/novada_scrape_github +++ observed/novada_scrape_github { "annotations": { "destructiveHint": false, - "description": "Extract structured GitHub repository data — repository details by URL, or multiple repositories from a GitHub search-results URL — through a GitHub-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"github.com\".\n\n**Use when:** \"get repository info (stars, forks, description, language, etc.) for this GitHub repo URL\", \"get the repositories listed on this GitHub search-results URL\".\n**Not for:** A single GitHub URL (repo, issue, PR, user) you just want read as plain text — use novada_extract. A general web/code search not scoped to GitHub, or a GitHub issue/PR/user lookup (no catalog operation exists for those) — use novada_search, or novada_extract for a known URL. A different platform's structured data (LinkedIn, Amazon, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured repository records (name, description, stars, forks, language, etc.) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 3 verified-working GitHub operations: two repository-by-URL lookups (`repository_by_url` and `repository_details_by_url` map to distinct catalog scraper_ids — github_repository_repo-url and github_repository_url respectively — both taking the same `url` param; the catalog documents no behavioral difference between them) and repository listing from a GitHub search-results URL (see the `operation` param's description for the exact `params` keys each needs). Every github.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured GitHub repository data — repository details by URL, or multiple repositories from a GitHub search-results URL — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"github.com\").\n\n**Use when:** \"get repository info (stars, forks, description, language, etc.) for this GitHub repo URL\", \"get the repositories listed on this GitHub search-results URL\".\n**Not for:** A single GitHub URL (repo, issue, PR, user) to read as plain text — use novada_extract. A general web/code search not scoped to GitHub, or a GitHub issue/PR/user lookup (no catalog operation exists for those) — use novada_search, or novada_extract for a known URL. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured repository records (name, description, stars, forks, language, etc.) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 3 verified-working GitHub operations: two repository-by-URL lookups (`repository_by_url` and `repository_details_by_url` map to distinct catalog scraper_ids — github_repository_repo-url and github_repository_url respectively — both taking the same `url` param; the catalog documents no behavioral difference between them) and repository listing from a GitHub search-results URL. Every github.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which GitHub operation to run. Each requires specific keys in `params`:\n- repository_by_url: params.url (repository URL, e.g. \"https://github.com/gin-gonic/gin\"); optional params.file_name\n- repository_details_by_url: params.url (repository URL, e.g. \"https://github.com/QwenLM/Qwen\"); optional params.file_name\n- repositories_by_search_url: params.search_url (a GitHub search-results URL, e.g. \"https://github.com/search?q=ai&type=repositories\"); optional params.page_limit, params.max, params.file_name", + "description": "GitHub operation to run (params keys per entry):\n- repository_by_url: params.url (repository URL, e.g. \"https://github.com/gin-gonic/gin\"); optional params.file_name\n- repository_details_by_url: params.url (repository URL, e.g. \"https://github.com/QwenLM/Qwen\"); optional params.file_name\n- repositories_by_search_url: params.search_url (a GitHub search-results URL, e.g. \"https://github.com/search?q=ai&type=repositories\"); optional params.page_limit, params.max, params.file_name", "enum": [ "repository_by_url", "repository_details_by_url", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_github" + "name": "novada_scrape_github", + "title": "Scrape GitHub" }
--- pinned/novada_scrape_google +++ observed/novada_scrape_google { "annotations": { "destructiveHint": false, - "description": "Extract structured Google SERP data — organic web search results, AI Mode answers, Maps place/review details, Shopping listings, Jobs, Hotels, and Videos — through a Google-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"google.com\". Returns raw structured SERP records, not a generated answer.\n\n**Use when:** \"get the raw Google search results (titles, links, ranks) for <query>\", \"what's in Google's AI Mode answer for <query>\", \"pull Google Maps reviews or place details for this URL / place_id / CID\", \"search Google Shopping for <keyword>\", \"find Google Jobs, Hotels, or Videos results for <query>\".\n**Not for:** A general question that just needs an answer or a few good links — use novada_search — multi-engine (google/duckduckgo/yandex), ranked and reranked, answer-oriented, and far cheaper than a raw-SERP scrape. A complex question needing cited multi-source synthesis — use novada_research. Reading one already-known URL's page content (not a search results page) — use novada_extract. A different platform's structured data (Amazon, LinkedIn, TikTok, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured SERP records per operation — organic results (title/url/snippet/rank), AI Mode answer content, Maps place details/reviews, Shopping listings (price/rating), and Jobs/Hotels/Videos listings — in the chosen format (markdown/json/csv/excel/html/toon), same rendering as novada_scrape.\n**Operations:** 13 verified-working Google operations spanning web search, AI Mode, Maps (location/place_id/CID/URL lookups + reviews), Shopping, Jobs, Hotels, and Videos (see the `operation` param's description for the exact `params` keys each needs). Every google.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured Google SERP data — organic web search, AI Mode answers, Maps place/review details, Shopping, Jobs, Hotels, Videos — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"google.com\"). Returns raw structured SERP records, not a generated answer.\n\n**Use when:** \"get the raw Google search results (titles, links, ranks) for <query>\", \"what's in Google's AI Mode answer for <query>\", \"pull Google Maps reviews or place details for this URL / place_id / CID\", \"search Google Shopping for <keyword>\", \"find Google Jobs, Hotels, or Videos results for <query>\".\n**Not for:** A general question needing just an answer or a few good links — use novada_search (multi-engine: google/duckduckgo/yandex, ranked/reranked, cheaper than a raw-SERP scrape). A complex question needing cited multi-source synthesis — use novada_research. Reading one already-known URL's page content — use novada_extract. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured SERP records per operation — organic results (title/url/snippet/rank), AI Mode answer content, Maps place details/reviews, Shopping listings (price/rating), Jobs/Hotels/Videos listings — in the chosen output format, same rendering as novada_scrape.\n**Ops:** 13 verified-working Google operations spanning web search, AI Mode, Maps (location/place_id/CID/URL lookups + reviews), Shopping, Jobs, Hotels, and Videos. Every google.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which Google operation to run. Each requires specific keys in `params`:\n- web_search: params.q (search query); optional params.domain, params.country, params.hl (language), params.location, params.start/params.num (pagination), params.ai_overview, params.safe, params.tbs (advanced filters)\n- web_search_by_domain: params.q (search query) and params.domain (Google TLD domain, e.g. \"google.com\"); optional params.country, params.hl, params.location, params.start, params.num\n- search_by_url: params.url (a full Google search results URL, e.g. \"https://www.google.com/search?q=...\"); optional params.device, params.render_js, params.no_cache\n- ai_mode: params.q (search query); optional params.gl (country), params.location, params.uule (encoded location)\n- hotels: params.q, params.domain, params.check_in_date, params.check_out_date (YYYY-MM-DD); optional params.country, params.hl, params.adults\n- jobs: params.q (search query); optional params.domain, params.country, params.hl, params.location, params.start, params.num\n- videos: params.q (search query); optional params.domain, params.country, params.hl, params.start, params.num\n- shopping: params.keyword (e.g. \"pizza\"); optional params.country\n- maps_by_location: params.country, params.keyword, params.merchant_limit (max merchants to return); optional params.lat, params.long, params.zl (zoom level)\n- maps_by_place_id: params.place_id (Google Place ID)\n- maps_by_cid: params.cid (Google Maps CID)\n- maps_by_url: params.url (a Google Maps place URL)\n- maps_reviews_by_url: params.url (Google Maps place URL); optional params.limit (days of reviews to fetch, default 30)", + "description": "Google operation to run (params keys per entry):\n- web_search: params.q (search query); optional params.domain, params.country, params.hl (language), params.location, params.start/params.num (pagination), params.ai_overview, params.safe, params.tbs (advanced filters)\n- web_search_by_domain: params.q (search query) and params.domain (Google TLD domain, e.g. \"google.com\"); optional params.country, params.hl, params.location, params.start, params.num\n- search_by_url: params.url (a full Google search results URL, e.g. \"https://www.google.com/search?q=...\"); optional params.device, params.render_js, params.no_cache\n- ai_mode: params.q (search query); optional params.gl (country), params.location, params.uule (encoded location)\n- hotels: params.q, params.domain, params.check_in_date, params.check_out_date (YYYY-MM-DD); optional params.country, params.hl, params.adults\n- jobs: params.q (search query); optional params.domain, params.country, params.hl, params.location, params.start, params.num\n- videos: params.q (search query); optional params.domain, params.country, params.hl, params.start, params.num\n- shopping: params.keyword (e.g. \"pizza\"); optional params.country\n- maps_by_location: params.country, params.keyword, params.merchant_limit (max merchants to return); optional params.lat, params.long, params.zl (zoom level)\n- maps_by_place_id: params.place_id (Google Place ID)\n- maps_by_cid: params.cid (Google Maps CID)\n- maps_by_url: params.url (a Google Maps place URL)\n- maps_reviews_by_url: params.url (Google Maps place URL); optional params.limit (days of reviews to fetch, default 30)", "enum": [ "web_search", "web_search_by_domain", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_google" + "name": "novada_scrape_google", + "title": "Scrape Google" }
--- pinned/novada_scrape_instagram +++ observed/novada_scrape_instagram { "annotations": { "destructiveHint": false, - "description": "Extract structured Instagram data — profiles, posts, reels, and comments — through an Instagram-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"instagram.com\".\n\n**Use when:** \"get the latest posts from this Instagram profile\", \"pull the comments on this Instagram post or reel\", \"get details for this single Instagram post or reel URL\", \"get Instagram profile info by URL or username\", \"get the reels posted by this Instagram profile\".\n**Not for:** A single Instagram URL you just want read as plain text — use novada_extract. A general web search not scoped to Instagram — use novada_search. A different platform's structured data (TikTok, Facebook, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured profile/post/reel/comment records (username, follower count, caption, like count, comment author/text, etc.) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 7 verified-working Instagram operations spanning profile lookup (by URL or username), posts and reels (by profile or by direct URL), and comments (see the `operation` param's description for the exact `params` keys each needs). `posts_by_profile` requires BOTH `profileurl` AND `resultsLimit` together. Every instagram.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured Instagram data — profiles, posts, reels, and comments — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"instagram.com\").\n\n**Use when:** \"get the latest posts from this Instagram profile\", \"pull the comments on this Instagram post or reel\", \"get details for this single Instagram post or reel URL\", \"get Instagram profile info by URL or username\", \"get the reels posted by this Instagram profile\".\n**Not for:** A single Instagram URL to read as plain text — use novada_extract. A general web search not scoped to Instagram — use novada_search. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured profile/post/reel/comment records (username, follower count, caption, like count, comment author/text, etc.) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 7 verified-working Instagram operations spanning profile lookup (by URL or username), posts and reels (by profile or by direct URL), and comments. `posts_by_profile` requires BOTH `profileurl` AND `resultsLimit` together. Every instagram.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which Instagram operation to run. Each requires specific keys in `params`:\n- comments_by_post_url: params.posturl (post/reel URL); optional params.file_name\n- reels_by_profile_url: params.url (profile URL); optional params.num_posts, params.uncrawled_posts, params.start_date, params.end_date, params.file_name\n- reel_by_url: params.url (a single reel URL); optional params.file_name\n- posts_by_profile: params.profileurl AND params.resultsLimit (BOTH required together); optional params.start_date, params.end_date, params.post_type (Post|Reel), params.file_name\n- post_by_url: params.posturl (a single post URL); optional params.file_name\n- profile_by_url: params.profileurl; optional params.file_name\n- profile_by_username: params.username; optional params.file_name", + "description": "Instagram operation to run (params keys per entry):\n- comments_by_post_url: params.posturl (post/reel URL); optional params.file_name\n- reels_by_profile_url: params.url (profile URL); optional params.num_posts, params.uncrawled_posts, params.start_date, params.end_date, params.file_name\n- reel_by_url: params.url (a single reel URL); optional params.file_name\n- posts_by_profile: params.profileurl AND params.resultsLimit (BOTH required together); optional params.start_date, params.end_date, params.post_type (Post|Reel), params.file_name\n- post_by_url: params.posturl (a single post URL); optional params.file_name\n- profile_by_url: params.profileurl; optional params.file_name\n- profile_by_username: params.username; optional params.file_name", "enum": [ "comments_by_post_url", "reels_by_profile_url", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_instagram" + "name": "novada_scrape_instagram", + "title": "Scrape Instagram" }
--- pinned/novada_scrape_linkedin +++ observed/novada_scrape_linkedin { "annotations": { "destructiveHint": false, - "description": "Extract structured LinkedIn data — job listings (by location/filters, by a jobs search-results URL, or a single job posting URL) and company profile info by URL — through a LinkedIn-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"linkedin.com\".\n\n**Use when:** \"find LinkedIn job listings in <location> matching <keyword/level/remote/etc.>\", \"get all the job listings from this LinkedIn jobs search URL\", \"get details for this single LinkedIn job posting URL\", \"get company info for this LinkedIn company URL\".\n**Not for:** A single LinkedIn URL you just want read as plain text — use novada_extract. A general web search not scoped to LinkedIn — use novada_search. A LinkedIn personal PROFILE (not a company or job) — no catalog operation exists for this today — use novada_extract on the profile URL, or novada_search. A different platform's structured data (GitHub, Amazon, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured job-listing/company records (title, location, level, company name, follower count, etc.) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 4 verified-working LinkedIn operations spanning job search (by location, with optional keyword/level/remote/company filters), job listings from a search-results URL, a single job posting by URL, and company info by URL (see the `operation` param's description for the exact `params` keys each needs). `jobs_search` requires `params.location` — the catalog's actual required key for this op, despite its upstream name reading \"By Keywords\" (keyword itself is optional there). Every linkedin.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured LinkedIn data — job listings (by location/filters, jobs search-results URL, or a single job posting URL) and company profile info by URL — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"linkedin.com\").\n\n**Use when:** \"find LinkedIn job listings in <location> matching <keyword/level/remote/etc.>\", \"get all the job listings from this LinkedIn jobs search URL\", \"get details for this single LinkedIn job posting URL\", \"get company info for this LinkedIn company URL\".\n**Not for:** A single LinkedIn URL to read as plain text — use novada_extract. A general web search not scoped to LinkedIn — use novada_search. A LinkedIn personal PROFILE (not a company or job) — no catalog operation exists for this today — use novada_extract on the profile URL, or novada_search. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured job-listing/company records (title, location, level, company name, follower count, etc.) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 4 verified-working LinkedIn operations spanning job search (by location, with optional keyword/level/remote/company filters), job listings from a search-results URL, a single job posting by URL, and company info by URL. `jobs_search` requires `params.location` — the catalog's actual required key for this op, despite its upstream name reading \"By Keywords\" (keyword itself is optional there). Every linkedin.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which LinkedIn operation to run. Each requires specific keys in `params`:\n- jobs_search: params.location (required, e.g. \"Germany\"); optional params.keyword, params.range (Any_time|Past_day|Past_week|Past_month), params.level, params.position_type, params.remote (On_site|Remote|Hybrid), params.company, params.selective_search, params.position_to_not_include, params.location_radius, params.page_limit, params.file_name\n- jobs_by_search_url: params.listing_url (a LinkedIn JOBS SEARCH RESULTS URL — returns multiple listings); optional params.page_limit, params.file_name\n- job_by_url: params.position_url (a single LinkedIn job POSTING URL); optional params.file_name\n- company_by_url: params.url (LinkedIn company page URL); optional params.file_name", + "description": "LinkedIn operation to run (params keys per entry):\n- jobs_search: params.location (required, e.g. \"Germany\"); optional params.keyword, params.range (Any_time|Past_day|Past_week|Past_month), params.level, params.position_type, params.remote (On_site|Remote|Hybrid), params.company, params.selective_search, params.position_to_not_include, params.location_radius, params.page_limit, params.file_name\n- jobs_by_search_url: params.listing_url (a LinkedIn JOBS SEARCH RESULTS URL — returns multiple listings); optional params.page_limit, params.file_name\n- job_by_url: params.position_url (a single LinkedIn job POSTING URL); optional params.file_name\n- company_by_url: params.url (LinkedIn company page URL); optional params.file_name", "enum": [ "jobs_search", "jobs_by_search_url", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_linkedin" + "name": "novada_scrape_linkedin", + "title": "Scrape LinkedIn" }
--- pinned/novada_scrape_perplexity +++ observed/novada_scrape_perplexity { "annotations": { "destructiveHint": false, - "description": "Extract the actual AI-generated answer Perplexity returns for a query — by a Perplexity query URL or a raw search term — through a Perplexity-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"perplexity.ai\". This scrapes Perplexity's own live-rendered answer page (the model's actual response text) — it is NOT a web search results list and NOT an indexed-page brand-mention scan.\n\n**Use when:** \"what does Perplexity AI answer for <query>\", \"get Perplexity's generated answer for this perplexity.ai URL\", \"get Perplexity's answer for the search term <term>\".\n**Not for:** A general web/multi-engine search for information (not specifically Perplexity's own generated answer) — use novada_search. Checking whether a brand is mentioned on AI-company indexed public pages (chatgpt.com/perplexity.ai/openai.com/etc.) — use novada_ai_monitor — that tool scans INDEXED PUBLIC PAGES for brand mentions across AI-company domains; it does not fetch a live generated answer for an arbitrary query the way this tool does. A complex question needing cited, multi-source synthesis — use novada_research. Reading one already-known URL's raw page content — use novada_extract. A different platform's structured data (Amazon, LinkedIn, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Perplexity's rendered answer content (the text of its generated response) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 2 verified-working Perplexity operations: answer by a perplexity.ai query URL, or answer by a raw search term (see the `operation` param's description for the exact `params` keys each needs). Every perplexity.ai catalog operation is currently status:\"ok\" — none are excluded for being backend_broken, unlike its sibling chatgpt.com, whose only 2 catalog operations are BOTH backend_broken (verified 2026-07-13, \"submit hangs >120s\") — which is why no novada_scrape_chatgpt tool exists.", + "description": "Extract the actual AI-generated answer Perplexity returns for a query — by a Perplexity query URL or a raw search term — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"perplexity.ai\"). Scrapes Perplexity's own live-rendered answer page (the model's actual response text) — NOT a web search results list and NOT an indexed-page brand-mention scan.\n\n**Use when:** \"what does Perplexity AI answer for <query>\", \"get Perplexity's generated answer for this perplexity.ai URL\", \"get Perplexity's answer for the search term <term>\".\n**Not for:** A general web/multi-engine search for information (not Perplexity's own generated answer) — use novada_search. Checking whether a brand is mentioned on AI-company indexed public pages — use novada_ai_monitor — scans INDEXED PUBLIC PAGES for brand mentions across AI-company domains; does not fetch a live generated answer for an arbitrary query. A complex question needing cited, multi-source synthesis — use novada_research. Reading one already-known URL's raw page content — use novada_extract. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Perplexity's rendered answer content (the text of its generated response) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 2 verified-working Perplexity operations: answer by a perplexity.ai query URL, or answer by a raw search term. Every perplexity.ai catalog operation is currently status:\"ok\" — unlike its sibling chatgpt.com, whose only 2 catalog operations are BOTH backend_broken (verified 2026-07-13, \"submit hangs >120s\") — which is why no novada_scrape_chatgpt tool exists.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which Perplexity AI operation to run. Each requires specific keys in `params`:\n- answer_by_url: params.url (a Perplexity AI query URL, e.g. \"https://www.perplexity.ai/?q=apple\"); optional params.file_name\n- answer_by_search_term: params.search_terms (e.g. \"Today's weather\"); optional params.file_name", + "description": "Perplexity AI operation to run (params keys per entry):\n- answer_by_url: params.url (a Perplexity AI query URL, e.g. \"https://www.perplexity.ai/?q=apple\"); optional params.file_name\n- answer_by_search_term: params.search_terms (e.g. \"Today's weather\"); optional params.file_name", "enum": [ "answer_by_url", "answer_by_search_term" - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_perplexity" + "name": "novada_scrape_perplexity", + "title": "Scrape Perplexity AI" }
--- pinned/novada_scrape_shein +++ observed/novada_scrape_shein { "annotations": { "destructiveHint": false, - "description": "Extract structured SHEIN product data — product details by product ID or product URL — through a SHEIN-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"shein.com\".\n\n**Use when:** \"get SHEIN product details for this product ID\", \"get SHEIN product details for this product URL\".\n**Not for:** A single SHEIN URL you just want read as plain text — use novada_extract. A general web search not scoped to SHEIN — use novada_search. SHEIN keyword or category product-list search (no working operation exists for these today) — use novada_search, or novada_extract on a SHEIN category/search page URL — the 3 catalog operations that would cover this (product list by keyword, by category ID, by category URL) are all backend_broken (submit endpoint hangs 60s+) and deliberately excluded from this tool's enum. A different platform's structured data (Amazon, Walmart, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured product records (title, price, rating, images, etc.) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 2 verified-working SHEIN operations: product lookup by product ID or by product URL (see the `operation` param's description for the exact `params` keys each needs). 3 known backend_broken SHEIN operations — product-list by keyword, by category ID, and by category URL, all failing with a 60s+ submit-endpoint hang — are intentionally NOT in this enum; this tool rejects them before any backend call, unlike novada_scrape(platform=\"shein.com\", ...), which still forwards them with a warning.", + "description": "Extract structured SHEIN product data — product details by product ID or product URL — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"shein.com\").\n\n**Use when:** \"get SHEIN product details for this product ID\", \"get SHEIN product details for this product URL\".\n**Not for:** A single SHEIN URL to read as plain text — use novada_extract. A general web search not scoped to SHEIN — use novada_search. SHEIN keyword or category product-list search (no working operation exists for these today) — use novada_search, or novada_extract on a SHEIN category/search page URL — the 3 ops that would cover this are all backend_broken (60s+ submit hang) and deliberately excluded from this enum. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured product records (title, price, rating, images, etc.) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 2 verified-working SHEIN operations: product lookup by product ID or by product URL. 3 known backend_broken SHEIN operations — product-list by keyword, by category ID, and by category URL, all failing with a 60s+ submit-endpoint hang — are intentionally NOT in this enum; this tool rejects them before any backend call, unlike novada_scrape(platform=\"shein.com\", ...), which still forwards them with a warning.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which SHEIN operation to run. Each requires specific keys in `params`:\n- product_by_id: params.ID (e.g. \"Tween-Girls-Casual-Solid-Color-Criss-Cross-Racerback-Sports-Dress-Kids-p-423721658\"); optional params.flow_retry_num, params.country\n- product_by_url: params.url (product page URL); optional params.flow_retry_num, params.country", + "description": "SHEIN operation to run (params keys per entry):\n- product_by_id: params.ID (e.g. \"Tween-Girls-Casual-Solid-Color-Criss-Cross-Racerback-Sports-Dress-Kids-p-423721658\"); optional params.flow_retry_num, params.country\n- product_by_url: params.url (product page URL); optional params.flow_retry_num, params.country", "enum": [ "product_by_id", "product_by_url" - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_shein" + "name": "novada_scrape_shein", + "title": "Scrape SHEIN" }
--- pinned/novada_scrape_tiktok +++ observed/novada_scrape_tiktok { "annotations": { "destructiveHint": false, - "description": "Extract structured TikTok data — profile info, post/video details, and post lists by profile, hashtag, or search URL — through a TikTok-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"tiktok.com\".\n\n**Use when:** \"get the latest posts from this TikTok profile\", \"get details for this single TikTok video URL\", \"pull TikTok profile info for this URL\", \"search TikTok profiles from this discover/search URL\", \"get posts from this TikTok hashtag/discover page\".\n**Not for:** A single TikTok URL you just want read as plain text — use novada_extract. A general web search not scoped to TikTok — use novada_search. A different platform's structured data (YouTube, Instagram, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured profile/post records (username, follower count, video description, likes, view count, etc.) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 5 verified-working TikTok operations: profile search by list URL, profile by URL, posts by list URL, posts by profile URL, and a single post by URL (see the `operation` param's description for the exact `params` keys each needs). Every tiktok.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured TikTok data — profile info, post/video details, and post lists by profile, hashtag, or search URL — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"tiktok.com\").\n\n**Use when:** \"get the latest posts from this TikTok profile\", \"get details for this single TikTok video URL\", \"pull TikTok profile info for this URL\", \"search TikTok profiles from this discover/search URL\", \"get posts from this TikTok hashtag/discover page\".\n**Not for:** A single TikTok URL to read as plain text — use novada_extract. A general web search not scoped to TikTok — use novada_search. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured profile/post records (username, follower count, video description, likes, view count, etc.) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 5 verified-working TikTok operations: profile search by list URL, profile by URL, posts by list URL, posts by profile URL, and a single post by URL. Every tiktok.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which TikTok operation to run. Each requires specific keys in `params`:\n- profiles_by_search_url: params.search_url (a TikTok search/discover URL listing profiles); optional params.country, params.page_turning\n- profile_by_url: params.url (profile URL, e.g. \"https://www.tiktok.com/@handle\"); optional params.country, params.file_name\n- posts_by_list_url: params.url (a discover/hashtag page URL); optional params.num_of_posts, params.file_name\n- posts_by_profile: params.url (profile URL); optional params.start_date, params.end_date, params.num_of_posts, params.what_to_collect, params.post_type, params.country, params.posts_to_not_include, params.file_name\n- post_by_url: params.url (a single TikTok post/video URL); optional params.country, params.file_name", + "description": "TikTok operation to run (params keys per entry):\n- profiles_by_search_url: params.search_url (a TikTok search/discover URL listing profiles); optional params.country, params.page_turning\n- profile_by_url: params.url (profile URL, e.g. \"https://www.tiktok.com/@handle\"); optional params.country, params.file_name\n- posts_by_list_url: params.url (a discover/hashtag page URL); optional params.num_of_posts, params.file_name\n- posts_by_profile: params.url (profile URL); optional params.start_date, params.end_date, params.num_of_posts, params.what_to_collect, params.post_type, params.country, params.posts_to_not_include, params.file_name\n- post_by_url: params.url (a single TikTok post/video URL); optional params.country, params.file_name", "enum": [ "profiles_by_search_url", "profile_by_url", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_tiktok" + "name": "novada_scrape_tiktok", + "title": "Scrape TikTok" }
--- pinned/novada_scrape_walmart +++ observed/novada_scrape_walmart { "annotations": { "destructiveHint": false, - "description": "Extract structured Walmart data — product details by keyword search, category URL, SKU, zip-code-specific pricing, or direct product URL — through a Walmart-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"walmart.com\".\n\n**Use when:** \"search Walmart for <keyword> and give me prices/ratings\", \"get product listings from this Walmart category URL\", \"what's the price/availability for this Walmart SKU\", \"get this Walmart product's info for a specific zip code\", \"get product details for this Walmart product URL\".\n**Not for:** A single Walmart URL you just want read as plain text — use novada_extract. A general web search not scoped to Walmart — use novada_search. A different platform's structured data (Amazon, SHEIN, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured product records (title, price, rating, availability, SKU, etc.) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 5 verified-working Walmart operations spanning keyword search, category-URL listings, SKU lookup, zip-code-specific pricing, and direct product URL (see the `operation` param's description for the exact `params` keys each needs). `product_by_keyword` requires BOTH `domain` AND `keyword` together; `product_by_category_url` requires ALL THREE of `category_url`, `all`, AND `page_limit` together; `product_by_url_and_zipcode` requires BOTH `url` AND `zipcode` together. Every walmart.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured Walmart data — product details by keyword search, category URL, SKU, zip-code-specific pricing, or direct product URL — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"walmart.com\").\n\n**Use when:** \"search Walmart for <keyword> and give me prices/ratings\", \"get product listings from this Walmart category URL\", \"what's the price/availability for this Walmart SKU\", \"get this Walmart product's info for a specific zip code\", \"get product details for this Walmart product URL\".\n**Not for:** A single Walmart URL to read as plain text — use novada_extract. A general web search not scoped to Walmart — use novada_search. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured product records (title, price, rating, availability, SKU, etc.) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 5 verified-working Walmart operations spanning keyword search, category-URL listings, SKU lookup, zip-code-specific pricing, and direct product URL. `product_by_keyword` requires BOTH `domain` AND `keyword` together; `product_by_category_url` requires ALL THREE of `category_url`, `all`, AND `page_limit` together; `product_by_url_and_zipcode` requires BOTH `url` AND `zipcode` together. Every walmart.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which Walmart operation to run. Each requires specific keys in `params`:\n- product_by_keyword: params.domain (e.g. \"https://www.walmart.com/\") AND params.keyword (BOTH required together); optional params.all, params.page_turning, params.file_name\n- product_by_category_url: params.category_url AND params.all AND params.page_limit (ALL THREE required together); optional params.file_name\n- product_by_url_and_zipcode: params.url AND params.zipcode (BOTH required together, e.g. zipcode \"95829\"); optional params.file_name\n- product_by_sku: params.sku (e.g. \"433078517\"); optional params.all, params.file_name\n- product_by_url: params.url (product page URL); optional params.all, params.file_name", + "description": "Walmart operation to run (params keys per entry):\n- product_by_keyword: params.domain (e.g. \"https://www.walmart.com/\") AND params.keyword (BOTH required together); optional params.all, params.page_turning, params.file_name\n- product_by_category_url: params.category_url AND params.all AND params.page_limit (ALL THREE required together); optional params.file_name\n- product_by_url_and_zipcode: params.url AND params.zipcode (BOTH required together, e.g. zipcode \"95829\"); optional params.file_name\n- product_by_sku: params.sku (e.g. \"433078517\"); optional params.all, params.file_name\n- product_by_url: params.url (product page URL); optional params.all, params.file_name", "enum": [ "product_by_keyword", "product_by_category_url", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_walmart" + "name": "novada_scrape_walmart", + "title": "Scrape Walmart" }
--- pinned/novada_scrape_x +++ observed/novada_scrape_x { "annotations": { "destructiveHint": false, - "description": "Extract structured X (Twitter) data — a single post and profile lookups by username or URL — through an X-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"x.com\".\n\n**Use when:** \"get the text/engagement stats for this X post URL\", \"get this X profile's info by username\", \"get this X profile's info by profile URL\".\n**Not for:** A single X/Twitter URL you just want read as plain text — use novada_extract. A general web search not scoped to X — use novada_search. A different platform's structured data (YouTube, Instagram, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured post/profile records (post text, like/reply/repost counts, profile bio, follower count, etc.) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 3 verified-working X (Twitter) operations: a single post by URL, and profile lookup by username or by profile URL (see the `operation` param's description for the exact `params` keys each needs). Every x.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured X (Twitter) data — a single post and profile lookups by username or URL — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"x.com\").\n\n**Use when:** \"get the text/engagement stats for this X post URL\", \"get this X profile's info by username\", \"get this X profile's info by profile URL\".\n**Not for:** A single X/Twitter URL to read as plain text — use novada_extract. A general web search not scoped to X — use novada_search. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured post/profile records (post text, like/reply/repost counts, profile bio, follower count, etc.) in the chosen output format — same rendering as novada_scrape.\n**Ops:** 3 verified-working X (Twitter) operations: a single post by URL, and profile lookup by username or by profile URL. Every x.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which X (Twitter) operation to run. Each requires specific keys in `params`:\n- post_by_url: params.post_url (e.g. \"https://x.com/user/status/123...\"); optional params.file_name\n- profile_by_username: params.user_name (e.g. \"BillGates\"); optional params.file_name\n- profile_by_url: params.profile_url (e.g. \"https://x.com/BillGates\"); optional params.file_name", + "description": "X (Twitter) operation to run (params keys per entry):\n- post_by_url: params.post_url (e.g. \"https://x.com/user/status/123...\"); optional params.file_name\n- profile_by_username: params.user_name (e.g. \"BillGates\"); optional params.file_name\n- profile_by_url: params.profile_url (e.g. \"https://x.com/BillGates\"); optional params.file_name", "enum": [ "post_by_url", "profile_by_username", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_x" + "name": "novada_scrape_x", + "title": "Scrape X" }
--- pinned/novada_scrape_yandex +++ observed/novada_scrape_yandex { "annotations": { "destructiveHint": false, - "description": "Extract structured Yandex web search SERP data through a Yandex-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"yandex.com\". Returns the raw organic-results SERP, with TLD/language/time-range controls novada_search does not expose, not a generated answer.\n\n**Use when:** \"get the raw Yandex search results (titles, links, ranks) for <query>\", \"search a specific Yandex TLD (params.yandex_domain, e.g. \"yandex.ru\") for Russian/Eastern European content\", \"search Yandex restricted to a time range (params.within)\".\n**Not for:** A general question that just needs an answer or a few good links — use novada_search with engine=\"yandex\" — same engine, but ranked/reranked and answer-oriented instead of a raw SERP dump. A complex question needing cited multi-source synthesis — use novada_research. Reading one already-known URL's page content (not a search results page) — use novada_extract. A different platform's structured data (Amazon, LinkedIn, TikTok, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured organic-result SERP records (title/url/snippet/rank) in the chosen format (markdown/json/csv/excel/html/toon), same rendering as novada_scrape.\n**Operations:** 1 verified-working Yandex operation (web search — see the `operation` param's description for the exact `params` keys it needs, including the required params.yandex_domain TLD selector). The single yandex.com catalog operation is currently status:\"ok\".", + "description": "Extract structured Yandex web search SERP data via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"yandex.com\"). Returns the raw organic-results SERP, with TLD/language/time-range controls novada_search does not expose, not a generated answer.\n\n**Use when:** \"get the raw Yandex search results (titles, links, ranks) for <query>\", \"search a specific Yandex TLD (params.yandex_domain, e.g. \"yandex.ru\") for Russian/Eastern European content\", \"search Yandex restricted to a time range (params.within)\".\n**Not for:** A general question needing just an answer or a few good links — use novada_search with engine=\"yandex\" (ranked/reranked instead of a raw SERP dump). A complex question needing cited multi-source synthesis — use novada_research. Reading one already-known URL's page content — use novada_extract. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured organic-result SERP records (title/url/snippet/rank) in the chosen output format, same rendering as novada_scrape.\n**Ops:** 1 verified-working Yandex operation (web search, requires params.yandex_domain TLD selector). The single yandex.com catalog operation is currently status:\"ok\".", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which Yandex operation to run. Each requires specific keys in `params`:\n- web_search: params.q (search query) and params.yandex_domain (Yandex TLD, e.g. \"yandex.com\", \"yandex.ru\"); optional params.lang, params.location, params.page, params.within (time range)", + "description": "Yandex operation to run (params keys per entry):\n- web_search: params.q (search query) and params.yandex_domain (Yandex TLD, e.g. \"yandex.com\", \"yandex.ru\"); optional params.lang, params.location, params.page, params.within (time range)", "enum": [ "web_search" ], - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_yandex" + "name": "novada_scrape_yandex", + "title": "Scrape Yandex" }
--- pinned/novada_scrape_youtube +++ observed/novada_scrape_youtube { "annotations": { "destructiveHint": false, - "description": "Extract structured YouTube data — video and channel metadata, transcripts, comments, and downloadable video/audio files — through a YouTube-only tool with a closed, typed `operation` enum. Same underlying engine as novada_scrape, pinned to platform=\"youtube.com\".\n\n**Use when:** \"get the transcript/subtitles for this YouTube video\", \"pull the comments on this YouTube video\", \"get channel info for this YouTube channel URL\", \"search YouTube channels for <keyword>\", \"find YouTube videos matching <keyword>, filtered by duration/upload date/attributes\".\n**Not for:** A single YouTube URL you just want read as plain text — use novada_extract. A general web/video search not scoped to YouTube — use novada_search. A different platform's structured data (TikTok, Instagram, etc.) — use novada_scrape with that platform's domain, or its own novada_scrape_<platform> tool.\n**Returns:** Structured video/channel/comment records (title, views, transcript text, comment author/text, channel subscriber count, etc.) plus downloadable video/audio file links, in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.\n**Operations:** 13 verified-working YouTube operations spanning transcripts, video/audio file downloads, channel lookup + search, comments, and video search by keyword/label/filters/playlist/channel (see the `operation` param's description for the exact `params` keys each needs). Every youtube.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", + "description": "Extract structured YouTube data — video/channel metadata, transcripts, comments, downloadable video/audio files — via a closed, typed `operation` enum (same engine as novada_scrape, pinned to platform=\"youtube.com\").\n\n**Use when:** \"get the transcript/subtitles for this YouTube video\", \"pull the comments on this YouTube video\", \"get channel info for this YouTube channel URL\", \"search YouTube channels for <keyword>\", \"find YouTube videos matching <keyword>, filtered by duration/upload date/attributes\".\n**Not for:** A single YouTube URL to read as plain text — use novada_extract. A general web/video search not scoped to YouTube — use novada_search. A different platform's data — use its own novada_scrape_<platform> tool, or novada_scrape(platform=\"<domain>\").\n**Returns:** Structured video/channel/comment records (title, views, transcript text, comment author/text, channel subscriber count, etc.) plus downloadable video/audio file links, in the chosen output format — same rendering as novada_scrape.\n**Ops:** 13 verified-working YouTube operations spanning transcripts, video/audio downloads, channel lookup + search, comments, and video search by keyword/label/filters/playlist/channel. Every youtube.com catalog operation is currently status:\"ok\" — none are excluded for being backend_broken.", "inputSchema": { "properties": { "format": { - "description": "Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.", + "description": "markdown (default table), json (records array), csv/excel/html (spreadsheet), toon (compact pipe-separated).", "enum": [ "json", "csv", - "description": "Max records to return. Default 20, max 100.", + "description": "Max records (default 20, max 100).", "maximum": 100, "minimum": 1, "type": "integer" - "description": "Which YouTube operation to run. Each requires specific keys in `params`:\n- transcript_by_video: params.video_id (e.g. \"LCAY3PGHZyw\"); optional params.subtitles_language, params.subtitles_type (auto_generated|uploader_provided), params.selected_only, params.file_name\n- video_file_by_url: params.url (video URL); optional params.resolution, params.video_codec (avc1|vp9|av01), params.audio_format (opus|m4a), params.bitrate, params.subtitles_language, params.selected_only, params.file_name\n- channel_by_url: params.url (channel URL, e.g. \"https://www.youtube.com/@disneykids\"); optional params.file_name\n- channels_by_keyword: params.keyword; optional params.page_numbers, params.file_name\n- comments_by_video: params.video_id; optional params.replay_times, params.sorting_methods, params.num_of_comments, params.file_name\n- audio_file_by_url: params.url (video URL — downloads its audio track); optional params.bitrate, params.audio_format (opus|m4a), params.kHz, params.is_subtitles, params.selected_format, params.file_name\n- video_by_id: params.video_id; optional params.file_name\n- video_by_url: params.url (video URL); optional params.all_labels, params.file_name\n- videos_by_keyword: params.keyword; optional params.num_of_posts, params.file_name\n- videos_by_filters: params.keyword_search; optional params.attributes, params.type (Videos|Movies), params.duration, params.upload_date, params.num_of_posts, params.file_name\n- videos_by_playlist_url: params.url (playlist/podcast URL); optional params.num_of_posts, params.file_name\n- channel_videos_by_url: params.url (a channel's /videos URL); optional params.sorting_method (Latest|Popular|Oldest), params.start_index, params.num_of_posts, params.file_name\n- videos_by_label: params.search_label (topic tag, e.g. \"music\"); optional params.num_of_posts, params.file_name", + "description": "YouTube operation to run (params keys per entry):\n- transcript_by_video: params.video_id (e.g. \"LCAY3PGHZyw\"); optional params.subtitles_language, params.subtitles_type (auto_generated|uploader_provided), params.selected_only, params.file_name\n- video_file_by_url: params.url (video URL); optional params.resolution, params.video_codec (avc1|vp9|av01), params.audio_format (opus|m4a), params.bitrate, params.subtitles_language, params.selected_only, params.file_name\n- channel_by_url: params.url (channel URL, e.g. \"https://www.youtube.com/@disneykids\"); optional params.file_name\n- channels_by_keyword: params.keyword; optional params.page_numbers, params.file_name\n- comments_by_video: params.video_id; optional params.replay_times, params.sorting_methods, params.num_of_comments, params.file_name\n- audio_file_by_url: params.url (video URL — downloads its audio track); optional params.bitrate, params.audio_format (opus|m4a), params.kHz, params.is_subtitles, params.selected_format, params.file_name\n- video_by_id: params.video_id; optional params.file_name\n- video_by_url: params.url (video URL); optional params.all_labels, params.file_name\n- videos_by_keyword: params.keyword; optional params.num_of_posts, params.file_name\n- videos_by_filters: params.keyword_search; optional params.attributes, params.type (Videos|Movies), params.duration, params.upload_date, params.num_of_posts, params.file_name\n- videos_by_playlist_url: params.url (playlist/podcast URL); optional params.num_of_posts, params.file_name\n- channel_videos_by_url: params.url (a channel's /videos URL); optional params.sorting_method (Latest|Popular|Oldest), params.start_index, params.num_of_posts, params.file_name\n- videos_by_label: params.search_label (topic tag, e.g. \"music\"); optional params.num_of_posts, params.file_name", "enum": [ "transcript_by_video", "video_file_by_url", - "description": "Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.", + "description": "Group outputs in a subfolder, e.g. 'competitor-pricing'.", "maxLength": 30, "type": "string" }, - "description": "Optional. Resume a previous slow task by its task_id instead of submitting a new billable one — same semantics as novada_scrape's task_id.", + "description": "Resume a previous slow task instead of submitting a new billable one.", "pattern": "^[a-zA-Z0-9_\\-\\.]{1,128}$", "type": "string" } - "name": "novada_scrape_youtube" + "name": "novada_scrape_youtube", + "title": "Scrape YouTube" }
--- pinned/novada_search +++ observed/novada_search { "annotations": { "destructiveHint": false, - "description": "Search the web and get clean, ready-to-use content. Returns titles, URLs, snippets — reranked by relevance. For complex questions needing multiple sources, use novada_research instead (it's faster and more thorough).\n\n**Use for:** Current events, finding URLs, fact lookup, competitive research. Set enrich_top=true to auto-extract the #1 result.\n**Not for:** Reading a known URL (novada_extract), multi-source report (novada_research).\n**Tip:** engine='google' (default) is the fastest and most reliable. duckduckgo/yandex are fallbacks and can be markedly slower.\n**Domain filtering:** includeDomains/excludeDomains are applied by injecting `site:domain` operators into the query (not API-side filtering).\n**Project grouping:** Pass `project=\"my-project\"` to group all outputs in a subfolder (e.g. ~/Downloads/novada-mcp/2026-06-26/my-project/). Useful for multi-step research tasks.", + "description": "Search the web for clean, ready-to-use content — titles, URLs, snippets, reranked by relevance. For multi-source questions, use novada_research instead (faster, more thorough).\n\n**Use for:** current events, URL lookup, fact-checking, competitive research. enrich_top=true auto-extracts the #1 result.\n**Not for:** a known URL (novada_extract) or a multi-source report (novada_research).\n**Tip:** engine='google' (default) is fastest/most reliable; duckduckgo/yandex are slower fallbacks.\n**Domain filtering:** includeDomains/excludeDomains inject `site:domain` into the query (not API-side).\n**Project grouping:** `project=\"my-project\"` groups outputs under a subfolder (~/Downloads/novada-mcp/<date>/<project>/).", "inputSchema": { "properties": { "country": { - "description": "When provided, automatically extracts content from the top top_n search result URLs and appends it to each result. Eliminates a separate novada_extract call. Note: adds latency proportional to top_n * extract_latency. Use top_n=1-3 for most queries.", + "description": "Auto-extracts content from the top top_n results and appends it — eliminates a separate novada_extract call. Adds latency proportional to top_n; use top_n=1-3 for most queries.", "properties": { "fields": { "items": { - "description": "Optional project name to group related outputs in a subfolder. E.g. 'france-vs-norway'. (local stdio only; no effect on the hosted endpoint)", + "description": "Group outputs in a subfolder, e.g. 'france-vs-norway'. Local stdio only — no effect on hosted.", "maxLength": 30, "type": "string" }, - "description": "Bias result authority. 'research'/'official': prepend social+PR domains to the query exclusions and boost authoritative sources (*.gov, *.edu, sec.gov, arxiv.org, reuters.com, wikipedia.org, nature.com …). 'social': keep social results (no down-rank). 'news'/'any'/omitted: mild default reranking. Independent of, and combined with, automatic query-intent detection.", + "description": "Bias result authority. 'research'/'official': exclude social+PR domains, boost authoritative sources (*.gov, *.edu, arxiv.org, reuters.com, wikipedia.org). 'social': keep social results (no down-rank). 'news'/'any'/omitted: mild default reranking. Combines with automatic query-intent detection.", "enum": [ "any", "news", - "name": "novada_search" + "name": "novada_search", + "title": "Web Search" }
--- pinned/novada_search_feedback +++ observed/novada_search_feedback { "annotations": { "destructiveHint": false, - "description": "Record search-result quality so future ranking can learn from it. Returns a thank-you/echo confirmation with an agent_instruction.\n\n**Best for:** After a novada_search call, tell Novada which result URLs were useful and rate the set (good/ok/bad). The signal biases future ranking.\n**Params:** search_id (the prior search's id), query, rating ('good'|'ok'|'bad'), useful_urls? (results you clicked/cited, max 50), note? (what was missing).\n**Scope:** In-memory feedback store, per-process — resets when the MCP server restarts. Nothing is persisted to disk. Auth-free (no API key needed).", + "description": "Record search-result quality so future ranking can learn from it. Returns a thank-you/echo confirmation with an agent_instruction.\n\n**Best for:** after a novada_search call, report which result URLs were useful and rate the set (good/ok/bad) — biases future ranking.\n**Params:** search_id (prior search's id), query, rating ('good'|'ok'|'bad'), useful_urls? (max 50), note? (what was missing).\n**Scope:** in-memory, per-process — resets on restart. Nothing persists. Auth-free.", "inputSchema": { "properties": { "format": { - "name": "novada_search_feedback" + "name": "novada_search_feedback", + "title": "Search Feedback" }
--- pinned/novada_session_stats +++ observed/novada_session_stats { "annotations": { "destructiveHint": false, - "description": "Return per-process / per-session usage telemetry: tool-call counts, the last-N calls, and process uptime.\n\n**Best for:** \"What have I called this session?\" / debugging an agent loop / seeing which Novada tools dominate usage.\n**Returns:** session_started, uptime, total_calls, per-tool counts (high→low), and the most-recent calls (newest first, capped by recent_limit).\n**Scope:** In-memory, per-process — resets when the MCP server restarts. Nothing is persisted to disk and nothing leaves the process. Auth-free (no API key needed).", + "description": "Per-process / per-session usage telemetry: tool-call counts, the last-N calls, and process uptime.\n\n**Best for:** \"what have I called this session?\" / debugging an agent loop / seeing which tools dominate usage.\n**Returns:** session_started, uptime, total_calls, per-tool counts (high→low), most-recent calls (newest first, capped by recent_limit).\n**Scope:** in-memory, per-process — resets on restart. Nothing persists or leaves the process. Auth-free.", "inputSchema": { "properties": { "format": { - "name": "novada_session_stats" + "name": "novada_session_stats", + "title": "Session Stats" }
--- pinned/novada_setup +++ observed/novada_setup { "annotations": { "destructiveHint": false, - "description": "The onboarding concierge and first-run front door of the Novada MCP. Call this FIRST when starting out, or whenever a tool reports a missing/invalid key.\n\n**What it does:**\n1. **Validates your key** — makes one cheap, authoritative account read (wallet balance) to confirm your key actually works, and shows your balance. No synthetic per-product probes, no credit cost.\n2. **Guides you if you have no key** — tells you to register at the Novada dashboard (free credits included for testing), where to copy your API key, and the exact config snippet for Claude Code / Claude Desktop / Cursor / VS Code / Windsurf.\n3. **Orients you** — a plain-language list of the core things you can do (search, extract, scrape, browser, account) plus the add-ons.\n\n**Three states it reports:** key present + valid (ready) · key present but rejected (fix it) · no key yet (register + free credits). Output also includes server_version (the running package version).\n\n**Auth-free by design:** this is the tool that helps you GET a key, so a missing key is the normal first-run state — it guides, it never errors. Includes a machine-usable agent_instruction so an AI knows exactly what to tell the user next.\n\n**Unified key:** NOVADA_API_KEY covers search, extract, unblock, scraper, research, crawl, map, browser and proxy auto-provisioning. NOVADA_BROWSER_WS and NOVADA_PROXY_ENDPOINT are optional add-ons that need no separate key.", + "description": "The onboarding concierge and first-run front door. Call this FIRST when starting out, or whenever a tool reports a missing/invalid key.\n\n**What it does:**\n1. **Validates your key** — one cheap account read (wallet balance) confirms it works and shows your balance. No per-product probes, no credit cost.\n2. **Guides you if keyless** — register at the Novada dashboard (free credits included), copy your API key, get exact config snippets for Claude Code/Desktop/Cursor/VS Code/Windsurf.\n3. **Orients you** — a plain-language list of core capabilities (search, extract, scrape, browser, account) plus add-ons.\n\n**Reports one of 3 states:** valid key (ready) · invalid key (fix it) · no key (register). Output includes server_version.\n**Auth-free by design:** a missing key never errors here — it guides, with a machine-usable agent_instruction for what to tell the user next.\n**Unified key:** NOVADA_API_KEY covers search/extract/unblock/scraper/research/crawl/map/browser/proxy auto-provisioning. NOVADA_BROWSER_WS/NOVADA_PROXY_ENDPOINT are optional add-ons needing no separate key.", "inputSchema": { "properties": {}, "type": "object" - "name": "novada_setup" + "name": "novada_setup", + "title": "Setup & Configuration" }
--- pinned/novada_site_copy +++ observed/novada_site_copy { "annotations": { "destructiveHint": false, - "description": "Copy an entire docs site or site section to disk as clean markdown — one .md file per page — and return a COMPACT manifest, not the page bodies. Use when you need a whole knowledge base on disk (offline docs ingest, RAG corpus, full-site mirror).\n\n**Discovery (in order):** (1) llms.txt / llms-full.txt if present (canonical, flat page list), (2) sitemap.xml, (3) scoped same-host BFS drained to completion. Path filters (select_paths/exclude_paths) and same-host are always enforced.\n**Best for:** \"Copy all of docs.x.com\", building a local docs corpus, ingesting an llms.txt index.\n**Not for:** A single page (use novada_extract), a handful of pages inline (use novada_crawl — it returns bodies), URL discovery only (use novada_map).\n**Output:** Each page is written to ~/Downloads/novada-mcp/<date>/<project|domain>/site-copy/<slug>.md as it completes. A manifest.json records {url,file,title,word_count,depth,bytes,status} per page plus run meta. The tool RETURNS a compact summary + the manifest path — Read the .md files or manifest.json, do not expect inline content.\n**Scale:** max_pages default 200, hard max 1000. Drains the in-scope queue until empty or the ceiling is hit.\n**Key rule:** Files are streamed to disk; the response is intentionally small. After it completes, Read manifest.json then open the specific .md files you need.", + "description": "Copy an entire docs site/section to disk as clean markdown — one .md file per page — returning a COMPACT manifest, not page bodies. Use for a whole knowledge base on disk (offline docs ingest, RAG corpus, full-site mirror).\n\n**Discovery order:** (1) llms.txt/llms-full.txt if present, (2) sitemap.xml, (3) scoped same-host BFS to completion. select_paths/exclude_paths and same-host are always enforced.\n**Best for:** \"copy all of docs.x.com\", a local docs corpus, ingesting an llms.txt index.\n**Not for:** a single page (novada_extract), a few pages inline (novada_crawl), URL discovery only (novada_map).\n**Output:** each page streams to `~/Downloads/novada-mcp/<date>/<project|domain>/site-copy/<slug>.md`; `manifest.json` records {url,file,title,word_count,depth,bytes,status} per page. The tool returns a compact summary + manifest path, not inline content — read the .md files or manifest.json after it completes.\n**Scale:** max_pages default 200, hard max 1000, drained until the queue is empty or the ceiling is hit.", "inputSchema": { "properties": { "exclude_paths": { - "name": "novada_site_copy" + "name": "novada_site_copy", + "title": "Site Copy" }
--- pinned/novada_static_ip_mgmt +++ observed/novada_static_ip_mgmt { "annotations": { "destructiveHint": true, - "description": "Manage static ISP IPs on the account. Wraps /v1/static_house/* developer-api endpoints.\n\n**Actions:** \"open\" = purchase new static IPs (WRITE, requires confirm:true). \"renew\" = renew existing IPs (WRITE, requires confirm:true). \"export\" = export filtered IP list (read-only). \"list\" = paginated IP list (read-only).\n**Behavior:** Without confirm:true on \"open\"/\"renew\", returns a preview and does NOT hit the API.\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", + "description": "Manage static ISP IPs (wraps /v1/static_house/* developer-api endpoints).\n\n**Actions:** \"open\" = purchase new IPs (WRITE, gated by approval_token). \"renew\" = renew existing IPs (WRITE, gated by approval_token). \"export\"/\"list\" = read-only.\n**Behavior:** call \"open\"/\"renew\" once WITHOUT `approval_token` to get a preview plus a fresh token (valid 10 minutes) — this does NOT hit the API. Re-call with the EXACT SAME parameters plus that token to execute. `confirm: true` is a deprecated no-op.\n**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).", "inputSchema": { "properties": { "action": { - "description": "Action to perform. \"open\" = purchase new static IPs (WRITE, requires confirm). \"renew\" = renew existing IPs (WRITE, requires confirm). \"export\" = export filtered IP list. \"list\" = list static IPs with pagination.", + "description": "Action to perform. \"open\" = purchase new static IPs (WRITE, requires approval_token). \"renew\" = renew existing IPs (WRITE, requires approval_token). \"export\" = export filtered IP list. \"list\" = list static IPs with pagination.", "enum": [ "open", "renew", + "approval_token": { + "description": "Two-step approval token, required to execute \"open\"/\"renew\". Omit on the first call to receive a preview + a fresh approval_token (valid 10 minutes). Re-call with the EXACT SAME parameters plus this field set to that token to execute. Never invent a value — an invented or stale token is rejected.", + "minLength": 1, + "type": "string" + }, "confirm": { "const": true, - "description": "REQUIRED for \"open\" and \"renew\" execution. Pass `true` ONLY after the human user has approved. If omitted, returns a dry-run preview without hitting the API.", + "description": "DEPRECATED — ignored. Setting this alone no longer authorizes \"open\"/\"renew\" execution (closed 2026-09, finding F2-2: an agent could self-supply confirm:true with no prior human-reviewed preview, including a PURCHASE — see F2-eval R9). Use approval_token instead: call once WITHOUT approval_token to receive a preview and a token, then call again with the identical parameters plus approval_token.", "type": "boolean" }, "duration": { - "name": "novada_static_ip_mgmt" + "name": "novada_static_ip_mgmt", + "title": "Static IP Manager" }
--- pinned/novada_verify +++ observed/novada_verify { "annotations": { "destructiveHint": false, - "description": "Use when you have a factual claim and need to check if it's supported by web sources. Runs 3 parallel searches (supporting, skeptical, fact-check angles) and returns a verdict: supported / unsupported / contested / insufficient_data.\n\n**Best for:** Checking claims before citing them, cross-validating research findings, detecting misinformation.\n**Not for:** Open-ended questions (use novada_research), reading a specific URL (use novada_extract).\n**Note:** Verdict is signal-based (search balance), not a definitive ruling. Confidence 0–100 indicates certainty.", + "description": "Check whether a factual claim is supported by web sources. Runs 3 parallel searches (supporting, skeptical, fact-check angles) and returns a verdict: supported / unsupported / contested / insufficient_data.\n\n**Best for:** checking claims before citing them, cross-validating findings, detecting misinformation.\n**Not for:** open-ended questions (novada_research) or reading a specific URL (novada_extract).\n**Note:** signal-based (search balance), not definitive. Confidence 0–100 indicates certainty.", "inputSchema": { "properties": { "claim": { - "name": "novada_verify" + "name": "novada_verify", + "title": "Fact Verification" }
Current tools
Show all 38 tool fingerprints
novada_account
novada_ai_monitor
novada_browser
novada_browser_flow
novada_capture_apikey
novada_crawl
novada_discover
novada_extract
novada_ip_whitelist
novada_map
novada_monitor
novada_proxy
novada_proxy_account_create
novada_proxy_account_list
novada_research
novada_scrape
novada_scrape_amazon
novada_scrape_bing
novada_scrape_duckduckgo
novada_scrape_facebook
novada_scrape_github
novada_scrape_google
novada_scrape_instagram
novada_scrape_linkedin
novada_scrape_perplexity
novada_scrape_shein
novada_scrape_tiktok
novada_scrape_walmart
novada_scrape_x
novada_scrape_yandex
novada_scrape_youtube
novada_search
novada_search_feedback
novada_session_stats
novada_setup
novada_site_copy
novada_static_ip_mgmt
novada_verify
Watch this server yourself
If you run this server, put the proxy in front of it. It pins these exact fingerprints on first connect and stops the session if they move.
npx -y mcp-pin@0.2.3 -- <your novada-mcp command>
Or subscribe to this page's RSS feed to be told when it changes.
Badge
The badge states one fact about time and nothing else. It never claims a server is safe.
[](https://mcp-pin.gautamkhosla.com/servers/b40d445a9d1392cf.html)