Bright Data MCP
brightdata/skills
Bright Data MCP handles ALL web data operations. An agent skill from brightdata/skills.
A skill your agent uses when opening, navigating, inspecting, testing, clicking, typing, filling, screenshotting, or verifying web pages and local HTTP targets (localhost, 127.0.0.1, ::1) inside…
$ npx skills add zai-org/ZCode --skill control-browser -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install zai-org/ZCode control-browser --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/zai-org/ZCode.git skills-src && mkdir -p .claude/skills && cp -r skills-src/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser .claude/skills/control-browser && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "control-browser" agent skill from https://github.com/zai-org/ZCode/tree/main/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser into .claude/skills/control-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "control-browser", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/zai-org/ZCode/tree/main/apps/zcode-cli/packages/browser-use-plugin/skills/control-browserType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add zai-org/ZCode --skill control-browser -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install zai-org/ZCode control-browser --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/zai-org/ZCode.git skills-src && mkdir -p .agents/skills && cp -r skills-src/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser .agents/skills/control-browser && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "control-browser" agent skill from https://github.com/zai-org/ZCode/tree/main/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser into .agents/skills/control-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "control-browser", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add zai-org/ZCode --skill control-browser -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install zai-org/ZCode control-browser --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/zai-org/ZCode.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser .cursor/skills/control-browser && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "control-browser" agent skill from https://github.com/zai-org/ZCode/tree/main/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser into .cursor/skills/control-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "control-browser", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/zai-org/ZCode.git --path apps/zcode-cli/packages/browser-use-plugin/skills/control-browser--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add zai-org/ZCode --skill control-browser -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install zai-org/ZCode control-browser --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/zai-org/ZCode.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser .gemini/skills/control-browser && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "control-browser" agent skill from https://github.com/zai-org/ZCode/tree/main/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser into .gemini/skills/control-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "control-browser", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install zai-org/ZCode control-browserInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add zai-org/ZCode --skill control-browser -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/zai-org/ZCode.git skills-src && mkdir -p .github/skills && cp -r skills-src/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser .github/skills/control-browser && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "control-browser" agent skill from https://github.com/zai-org/ZCode/tree/main/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser into .github/skills/control-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "control-browser", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add zai-org/ZCode --skill control-browser -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install zai-org/ZCode control-browser --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/zai-org/ZCode.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser .opencode/skills/control-browser && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "control-browser" agent skill from https://github.com/zai-org/ZCode/tree/main/apps/zcode-cli/packages/browser-use-plugin/skills/control-browser into .opencode/skills/control-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "control-browser", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
control-browserA skill your agent uses when opening, navigating, inspecting, testing, clicking, typing, filling, screenshotting, or verifying web pages and local HTTP targets (localhost, 127.0.0.1, ::1) inside…
Control Browser is an agent skill from zai-org/ZCode. Use when opening, navigating, inspecting, testing, clicking, typing, filling, screenshotting, or verifying web pages and local HTTP targets (localhost, 127.0.0.1, ::1) inside ZCode, including browser/web-UI automation, rendered-page scraping, frontend checks, and visible page-state reading. Prefer this over Computer Use for anything that stays inside a web page, unless the user explicitly asks for Computer Use. Main agent only.
Its SKILL.md is about 4.6k tokens, which your agent loads only when the skill is triggered. It is a single SKILL.md file with no bundled scripts.
It sits in Productivity & Automation, covering Browser automation, Desktop control and Frontend development. It works with JavaScript and Model Context Protocol. The repository describes itself as: Z.ai's coding agent harness. Powerful, intelligent, extensible. The licence is Apache-2.0.
8 steps, taken from the first numbered list in SKILL.md.
Read from SKILL.md and the folder at commit 29628c9. It shows what the files ask for, not the result of running them.
Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.
From allowed-tools in the SKILL.md frontmatter.
No scripts in the folder and no shell commands in SKILL.md (its code samples are javascript).
From the folder's file list and the shell code blocks in SKILL.md.
No URLs in SKILL.md.
From URLs in SKILL.md, links to its own repository left out.
Names no API keys, tokens, secrets or passwords.
From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Control Browser loads about 4.6k tokens when it runs. Until then it costs about 112 tokens; SKILL.md has 2,390 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check found no risky patterns in SKILL.md.
Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from zai-org/ZCode at commit 29628c9, republished under its Apache-2.0 licence (© zai-org). 2,390 words, ~4,585 tokens.
.claude/skills/control-browser/SKILL.md (or your agent's skills folder).Use this skill for browser / web-UI tasks: opening and navigating pages, inspecting or reading rendered content, testing local apps, clicking, typing, filling, taking screenshots, and verifying visible page state.
If this skill is available in the session, treat it as required reading before browser work. Follow it before saying the browser is unavailable and before falling back to bash (curl/open), webfetch, or any other tool for a browser task.
The browser registry is driven from the Node REPL MCP js tool. In this environment its callable id normally appears as mcp__node_repl__js. The MCP frontend is shared for a workspace, but every js call runs in a fresh JavaScript kernel, so variables, imports, module cache, browser, and tab bindings do not persist. Persistent BrowserControl tabs are the continuity boundary and must be recovered from current tab facts.
The browser-client module is the browser entry point and is available at scripts/browser-client.mjs under this plugin's root. Resolve that root only from process.env.ZCODE_PLUGIN_ROOT, then convert the joined path with pathToFileURL. Never derive the plugin root from this skill's base directory or leave a synthetic root placeholder for the model to resolve. If the host root is unavailable or the resolved module cannot be imported, stop and report the exact setup error.
Initialize at the start of every mcp__node_repl__js call that uses the browser. The bootstrap deliberately does not select a backend; apply the user's existing backend choice or the selection rules below after setup.
const browserPluginRoot = process.env.ZCODE_PLUGIN_ROOT;
if (!browserPluginRoot) {
throw new Error("Browser plugin root is unavailable in the node_repl host");
}
const { join } = await import("node:path");
const { pathToFileURL } = await import("node:url");
const browserClientUrl = pathToFileURL(
join(browserPluginRoot, "scripts", "browser-client.mjs"),
).href;
const { setupBrowserRuntime } = await import(browserClientUrl);
await setupBrowserRuntime({ globals: globalThis });Run setup and all later browser calls through mcp__node_repl__js, passing JavaScript as the code argument. The tool has no command parameter.
Backend types are iab, extension, and cdp; Playwright is a tab API surface, not a backend. Always use await agent.browsers.list() as the availability source. Desktop normally reports IAB; a CLI explicitly started with --browser-use=headless reports managed Chromium as cdp. Headless is a CDP launch mode, not a backend type. Never claim Chrome extension or CDP support when that descriptor is absent, and never silently substitute IAB after the user explicitly selected another backend.
User-facing progress should stay non-technical: describe it as "opening the browser" / "checking the page", not "Node REPL", "CDP", or "webview".
Recreate the same selected browser wrapper in every fresh call using the user's explicit backend choice or the same verified URL/default rule. A fresh JavaScript kernel does not mean the browser disconnected and is not permission to switch backend. Do not reuse a tab id from memory as the target of a new logical operation batch without validation: first return the complete current tab list to the model, then in the next JS call match the intended id/url/title and call tabs.get(id).
App-provided <in-app-browser-context source="ambient-ui-state"> is current UI state, not part of the user's request.
It can tell you which visible page to inspect, but it is not evidence that the user explicitly selected IAB or Chrome.
In the first browser call, run the bootstrap, select the backend, and emit the complete API guide in one go. On later fresh calls, run the bootstrap and repeat only the same backend selection; the API guide remains in model context and does not need to be emitted again. Never create an iab alias and then call browser.*.
If the user explicitly asks for ZCode's in-app browser:
const browser = await agent.browsers.get("iab");
nodeRepl.write(await browser.documentation());If the user explicitly asks for the CLI-managed headless browser and discovery advertises cdp:
const browser = await agent.browsers.get("cdp");
nodeRepl.write(await browser.documentation());If the task has a target URL but no explicit browser choice, replace the example URL with the real target:
const browser = await agent.browsers.getForUrl("https://example.com/");
nodeRepl.write(await browser.documentation());Only when neither a browser nor target URL is specified:
const browser = await agent.browsers.getDefault();
nodeRepl.write(await browser.documentation());Do not slice, truncate, or summarize it. Only if the tool output itself reports truncation may you read it in smaller chunks. It documents every default method, the Playwright DOM snapshot→locator workflow, the snapshot-ref, cua, and dom_cua escape-hatch paths, and safety rules. Screenshot instructions are intentionally lookup-only and must not be loaded unless the visual branch below applies.
Start every browser js call with the bootstrap, then assign the selected backend to a local browser binding. If the user explicitly asks for ZCode's in-app browser, use const browser = await agent.browsers.get("iab"). If they explicitly ask for Chrome, use await agent.browsers.get("extension") only when the runtime advertises it. For an unspecified target URL use await agent.browsers.getForUrl(url); with no URL/backend preference use await agent.browsers.getDefault().
browser.tabs.new() automatically opens and activates the IAB pane so the user can see browser use. Use the advertised visibility capability only when the task explicitly needs to hide the pane or show it again.
At the start of every logical tab operation batch, make a dedicated JS call whose result is the complete
await browser.tabs.list() array, so the model sees all current ids, URLs, titles, and the active marker. Only in
the next JS call may you match the intended tab by stable id or explicit URL/title facts and call
browser.tabs.get(id) before the first read or action. An internal SDK validation or a list hidden inside the same
cell does not count as model inspection. tabs.get(id) activates that tab in its owning session; it is shown only
when that session is currently in the foreground. Never choose [0], at(-1), or an id remembered without validation.
If no controlled tab matches, inspect browser.user.openTabs() and claim the matching returned object. Create a new
tab only after both lists fail to identify the page. This is the pre-action target-selection protocol; it is distinct
from the combined post-action observation in step 7.
If the task names a new URL, prefer the reuse-aware entry: await agent.browsers.open(url) reuses an existing
same-site controlled tab (same hostname), activates it so the user sees it, and navigates in place, instead of
stacking a new tab on every navigation. Only when the task genuinely needs a parallel independent tab, create one
explicitly and follow this navigation sequence:
const tab = await browser.tabs.new();
await tab.goto("https://...");
await tab.playwright.waitForLoadState({ state: "domcontentloaded" });After every successful tab.goto(url), explicitly call await tab.playwright.waitForLoadState({ state: "domcontentloaded" }) before the first title, URL, or DOM observation. This explicit confirmation is required in the model-visible trajectory even when the backend navigation has already settled. Do not replace it with networkidle or a fixed sleep. Do not navigate to the same URL again; use tab.reload() only when a refresh is truly needed. A direct URL must come from the user, visible page facts, or an authoritative lookup — never guess path variants or resource IDs. Routine URL/load-state waits remain capped at 3000ms.
await tab.playwright.domSnapshot() is your primary way to read and understand the page. It returns the compact AI/ARIA tree, including computed roles, accessible names, states, open shadow DOM, and iframe bodies when available. Reuse the latest relevant snapshot until it becomes stale. If that snapshot already contains the target, act from its facts directly; do not write evaluate() code to rediscover related elements, enumerate inputs, dump HTML, or probe guessed selectors.
Build a stable Playwright locator only from snapshot facts. Never guess a label, accessible name, placeholder, selector, or URL pattern, and never use a guessed locator as an exploratory probe. Confirm count() when uniqueness is not obvious; if it is 0, re-snapshot immediately instead of action-waiting, and if it is greater than 1, tighten scope instead of using a positional shortcut. Then act through getByRole/getByText/getByLabel/getByPlaceholder/getByTestId/locator and terminal methods such as click/fill/press/selectOption/check.
A snapshot-proven heading or visible text does not need a link or button role to be clicked. Do not replace a snapshot-proven heading with a guessed link role. When the user's request authorizes navigation and that actual heading/text target is unique, click it directly; the DOM event may bubble to a JavaScript card handler.
The name option of getByRole(...) accepts a plain string or RegExp, including regex values created in the Node REPL VM.
After an action, collect the cheapest observation that answers your next question — use a targeted locator state check when possible and a fresh domSnapshot() when new locator ground truth is needed. Use at most one state-changing action per observation cycle. An unchanged source-tab URL does not prove the click failed. Judge an action by whether its expected effect appeared, not by whether browser.tabs.list() is non-empty. An existing source tab or unrelated controlled tab is not an action effect. The expected effect may be a source-page state change or a tab whose verified URL/title matches the intended result.
When an action may open a popup/new tab and the source tab does not show the expected effect, read browser.tabs.list() and browser.user.openTabs() unconditionally in the same observation cell. Prefer one combined observation:
const [controlledTabs, userTabs] = await Promise.all([
browser.tabs.list(),
browser.user.openTabs(),
]);
({ controlledTabs, userTabs });Return { controlledTabs, userTabs } as that cell's final result so the model makes one decision from both lists. Do not return the controlled list first or decide whether to query user tabs from its contents. Match both lists by verified id/url/title, then in the next cell activate the matching controlled tab or claim a matching user tab. Only after the source page and the combined tab observation all fail to show the expected effect may you take a fresh snapshot and choose a new locator. Do not request a DOM snapshot and a screenshot both by default.
Browser tabs persist for the lifetime of the current ZCode process unless you explicitly call tab.close() or
the user closes them. Use browser.tabs.finalize({ keep }) only to mark listed pages as deliverable or
handoff; omitting a tab from keep does not close it. Do not close research/source tabs merely because the
turn is ending.
playwright.domSnapshot() to read content and construct locators. Use targeted locator reads for selected/checked/success state once the target is known. It is cheaper and more precise than a screenshot.domSnapshot() and screenshot() in the same JS cell by default.screenshot() only when vision actually matters: (a) you need visual confirmation of layout / styling / rendering, (b) the user asked you to screenshot or to visually test a page, or (c) the target isn't in the snapshot (canvas / custom-drawn / non-DOM widget) and you need to aim coordinates.nodeRepl.write(await agent.documentation.get("screenshots")).screenshot() call must be emitted in the same JS cell with nodeRepl.emitImage(await tab.screenshot()). Never leave tab.screenshot() as the final expression and never return its Uint8Array bytes directly. If the user asked for screenshots, include the emitted images in your final response.When the task needs a WebM recording of an IAB tab, first read
nodeRepl.write(await agent.documentation.get("recording")). Use only the advertised
tab.recording.start/status/cancel API; do not launch an external browser or pass raw page code. A
recording is an asynchronous job and may outlive the fresh JavaScript call that starts it. Preserve its
string id, recover the same verified tab before every status/cancel batch, and pass a workspace-relative
.webm outputPath only when polling for the deliverable artifact.
tab.cua.* — coordinate path (visual): click({x,y}), double_click, move (hover), anchored
scroll({x,y,scrollX,scrollY}), full-path drag({path}), keypress({keys}), and type. Pair with
nodeRepl.emitImage(await tab.screenshot()) to aim. Use for canvas / custom-drawn / non-DOM widgets the snapshot misses.tab.dom_cua.* — node path (node_id comes from get_visible_dom()): click({node_id}), double_click({node_id}), scroll({node_id?,x,y}), keypress({keys}), and type({text}) after focusing the target.tab.playwright.waitForTimeout(timeoutMs) — fixed wait for the rare case where no concrete
page state can be observed yet. timeoutMs must be a non-negative integer. Do not call
tab.waitForTimeout(...); that root-level API does not exist in this runtime. Prefer a targeted wait or fresh domSnapshot()
over routine sleeps.tab.playwright.getByRole/getByText/getByLabel/getByPlaceholder/getByTestId/locator — lazy locator builders. Prefer these when a targeted state wait or a strict DOM action is clearer than a
snapshot ref. Common terminal methods include click, dblclick, fill, type, press, check,
uncheck, selectOption, waitFor, count, allTextContents, textContent, innerText,
getAttribute, isVisible, isEnabled, evaluate, and downloadMedia.tab.playwright.evaluate(...) and locator evaluate(...) execute JavaScript in the page context and may change page state. Use them for page-side logic that cannot be expressed through the high-level locator API; use the normal action methods when they communicate the intended interaction more clearly.tab.playwright.waitForURL(...), waitForLoadState(...), and expectNavigation(...).
Download events are supported. IAB file chooser/upload is explicitly unsupported.goto() accepts http:, https:, and exact about:blank. file:, other about:*, data:, and
javascript: targets are not navigable. A file: URL may still be used only as a getForUrl() backend-selection
hint when multiple backends exist.networkidle is present in the shared type but is rejected by every ZCode browser backend. For
expectNavigation(...), pass an expected url when the action must prove a new navigation; without url, an
already-loaded old page can satisfy the load-state waiter.BrowserCommandError on failure. A failed command does not mean the IAB or tab crashed. After a locator timeout/strict/selector-parse failure, take a fresh domSnapshot() and rebuild it from snapshot-proven facts; never retry the same locator. Routine locator, evaluate, and page-state operations use a 3000ms timeout budget.js call starts in a fresh kernel. Re-run the bootstrap and recreate the same browser wrapper from the user's explicit choice or the same verified URL/default rule. Before each new logical operation batch, recover tabs in a dedicated JS call and return await browser.tabs.list() to the model. After inspecting that output, use a second fresh JS call to select one by verified id/url/title and call browser.tabs.get(info.id) to activate it. tabs.list() returns metadata, not controllable Tab objects. Never select by array position when multiple tabs exist. If the list is empty, inspect browser.user.openTabs() and claim the matching user tab before creating a new one. This is pre-action stale-binding recovery; it does not override the same-cell combined tab observation required after an action may have opened a popup/new tab. Do not switch backend or create a duplicate tab merely because JavaScript bindings are fresh.js tool drives this browser. Do not use external browser MCP tools or shell browsers for it.© zai-org, Apache-2.0. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
Just SKILL.md in apps/zcode-cli/packages/browser-use-plugin/skills/control-browser of zai-org/ZCode.
Open the folder on GitHubat commit 29628c9
Control Browser next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Control Browser this skillzai-org/ZCode | 7.5k | — | ~4.6k | Automated safety check: Pass | Apache-2.0 | |
| Bright Data MCPbrightdata/skills | 264 | 1 repos | ~3.7k | Automated safety check: Pass | MIT | |
| Scrapingbee CLIScrapingBee/scrapingbee-cli | 108 | — | ~3.1k | Automated safety check: Pass | MIT | |
| Anti Detect Browserantibrow/anti-detect-browser-skills | 914 | — | ~9.8k | Automated safety check: Warn | MIT | |
| Skyvern Browser AutomationSkyvern-AI/skyvern | 23k | — | ~1.9k | Automated safety check: Pass | AGPL-3.0 | |
| Agent Browseroxylabs/agent-skills | 875 | — | ~3k | Automated safety check: Pass | MIT |
brightdata/skills
Bright Data MCP handles ALL web data operations. An agent skill from brightdata/skills.
ScrapingBee/scrapingbee-cli
Fetch and read any web page, search the web, crawl a site, or pull structured data out of pages.
antibrow/anti-detect-browser-skills
Drive Chromium from standard Playwright APIs with a real-device fingerprint applied in the kernel, one persistent isolated profile per identity, and a per-profile proxy whose exit IP sets timezone…
Skyvern-AI/skyvern
Automates websites with Skyvern's AI browser agent to fill forms, extract data, download files, log in and run multi-step workflows through SDKs, REST, MCP or a CLI.
oxylabs/agent-skills
Connects to Oxylabs remote agent browsers over the Chrome DevTools Protocol (CDP) with Playwright or Puppeteer.
Hacker-Valley-Media/Interceptor
Drive a signed-in Chrome / Brave / Safari session via the interceptor CLI: open/read pages, click, type, inspect DOM/text/network, automate rich browser editors and scene graphs, capture…
zai-org/ZCode
Apply the repository's architecture policy to code changes by generating a bounded context package, checking module and layer boundaries, and reporting baseline-aware violations.
zai-org/ZCode
Map a ZCode behavior change to current UI surfaces, state owners, protocol commands, persistence, and validation.
zai-org/ZCode
A skill your agent uses when needs to inspect TypeScript export references in the z-code workspace, list exports from a file, verify whether an export is unused before deletion, investigate who…
zai-org/ZCode
A skill your agent uses when writing, debugging, or resubmitting a dynamic-workflow script for the CreateWorkflow tool: choosing subagent topology, typing subagent results, fanning out over files or…
Works with
Categories
A skill your agent uses when opening, navigating, inspecting, testing, clicking, typing, filling, screenshotting, or verifying web pages and local HTTP targets (localhost, 127.0.0.1, ::1) inside…. Control Browser is an agent skill from zai-org/ZCode.1, ::1) inside ZCode, including browser/web-UI automation, rendered-page scraping, frontend checks, and visible page-state reading.
Control Browser fits situations like: verifying web pages and local HTTP targets (localhost; including browser/web-UI automation; rendered-page scraping; frontend checks.
Run `npx skills add zai-org/ZCode --skill control-browser -a claude-code`. Or copy the skill folder (apps/zcode-cli/packages/browser-use-plugin/skills/control-browser in zai-org/ZCode) into .claude/skills/control-browser in your project. Claude Code loads it when a task matches its description.
Run `npx skills add zai-org/ZCode --skill control-browser -a codex`. Or copy the skill folder (apps/zcode-cli/packages/browser-use-plugin/skills/control-browser in zai-org/ZCode) into .agents/skills/control-browser in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add zai-org/ZCode --skill control-browser -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/control-browser, .gemini/skills/control-browser, .github/skills/control-browser and .opencode/skills/control-browser in your project.
SKILL.md names no scripts, command-line tools or credentials: Control Browser is instructions for the agent only.
SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. Review the folder before installing.
Control Browser is published under the Apache-2.0 licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.6k tokens (SKILL.md is roughly 18k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full.
Skills that share tags, products or a category with Control Browser: Bright Data MCP (brightdata/skills, 264 stars), Scrapingbee CLI (ScrapingBee/scrapingbee-cli, 108 stars), Anti Detect Browser (antibrow/anti-detect-browser-skills, 914 stars) and Skyvern Browser Automation (Skyvern-AI/skyvern, 23k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
zai-org (a GitHub organization) maintains it in zai-org/ZCode, which has 7,486 GitHub stars. The repository holds 5 skills in this directory. The repository was last updated on September 29, 2026.
Source: zai-org/ZCode on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.