Use when browser work requires choosing between a connector, a local browser, and an existing authenticated session, or when an agent must safely operate the user's logged-in browser - «открой в моём браузере», «используй мою сессию», «поработай в залогиненном браузере», "use my logged-in browser". Do not use for ordinary web research that can be completed with direct HTTP/search tools or for browser implementation details already owned by a project-specific test skill.
Installs into .claude/skills of the current project.
Are you the author of X9 Browser Session?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/xonika9-x9-browser-session)
---
name: x9-browser-session
description: Use when browser work requires choosing between a connector, a local browser, and an existing authenticated session, or when an agent must safely operate the user's logged-in browser - «открой в моём браузере», «используй мою сессию», «поработай в залогиненном браузере», "use my logged-in browser". Do not use for ordinary web research that can be completed with direct HTTP/search tools or for browser implementation details already owned by a project-specific test skill.
---
# Browser session
Use this skill in OpenCode, Claude Code, and Codex. It owns shared route selection, the
verified Edge adapter, runtime-specific extension and in-app surfaces, CDP fallbacks,
task-tab isolation, and focus safety. Re-check installed tool instructions and live
schemas when a named surface is absent.
## `chrome-devtools` MCP allowlist
Targets in this list bypass the browser extension in every route that offers one. An
entry matches the exact hostname and its subdomains; do not infer sibling or look-alike
domains.
- `avito.ru`
## Avito traffic discipline
Treat one account, browser profile, and public IP as one browsing lane for the whole
parent task. Avito work is sequential even when the rest of the research is delegated:
- appoint one Avito operator; subagents may analyze captured data but must not browse
`avito.ru` concurrently;
- keep only one Avito navigation, search, or listing load in flight. Prefer one task
tab; extra tabs may hold queued pages, but interact with only one at a time;
- let the current page finish loading and inspect it before requesting the next page;
shortlist from search results and reuse captured data instead of repeatedly reopening
or refreshing listings;
- do not bulk-load listings, paginate rapidly, poll availability, or repeat searches
and listing loads to work around throttling;
- when Avito shows a security warning, a `Продолжить`/`Continue` button leading to
CAPTCHA, or the CAPTCHA itself, keep the same page, controller, and profile. Wait
five seconds without another request and inspect it. If the challenge remains,
refresh that page at most twice, waiting five seconds and inspecting after each
refresh. Do not click that button or attempt to solve the CAPTCHA. Continue serial
browsing as soon as the requested content is visible;
- use the same bounded refreshes for a transient Avito error or site timeout page only
when the page can be safely reloaded. If the challenge or error remains after them,
or Avito returns `429` or access-denied, stop Avito requests across the parent task,
preserve collected results, and return `DEGRADED`. Do not switch controllers,
profiles, agents, or IP addresses to continue;
- resume only when the user requests another check or ordinary access is already
visibly restored. Perform that check serially through the same browser profile.
## Choose the surface
1. Prefer a purpose-built connector, API, or CLI when it can perform the semantic
operation. An explicit request to open, inspect, or operate a browser UI overrides
this preference.
2. Resolve the allowlist branch before initializing any browser controller. When the
target hostname matches the
[`chrome-devtools` MCP allowlist](#chrome-devtools-mcp-allowlist), use the runtime's
MCP route: OpenCode uses the live `chrome-devtools` target in its current tool catalog
without inferring a profile; Claude Code and Codex use MCP against the verified Edge
profile. Before declaring MCP unavailable, inspect both the directly exposed and
lazily discoverable live tool catalog; absence from the primary tool list is not
evidence that the MCP is unavailable. This route overrides the runtime default and
an explicit in-app selection. If MCP cannot attach or complete the operation,
continue directly to the `agent-edge` fallback under the shared unattended-Edge
condition.
3. In Claude Code or Codex, use the runtime's in-app browser immediately when the user
explicitly requests it. That explicit choice is sticky: do not substitute Edge or
another browser after an authentication or connection failure unless the user
approves the switch.
4. In Claude Code or Codex, use the runtime's in-app browser for local web development
and previews unless the user explicitly requests Edge:
- Codex: its in-app browser;
- Claude Code: its Browser pane.
5. For every other browser-control task, use the runtime-specific default:
- OpenCode: the live `chrome-devtools` MCP exposed in the current tool catalog;
- Codex: its browser extension in the verified Edge profile;
- Claude Code: `chrome-devtools` MCP against that Edge profile. Do not use the
Claude browser extension unless the user explicitly requests it.
6. In Codex, if the extension is unavailable, disconnected, or lacks a required
DevTools capability, retry its documented recovery once and then use
`chrome-devtools` MCP against the same Edge profile.
7. If MCP cannot attach or cannot perform the required operation, use `agent-edge`,
which connects `agent-browser` to the same Edge profile. Because the current
`agent-browser` brings newly created and selected tabs to the foreground, use this
fallback only when the user is not simultaneously working in Edge. If that condition
is unknown and the fallback would require creating or switching tabs, ask one short
question instead of taking over the window.
8. Once a controller works, keep it through ordinary stale-reference, redraw, and
timeout errors. Do not alternate controllers on the same task tab.
Outside the allowlist route above, the in-app browser remains the isolated route in
Claude Code and Codex for an explicit request and local web development. It has a
separate profile and does not carry the user's Edge extensions. Use Edge when exact
account state, region, cart, saved data, personalized content, ad blocking, or another
installed extension matters.
## Transient page recovery
When an inspected page shows a temporary loading error, a blank page in place of
expected content, a site timeout page, or a security or CAPTCHA screen, refresh its
task-owned tab up to twice, with a short pause and a fresh inspection after each
refresh. Try the refresh before clicking a button that opens a CAPTCHA; do not solve
the challenge automatically. Stop when the intended content appears or the attempts
are exhausted; report the remaining failure. Refresh only when repeating the current
page load is safe: never replay a submission, purchase, message, or other action that
could change state. A `429` or access-denied response is a stop signal. For Avito,
use its specific traffic discipline above instead of this general recovery rule.
## Browser and profile continuity
Keep the browser and existing profile selected by this skill for all work within that
surface, including local HTML previews and testing. Use task-owned background tabs;
do not pass `isolatedContext` or an equivalent new-context option, create a fresh
profile, or launch a clean browser unless the user explicitly requests that isolation.
This preserves the selected testing environment, not just authentication.
Establish the actual controller-to-browser/profile binding from the current runtime's
connection evidence. For a CDP route, tie the controller's target endpoint to the
browser process and expected profile. A separately reachable CDP port, controller
availability, or a matching User-Agent does not establish that binding.
After a browser restart or controller reconnection, discard stale page IDs. Resume
only when the binding above is re-established, then enumerate the pages again. If it
cannot be established, stop dependent browser work and report the missing evidence
instead of creating another context. This recovery rule takes precedence over the
general fallback chain for a lost connection to an already selected browser.
## Shared Edge safety
Treat the executable, profile, extensions, localhost CDP endpoint, launcher, and
controllers as adapter parameters. On another machine, substitute and verify them
instead of copying the Edge-specific values below.
- use the dedicated, continuously used automation profile rather than the browser's
default profile;
- attach every controller to that same existing Edge profile rather than launching a
clean browser;
- apply [browser and profile continuity](#browser-and-profile-continuity) to the
actual Edge connection, including unauthenticated previews and tests;
- create a task-owned background tab; never assume the user's active tab is the task tab;
- with an extension, use its session-owned logical task tab and leave it inactive;
- with `chrome-devtools`, create the page with `background: true`, select it with
`bringToFront: false`, and never invoke `Page.bringToFront` or
`Target.activateTarget`;
- never control one tab through the extension and CDP at the same time;
- keep credentials, cookies, tokens, and local storage in the dedicated browser profile rather than copying them into prompts or repository files;
- assume the controller and model can receive inspected page contents and network data; avoid opening unrelated private surfaces, do not capture network headers unless the task requires them, and never echo secret header values into chat, logs, or files.
Do not run browser-wide HAR or broad network capture in the personal Edge profile.
That work requires the user's explicit approval of a separate disposable browser
profile; without it, omit the capture rather than silently switching environments.
## Verified Edge adapter
- Profile: `~/Library/Application Support/Microsoft Edge Automation`.
- Launcher: `~/Applications/Edge (Agent).app` with remote-debugging port `9223`.
- Codex primary outside the exceptions in [Choose the surface](#choose-the-surface):
the ChatGPT browser extension installed in this Edge.
- Claude Code primary outside the local-development exception: `chrome-devtools` MCP.
- Codex MCP route: `chrome-devtools` MCP configured with
`--browserUrl http://127.0.0.1:9223`.
- Last fallback: `agent-edge`, which wraps `agent-browser --cdp 9223` against the same
profile.
- Leave pre-existing tabs, windows, downloads, bookmarks, and settings untouched.
- Re-snapshot after navigation, filtering, modal changes, and redraws because element references become stale.
- If an Edge route cannot attach, confirm that `Edge (Agent).app` is running before
declaring that controller unavailable.
Read before mutating. Posting, purchasing, sending, deleting, or changing account data still requires authority from the user's request.
## OpenCode
- Use the live `chrome-devtools` MCP in the current tool catalog as the primary
browser-control surface. Do not infer configuration paths, flags, or a separate
in-app browser from another runtime.
- Create a task-owned page with `background: true`, select it with
`bringToFront: false`, and keep one controller on that task page. Apply the shared
private-surface safety and Avito traffic rules.
- If the MCP is absent, use `agent-edge` only under the shared unattended-Edge
condition. A restart conclusion is permitted only when safe evidence shows that the
MCP is configured but not visible in the live catalog; otherwise return `DEGRADED` or
`BLOCKED` with the missing prerequisite.
## Claude Code
- For local web development, previews, and an explicit request for the built-in
browser, use the Claude Code Browser pane. Read its current tool instructions
before acting; this exception remains primary for that scope.
- For other browser work, use the `chrome-devtools` MCP from `~/.claude.json` with the
shared focus-safe rules. Do not initialize or fall back to the Claude browser
extension unless the user explicitly requests that extension.
- If MCP tools are absent after Edge is running, restart Claude Code once. Use
`agent-edge` only under the shared unattended-Edge condition.
## Codex
Resolve the hostname and its allowlist branch before calling any Codex browser-control
tool. For an allowlisted hostname, inspect the live lazy tool catalog for
`mcp__chrome_devtools__list_pages` and the related `mcp__chrome_devtools__*` tools. In
the current Codex runtime, this catalog is available as `ALL_TOOLS` inside
`functions.exec`. When the tools are present, begin with
`mcp__chrome_devtools__list_pages`; do not initialize `mcp__cua_repl` on this branch.
When the selected branch is the in-app browser or Edge extension, use the live
browser-control tool instructions as the API owner. The current desktop surface for
those branches is `mcp__cua_repl.js`; read its entry-point contract before initializing
it, then use only the `cua` APIs documented by that tool and its returned documentation.
If that surface is absent, discover the installed browser controller rather than
assuming a skill name or initialization method from another Codex version.
- For the in-app branch selected by [Choose the surface](#choose-the-surface), select
the explicit `iab` binding. The current entry point is `cua.createBrowserTab` with
that browser identifier; choose visibility according to the requested preview.
- For the Edge extension branch, select Edge explicitly through the documented
named-browser entry point. Do not let URL-based default selection choose a different
browser. Use the tool's session name and task-tab ownership contract; resolve a
user-mentioned existing tab through its documented inventory and selection route.
- Verify the actual selected profile under [browser and profile continuity](#browser-and-profile-continuity).
Follow documented background-tab semantics; do not invent focus or profile options.
A route that cannot preserve the required profile or focus is unavailable for that
task and follows the permitted fallback chain.
- The Codex MCP route uses `~/.codex/config.toml` and the shared focus-safe rules.
It is primary for allowlisted hostnames. Outside the allowlist, enter it only after
the Edge extension remains unavailable following its documented troubleshooting.
- If MCP tools are absent after Edge is running, restart Codex once. Use `agent-edge`
only under the shared unattended-Edge condition.
## Install an adapter
Read [references/setup.md](references/setup.md) for the portable adapter contract and the verified Edge example. Never commit browser profile contents or credentials.
## Failure behavior
For the Avito signals defined in
[Avito traffic discipline](#avito-traffic-discipline), follow that section's stop rule
instead of entering the controller fallback chain.
Report cancelled or failed browser calls as failures. For an implicit/default browser
selection, use the runtime-specific chain: Codex extension → MCP → `agent-edge`;
OpenCode MCP → `agent-edge`; Claude Code MCP → `agent-edge`; use the allowlist route defined in
[Choose the surface](#choose-the-surface) instead of the Codex default. For an allowed
explicit in-app choice, do not enter an Edge chain without approval. If an implicitly
selected local-development browser is unavailable, use the runtime's Edge chain and
report the fallback. Do not substitute remembered data or a public page when the task
required the authenticated source. Return `DEGRADED` or `BLOCKED` with the failed route
and missing prerequisite when the permitted chain is exhausted.
## Done
Report the runtime, browser surface, controller, task-owned tab or page, requested
result, and any checks that could not be completed. For mutating work, verify the
resulting UI state or server response before claiming completion.
The [onboarding declaration](references/onboarding.json) is the machine-readable onboarding contract.