First-time installation
When the user uses it for the first time, execute the following process:
Step 1: Runtime environment detection
bash ~/.claude/skills/web-access/scripts/check-deps.sh
Step 2: The AI handles missing dependencies based on the output
The detection script only reports facts; installation decisions are made by the AI. Install whatever is missing; when Chrome is missing, prompt the user to download it manually (it cannot be installed automatically).
Step 3: After installation is complete, explain the following to the user
web-access is ready. For any networking needs, just say so directly, and I will automatically choose the most suitable method:
- Only need search results → search directly, fastest
- Need to view the full page → scrape the page content without launching a browser
- Need login/dynamic pages/browser operations → automatically launch the browser; after logging in once, it is persistently saved. Supports multiple sub-agent clusters using multiple browsers in parallel.
Windows users need a Git Bash environment (installing Git for Windows is sufficient).
Browsing philosophy
Browse like a human, not execute a program like a robot.
When humans browse web pages, they do not list complete steps before starting; instead, they enter with a goal, judge as they look, solve obstacles when encountered, and go deeper when the content found is insufficient—making decisions throughout around "what do I want to get." All behaviors of this skill should follow this logic.
Three core judgments:
① What do I need? — Task-driven: first think clearly about the nature of the target information, then choose the lightest method that can reach it directly. Do not use heavy tools for lightweight tasks, and do not use lightweight tools for content they cannot cover.
② Is it enough? — If the information obtained can complete the task, then it is enough. Do not over-collect, and do not waste cost for the sake of "completeness." To roughly understand a video, a few frames are enough; to understand an article, reading the text is enough; there is no need for full-page screenshots to do things that can be done with the accessibility tree.
③ What to do when encountering obstacles? — Solve them within the layer, do not retreat, and do not disturb the user. Pop-ups, login walls, ads, loading failures—judge like a human whether this obstacle really blocks the target content: if it blocks it, handle it; if not, bypass it and continue. Only inform the user when it is confirmed that it cannot be solved on your own.UI interaction is also a bypassable indirect layer: paging, expanding, and clicking are not the only paths to obtain content—the content may already be in the website, and interaction is only a display method.
Information acquisition channel selection
- First evaluate the task, then choose the channel: decide the starting point based on "the nature of the target information and what tool can obtain it directly," and choose the lightest solution that can reach it directly.
- Ensure the authenticity of information; first-hand information is better than second-hand information: search engines and aggregation platforms are entry points for information discovery. When there is no qualitative improvement after multiple search attempts, upgrade to a more fundamental acquisition method: locate first-hand sources (official websites, official platforms, original pages).
| Scenario | Channel |
|---|---|
| Only need to search summaries or keyword results, or need to discover information sources | WebSearch |
| URL known, read page content | Jina(Default, executes JS rendering at the underlying level); when you need to read structured fields in the HTML source (meta, JSON-LD, etc.), switch to WebFetch(does not execute JS rendering) |
| URL is a PDF | Jina |
| Non-public content, or platforms where the static layer is known to be ineffective (public content on Xiaohongshu, WeChat Official Accounts, etc. is also restricted by anti-crawling measures) | Browser CDP(direct, skips the static layer) |
| Need dynamic content, logged-in state, interactive operations, or need to freely navigate and explore within the browser like a human | Browser CDP |
Browser CDP does not require the URL to be known—you can start from any entry point and find the target content through in-page search, clicking, navigation, and other methods.
Jina: The invocation method is r.jina.ai/example.com(prefix the URL, without retaining the original website's http prefix). Limited to 20 RPM, saving more AI context.
Under the hood, Puppeteer is used to render the page (able to handle JS/SPA), then the Readability algorithm extracts the main article content and converts it to Markdown, filtering out noise such as navigation, ads, and sidebars. Suitable for pages centered on body text such as articles, blogs, documentation, and PDFs; for non-article-structured pages such as video pages, data dashboards, and product pages, it may extract the wrong blocks. After getting the result, judge whether the content matches the task expectations; if not, switch access strategies.
WebFetch: Directly fetch the raw HTML without executing JS. Structured fields such as meta and JSON-LD are usually statically embedded in the HTML by the server, and WebFetch can read them directly; if the fields are dynamically injected by JS, WebFetch similarly cannot get them. When requesting, add the header Accept: text/markdown, text/html, and websites that support this protocol return Markdown directly.
Selection logic: Use Jina by default—Jina executes JS at the underlying level and can handle dynamically rendered pages. Only when the task may need to read the HTML source should WebFetch be used. When neither Jina nor WebFetch can handle it (cannot obtain the required information, errors, requires login) → escalate to the browser layer.
Downgrade prohibited: After entering a heavier channel, you must not go back and use a lightweight tool to accomplish the same goal—that is equivalent to retreading a known blocked path. When the browser layer encounters obstacles, they should be resolved within the layer (such as handling login), rather than detouring back. The only exception: new sub-goals derived during browser operations may reselect the channel.
After entering the browser layer, distinguish the nature of the task:
- Operational type(navigation, form filling, clicking): use the accessibility tree to perceive the interface; only use screenshots as an auxiliary when it cannot be recognized
- Content type(reading posts, viewing information, analyzing pages): use the accessibility tree to read the text structure, and at the same time judge whether images carry core information—if so, extract the image URLs and read them in a targeted way
Image judgment: For social media, illustrated blog posts, and screenshot-type content, images are valuable by default; actively fetch them. For tool-type and navigation-type pages, the accessibility tree is sufficient by default.
Browser CDP mode
Startup
# 单 agent 任务(默认端口 9222)
bash ~/.claude/skills/web-access/scripts/ensure-browser.sh
# 并行任务(端口由主 agent 在 task prompt 中指定,见「并行调研」章节)
bash ~/.claude/skills/web-access/scripts/ensure-browser.sh $PORT
Output Browser ready on port XXXX. After startup, the following two steps must be performed:
# 解析端口并设置 session(所有后续命令自动继承,无需重复传参)
PORT=<从输出解析的端口号>
export AGENT_BROWSER_SESSION="port-${PORT}"
Output status description:
Browser ready on port XXXX→ can be used directly; set PORT and SESSION and continue (close after the task ends)ERROR→ executebash ~/.claude/skills/web-access/scripts/close-browser.sh [端口]then run again
⚠️ Downgrading strictly prohibited: Use only agent-browser CDP mode; do not switch to other browser tools/MCP.
Common Commands
Record the port number in the ensure-browser.sh output as $PORT, and use this port uniformly in subsequent commands:
agent-browser --cdp $PORT open <url> # 打开页面
agent-browser --cdp $PORT snapshot -i # 可交互元素(操作用)
agent-browser --cdp $PORT snapshot # 完整无障碍树(读文字用)
agent-browser --cdp $PORT click @ref-123 # 点击元素
agent-browser --cdp $PORT fill @ref-123 "内容" # 填写输入框
agent-browser --cdp $PORT wait load networkidle # 仅用于 click/fill 触发导航后;open 已内置等待,勿在 open 后使用
agent-browser --cdp $PORT scroll down 3000 # 触发懒加载
agent-browser --cdp $PORT screenshot /tmp/x.png
agent-browser --cdp $PORT screenshot --annotate # snapshot -i ref 失效时的升级方案,见 references/commands.md
agent-browser --cdp $PORT eval "<js>" # 执行 JS,用于提取 DOM 信息
Image Extraction
When determining that content is in an image, use eval to get the image URL directly from the DOM, then open and screenshot it in a targeted way—far more precise than a full-page screenshot.
Technical Facts:
- There is a large amount of content on the page that has loaded but is not displayed—images in carousels that are not the current frame, text in collapsed sections, lazy-loading placeholder elements, etc. They exist in the DOM but are invisible to the user. The visual layer is merely a projection of the DOM data. Thinking in terms of data structures (containers, attributes, node relationships) allows direct access to this content without depending on whether the visual layer presents it.
- Scrolling to the bottom triggers lazy loading, causing images that have not entered the viewport to finish loading. If you use
evalto extract image URLs before scrolling, some images may not have loaded yet.
After obtaining the image URL, the Read tool natively supports reading local image files. For public image URLs that do not require a session, you can download them locally and read them with Read, without going through the browser. Only images that require a session/cookie need to be opened + screenshotted in the browser.
Video Content Acquisition
In CDP headed mode, the browser renders for real, and screenshots can capture the current video frame. Core capabilities:seek to any point in time and screenshot, enabling discrete sampling and analysis of video content.
# 获取总时长,制定采样计划
agent-browser --cdp $PORT eval "document.querySelector('video').duration"
# seek + 播放 + 截图
agent-browser --cdp $PORT eval "var v=document.querySelector('video'); v.currentTime=60; v.play()"
sleep 2
agent-browser --cdp $PORT screenshot /tmp/frame.png
# 全屏截图画面更清晰
agent-browser --cdp $PORT eval "document.querySelector('video').requestFullscreen()"
The frame sampling granularity (for reference only; analyze specific videos on a case-by-case basis: rough understanding → 30-60s intervals; understanding narrative → 10s; fine-grained analysis → 1-2s) is determined by the task requirements at your own discretion, with no need for the user to specify it.
Login Determination
There is only one core question in login determination:Have you obtained the target content?
After opening the page, first try to obtain the target content, and keep doing so. During this process, make a judgment based on two aspects of information:
- Domain knowledge: knowledge about the website—X/Twitter's latest timeline, Xiaohongshu's private content, Weibo's full comments, etc. This type of content usually requires login to obtain complete data
- Actual page feedback: Does the content match expectations? Is it a degraded version (e.g., popular posts instead of the latest posts)? Are there obvious omissions?
Even if the page shows a login prompt, as long as the target content has already been obtained, there is no need to bother the user to log in.
Only when it is confirmed thatthe target content cannot be obtainedshould you infer: Can logging in solve this problem? If the inference holds, tell the user:
"The current page cannot obtain [specific content] without logging in. Please log in to [website name] in the already opened Chrome window, and tell me to continue after you're done."
After logging in, there is no need to restart the browser; just continue the original task directly.
Task End
After the task ends, close the browser (you must use this script; do not kill directly, otherwise it will leave a crashed window):
bash ~/.claude/skills/web-access/scripts/close-browser.sh [端口] # 默认 9222
close-browser.sh cleans up both the Chrome process and the agent-browser session daemon; the caller does not need any additional action.
Parallel Research: Sub-Agent Divide-and-Conquer Strategy
The task contains multipleindependentWhen researching goals (such as researching N projects or N sources at the same time), encourage reasonable divide-and-conquer by having sub-agents execute in parallel, rather than having the main agent process them serially.
Benefits:
- Speed: Multiple sub-agents run in parallel, so total elapsed time is approximately the duration of a single subtask.
- Context protection: Scraped content does not enter the main agent's context; the main agent only receives summaries, saving tokens.
Sub-agents need to inherit the skill:
In the sub-agent prompt, write 遵循 web-access skill 的指引 , and the sub-agent will automatically load the skill. There is no need to copy the skill content or specify a path in the prompt.
How to write sub-agent prompts: goal-oriented, not step instructions
Sub-agents have complete skill knowledge and independent judgment capability. The main agent's responsibility is to state clearlywhat is wanted, and only limithow to do itwhen necessary and certain. Over-specifying steps deprives the sub-agent of room for judgment and instead introduces the main agent's mistaken assumptions.
Wrong: over-specification (pre-filling unverified URLs/accounts):
打开 https://x.com/SomeAccount,抓取最新推文
Correct: goal-oriented (sub-agent discovers the path autonomously):
找到 XX 的官方 X 账号,获取最新推文内容
Key principle: do not pre-fill unverified information. Only when information comes directly from the user or has been confirmed may it be passed in directly.
Criteria for divide-and-conquer judgment:
| Suitable for divide-and-conquer | Not suitable for divide-and-conquer |
|---|---|
| Goals are mutually independent, and results do not depend on each other | Goals have dependencies; the next one needs the previous one's result |
| Each subtask is large enough (multi-page scraping, multiple rounds of searching) | Simple single-page lookup; divide-and-conquer overhead outweighs the benefit |
| Tasks that need a CDP browser or run for a long time | Lightweight queries that can be completed with a few WebSearch / Jina calls |
CDP concurrency: each port starts an independent Chrome instance, without interfering with each other.
When the main agent starts sub-agents, it should explicitly specify in the task prompt for each sub-agent an exclusive port to avoid browser instance conflicts (starting from 9222, choose within the range 9222–9299, and each sub-agent uses a different port). After receiving the port, the sub-agent calls ensure-browser.sh <PORT> to start.
Special task rules
Verification tasks
The goal of verification isfirst-hand sources, not more second-hand reports—multiple media outlets citing the same error can create an illusion of circular corroboration.
Search is used tolocatesources, not toproveauthenticity. After finding the source, directly access and read the original text.
| Information type | First-hand source |
|---|---|
| Policy/regulation | Official website of the issuing agency |
| Corporate announcement | Company's official news page |
| Academic statement | Original paper/institutional official website |
When the official website cannot be found: original reporting by authoritative media (not reposts) may serve as secondary evidence, but it must be explained to the user: "The official original text was not found. The following verification comes from a [media name] report, and there may be transcription errors."
Understanding the boundaries of tool capabilities
When there are questions about the capabilities of any tool (MCP, CLI, library),If you do not have enough knowledge to be sure, check the official documentation first. If the documentation is insufficient, consider looking at the source code before making a judgment, and do not guess or shift uncertainty onto the user.
References index
| File | When to load |
|---|---|
references/commands.md |
When less commonly used commands are needed (drag, storage, pdf, etc.) |
references/login-flow.md |
When details of the login flow are needed |