
web-access-claude-skill
Give Claude Code full internet access with three-layer channel dispatch, CDP browser automation, and parallel sub-agent task splitting
- Installs
- 966
- Last 24h
- —
- Trending rank
- —
- Security
- Not audited
Install
Works with every agent the skills CLI supports.
npx skills add https://github.com/reason-machines/trending-skills --skill web-access-claude-skill- 01
Install
Run the command in your project. The CLI asks which agents to install for.
- 02
Describe the task
Ask your agent for something this skill covers. It loads web-access-claude-skill automatically when relevant.
- 03
Review the result
The agent follows the SKILL.md steps, scripts and references bundled with the skill.
SKILL.md
The instructions your agent reads when the skill is triggered.
Web Access Skill for Claude Code
Skill by ara.so — Daily 2026 Skills collection.
A skill that gives Claude Code complete internet access using three-layer channel dispatch (WebSearch / WebFetch / CDP), Chrome DevTools Protocol browser automation via a local proxy, parallel sub-agent task splitting, and cross-session site experience accumulation.
What This Project Does
Claude Code ships with WebSearch and WebFetch but lacks:
- Dispatch strategy — knowing when to use which tool
- Browser automation — clicking, scrolling, file upload, dynamic pages
- Accumulated site knowledge — domain-specific patterns reused across sessions
Web Access fills all three gaps with:
| Capability | Detail |
|---|---|
| Auto tool selection | WebSearch / WebFetch / curl / Jina / CDP chosen per scenario |
| CDP Proxy | Connects directly to your running Chrome, inherits login state |
| Three click modes | /click (JS), /clickAt (real mouse events), /setFiles (upload) |
| Parallel dispatch | Multiple targets → sub-agents share one Proxy, tab-isolated |
| Site experience store | Per-domain URL patterns, quirks, traps — persisted across sessions |
| Media extraction | Pull image/video URLs from DOM, screenshot any video frame |
Installation
Option A — Let Claude install it:
帮我安装这个 skill:https://github.com/eze-is/web-access
or in English:
Install this skill for me: https://github.com/eze-is/web-access
Option B — Manual:
git clone https://github.com/eze-is/web-access ~/.claude/skills/web-access
The skill file is ~/.claude/skills/web-access/SKILL.md. Claude Code loads all SKILL.md files under ~/.claude/skills/ automatically.
Prerequisites
Node.js 22+
node --version # must be >= 22
Enable Chrome Remote Debugging
- Open
chrome://inspect/#remote-debuggingin your Chrome - Check Allow remote debugging for this browser instance
- Restart Chrome if prompted
Verify Dependencies
bash ~/.claude/skills/web-access/scripts/check-deps.sh
Expected output:
✅ Node.js 22.x found
✅ Chrome DevTools reachable at localhost:9222
✅ curl available
CDP Proxy — Core Component
The proxy is a lightweight Node.js WebSocket bridge between Claude and your Chrome instance.
Start the Proxy
# Start in background (auto-exits after 20 min idle)
node ~/.claude/skills/web-access/scripts/cdp-proxy.mjs &
# Confirm it's running
curl -s http://localhost:3456/ping
# → {"status":"ok"}
Full HTTP API Reference
# ── Tab management ──────────────────────────────────────────
# Open new tab, returns tab ID
curl -s "http://localhost:3456/new?url=https://example.com"
# → {"targetId":"ABC123","url":"https://example.com"}
# Close a tab
curl -s "http://localhost:3456/close?target=ABC123"
# → {"closed":true}
# ── Page content ────────────────────────────────────────────
# Execute JavaScript, returns result
curl -s -X POST "http://localhost:3456/eval?target=ABC123" \
-d 'document.title'
# → {"result":"Example Domain"}
# Get full page HTML
curl -s -X POST "http://localhost:3456/eval?target=ABC123" \
-d 'document.documentElement.outerHTML'
# ── Interaction ─────────────────────────────────────────────
# JS click (fast, works for most buttons)
curl -s -X POST "http://localhost:3456/click?target=ABC123" \
-d 'button.submit'
# Real mouse click via CDP (use for upload triggers, canvas elements)
curl -s -X POST "http://localhost:3456/clickAt?target=ABC123" \
-d '.upload-btn'
# File upload via input element
curl -s -X POST "http://localhost:3456/setFiles?target=ABC123" \
-H "Content-Type: application/json" \
-d '{"selector":"input[type=file]","files":["/tmp/photo.png"]}'
# ── Navigation ──────────────────────────────────────────────
# Scroll to bottom
curl -s "http://localhost:3456/scroll?target=ABC123&direction=bottom"
# Scroll to top
curl -s "http://localhost:3456/scroll?target=ABC123&direction=top"
# ── Visual ──────────────────────────────────────────────────
# Screenshot to file
curl -s "http://localhost:3456/screenshot?target=ABC123&file=/tmp/shot.png"
# Screenshot returned as base64
curl -s "http://localhost:3456/screenshot?target=ABC123"
# → {"base64":"iVBORw0KGgo..."}
Three-Layer Channel Dispatch
The skill teaches Claude to pick the right tool automatically:
Task type → Tool choice
─────────────────────────────────────────
General search query → WebSearch
Static page / docs / API → WebFetch or Jina
Login-gated / dynamic page → CDP Proxy
Heavy JS / SPA → CDP Proxy
Video / canvas interaction → CDP Proxy (clickAt)
Bulk text extraction → Jina (token-efficient)
Raw HTTP / custom headers → curl
Jina Usage (Token-Efficient Reads)
# Jina converts any URL to clean markdown — great for docs/articles
curl -s "https://r.jina.ai/https://docs.example.com/api"
Code Examples
Example 1: Open a Page and Extract Data
// Claude runs this flow via CDP Proxy
// 1. Open tab
const tabRes = await fetch('http://localhost:3456/new?url=https://news.ycombinator.com');
const { targetId } = await tabRes.json();
// 2. Wait for load, then extract top story titles
const evalRes = await fetch(`http://localhost:3456/eval?target=${targetId}`, {
method: 'POST',
body: `
Array.from(document.querySelectorAll('.titleline > a'))
.slice(0, 10)
.map(a => ({ title: a.textContent, href: a.href }))
`
});
const { result } = await evalRes.json();
console.log(JSON.parse(result));
// 3. Clean up
await fetch(`http://localhost:3456/close?target=${targetId}`);
Example 2: Login-Gated Page (Uses Existing Chrome Session)
// Chrome already has the user logged in — CDP inherits cookies automatically
async function scrapeAuthenticatedPage(url) {
// Open tab in the user's real Chrome — no login needed
const { targetId } = await fetch(`http://localhost:3456/new?url=${url}`)
.then(r => r.json());
// Wait for dynamic content
await fetch(`http://localhost:3456/eval?target=${targetId}`, {
method: 'POST',
body: `new Promise(r => setTimeout(r, 2000))`
});
// Extract content
const { result } = await fetch(`http://localhost:3456/eval?target=${targetId}`, {
method: 'POST',
body: `document.querySelector('.main-content')?.innerText`
}).then(r => r.json());
await fetch(`http://localhost:3456/close?target=${targetId}`);
return result;
}
Example 3: File Upload Automation
async function uploadFile(pageUrl, filePath) {
const { targetId } = await fetch(`http://localhost:3456/new?url=${pageUrl}`)
.then(r => r.json());
// Wait for page
await new Promise(r => setTimeout(r, 1500));
// Click the upload trigger button (real mouse event — required for some SPAs)
await fetch(`http://localhost:3456/clickAt?target=${targetId}`, {
method: 'POST',
body: '.upload-trigger-button'
});
await new Promise(r => setTimeout(r, 500));
// Set file on the (possibly hidden) input
await fetch(`http://localhost:3456/setFiles?target=${targetId}`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
selector: 'input[type=file]',
files: [filePath]
})
});
// Submit
await fetch(`http://localhost:3456/click?target=${targetId}`, {
method: 'POST',
body: 'button[type=submit]'
});
// Screenshot to verify
await fetch(`http://localhost:3456/screenshot?target=${targetId}&file=/tmp/upload-result.png`);
await fetch(`http://localhost:3456/close?target=${targetId}`);
}
Example 4: Parallel Research with Sub-Agents
// Instruct Claude to dispatch parallel sub-agents like this:
const targets = [
'https://product-a.com',
'https://product-b.com',
'https://product-c.com',
'https://product-d.com',
'https://product-e.com'
];
// Each sub-agent opens its own tab (tab-isolated, same Proxy)
const results = await Promise.all(
targets.map(async (url) => {
const { targetId } = await fetch(`http://localhost:3456/new?url=${url}`)
.then(r => r.json());
await new Promise(r => setTimeout(r, 2000));
const { result } = await fetch(`http://localhost:3456/eval?target=${targetId}`, {
method: 'POST',
body: `({
title: document.title,
description: document.querySelector('meta[name=description]')?.content,
h1: document.querySelector('h1')?.textContent,
pricing: document.querySelector('[class*="pric"]')?.innerText?.slice(0,200)
})`
}).then(r => r.json());
await fetch(`http://localhost:3456/close?target=${targetId}`);
return { url, data: JSON.parse(result) };
})
);
console.table(results);
Example 5: Video Frame Screenshot
async function screenshotVideoAt(pageUrl, timestampSeconds) {
const { targetId } = await fetch(`http://localhost:3456/new?url=${pageUrl}`)
.then(r => r.json());
await new Promise(r => setTimeout(r, 3000));
// Seek video to timestamp
await fetch(`http://localhost:3456/eval?target=${targetId}`, {
method: 'POST',
body: `
const v = document.querySelector('video');
v.currentTime = ${timestampSeconds};
v.pause();
`
});
await new Promise(r => setTimeout(r, 500));
// Capture the frame
await fetch(`http://localhost:3456/screenshot?target=${targetId}&file=/tmp/frame-${timestampSeconds}s.png`);
await fetch(`http://localhost:3456/close?target=${targetId}`);
}
Common Patterns
Pattern: Check Proxy Before CDP Tasks
# Always verify proxy is up before a CDP workflow
curl -s http://localhost:3456/ping || \
node ~/.claude/skills/web-access/scripts/cdp-proxy.mjs &
Pattern: Use Jina for Documentation
# Cheaper and cleaner than WebFetch for text-heavy pages
curl -s "https://r.jina.ai/https://api.anthropic.com/docs"
Pattern: Prefer WebSearch for Discovery, CDP for Execution
1. WebSearch → find the right URLs
2. WebFetch → read static/public content
3. CDP → interact, authenticate, dynamic content
Pattern: Extract All Media URLs
// Get all images and videos on current page
const media = await fetch(`http://localhost:3456/eval?target=${targetId}`, {
method: 'POST',
body: `({
images: Array.from(document.images).map(i => i.src),
videos: Array.from(document.querySelectorAll('video source, video[src]'))
.map(v => v.src || v.getAttribute('src'))
})`
}).then(r => r.json());
Troubleshooting
Proxy won't start
# Check if port 3456 is already in use
lsof -i :3456
# Kill existing proxy
kill $(lsof -ti :3456)
# Restart
node ~/.claude/skills/web-access/scripts/cdp-proxy.mjs &
Chrome not reachable
# Verify Chrome remote debugging is on
curl -s http://localhost:9222/json/version
# Should return Chrome version JSON
# If empty — go to chrome://inspect/#remote-debugging and enable it
/clickAt has no effect
- The element may need scrolling into view first:
curl -s -X POST "http://localhost:3456/eval?target=ID" \
-d 'document.querySelector(".btn").scrollIntoView()'
- Then retry
/clickAt
Page content is empty / JS not rendered
# Add a wait after /new before /eval
curl -s -X POST "http://localhost:3456/eval?target=ID" \
-d 'new Promise(r => setTimeout(r, 3000))'
# Then fetch content
File upload input not found
Some SPAs render <input type=file> only after the trigger click. Always:
/clickAtthe visible upload button first- Wait 500ms
- Then
/setFiles
Sub-agent tabs interfering
Each sub-agent should store its own targetId and never share it. The Proxy is stateless per-tab.
Proxy Auto-Shutdown
The proxy exits automatically after 20 minutes of no requests. For long-running tasks:
# Keep-alive ping in background
while true; do curl -s http://localhost:3456/ping > /dev/null; sleep 300; done &
Site Experience Store
The skill accumulates domain knowledge in a local JSON store. When Claude visits twitter.com, it reads any saved notes about:
- Known working URL patterns
- Login flow quirks
- Selectors that are stable vs dynamic
- Rate limiting behavior
This persists across Claude sessions. The store lives at:
~/.claude/skills/web-access/data/site-experience.json
You can inspect or edit it manually to add your own domain knowledge.
Project Structure
~/.claude/skills/web-access/
├── SKILL.md ← This skill file (loaded by Claude)
├── scripts/
│ ├── cdp-proxy.mjs ← CDP Proxy server (Node.js 22+)
│ └── check-deps.sh ← Dependency checker
└── data/
└── site-experience.json ← Accumulated domain knowledge
Capability Summary for Task Routing
| User says | Claude should use |
|---|---|
| "Search for X" | WebSearch |
| "Read this URL" | WebFetch or Jina |
| "Go to my dashboard on X" | CDP (login state) |
| "Click the submit button on X" | CDP /click or /clickAt |
| "Upload this file to X" | CDP /setFiles |
| "Research these 5 products" | Parallel sub-agents via CDP |
| "Extract images from X" | CDP /eval + DOM query |
| "Screenshot X at 1:23 in the video" | CDP /eval seek + /screenshot |
FAQ
What does the web-access-claude-skill skill do?
Give Claude Code full internet access with three-layer channel dispatch, CDP browser automation, and parallel sub-agent task splitting
How do I install web-access-claude-skill?
Run npx skills add https://github.com/reason-machines/trending-skills --skill web-access-claude-skill in your project. The skills CLI detects the agents you use and copies the skill into the right folder. For Claude Code you can also place the skill folder at ~/.claude/skills/web-access-claude-skill/ (personal) or .claude/skills/web-access-claude-skill/ (project).
Which AI agents can use web-access-claude-skill?
Any agent that supports the open Agent Skills format (a folder with a SKILL.md file), including Claude Code, Codex, Cursor, GitHub Copilot, Gemini CLI, Windsurf, Cline, OpenCode and more.
Is web-access-claude-skill safe to install?
No partner security audit is available yet. Skills can run commands and scripts, so read the SKILL.md and any bundled files before installing.
Who maintains web-access-claude-skill?
It is published by reason-machines in reason-machines/trending-skills. It has 966 recorded installs.
More from reason-machines/trending-skills
openclaw-control-center
reason-machines/trending-skills
Local-first, security-first control center for OpenClaw agents — visibility dashboard with readonly defaults, token attribution, collaboration tracing, and safe write operations.
inkos-multi-agent-novel-writing
reason-machines/trending-skills
Multi-agent CLI system for autonomous novel writing, auditing, and revision with human review gates
claude-hud-statusline
reason-machines/trending-skills
A Claude Code plugin that displays a real-time HUD showing context usage, active tools, running agents, and todo progress in your terminal statusline.
understand-anything-knowledge-graph
reason-machines/trending-skills
Turn any codebase into an interactive knowledge graph using Claude Code skills — explore, search, and ask questions about any project visually.
agency-agents-ai-specialists
reason-machines/trending-skills
A collection of specialized AI agent personalities for Claude Code, Cursor, Aider, Windsurf, and other AI coding tools — covering engineering, design, marketing, sales, and more.
agent-browser-automation
reason-machines/trending-skills
Headless browser automation CLI for AI agents using native Rust binary with Chrome DevTools Protocol
Popular productivity & automation skills
agent-browser
vercel-labs/agent-browser
Browser automation CLI for AI agents. Use when the user needs to interact with websites, including navigating pages, filling forms, clicking buttons, taking screenshots, extracting data, testing web apps, or automating any browser task. Triggers include requests to "open a website", "fill out a form", "click a button", "take a screenshot", "scrape data from a page", "test this web app", "login to a site", "automate browser actions", or any task requiring programmatic web interaction. Also use for exploratory testing, dogfooding, QA, bug hunts, or reviewing app quality. Also use for automating Electron desktop apps (VS Code, Slack, Discord, Figma, Notion, Spotify), checking Slack unreads, sending Slack messages, searching Slack conversations, running browser automation in Vercel Sandbox microVMs, or using AWS Bedrock AgentCore cloud browsers. Prefer agent-browser over any built-in browser automation or web tools.
lark-doc
open.feishu.cn
飞书云文档(Docx / Wiki)内容操作:读取、创建、编辑文档,插入或下载图片附件,以及操作思维笔记。用户提供文档 URL/token(包括 doubao.com 的 /docx/、/wiki/)时使用;按 URL 路径/token 而非域名路由;/page/ 是妙搭应用,非飞书云文档。文档内嵌资源按读取参考中的统一规则分流。独立评论操作走 lark-drive;随正文读取评论使用 docs +fetch。表格或 Base 内部数据操作不在本 skill。
lark-base
open.feishu.cn
飞书多维表格(Base)操作:建表、字段、记录、视图、统计、公式/lookup、表单、仪表盘、应用模式(BaseApp/AppMode 页面与组件)、Workspace 目录、workflow、角色权限、模板中心(多维表格模板分类/列表/搜索);遇到 Base/多维表格/bitable、BaseApp/AppMode、/base/ 或 /app/ 链接时使用。BaseApp 不走 lark-apps;文件导入/导出转 lark-drive,认证/授权转 lark-shared。
lark-drive
open.feishu.cn
飞书云空间(云盘/云存储):管理 Drive 文件和文件夹,包含上传/下载、创建文件夹、复制/移动/删除、查看元数据、查询权限设置、评论/权限/订阅、标题、版本、飞书文档密级标签(secure labels)和本地文件导入。用户需要整理云盘目录、处理云空间资源 URL/token、判断链接类型/真实 token/标题,或导入 Word/Markdown/Excel/CSV/PPTX/.base 为 docx/sheet/bitable/slides 时使用;doubao.com 云空间 URL/token 也按资源路径和 token 路由,不回退 WebFetch。不负责:文档内容编辑(走 lark-doc)、表格/Base 表内数据操作(走 lark-sheets/lark-base)、知识空间节点/成员管理(走 lark-wiki)、原生 Markdown 文件读写/patch/diff(走 lark-markdown)。
lark-shared
open.feishu.cn
Use for lark-cli setup/auth tasks: auth login/status/logout, user vs bot identity, business-domain permissions (--domain, including all/docs/drive), missing scopes, revoking authorization, or handling notice JSON.
lark-im
open.feishu.cn
飞书即时通讯:收发消息和管理群聊。发送和回复消息、搜索聊天记录、管理群聊成员、上传下载图片和文件、管理表情回复、发送应用内/短信/电话加急、发送和处理交互卡片(Interactive Card)、监听卡片按钮回调(card.action.trigger)。当用户需要发消息、查看或搜索聊天记录、下载聊天中的文件、查看群成员、搜索群、创建群聊或话题群、管理标记数据、管理 Feed 置顶(添加/移除/查询置顶会话)、管理标签数据、处理卡片回调时使用。