MCP server intelligence profile

crawlio-browser MCP Server

MCP server that gives AI full control of a live Chrome browser via CDP, with 145 tools for framework-aware intelligence, evidence analysis, and SEO auditing. Connects to your existing Chrome via an extension, enabling interaction with dynamic and authenticated web pages

Local OnlyOfficial distributionCrawlio-app
Verified cleanNpm · 1.11.0

Our scanner tested version 1.11.0 without proving a finding in the methods exercised. This is not a guarantee that every deployment is secure.

1Distribution channel
7Independently observed tools
0Linked remote endpoints
AvailableVersion intelligence

Install and connect

Installation and connection instructions are shown only when supported by retained package, repository, or endpoint evidence.

Install crawlio-browser from npm

Version 1.11.0 declares 1 executable entrypoint.

npm install --save-exact crawlio-browser@1.11.0
npx -y -p crawlio-browser@1.11.0 crawlio-browser
MCP client configuration example
{
  "mcpServers": {
    "crawlio-browser": {
      "command": "npx",
      "args": [
        "-y",
        "-p",
        "crawlio-browser@1.11.0",
        "crawlio-browser"
      ]
    }
  }
}

Identity

Canonical slugcrawlio-browser-dd1316dfDeploymentLocal Only
Canonical packagenpm:crawlio-browserRepositoryCrawlio-app/crawlio-browser
First publishedLatest release
Last security verificationAug 22, 2026Classification confidence90%
PublicationPublishedOfficial distributionYes

Distributions

ChannelIdentifierCurrent versionVersionsSource
npmcrawlio-browser1.11.01Repository

Current release

PackageVersionPublished / observedInventorySecurity scan
npmcrawlio-browser1.11.0CurrentSep 5, 20267 toolsSucceeded · 0 resources · 0 promptsVerified clean
Enterprise protection

Continuously monitor this MCP for security risk

Independently scan the exact version your agents use, receive alerts when its risk changes, and investigate every finding with retained version evidence.

  • Independent exact-version security scans
  • Continuous release and vulnerability monitoring
  • Risk-change alerts with capability context
  • Historical evidence and API exports
Custom pricingContact salesTailored to your organization, integrations, data needs, and support requirements.

Current version evidence

Provenanceartifact_hash_verifiedSignature
MCP SDK@modelcontextprotocol/sdk Artifact SHA-256e421d67788c379fd72ac1beb0d76a291a68b59d8f0c145381c19b3e7496d5044
Scannermcp-proof-engine 0.1.0Scan completedAug 22, 2026
Security rating50 / 100Methodologyversion-rating-1.0
Executable entrypoints
[
  "crawlio-browser"
]
Rating reasons
[
  "security_contact_or_disclosure"
]
0Proven
510Clean
6Inconclusive
0Flaky
0Errors

Current protocol inventory

2025-06-18Negotiated protocol
crawlio-browserServer-reported name
1Capability groups
Aug 22, 2026Observed

Tools 7

ToolCategoryAnnotationsRisk
cancel_jobCancel a running background execute job by jobId — terminates its sandbox worker. No-op if the job already finished.
Input schema
{
  "type": "object",
  "properties": {
    "jobId": {
      "type": "string",
      "description": "Job id to cancel"
    }
  },
  "required": [
    "jobId"
  ]
}
connect_tabPin a browser tab for subsequent commands and start CDP capture. Three modes: (1) provide a URL: with the optional tabs grant Crawlio reuses a match, otherwise it creates a fresh owned tab; (2) provide a tabId to adopt a specific existing tab (tabs grant required); (3) no args to discover and pin the active tab (tabs grant required). Pass background:true to avoid stealing the user's active tab/window focus.
Input schema
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "URL to open — reuses a match when tab metadata is granted, otherwise creates a fresh owned tab"
    },
    "tabId": {
      "type": "number",
      "description": "Specific tab ID to connect to (use list_tabs to discover IDs)"
    },
    "background": {
      "type": "boolean",
      "description": "Connect + drive the tab without activating it or focusing its window (no focus-steal). The tab opens/loads in the background; input and screenshots use CDP so they work without foreground focus."
    }
  }
}
executeExecute JavaScript code with access to the browser bridge, Crawlio HTTP client, and smart object. Use search() first to discover available commands and their parameters. IMPORTANT WARNINGS: - smart.screenshot() does NOT exist. For screenshots: bridge.send({ type: 'take_screenshot' }). - For structured page evidence, prefer smart.extractPage() — runs 7 ops in parallel with typed gaps[]. - capture_page returns a ~1KB shaped summary. For raw data, use stop_network_capture or get_console_logs. - Use smart.waitForIdle() instead of sleep(). Use smart.scrollCapture() instead of manual scroll loops. - Scope large snapshots with smart.snapshot({ compact: true, maxDepth: 8, selector: '#main' }); use { interactive: true } for controls only. - For cross-page navigation, use smart.navigate(url) — never location.href = "..." (breaks CDP). Available in scope: - bridge.send(command, timeout?) — send command to browser extension via WebSocket command must have a `type` field matching a command name (e.g. { type: 'list_tabs' }) - crawlio.api(method, path, body?) — generic HTTP to ControlServer e.g. await crawlio.api('GET', '/status') e.g. await crawlio.api('POST', '/start', { url: 'https://example.com' }) e.g. await crawlio.api('POST', '/export', { format: 'zip', destinationPath: '/tmp/site.zip' }) e.g. await crawlio.api('PATCH', '/settings', { settings: { maxConcurrent: 8 } }) Returns { status: number, data: unknown } - crawlio.getStatus() — shortcut for GET /status - crawlio.startCrawl(url) — shortcut for POST /start - crawlio.getEnrichment(url?) — shortcut for GET /enrichment - crawlio.getCrawledURLs(params?) — shortcut for GET /crawled-urls - crawlio.postEnrichment(url, data) — shortcut for POST /enrichment/bundle - sleep(ms) — async wait (max 30s) - TIMEOUTS — per-command timeout constants - compileRecording(session, { name, description? }) — compile RecordingSession to SKILL.md Returns { skillMarkdown, name, pageCount, interactionCount } - ocrScreenshot(opts?) — extract text from current page via macOS Vision.framework OCR (macOS only) opts: { fullPage?: boolean, selector?: string } Returns { regions: [{ text, confidence, bounds }], regionsLimited? } - saveArtifact(name, contents, opts?) — persist bulk data straight to disk (host-side), bypassing the return value. Use this for large extractions instead of returning megabytes: accumulate rows in the sandbox, then write them. name: safe relative path (e.g. 'hfs/cross_ref.ndjson'); contents: string (objects are JSON-stringified); opts: { append?: boolean } to stream in chunks. Writes under ~/.crawlio/artifacts (CRAWLIO_ARTIFACT_DIR). Returns { path, bytes }. Ideal pattern: authed in-page fetch via bridge → accumulate → saveArtifact → return { path, bytes }. - smart — auto-waiting wrappers and framework-specific data accessors: smart.evaluate(expr) → {result, type} — access .result for value. Never JSON.parse() the return directly. smart.click(selector, opts?) — poll + click + 500ms settle (accepts CSS or snapshot [ref=X]) smart.type(selector, text, opts?) — poll + type + 300ms settle smart.navigate(url, opts?) — navigate + 1000ms settle smart.waitFor(selector, timeout?) — poll until actionable smart.snapshot(opts?) — capture accessibility snapshot. opts: { interactive?: boolean, compact?: boolean, maxDepth?: number, selector?: string }. smart.scrollCapture(opts?) — state-aware page scroll with screenshots, stops at page bottom smart.waitForIdle(timeout?) — wait for DOM mutations to settle (500ms quiet window) smart.extractPage(opts?) — capture_page + perf + security + fonts + meta + accessibility + mobileReadiness. Returns { capture, performance, security, fonts, meta, accessibility, mobileReadiness, gaps[] }. opts: { trace: true } adds _trace. smart.comparePages(urlA, urlB, opts?) — navigate to each URL, run extractPage(), return { siteA, siteB, scaffold }. scaffold has dimensions[], sharedFields, missingFields, metrics. smart.finding({ claim, evidence, sourceUrl, confidence, method, dimension? }) — create validated Finding, accumulate in session. Confidence auto-capped if dimension has active gap with reducesConfidence. smart.findings() — return all accumulated Finding[] from current session. smart.clearFindings() — reset accumulated findings and session gaps. smart.detectTables(opts?) — find repeating data patterns in the page. Native <table> elements first (strategy 'table-rows'), then class-frequency div-soup scan with geometric filters (strategy 'sibling-repeated-blocks'). Returns TableCandidate[] (selector, score, rowCount, sampleText, confidence 0..1, strategy, warnings[]). smart.extractTable(selector, opts?) — extract structured data from a container. Native tables get thead-derived column names + <name>_url companions; div-soup gets semantic link-first naming. Returns { columns, rows, totalRows, truncated }. opts: { maxRows: 200 }. smart.detectSections(opts?) — perceive page structure: depth-capped SectionNode tree from semantic tags, ARIA landmarks, data-component/testid attrs, and PascalCase/BEM class hints. Each node: role, source, name, selector (+ selectorVerified), box, inViewport, interactiveCount, textLength, headings, children. Emits SELECTORS, never [ref=eN] handles — compose with bridge.send({ type: 'browser_snapshot', selector }) for fresh interaction refs inside a region. opts: { maxDepth: 2, maxSections: 40 }. smart.waitForNetworkIdle(opts?) — wait for all network requests to settle (CDP-level, catches fetch/XHR/images/CSS/fonts). Returns { status, elapsed }. opts: { timeout: 15000, idleTime: 500 }. smart.extractData(opts?) — compound: detectTables + extractTable + JSON-LD. Returns { tables, structuredData, url }. smart.parseTrackingPixels() — parse captured network data for tracking pixel fires (Facebook, GA4, TikTok, LinkedIn, Pinterest). Returns { totalPixelFires, vendors, pixels, events, unrecognizedTrackingUrls }. smart.validateTracking() — validate tracking events against per-vendor parameter schemas (Facebook 18 standard + GA4 recommended). Returns { events, issues, errorCount, warningCount, infoCount, isHealthy }. Each issue has severity (error/warning/info), code, message, recommendation, and optional parameter. smart.inspectDataLayer() — inspect tracker runtime state via CDP (fbq queue, GA4 dataLayer, GTM containers, TikTok ttq). Returns DataLayerState with null for absent trackers. No content script needed. smart.detectDuplicates() — detect duplicate pixel fires grouped by vendor+pixelId+eventName+URL. Excludes PageView (legitimate SPA behavior). Returns DuplicateCluster[] with count and timestamps. smart.detectTechnologies(opts?) — detect technologies via fingerprint matching against CDP signals (headers, scripts, JS globals, meta, cookies, URL). Returns TechnographicResult { technologies[], categories, totalDetected, highConfidenceCount, signalsUsed }. Each technology has numeric confidence (0-100, additive), version, matchedSignals[]. opts: { confidenceThreshold: 1 }. smart.diffSnapshots(before?) — Myers diff current ARIA snapshot against baseline. If before omitted, uses last cached snapshot. Returns { diff, additions, removals, unchanged, changed }. Framework namespaces (injected based on detected framework): smart.react.{getVersion,getRootCount,hasProfiler,isHookInstalled} smart.vue.{getVersion,getAppCount,getConfig,isDevMode} smart.angular.{getVersion,isDebugMode,isIvy,getRootCount,getState} smart.svelte.{getVersion,getMeta,isDetected} smart.redux.{isInstalled,getStoreState} smart.alpine.{getVersion,getStoreKeys,getComponentCount} smart.nextjs.{getData,getRouter,getSSRMode,getRouteManifest} smart.nuxt.{getData,getConfig,isSSR} smart.remix.{getContext,getRouteData} smart.gatsby.{getData,getPageData} smart.shopify.{getShop,getCart} smart.wordpress.{isWP,getRestUrl,getPlugins} | smart.woocommerce.{getParams} smart.laravel.{getCSRF} | smart.django.{getCSRF} | smart.drupal.{getSettings} smart.jquery.{getVersion} Example (HTTP API): const { data } = await crawlio.api('GET', '/status'); return data; Example (browser): const tabs = await bridge.send({ type: 'list_tabs' }, 5000); return tabs; Example (smart — auto-waiting click): await smart.click('#submit-btn'); return await smart.snapshot(); Example (smart — framework data): const nextData = await smart.nextjs?.getData(); return { page: nextData?.page, buildId: nextData?.buildId }; Example (session recording + compile): const s = await bridge.send({ type: 'start_recording', maxDurationSec: 120 }); // ... interact with page ... const session = await bridge.send({ type: 'stop_recording' }); const skill = compileRecording(session, { name: 'my-flow' }); return skill; IMPORTANT: Keep scripts fast (<15s). Each smart.click costs ~1-2s. Never loop 5+ clicks — use smart.evaluate to read DOM data in bulk instead. IMPORTANT: smart.evaluate returns {result, type}. Access .result for the value. Never JSON.stringify inside evaluate then JSON.parse outside — just return objects directly.
Input schema
{
  "type": "object",
  "properties": {
    "code": {
      "type": "string",
      "description": "Async JavaScript function body. Has bridge, crawlio, sleep, TIMEOUTS, smart, compileRecording, ocrScreenshot, saveArtifact in scope. Must return a value (for bulk data, saveArtifact to disk and return { path, bytes })."
    },
    "tabId": {
      "type": "number",
      "description": "Target tab id from list_tabs. Every bridge.send in the script that does not name its own tabId runs against this tab (default: the connected tab)."
    },
    "background": {
      "type": "boolean",
      "description": "Run detached: returns { jobId } immediately and keeps executing server-side up to the sandbox cap (~120s). Poll get_job_result(jobId) for the result. Use for heavy/long runs (e.g. navigate + OCR) that would exceed a normal synchronous tool-call timeout."
    }
  },
  "required": [
    "code"
  ]
}
get_job_resultPoll a background execute job by jobId (returned by execute({ background: true })). Returns { status: running|done|error|cancelled, value?, console?, error?, ageMs, runtimeMs? }, or { status: 'not_found' } if unknown/expired (finished jobs are kept ~10 min). phase/percent come from reportPhase(name, percent) calls inside the job; phases is the recent timeline while it is still running.
Input schema
{
  "type": "object",
  "properties": {
    "jobId": {
      "type": "string",
      "description": "Job id from execute({ background: true })"
    }
  },
  "required": [
    "jobId"
  ]
}
list_jobsList background execute jobs (running + recently finished). Returns { count, jobs: [{ jobId, status, ageMs, runtimeMs? }] }.
Input schema
{
  "type": "object",
  "properties": {}
}
observeManage extension-resident observation. Actions: training_start, training_status, training_stop, training_clear, training_artifacts; recording_start, recording_status, recording_stop, recording_clear, recording_artifacts (RecordingBundle aliases); monitor_start, monitor_status, monitor_results, monitor_stop, monitor_clear. Training and monitors continue while MCP is disconnected; stop materializes canonical files and confirmed clear deletes only Chrome-retained records.
Input schema
{
  "type": "object",
  "properties": {
    "action": {
      "type": "string",
      "enum": [
        "training_start",
        "training_status",
        "training_stop",
        "training_clear",
        "training_artifacts",
        "recording_start",
        "recording_status",
        "recording_stop",
        "recording_clear",
        "recording_artifacts",
        "monitor_start",
        "monitor_status",
        "monitor_results",
        "monitor_stop",
        "monitor_clear"
      ]
    },
    "url": {
      "type": "string"
    },
    "runId": {
      "type": "string"
    },
    "bundleID": {
      "type": "string"
    },
    "outputDir": {
      "type": "string"
    },
    "monitorId": {
      "type": "string"
    },
    "intervalMinutes": {
      "type": "number"
    },
    "maxDurationSec": {
      "type": "number"
    },
    "maxInteractions": {
      "type": "number"
    },
    "active": {
      "type": "boolean",
      "description": "Open the training tab in the foreground (default true)"
    },
    "fetchBodies": {
      "type": "boolean"
    },
    "confirm": {
      "type": "boolean",
      "description": "Must be true for training_clear/recording_clear"
    },
    "closeTab": {
      "type": "boolean"
    },
    "captureStorageValues": {
      "type": "boolean"
    },
    "limit": {
      "type": "number"
    },
    "includeSnapshot": {
      "type": "boolean"
    },
    "label": {
      "type": "string"
    }
  },
  "required": [
    "action"
  ]
}
searchSearch available commands by keyword — both browser automation (via bridge.send) and Crawlio HTTP endpoints (via crawlio.api). Returns matching command names, descriptions, and parameter schemas. Use this to discover what commands are available before writing execute() code.
Input schema
{
  "type": "object",
  "properties": {
    "query": {
      "type": "string",
      "description": "Search keyword (e.g. 'screenshot', 'cookie', 'network', 'navigate')"
    },
    "limit": {
      "type": "number",
      "description": "Max results (default: 10)"
    }
  },
  "required": [
    "query"
  ]
}

Resources 0

  • None observed.

Resource templates 0

  • None observed.

Prompts 0

  • None observed.

Remote endpoints

EndpointTransportAuthenticationHealthObserved
No verified remote endpoint is linked.

crawlio-browser MCP Server questions

How do I install crawlio-browser MCP Server?

Install the selected package version with: npm install --save-exact crawlio-browser@1.11.0

What tools does crawlio-browser MCP Server provide?

crawlio-browser MCP Server exposed 7 tools during independent protocol observation, including cancel_job, connect_tab, execute, get_job_result, list_jobs, observe, search.

Is crawlio-browser MCP Server secure?

Our scanner tested version 1.11.0 without proving a finding in the methods exercised. This is not a guarantee that every deployment is secure.

Explore related MCP server guides

Curated product and capability guides containing this catalog record.

Official vs Community MCP ServersMCP Servers With Completed Verification

Let’s talk about MCP security.

Share your details and our security team will contact you.