{
  "name": "web-read",
  "toolName": "web_read",
  "tier": "tool",
  "category": "consuming",
  "title": "Web Page Reader",
  "description": "Open any URL in a headless browser (Playwright Python) and return the page's MAIN TEXT — title, headings, paragraphs, lists, code blocks and tables — as Markdown, plain text, or structured JSON. Boilerplate (nav / sidebar / comments / ads / footer) is stripped by a Readability-style pass, and JS-rendered pages work because a real browser runs the page. This is the tool to use whenever you need to KNOW WHAT A PAGE SAYS: summarizing an article, pulling source material for a script, reading a README or docs page, checking what a link contains. It returns text, not pictures — for a screenshot (png/jpg) use web_screenshot, for a recording (mp4/webm) use web_record. GitHub repository pages also return observed Stars/Forks/Watchers before sidebar cleanup (missing counters stay unknown). Reuse successful reads across script and template fields; do not repeat the same URL just for counters already returned. Output is capped by max_chars (default 20000) and truncated on a block boundary; pass an `output` path to keep the full text on disk.",
  "auth": "none",
  "envVars": [
    "WEB_CAPTURE_BROWSER",
    "WEB_CAPTURE_ALLOW_PRIVATE_HOSTS",
    "PLAYWRIGHT_BROWSERS_PATH"
  ],
  "entry": {
    "type": "python",
    "scriptPath": "../web-screenshot/scripts/read_page.py"
  },
  "parameters": {
    "type": "object",
    "properties": {
      "url": {
        "type": "string",
        "description": "Target page URL (http/https). Private / loopback / link-local addresses are refused unless WEB_CAPTURE_ALLOW_PRIVATE_HOSTS=1."
      },
      "format": {
        "type": "string",
        "enum": ["markdown", "text", "json"],
        "description": "markdown (default: keeps headings, lists, code fences, tables) | text (plain) | json (structured blocks + metadata, not truncated)"
      },
      "max_chars": {
        "type": "number",
        "description": "Cap on the printed text, cut at a block boundary with an explicit [truncated] notice (default 20000, 0 = unlimited). Raise it when you need the whole document; a very long page will otherwise fill your context."
      },
      "selector": {
        "type": "string",
        "description": "Read only inside this CSS selector, preserving the selected region's sidebar/button text instead of pruning boilerplate. Scripts/styles are still removed. Leave empty to auto-detect the article container; use a targeted selector only for a concrete missing required fact."
      },
      "include_links": {
        "type": "boolean",
        "description": "Keep hyperlinks as [text](url) instead of plain text. Useful when you need to follow links from the page."
      },
      "include_images": {
        "type": "boolean",
        "description": "Keep images as ![alt](src). Useful for harvesting illustration URLs out of an article."
      },
      "output": {
        "type": "string",
        "description": "Also write the FULL (untruncated) text to this local path. stdout still respects max_chars — use this when a long page must be kept for later steps."
      },
      "settle_ms": {
        "type": "number",
        "description": "Extra wait before extracting, in ms. Raise for pages that render content late."
      },
      "wait_for_selector": {
        "type": "string",
        "description": "Wait for this CSS selector before extracting (the reliable fix for JS-rendered content)"
      },
      "wait_for_timeout": {
        "type": "number",
        "description": "Fixed wait before extracting, in ms"
      },
      "device": {
        "type": "string",
        "description": "Device emulation name, e.g. 'iPhone 15 Pro' — some sites serve a leaner page to mobile"
      },
      "viewport": {
        "type": "string",
        "description": "Viewport as 'width,height', e.g. '1280,800'"
      },
      "color_scheme": {
        "type": "string",
        "enum": ["light", "dark", "no-preference"],
        "description": "Emulate prefers-color-scheme"
      },
      "user_agent": {
        "type": "string",
        "description": "Override the User-Agent (try this when a site blocks headless browsers)"
      },
      "timeout": {
        "type": "number",
        "description": "Global Playwright action timeout in ms"
      },
      "ignore_https_errors": {
        "type": "boolean",
        "description": "Ignore HTTPS certificate errors"
      },
      "storage_state": {
        "type": "string",
        "description": "Path to a Playwright storageState JSON file (logged-in session)"
      },
      "cookies": {
        "type": "string",
        "description": "Playwright cookies as a JSON string or a path to a JSON file (top level is an array)"
      },
      "browser": {
        "type": "string",
        "enum": ["chromium", "firefox", "webkit"],
        "description": "Browser engine (default chromium)"
      },
      "quiet": {
        "type": "boolean",
        "description": "Suppress the extraction diagnostics on stderr"
      }
    },
    "required": ["url"]
  },
  "ui": {
    "primary": ["url", "format", "max_chars"],
    "advanced": [
      "selector",
      "include_links",
      "include_images",
      "wait_for_selector",
      "settle_ms",
      "device",
      "viewport",
      "color_scheme",
      "timeout"
    ],
    "hidden": [
      "output",
      "quiet",
      "user_agent",
      "ignore_https_errors",
      "storage_state",
      "cookies",
      "browser",
      "wait_for_timeout"
    ]
  }
}
