Tell Solari to sign in to a site automatically using a connected password manager.
`domain` is the site, e.g. 'github.com'. `manager` is the NAME of a connected password manager (see solari_browser_autologin_status) — omit it to mean 'remember the session but ask a human for a fresh login'. `item` is an optional 'Vault/Item' path for when one site has several logins; omit it to match by site.
This only says WHICH credential to use — it never handles the credential itself.

Check whether this account can sign in to websites automatically, and get a direct setup link if it cannot.
Call this when a task will clearly need a login, BEFORE you start — if nothing is set up you can tell the user once, up front, with a link, instead of interrupting them mid-run. Also worth calling if a login keeps needing a human.
Returns the connected password managers, the sites already configured, and `setupUrl`. If `configured` is false, SHOW setupUrl TO THE USER: it opens the page where they connect a password manager. You cannot do that step for them — it needs a credential that must never pass through you — but the link removes all the guesswork.

Wait for the human to finish the sign-in you requested with solari_browser_login. Blocks until they are done, the link expires, or timeoutMs elapses. Returns only a status — never anything the user typed. On 'completed' the session is yours again, on the same page, still signed in, and you can carry on where you left off. On 'expired' or 'timeout' the user did not finish: ask if they still want to, and call solari_browser_login again for a fresh link rather than retrying this.

Click on the page: give a CSS selector, or x/y viewport coordinates (e.g. from a screenshot).

Close a browser session and release it.

Start a Solari cloud browser session. Use this whenever you need to browse the web. Returns a sessionId for the other solari_browser_* tools.
mode defaults to 'stealth' — the anti-bot hardened pool. Just call this with no arguments and you get it; you do NOT need to ask for stealth explicitly. Stealth is the right default for the open web: ordinary sites work fine on it, and it is what keeps bot-detection from blocking the session.
Pass mode:'fast' ONLY for a site you already know does not fingerprint or block automation (internal tools, localhost, your own app, plain docs/API pages) and you want the lower-latency pool. If a page in fast mode returns a block/captcha/challenge, close the session and retry with mode:'stealth'.
captcha auto-solving is ALSO on by default (it follows the pool: on for stealth, off for fast). Pass captcha:false to turn it off — solving a challenge costs money and adds latency, so switch it off for sites you know never challenge.
proxy ('smart' | country code like 'us') REQUIRES stealth, as does captcha; both are rejected if you ask for them explicitly in fast mode. recording gives an rrweb replay.

Evaluate a JavaScript expression on the page and return its JSON-serialized result.

Press a key in the browser session (e.g. 'Enter', 'Escape', 'ArrowDown', 'PageDown'). Chords use '+' (e.g. 'Control+a').

Get this session signed in. Call it the moment you hit a login form, a 2FA prompt, or anything asking for a password — you must never handle credentials yourself.
It tries the account's connected password manager FIRST: if one is set up for this site, you are signed in automatically and NO human is involved — the reply says signedIn:true and you simply carry on. Otherwise it falls back to asking a human.
Two ways to call it:
HOT — pass `sessionId` when you are ALREADY on a login wall mid-task. The user gets a live view of the exact page you are on and types into it; you resume on that same page.
COLD — pass `profileName` when you know a task will need a login and no session is open yet. The user signs in once in a profile editor, and every later solari_browser_create({profileId}) starts already authenticated. Prefer this when you can: nobody has to be watching mid-run. The profile is created if it does not exist.
Pass exactly one of the two. Either way, SHOW THE RETURNED URL TO THE USER, then call solari_browser_await_login.
In the HOT case your access to that session is REVOKED while the handoff is open — deliberately, so you cannot observe what they type — and the link expires in 5 minutes. Cold links last longer and revoke nothing, because there is no session yet.
`reason` is required and is shown to the user — say plainly which site is asking and what for, because they are being asked to type a password on your say-so.

Navigate the browser session to a URL. Returns final url, title and HTTP status.

List saved browser profiles for this account. A profile is a stored signed-in state (cookies + localStorage) that solari_browser_create({profileId}) replays, so the session starts already logged in.
Check here FIRST when a task will need a login: if a profile for that site already exists, use it and no human is involved at all. `version` is 1 and `populated` is false for a profile nobody has signed into yet — that one still needs solari_browser_login({profileName}).

Read the current page. format 'text' (default) returns visible text; 'links' returns clickable links {text, href}; 'html' returns HTML with scripts/styles stripped. Large output is truncated with an explicit marker.

Get the session-replay URL for a browser session created with recording: true. May 404 for a few seconds right after close — retry.

Save this session's signed-in state (cookies + localStorage) into an existing profile, so future sessions start already logged in and no human is needed again. Pass the profileId to overwrite.
ONLY do this when the user has asked you to remember the login. It is deliberately not automatic: a saved profile holds live session cookies, which bypass 2FA — it is a credential store, and it should exist because someone chose it. If they have not said so, ask first.
Returns what was captured (cookie count and origins) so the user can see what they just persisted.

Screenshot the browser session's current page (JPEG). fullPage captures the whole scrollable page (may be downscaled by the client if very tall).

Type text into the page. Optionally focus a CSS selector first. clear:true replaces the field's existing value (otherwise text is appended at the caret). pressEnter submits.

Click the desktop at (x, y).

Re-attach to an existing sandbox or desktop by id (e.g. across restarts); resumes it if paused. The kind is read from the gateway, so you don't need to know it. Returns { sessionId, kind, state }.

Create a GUI desktop (microVM). Returns sessionId + streamUrl (noVNC).

Run a shell command in a session. Returns { stdout, stderr, exitCode }.

Get a public preview URL for an in-guest port (e.g. a dev server on :3000). Returns { url, token? }.

Press a key or chord (e.g. 'Return', 'ctrl+c') on the desktop.

Destroy a session by id.

List the org's live VMs — BOTH sandboxes and desktops. Each entry is labelled with its `kind`; `registered:true` means this MCP session already holds a handle so the other tools accept its sessionId directly (otherwise call solari_connect first). Optional kind/state filters.

List a guest directory.

Launch an application on the desktop. Returns its pid.

Read an in-guest text file.

Run code (default Python) in a session's kernel. Returns results incl. structured charts.

Start a shell command in the background (non-blocking). Returns its cmdId; the process keeps running after this call.

Create a headless sandbox (microVM). Returns its sessionId.

Capture the desktop screen as a PNG image.

Type text into the focused desktop element.

Write a text file into the guest.


Single-call account & billing dashboard. Composes wallet balance, plan balances, capture logs, and health entitlements based on the `section` param.

**Best for:** "What's my Novada account status?" / "How much do I have left?" / one-shot health snapshot.
**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.
**section="balance":** Master wallet currency balance.
**section="usage":** Paginated wallet transaction / usage history. Pass start_time/end_time/page/page_size.
**section="plans":** Per-product plan balances (residential/isp/mobile/datacenter/static/capture). Pass products[] to filter.
**section="traffic":** Daily proxy traffic consumption across products. Pass start_time/end_time/products[].
**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).
**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.

Inclusive end date YYYY-MM-DD (usage/traffic sections only).

Output format. 'card' (default): human-readable markdown card — scannable headline, status table with icons, expired plans highlighted. 'json': clean flat structured object for programmatic use — no data.data nesting, human-readable values, errors[] aggregated.

1-based page index (usage section only).

Page size, max 200 (usage section only).

Subset of products to query (plans/traffic sections only). plans: residential|isp|mobile|datacenter|static|capture. traffic: residential|isp|mobile|datacenter|static.

Which account data to fetch. 'summary' (default): full dashboard — wallet balance + plan balances + recent capture logs + health entitlements (proxy/browser). 'balance': master wallet balance (currency). 'usage': paginated wallet usage/transaction history. 'plans': per-product plan balances (residential/isp/mobile/datacenter/static/capture). 'traffic': daily proxy traffic consumption.

Inclusive start date YYYY-MM-DD (usage/traffic sections only).

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.

Searches 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.

**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.
**Best for:** Checking whether a brand appears on AI-company public docs/blogs/changelogs; competitive presence on indexed pages of AI platforms.
**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).
**Output:** Per-domain sentiment (positive/neutral/negative), key claims from indexed snippets, competitor mentions, source URLs.
**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.

Brand or product name to search for on AI-company public web domains. E.g. 'novada', 'firecrawl', 'stripe'.

Domain groups to search (each key → a set of AI-company public web domains, e.g. 'chatgpt' → chatgpt.com + openai.com). This does NOT query the live AI models — it searches their indexed public pages. Options: 'chatgpt', 'perplexity', 'grok', 'claude', 'gemini'. Default: ['chatgpt', 'perplexity', 'grok'].

Topic filter to narrow the search. Only the FIRST entry is used; the rest are ignored. E.g. ['pricing']. Default: general brand mentions.

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.

**Best for:** Login flows, paginated content, interactive SPAs, form submission, visual verification, scraping behind user interactions.
**Not for:** Simple page reading (use novada_extract), structured data (use novada_scrape), raw HTML (use novada_extract with format="html").
**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).
**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.
**Auth:** NOVADA_API_KEY (auto-provisions Browser API credentials). NOVADA_BROWSER_WS is optional — set it to override auto-provision.
**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.)
**Constraint:** close_session and list_sessions must be the only action in the call — they cannot be combined with other actions.

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.

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.

JavaScript expression to evaluate in the page context. Max 2000 chars. ASCII only. Must not make network requests.

Milliseconds to wait (100–30000). Example: {action: "wait", ms: 2000}

CSS selector to wait for (e.g. '#results'). If omitted, waits for ms milliseconds.

Alias for ms — prefer ms for clarity. Example: {action: "wait", timeout: 2000}

CSS selector to hover over.

Key to press. E.g. 'Enter', 'Tab', 'Escape', 'ArrowDown', 'Space'. Follows Playwright key names.

Optional CSS selector to focus before pressing the key.

CSS selector for the <select> element.

The option value (or label text) to select.

ISO 2-letter country code (e.g. 'us', 'gb'). NOTE: accepted but NOT yet applied — the browser exit node is not geo-routed by this param today. Do not rely on it for geo-restricted platforms.

Optional session ID for persistent browser state across calls. Reuses the same browser page (cookies, localStorage, login state). Warm reuse is ~5x faster (~1.5s vs ~8s cold start). Sessions expire after 10 minutes of inactivity.

Total timeout for all actions in ms. Default 60000.

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.

**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.
**Use novada_browser_flow when:** you specifically need the simplified flow API, or you have an existing workflow built around it.
**Actions:** click, scroll, wait, type, screenshot — up to 20 per call.
**Sessions:** Pass session_id to reuse the same browser instance across calls (preserves cookies, login state). Sessions expire after 10 minutes of inactivity.
**Not for:** Single URL reading without interaction (use novada_extract), structured platform data (use novada_scrape).

Ordered sequence of browser actions to execute. Each action has a type and optional selector/value/delay.

Delay in milliseconds before executing this action. Max 30000ms.

CSS selector for click/type actions. Not required for scroll/wait/screenshot.

Action type to perform on the page.

Text to type (for 'type' action) or scroll direction (for 'scroll': 'up'|'down').

Optional 2-letter ISO 3166-1 country code for geo-targeting the browser session (e.g. 'us', 'gb', 'de').

Optional session ID for sticky sessions. When provided, the same browser session is reused across calls — preserving cookies, login state, and localStorage. Sessions expire after 10 minutes of inactivity.

The URL to open in the cloud browser. Must be a publicly accessible HTTP/HTTPS URL.

Get or reset the Capture API key for the account. Wraps POST /v1/capture/get_apikey and /v1/capture/reset_apikey.

**Actions:** "get" = retrieve the current capture/scraper API key (read-only). "reset" = regenerate the key — DESTRUCTIVE, invalidates the old key, requires confirm:true.
**Behavior:** Without confirm:true on "reset", returns a warning preview and does NOT call the API.
**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).

Action to perform. 'get': retrieve the current capture/scraper API key (read-only). 'reset': regenerate the API key — DESTRUCTIVE, invalidates the old key.

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.

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/**").

**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.

**Best for:** Competitive content analysis, extracting a handful of related pages inline (returns page bodies directly).
**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).

Common mistakes:
- Do NOT set max_pages > 10 for large sites — crawl time scales linearly (~1.4s/page). At max_pages=20, expect 28s minimum.
- Do NOT use novada_crawl to fetch one page — use novada_extract which is faster and simpler.
- Use select_paths to restrict to relevant URL patterns before setting max_pages high.

When to use:
- You need content from a small set of related pages on one domain (e.g., all /docs/* pages, up to 20).
- You need BFS discovery of related content under a path prefix and want bodies inline.

Not for:
- Single-URL extraction — use novada_extract.
- Finding all URLs on a site without downloading content — use novada_map.
- Copying a whole docs site or knowledge base to disk — use novada_site_copy (handles hundreds of pages, returns a manifest).

**Rendering:** The `render` param defaults to "auto" (tries static first, escalates to JS rendering on detection) — it is not static-only.

Glob patterns for URL paths to skip entirely. '*' matches within a path segment, '**' matches across segments. E.g. ['/blog/**', '/changelog/**'].

Output format. 'markdown': human-readable (default). 'json': structured object for programmatic agent use.

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.

Rendering mode. 'auto': uses static, escalates to render on first JS-heavy page detection. 'static': always static. 'render': always render (slower, handles JS sites).

Glob patterns to restrict crawled URL paths. '*' matches within a path segment, '**' matches across segments, '?' matches one char. E.g. ['/docs/**', '/api/**'].

Crawl traversal order. 'bfs' (default): breadth-first — visits all pages at current depth before going deeper, good for broad discovery. 'dfs': depth-first — follows links deeply before backtracking, good for exploring specific paths.

List all available Novada tools with name, description, category, and status.

**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.
**Returns:** Markdown table grouped by category — Content Retrieval, Scraping & Verification, Proxy, Browser & Rendering, Account & Billing, Health & Discovery.
**Filter:** Pass category to narrow to a specific group (e.g. category="Proxy" to see all proxy tools).
**Status legend:** active = available now. Output also includes server_version (the running package version).

**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.

Optional category filter. One of: 'Content Retrieval', 'Scraping & Verification', 'Proxy', 'Browser & Rendering', 'Account & Billing', 'Health & Discovery'. Omit to list all tools.

Content Retrieval
Scraping & Verification
Proxy
Browser & Rendering
Account & Billing
Health & Discovery

Optional platform domain to look up (e.g. 'amazon.com', 'tiktok.com'). When provided, returns all operations for that platform from the scraper catalog — free, no API call, no credit cost. Mutually exclusive with category: if both are provided, platform takes priority.

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.

**CRITICAL — Format Selection:**
- `format="markdown"` (default): full-page content for reading/analysis. Best for articles, docs.
- `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".
- `format="html"`: raw HTML source (truncated at 100K chars by default; pass max_chars to adjust). Best for debugging or custom DOM parsing.
- `clean=true`: strip nav/sidebar, return main content only (~15K chars vs ~100K full page).

Common mistake: using markdown when you need specific data — use `format="json"` + `fields=["price","title"]` instead.

**Use for:** Reading pages, batch-extracting search results, pulling structured fields (price, author, date). Works on anti-bot pages automatically.
**Not for:** URL discovery (novada_map), multi-page crawl (novada_crawl), platform data like Amazon/LinkedIn (novada_scrape is richer).
**Key rule:** Leave render="auto" (default). Only set render="render" for known JS-heavy SPAs. Auto mode is 15-100x faster on static sites.
By default returns full page content for maximum information. Add clean=true to extract only the main article body (strips nav/footer/ads).

**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.
**Results auto-saved:** Every extraction saves to `~/Downloads/novada-mcp/YYYY-MM-DD/` automatically. File path shown at the top of each response.
**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.

Set true to extract only main article content (strips nav, footer, ads). Default false returns full page markdown for maximum content coverage.

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.

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.

Output format. 'markdown' (default): structured readable output. 'text': plain text. 'html': raw HTML (truncated at 100K chars by default; pass max_chars to adjust). 'json': structured JSON object with typed fields — best for programmatic agent consumption.

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.

Optional project name to group related outputs in a subfolder. E.g. 'france-vs-norway'. (local stdio only; no effect on the hosted endpoint)

Optional query for relevance context. Helps the calling agent focus on relevant sections.

Rendering mode. 'auto' (default): tries static first, escalates if JS-heavy. 'static': static HTML only. 'js' (or 'render'): force JS rendering via Web Unblocker. 'browser': force Browser API CDP (requires NOVADA_BROWSER_WS).

URL or array of URLs (max 10) to extract. Batch mode processes in parallel. Accepted shapes: single string, array of strings, or use the urls alias.

Array of URLs to extract in parallel (max 10). Alias for url when passing multiple URLs. Use for batch research workflows extracting from several pages in one call. Returns a structured markdown document with one labeled section per URL (### [1/N] url). Single url param still returns a single markdown document.

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.

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.

Manage IP whitelist for proxy products. Supports add/list/delete/remark for Residential (1), Unlimited (4), and Static ISP (5) products.

**Actions:** "add" (WRITE — requires confirm), "list" (read-only), "del" (WRITE — requires confirm), "remark" (update note on entry).
**Required:** action, product (1=Residential, 4=Unlimited, 5=Static ISP).
**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).

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.

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.

End datetime filter for action="list" (e.g. "2026-12-31").

Whitelist entry ID (required for action="remark").

IP address to whitelist (required for action="add"). For action="list", optional filter by specific IP.

Comma-separated list of IPs to remove (required for action="del").

Lock filter for action="list". 0=Unlocked, 1=Locked.

REQUIRED. Product type code as string: 1=Residential, 4=Unlimited, 5=Static ISP.

Optional remark/note. Used by action="add" and action="remark".

Start datetime filter for action="list" (e.g. "2026-01-01").

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.

**Best for:** Site structure discovery, finding the correct subpage URL when you extracted the wrong page, pre-flight before novada_crawl or novada_extract.
**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).
**Note:** Limited results on JavaScript SPAs — will flag this in output.

Link-hops from root to follow. Default 2. Higher = more pages found but slower.

Detect changes on a web page over time. Extracts content, computes a hash, compares with previous check. Returns changed/unchanged + field-level diffs.

**Use for:** E-commerce price monitoring, stock availability tracking, content change detection, competitive pricing alerts.
**How:** First call = baseline. Subsequent calls compare against baseline and report changes. Pass fields=["price","availability"] for field-level diffs with % change.
**Not for:** One-time extraction (novada_extract), full crawl (novada_crawl).

⚠ **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.

Specific fields to track for changes (e.g. ['price', 'availability', 'rating']). When provided, change detection focuses on these fields. Without fields, tracks full page content hash.

Output format. 'markdown' (default): human-readable change report. 'json': structured object for programmatic agent use.

URL to monitor for changes. E.g. a product page, pricing page, or any content page.

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.

**Best for:** When you need a specific country/city IP, sticky sessions for multi-step workflows, or testing geo-restricted content.
**Not for:** Web page extraction (use novada_extract — proxy is automatic), web search (use novada_search).
**Formats:** "url" for Node.js/Python, "env" for shell variables, "curl" for CLI requests.
**Requires:** NOVADA_PROXY_ENDPOINT env var. NOVADA_PROXY_USER/PASS are auto-fetched from your account using NOVADA_API_KEY if not explicitly set.

**Proxy type guide (pass as `type` param):**
- `residential` — strongest anti-bot bypass, real home ISP IPs, best for geo-restricted / protected pages; escalate HERE when blocked
- `isp` — looks like a home user (ISP-assigned), best for social media / ecommerce; note: ignores country param
- `datacenter` — fastest and cheapest, best for non-anti-bot targets and high-volume scraping
- `mobile` — 4G/5G device IPs, best for mobile-targeted content and app APIs
- `static` — same dedicated ISP IP every request (requires session_id + country), best for account-management workflows
- `dedicated` — exclusive clean datacenter IP not shared with others (requires session_id), best for high-trust platforms

**Escalation path when blocked:** datacenter → isp → residential

City name for city-level targeting. Requires country to be set.

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.

Output SHAPE of the returned proxy config — not a data content format. 'url': proxy URL string (default). 'env': shell export commands. 'curl': curl --proxy flag.

Session ID for sticky routing — same session_id returns same IP across requests.

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).

residential isp datacenter mobile static dedicated

⚠ WRITE — Create a proxy sub-account. Two-step confirm gate.

**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.

**Best for:** Provisioning a team-member or per-project sub-account against your master plan.
**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.
**Wire format:** multipart/form-data (per developer-api spec).
**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).

REQUIRED. Sub-account name. 3-64 chars, alphanumeric + underscore/hyphen only.

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.

Optional data cap in GB, as a string (e.g. "10" = 10 GB). Omit for no cap. Server expects string, not number.

REQUIRED. Sub-account password. 8-64 chars. Will be sent to server in multipart body — caller decides storage.

REQUIRED. Product type code as string: 1=Residential, 2=Rotating ISP, 3=Rotating Datacenter, 4=Unlimited, 7=Unblocker, 9=Mobile. Must match a product provisioned on the account.

Optional note/label for this sub-account.

REQUIRED. Account status: "1" = active (default), "-3" = personal disabled.

List proxy sub-accounts. Wraps developer-api POST /v1/proxy_account/list.

**Best for:** Auditing sub-accounts, finding account names before rotating credentials.
**Params:** product (REQUIRED — same codes as create), page, limit (max 200), status? ("1"|"-3"), account? (exact-match filter).
**Wire format:** multipart/form-data.
**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).

Optional filter — exact-match account name. (API field is `account`, not `username`.)

Entries per page, max 200. (API field is `limit`, not `page_size`.)

1-based page index.

Optional filter: "1" = active, "-3" = disabled. Omit for both.

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.

**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.
**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.
**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.
**Depth:** "quick" (3 queries), "deep" (6), "comprehensive" (8-9), "auto" (default: picks quick or deep by question length — never comprehensive).
**Key advantage:** Agents call this ONCE instead of orchestrating search→extract manually. Saves tokens, time, and complexity.
**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.
**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.

'quick'=3 searches, 'deep'=6, 'comprehensive'=8-9, 'auto' (default)=picks quick or deep by question length — never comprehensive.

ISO date YYYY-MM-DD. Return results published on or before this date.

Optional focus area to guide sub-query generation. E.g. 'technical implementation', 'business impact', 'recent news only'.

Optional project name to group related outputs in a subfolder. E.g. 'france-vs-norway'. (local stdio only; no effect on the hosted endpoint)

REQUIRED — provide either `question` or `query`. Alias for `question` — use either.

REQUIRED — provide either `question` or `query`. The research question to answer (min 5 characters).

ISO date YYYY-MM-DD. Return results published on or after this date.

Limit results to a time window. 'day'=last 24h, 'week'=last 7 days, 'month'=last 30 days, 'year'=last 12 months.

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.

**Best for:** E-commerce product data, social posts/comments, job listings, reviews, real estate, market data.
**Not for:** General web pages not in the platform list — use novada_extract for arbitrary URLs instead.
**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).
**Example:** platform="amazon.com", operation="amazon_product_keywords", params={keyword:"iphone 16", num:5}
**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.
**Discover platforms:** Read the `novada://scraper-platforms` MCP resource for the complete platform list with operation IDs and required params.
**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).
**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.

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).

Max records to return. Default 20, max 100.

Scraping operation ID. Examples: 'amazon_product_keywords', 'amazon_product_asin', 'tiktok_posts_url', 'linkedin_company_information_url', 'github_repository_repo-url', 'twitter_profile_username', 'youtube_video_search_label'. Read novada://scraper-platforms resource for the complete list with required params.

Operation-specific parameters. E.g. { keyword: 'iphone 16', num: 5 } for keyword search, { url: 'https://...' } for URL-based ops, { asin: 'B09...' } for ASIN lookup.

Platform domain to scrape. E.g. 'amazon.com', 'reddit.com', 'tiktok.com', 'linkedin.com', 'google.com'.

Optional. When provided, skips submitting a new scrape task and fetches the result of this existing task_id directly — no new billable task is created. Use this to resume a previous novada_scrape call that returned status:processing without incurring a duplicate charge. platform and operation are still required (used for display only when resuming).

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".

**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".
**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.
**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).
**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.

Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.

Which Amazon operation to run. Each requires specific keys in `params`:
- product_by_asin: params.asin (e.g. "B0BWBK8F37")
- product_by_url: params.url (product page URL); optional params.zip_code
- products_by_keywords: params.keyword; optional params.max_pages, params.min_price, params.max_price
- bestsellers: params.url (a Best Sellers list page URL); optional params.max_pages
- reviews_by_url: params.url (product page URL)
- seller_by_url: params.url (seller page URL)
- listings_by_keyword: params.keyword and params.domain (e.g. "https://www.amazon.com"); optional params.max_pages
- global_product_by_url: params.url
- global_product_by_category_url: params.url (category/search URL) and params.maximum; optional params.sort_by, params.get_sponsored
- global_product_by_keyword_and_brand: params.keyword, params.brands, params.max_pages

Operation-specific parameters for the selected `operation`. E.g. { asin: "B0BWBK8F37" } for product_by_asin, { url: "https://www.amazon.com/dp/..." } for product_by_url/reviews_by_url/seller_by_url/bestsellers/global_product_by_url, { keyword: "wireless earbuds" } for products_by_keywords.

Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.

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.

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.

**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>".
**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.
**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.
**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.

Which Bing operation to run. Each requires specific keys in `params`:
- web_search: params.q (search query); optional params.device, params.country, params.lg (language), params.location, params.start, params.num, params.safe, params.filters
- 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
- 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")
- shopping: params.q (search query); optional params.country, params.lg, params.start, params.filters

Operation-specific parameters for the selected `operation`. E.g. { q: "wireless earbuds" } for web_search/videos/news/shopping; all four operations share the same q-driven query shape.

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.

**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".
**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.
**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.
**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".

Which DuckDuckGo operation to run. Each requires specific keys in `params`:
- 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)

Operation-specific parameters for the selected `operation`. E.g. { q: "wireless earbuds", kl: "us-en" } for web_search.

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".

**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".
**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.
**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.
**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.

Max records to return. Default 20, max 100.

Which Facebook operation to run. Each requires specific keys in `params`:
- profile_by_url: params.url (personal/page homepage URL); optional params.file_name
- events_by_search_url: params.url (an activity/events search URL); optional params.file_name
- event_by_url: params.url (a single event URL); optional params.file_name
- events_by_list_url: params.url (a page's /events list URL); optional params.upcoming_events, params.file_name
- post_by_url: params.url (post URL); optional params.file_name
- comments_by_post_url: params.url (post URL); optional params.get_all_replies, params.limit_records, params.file_name

Operation-specific parameters for the selected `operation`. E.g. { url: "https://www.facebook.com/handle" } for profile_by_url/post_by_url/comments_by_post_url/event_by_url/events_by_list_url/events_by_search_url.

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".

**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".
**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.
**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.
**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.

Which GitHub operation to run. Each requires specific keys in `params`:
- repository_by_url: params.url (repository URL, e.g. "https://github.com/gin-gonic/gin"); optional params.file_name
- repository_details_by_url: params.url (repository URL, e.g. "https://github.com/QwenLM/Qwen"); optional params.file_name
- 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

Operation-specific parameters for the selected `operation`. E.g. { url: "https://github.com/gin-gonic/gin" } for repository_by_url/repository_details_by_url, { search_url: "https://github.com/search?q=ai&type=repositories" } for repositories_by_search_url.

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.

**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>".
**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.
**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.
**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.

Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.

Which Google operation to run. Each requires specific keys in `params`:
- 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)
- 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
- 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
- ai_mode: params.q (search query); optional params.gl (country), params.location, params.uule (encoded location)
- hotels: params.q, params.domain, params.check_in_date, params.check_out_date (YYYY-MM-DD); optional params.country, params.hl, params.adults
- jobs: params.q (search query); optional params.domain, params.country, params.hl, params.location, params.start, params.num
- videos: params.q (search query); optional params.domain, params.country, params.hl, params.start, params.num
- shopping: params.keyword (e.g. "pizza"); optional params.country
- maps_by_location: params.country, params.keyword, params.merchant_limit (max merchants to return); optional params.lat, params.long, params.zl (zoom level)
- maps_by_place_id: params.place_id (Google Place ID)
- maps_by_cid: params.cid (Google Maps CID)
- maps_by_url: params.url (a Google Maps place URL)
- maps_reviews_by_url: params.url (Google Maps place URL); optional params.limit (days of reviews to fetch, default 30)

Operation-specific parameters for the selected `operation`. E.g. { q: "wireless earbuds" } for web_search/ai_mode, { keyword: "pizza" } for shopping, { url: "https://www.google.com/maps/place/..." } for maps_by_url/maps_reviews_by_url, { place_id: "ChIJ..." } for maps_by_place_id.

Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.

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.

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".

**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".
**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.
**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.
**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.

Which Instagram operation to run. Each requires specific keys in `params`:
- comments_by_post_url: params.posturl (post/reel URL); optional params.file_name
- reels_by_profile_url: params.url (profile URL); optional params.num_posts, params.uncrawled_posts, params.start_date, params.end_date, params.file_name
- reel_by_url: params.url (a single reel URL); optional params.file_name
- 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
- post_by_url: params.posturl (a single post URL); optional params.file_name
- profile_by_url: params.profileurl; optional params.file_name
- profile_by_username: params.username; optional params.file_name

Operation-specific parameters for the selected `operation`. E.g. { posturl: "https://www.instagram.com/p/..." } for comments_by_post_url/post_by_url, { profileurl: "https://www.instagram.com/handle/", resultsLimit: 10 } for posts_by_profile, { username: "handle" } for profile_by_username.

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".

**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".
**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.
**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.
**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.

Which LinkedIn operation to run. Each requires specific keys in `params`:
- 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
- jobs_by_search_url: params.listing_url (a LinkedIn JOBS SEARCH RESULTS URL — returns multiple listings); optional params.page_limit, params.file_name
- job_by_url: params.position_url (a single LinkedIn job POSTING URL); optional params.file_name
- company_by_url: params.url (LinkedIn company page URL); optional params.file_name

Operation-specific parameters for the selected `operation`. E.g. { location: "Germany", keyword: "product manager" } for jobs_search, { listing_url: "https://www.linkedin.com/jobs/search?..." } for jobs_by_search_url, { position_url: "https://www.linkedin.com/jobs/view/..." } for job_by_url, { url: "https://www.linkedin.com/company/..." } for company_by_url.

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.

**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>".
**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.
**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.
**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.

Max records to return. Default 20, max 100.

Which Perplexity AI operation to run. Each requires specific keys in `params`:
- answer_by_url: params.url (a Perplexity AI query URL, e.g. "https://www.perplexity.ai/?q=apple"); optional params.file_name
- answer_by_search_term: params.search_terms (e.g. "Today's weather"); optional params.file_name

Operation-specific parameters for the selected `operation`. E.g. { url: "https://www.perplexity.ai/?q=apple" } for answer_by_url, { search_terms: "Today's weather" } for answer_by_search_term.

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".

**Use when:** "get SHEIN product details for this product ID", "get SHEIN product details for this product URL".
**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.
**Returns:** Structured product records (title, price, rating, images, etc.) in the chosen format (markdown/json/csv/excel/html/toon) — same rendering as novada_scrape.
**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.

Which SHEIN operation to run. Each requires specific keys in `params`:
- 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
- product_by_url: params.url (product page URL); optional params.flow_retry_num, params.country

Operation-specific parameters for the selected `operation`. E.g. { ID: "Tween-Girls-...-p-423721658" } for product_by_id, { url: "https://us.shein.com/...html" } for product_by_url.

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".

**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".
**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.
**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.
**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.

Output format. 'markdown' (default): structured table. 'json': structured records array. 'csv'/'excel'/'html': spreadsheet-ready. 'toon': token-optimized pipe-separated format.

Which TikTok operation to run. Each requires specific keys in `params`:
- profiles_by_search_url: params.search_url (a TikTok search/discover URL listing profiles); optional params.country, params.page_turning
- profile_by_url: params.url (profile URL, e.g. "https://www.tiktok.com/@handle"); optional params.country, params.file_name
- posts_by_list_url: params.url (a discover/hashtag page URL); optional params.num_of_posts, params.file_name
- 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
- post_by_url: params.url (a single TikTok post/video URL); optional params.country, params.file_name

Operation-specific parameters for the selected `operation`. E.g. { url: "https://www.tiktok.com/@handle" } for profile_by_url/posts_by_profile/post_by_url, { search_url: "https://www.tiktok.com/search?q=..." } for profiles_by_search_url.

Optional project name to group related outputs in a subfolder. E.g. 'competitor-pricing'.

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.

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".

**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".
**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.
**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.
**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.

Which Walmart operation to run. Each requires specific keys in `params`:
- 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
- product_by_category_url: params.category_url AND params.all AND params.page_limit (ALL THREE required together); optional params.file_name
- product_by_url_and_zipcode: params.url AND params.zipcode (BOTH required together, e.g. zipcode "95829"); optional params.file_name
- product_by_sku: params.sku (e.g. "433078517"); optional params.all, params.file_name
- product_by_url: params.url (product page URL); optional params.all, params.file_name

Operation-specific parameters for the selected `operation`. E.g. { domain: "https://www.walmart.com/", keyword: "shoes" } for product_by_keyword, { sku: "433078517" } for product_by_sku, { url: "https://www.walmart.com/ip/..." } for product_by_url/product_by_url_and_zipcode.

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".

**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".
**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.
**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.
**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.

Which X (Twitter) operation to run. Each requires specific keys in `params`:
- post_by_url: params.post_url (e.g. "https://x.com/user/status/123..."); optional params.file_name
- profile_by_username: params.user_name (e.g. "BillGates"); optional params.file_name
- profile_by_url: params.profile_url (e.g. "https://x.com/BillGates"); optional params.file_name

Operation-specific parameters for the selected `operation`. E.g. { post_url: "https://x.com/user/status/123" } for post_by_url, { user_name: "BillGates" } for profile_by_username, { profile_url: "https://x.com/BillGates" } for profile_by_url.

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.

**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)".
**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.
**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.
**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".

Max records to return. Default 20, max 100.

Which Yandex operation to run. Each requires specific keys in `params`:
- 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)

Operation-specific parameters for the selected `operation`. E.g. { q: "wireless earbuds", yandex_domain: "yandex.com" } for web_search.

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".

**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".
**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.
**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.
**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.

Which YouTube operation to run. Each requires specific keys in `params`:
- 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
- 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
- channel_by_url: params.url (channel URL, e.g. "https://www.youtube.com/@disneykids"); optional params.file_name
- channels_by_keyword: params.keyword; optional params.page_numbers, params.file_name
- comments_by_video: params.video_id; optional params.replay_times, params.sorting_methods, params.num_of_comments, params.file_name
- 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
- video_by_id: params.video_id; optional params.file_name
- video_by_url: params.url (video URL); optional params.all_labels, params.file_name
- videos_by_keyword: params.keyword; optional params.num_of_posts, params.file_name
- 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
- videos_by_playlist_url: params.url (playlist/podcast URL); optional params.num_of_posts, params.file_name
- 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
- videos_by_label: params.search_label (topic tag, e.g. "music"); optional params.num_of_posts, params.file_name

Operation-specific parameters for the selected `operation`. E.g. { video_id: "LCAY3PGHZyw" } for transcript_by_video/comments_by_video/video_by_id, { url: "https://www.youtube.com/watch?v=..." } for video_file_by_url/audio_file_by_url/video_by_url, { keyword: "proxy" } for channels_by_keyword/videos_by_keyword.

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).

**Use for:** Current events, finding URLs, fact lookup, competitive research. Set enrich_top=true to auto-extract the #1 result.
**Not for:** Reading a known URL (novada_extract), multi-source report (novada_research).
**Tip:** engine='google' (default) is the fastest and most reliable. duckduckgo/yandex are fallbacks and can be markedly slower.
**Domain filtering:** includeDomains/excludeDomains are applied by injecting `site:domain` operators into the query (not API-side filtering).
**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.

ISO date YYYY-MM-DD. Return results published on or before this date.

Search engine to use. 'google': best general relevance + fastest (default, recommended). 'duckduckgo': privacy-focused (markedly slower). 'yandex': Russian/Eastern European content.

Auto-extract full content from the top result. Shorthand for extract_options.top_n=1. Adds ~2-4s latency. Default: false.

Exclude results from these domains. E.g. ['reddit.com', 'quora.com']. Max 10.

When true, hard-drop social and press-release results (facebook, linkedin, x/twitter, instagram, tiktok, reddit, quora, medium, prnewswire, businesswire, globenewswire, prweb, einpresswire) from the response after fetching.

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.

Output format. 'markdown' (default): structured readable output. 'json': structured JSON object with typed fields — best for programmatic agent consumption.

Number of top search results to auto-extract. Default: 3. Max: 10.

Output format. 'markdown': human-readable (default). 'json': structured object for programmatic agent use.

Only return results from these domains. E.g. ['github.com', 'arxiv.org']. Max 10.

Optional project name to group related outputs in a subfolder. E.g. 'france-vs-norway'. (local stdio only; no effect on the hosted endpoint)

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.

ISO date YYYY-MM-DD. Return results published on or after this date.

Limit results to a time window. 'day'=last 24h, 'week'=last 7 days, 'month'=last 30 days, 'year'=last 12 months.

Record search-result quality so future ranking can learn from it. Returns a thank-you/echo confirmation with an agent_instruction.

**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.
**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).
**Scope:** In-memory feedback store, per-process — resets when the MCP server restarts. Nothing is persisted to disk. Auth-free (no API key needed).

Output format. 'markdown' (default): human-readable confirmation. 'json': structured object for programmatic agent use.

Optional free-text note — what was missing, what would have ranked better, etc.

The query text that produced the results being rated.

Overall quality of the result set. 'good': relevant + sufficient. 'ok': partially useful. 'bad': irrelevant or missing what you needed.

The id of the search this feedback is about. Use the search_id returned by a prior novada_search call (or any stable identifier you used for the query).

URLs from the result set that were actually useful. Drives future ranking — list the results you clicked or cited. Max 50.

Return per-process / per-session usage telemetry: tool-call counts, the last-N calls, and process uptime.

**Best for:** "What have I called this session?" / debugging an agent loop / seeing which Novada tools dominate usage.
**Returns:** session_started, uptime, total_calls, per-tool counts (high→low), and the most-recent calls (newest first, capped by recent_limit).
**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).

Output format. 'markdown' (default): human-readable report. 'json': structured object for programmatic agent use.

How many of the most-recent tool calls to include in the recent_calls list. Default 10, max 100. Counts and totals always cover the whole session regardless of this value.

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.

**What it does:**
1. **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.
2. **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.
3. **Orients you** — a plain-language list of the core things you can do (search, extract, scrape, browser, account) plus the add-ons.

**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).

**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.

**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.

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).

**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.
**Best for:** "Copy all of docs.x.com", building a local docs corpus, ingesting an llms.txt index.
**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).
**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.
**Scale:** max_pages default 200, hard max 1000. Drains the in-scope queue until empty or the ceiling is hit.
**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.

Glob patterns for URL paths to skip entirely. '*' matches within a path segment, '**' matches across segments. E.g. ['/blog/**', '/changelog/**'].

When true, also copy pages on subdomains of the root host. Default false (same-host only).

BFS link-hops from root when no llms.txt/sitemap is found. Default 5. Ignored for llms.txt/sitemap discovery (which is flat).

Maximum pages to copy. Default 200, hard max 1000. The run drains the in-scope queue until empty or this ceiling is hit — it is a safety bound, not a target.

Optional project name to group outputs under ~/Downloads/novada-mcp/<date>/<project>/site-copy/. Defaults to the site domain. (local stdio only; no effect on the hosted endpoint)

Rendering mode for each page fetch. 'auto' (default): static, escalate to render on JS-heavy detection. 'static': always static. 'render': always render (slower).

Glob patterns to restrict copied URL paths. '*' matches within a path segment, '**' matches across segments, '?' matches one char. E.g. ['/docs/**', '/api/**']. Same-host is always enforced.

Manage static ISP IPs on the account. Wraps /v1/static_house/* developer-api endpoints.

**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).
**Behavior:** Without confirm:true on "open"/"renew", returns a preview and does NOT hit the API.
**Auth:** NOVADA_DEVELOPER_API_KEY (falls back to NOVADA_API_KEY).

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.

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.

Required for "open" and "renew". Activation/renewal period: "week" or "month".

Required for "open". IP type: "normal" (Standard) or "premium" (Premium).

Auto-renew filter for "list"/"export". 1=Yes, -1=No.

Search filter for "list"/"export". Searches remarks, order number, or IP.

Entries per page for "list" action. Default 50, max 200.

Required for "open". Number of static IPs to activate.

Page number for "list" action. Default 1.

Required for "open". Area/region code. Also optional filter for "list" and "export".

Required for "renew". Comma-separated list of IPs to renew.

Filter for "list"/"export". ""=All, "1"=In use, "2"=Expired, "3"=Released.

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.

**Best for:** Checking claims before citing them, cross-validating research findings, detecting misinformation.
**Not for:** Open-ended questions (use novada_research), reading a specific URL (use novada_extract).
**Note:** Verdict is signal-based (search balance), not a definitive ruling. Confidence 0–100 indicates certainty.

The factual claim to verify (min 10 chars)

Optional context to narrow the search (e.g. 'as of 2024', 'in the US')


Read one or more webpages as clean markdown with source metadata.

Use it after web_search when a result needs full-page content, or call it directly with known URLs.

Maximum characters to extract per page (must be a positive number, default: 12000).

URLs to read. Batch multiple URLs in one call.

Search the web and return ranked search results with titles, URLs, highlights, and source labels.

Use it for current facts, docs, news, people, companies, and other web questions.
Follow promising URLs with web_fetch when you need full markdown content.

Backward-compatible alias for numResults. Number of search results to return (default: 5, range: 1-15).

Natural language search query. Describe the ideal page, not just keywords.


List films, shows or games by score, by release date or by current popularity. Use this when there is no specific title to look up: best rated, newest, what people are looking at now. Filter by genre with a single name such as Horror, Comedy or Action. Sorting by score returns the all-time ranking, which is dominated by older titles: combine with a genre to narrow it. Scores come back on their own scales, 100 for critics and 10 for users. Paging is approximate: Metacritic does not order tied entries stably, so an entry can appear on two consecutive pages. Deduplicate by slug rather than counting rows.

Single genre name, such as Horror. Omit for all genres.

Which catalogue to list.

How many rows to return.

How many rows to skip, for paging.

'score' is the critic ranking, 'recent' is by release date, 'popular' is current attention.

Pass as 'offset' for the next page. Tied entries are not ordered stably upstream, so deduplicate by slug across pages.

Critic score, out of 100. Not comparable to user_score without rescaling.

Age rating as published, such as R or TV-MA.

Identifier to pass to get_title and get_reviews, with 'kind'.

Metacritic page. Show this when citing the entry.

Audience score, out of 10. Not comparable to metascore without rescaling.

id kind title slug year release_date rating metascore user_score source_url

How many entries match upstream, which is the size of what this samples.

kind sort genre results total_available offset next_offset notes

Browse rankings

Read individual reviews of a Metacritic entry, from critics or from users. Get the slug and kind from search_titles first. Filter with 'sentiment' to read only what praised or panned it, which Metacritic groups itself. Metacritic returns a fixed sample rather than the full list, so 'total_available' is usually far larger than what comes back, and there is no way to page past the sample. Critic reviews carry the publication and a link to the original article: quote them with both. Critic scores run to 100 and user scores to 10, so do not average the two together.

Which catalogue the entry belongs to. Pass it back with the slug.

How many reviews to return from the sample Metacritic publishes.

How many of the sampled reviews to skip. The sample itself cannot be paged past.

Which slice to read. Metacritic groups reviews this way itself.

Identifier from search_titles, such as 'the-matrix'.

'critic' is the professional press, 'user' is the audience.

Pass as 'offset' for the next page.

Scale for this review's score: 100 for critics, 10 for users.

Who ran it. Name it when quoting.

Excerpt as published, truncated if long.

Original article. Link it when quoting.

quote score max publication author url date

Metacritic page these reviews belong to. Cite it when an article link is missing.

How many reviews Metacritic counts in total. Usually far more than it serves here.

slug kind source_url source sentiment reviews total_available offset next_offset notes

Read reviews

Read one Metacritic entry by slug and kind, both from search_titles. Sections are opt-in because a full entry is large: 'basic' and 'scores' are the default and cover most questions. 'scores' fetches the critic and audience breakdowns, each with its own scale, so never compare the two numbers directly. Sections gate the payload: asking for 'scores' alone returns no description, and 'basic' alone returns no scores. 'networks' lists the broadcasters of a show; 'where_to_watch' costs an extra request and covers films and shows only. A long description paginates: when 'truncated' is true, call again with 'offset' set to 'next_offset'.

Character budget for the description.

Where to resume the description.

Which parts to return. Each extra section beyond the default costs a request.

basic scores awards production networks where_to_watch

One tally per ceremony. Metacritic publishes no per-category detail.

Awards body, such as 'Academy Awards, USA'.

Null when the source records no win.

Scale this score is on: 100 for critics, 10 for users.

Metacritic's own wording for the verdict.

Runtime in minutes for a film, or the length of a typical episode for a show.

IMDb identifier, usable to cross-reference other sources.

Broadcasters, for shows.

Pass as 'offset' to read the rest.

Length of the full description.

Read an entry

Search Metacritic for films, shows and games by title. Returns one compact row per match, carrying the critic Metascore, so a question about the critical verdict needs no second call. Search rows carry no audience score: use get_title for that, or browse_titles, which does return it. Use the slug and kind with get_title for the full entry, or with get_reviews for what critics wrote. There is no paging: 'limit' is the only lever, and results always start from the most relevant match. This searches titles only. It cannot find an entry from a plot detail, a person or a studio.

Restrict results to one catalogue. Metacritic searches all three at once.

How many rows to return.

Title or part of one, for example 'the matrix'.

How many entries Metacritic counted. For a query of several words it counts entries matching any one of them, so the number is far larger than the useful matches and should not be read as a match count.

Search Metacritic