Isolated Linux Agent Workspace
agent-sh/agent-workspace-linux
Drives a hidden, agent-owned Linux desktop and browser over MCP for GUI testing and web automation without touching the user's real desktop.
Control, inspect, or audit Horizon browser panels through public browser MCP tools.
$ npx skills add peters/horizon --skill horizon-browser -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install peters/horizon horizon-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/peters/horizon.git skills-src && mkdir -p .claude/skills && cp -r skills-src/assets/plugins/codex/skills/horizon-browser .claude/skills/horizon-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 "horizon-browser" agent skill from https://github.com/peters/horizon/tree/main/assets/plugins/codex/skills/horizon-browser into .claude/skills/horizon-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "horizon-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/peters/horizon/tree/main/assets/plugins/codex/skills/horizon-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 peters/horizon --skill horizon-browser -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install peters/horizon horizon-browser --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/peters/horizon.git skills-src && mkdir -p .agents/skills && cp -r skills-src/assets/plugins/codex/skills/horizon-browser .agents/skills/horizon-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 "horizon-browser" agent skill from https://github.com/peters/horizon/tree/main/assets/plugins/codex/skills/horizon-browser into .agents/skills/horizon-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "horizon-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 peters/horizon --skill horizon-browser -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install peters/horizon horizon-browser --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/peters/horizon.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/assets/plugins/codex/skills/horizon-browser .cursor/skills/horizon-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 "horizon-browser" agent skill from https://github.com/peters/horizon/tree/main/assets/plugins/codex/skills/horizon-browser into .cursor/skills/horizon-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "horizon-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/peters/horizon.git --path assets/plugins/codex/skills/horizon-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 peters/horizon --skill horizon-browser -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install peters/horizon horizon-browser --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/peters/horizon.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/assets/plugins/codex/skills/horizon-browser .gemini/skills/horizon-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 "horizon-browser" agent skill from https://github.com/peters/horizon/tree/main/assets/plugins/codex/skills/horizon-browser into .gemini/skills/horizon-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "horizon-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 peters/horizon horizon-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 peters/horizon --skill horizon-browser -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/peters/horizon.git skills-src && mkdir -p .github/skills && cp -r skills-src/assets/plugins/codex/skills/horizon-browser .github/skills/horizon-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 "horizon-browser" agent skill from https://github.com/peters/horizon/tree/main/assets/plugins/codex/skills/horizon-browser into .github/skills/horizon-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "horizon-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 peters/horizon --skill horizon-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 peters/horizon horizon-browser --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/peters/horizon.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/assets/plugins/codex/skills/horizon-browser .opencode/skills/horizon-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 "horizon-browser" agent skill from https://github.com/peters/horizon/tree/main/assets/plugins/codex/skills/horizon-browser into .opencode/skills/horizon-browser/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "horizon-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.
horizon-browserControl, inspect, or audit Horizon browser panels through public browser MCP tools.
Horizon Browser is an agent skill from peters/horizon. Control, inspect, or audit Horizon browser panels through public browser MCP tools.
Its SKILL.md is about 4.8k 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 MCP servers and Browser automation. It works with Model Context Protocol. The repository describes itself as: GPU-accelerated terminal board that puts all your sessions on an infinite canvas. The licence is MIT.
Read from SKILL.md and the folder at commit 39421a4. 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.
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.
Horizon Browser loads about 4.8k tokens when it runs. Until then it costs about 25 tokens; SKILL.md has 2,673 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 peters/horizon at commit 39421a4, republished under its MIT licence (© peters). 2,673 words, ~4,770 tokens.
.claude/skills/horizon-browser/SKILL.md (or your agent's skills folder).Native VNC Device panels, simulators, and isolated desktop tests use the
horizon-device skill. The workflow below applies to browser pages.
Use the browser_* MCP tools as the only agent-facing browser contract. Do
not inspect Horizon runtime files, connect to raw CDP/BiDi/WebDriver endpoints,
or invoke a browser-control CLI. If the MCP tools are unavailable, report that
the Horizon browser MCP server is not connected.
Start with browser_list when the panel id is unknown. If it returns no panels,
call browser_create; this opens a panel in the current agent's Horizon
workspace and returns its ready panel id once the backend is ready and, when
you passed a url, once that page committed (navigation: committed). A
navigation: pending result means the panel is controllable but the first
page had not committed within the bounded startup wait, so use browser_wait
or browser_panel before reading it; navigation: failed means that page
failed to load (navigation_error says why) and you must navigate again or
fix the URL; navigation: superseded means the user navigated the panel
first, so read panel.url before acting. If browser_list returns a usable panel, reuse
that panel for iframe, popup, dialog, and consent interactions. Never create or
reveal a helper panel as a workaround. Only when the user explicitly requests
another independent browser session may you call browser_create with
allow_additional: true. Omit backend to use Horizon's
configured browser, or select chromium, firefox, or safari when the
platform supports it. To run at a configured remote target instead of a
local browser, pass target with its name and omit backend; Horizon
resolves the provider and credentials from its configuration, and a
refusal carries a typed code and at most the target, provider or credential
reference name, never a credential value. Such a panel reports
remote_target, remote_device (the model, OS version and hardware
evidence the provider itself reported, verified against the target before
the panel became ready), classic WebDriver and no network capture. A target
that requires a physical device is refused as remote_device_rejected unless
that evidence confirms it, after Horizon attempts to release the session; a
remote_allocation_unknown refusal means a device may still be held, so check
with the user before creating again; remote_authentication_failed,
remote_not_entitled and remote_device_unavailable say which of the
credential, the account's automation access or the device request the provider
refused, with nothing held. Cite remote_device, not the target
name, as real-device evidence. Set visible: false for background automation; use
browser_visibility to show or hide the live panel later without stopping its
session, capture, ownership, or MCP control. Call browser_close on a panel
you own when the user is done with it or a remote device session must be
released now; it stops the session, releases any remote allocation, and the
panel leaves browser_list. Read anything you still need from
browser_audit before closing: it answers only for a live panel. An optional bare-host url
defaults to HTTPS while explicit HTTP remains available. Use browser_panel
for a known panel. Discovery and control are scoped to the workspace that
contains your agent panel: browser_list never shows panels from other
workspaces, every other tool rejects their ids, and a panel's visible field
is host presentation state, not proof that the panel is in your workspace. If
nothing usable is listed, create a panel rather than guessing an id. Before
interacting, call browser_snapshot or browser_query and prefer its
short-lived ref in browser_act. Navigation, another snapshot or query, and
browser_wait can invalidate earlier refs, so reacquire a ref immediately
before an action when the page may have changed.
When the user explicitly requests another panel sharing an existing login, call
browser_duplicate with the source panel_id. The source must be a ready local
Chromium or Firefox panel in your workspace; ownership and handoff guards still
apply. The panels share cookies and persistent site storage, so logging out in
one affects the others. Navigation and input are independent; forms, history,
and live JavaScript state are not copied. This does not authorize helper panels
as a workaround for iframe, popup, dialog, or consent interactions.
Snapshots expose iframe boundaries as iframe nodes. On local Chromium and
Firefox, snapshots and queries also return child-frame nodes, including nodes
inside cross-origin frames. Use their returned refs with browser_act click
or fill. A frame navigation makes its old refs stale. If a frame changes during
a scan, the scan returns stale_reference; take a new snapshot or query.
Context events from unrelated pages do not invalidate this scan.
Chromium ignores destruction of isolated execution contexts during a scan.
Nested session retirement processes each tracked parent link once and preserves siblings.
Direct selector actions, browser_wait, and browser_evaluate target the
top-level document. Child-frame
refs do not support scroll or set_files. Safari and remote sessions scan only
the top-level document. If these tools cannot reach the embedded frame content,
use browser_handoff on the original panel only when its capabilities include
handoff. Remote sessions do not support manual steering and return
unsupported_backend; report that limitation. Do not open a separate panel for
the frame.
Local fills support contenteditable elements, textareas, and input types text,
search, tel, url, email, password, and number. Other controls and
read-only fields return element_not_editable; use set_files for file inputs.
If an onfocus handler redirects focus or an inert ancestor prevents focus, the
fill returns element_not_focused before it clears the value or sends an input
event. If an input handler moves focus during clearing, the fill stops before
it sends the requested text to the field that receives focus. The check retains
the original element even if the handler transfers its selector to another field.
The focus and clearing checks wait for queued microtasks, including nested microtasks.
If a focus or clearing handler disables the target, fill returns element_disabled.
These checks cover native and ARIA disabled state, including queued changes.
browser_navigate returns a typed outcome: by default it waits until the
document committed and reports committed_url, title when known, loading,
redirected, and state. Check completed; a timed_out state carries the
latest page state so you can inspect or retry, and wait: dom_content_loaded
or wait: dispatched (handed to the backend, browser acceptance not awaited)
change how long it waits; timeout_millis is raised to
at least 1000 ms, and on Safari every wait returns once the page loaded or the
bound elapsed. After navigation or
interaction, verify the visible outcome with browser_wait, browser_query,
or a new snapshot. browser_wait is one audited engine-side action that
observes the page itself: it returns the matched nodes and elapsed_millis,
and fails with a typed code (wait_timeout, wait_navigation_invalidated,
wait_ownership_lost, wait_handoff_pending, wait_superseded,
browser_unavailable when the backend stops) instead of looping on queries,
so do not poll it in a tight loop; pick a timeout_millis that covers the
expected change. Use browser_evaluate only when the semantic tools cannot
answer the question.
browser_http_auth operations are set and clear.
If a page presents HTTP Basic or Digest authentication, call
browser_http_auth with operation: set, the username and password the user
supplied, and origin (http://host[:port] or https://host[:port]) when
known, before browser_navigate, or set then reload if the protected page is
already open. If origin is omitted, it binds to the current page origin and
fails when the page has none. If the user has not supplied credentials, ask for
a username and password instead of guessing. The engine provides those
credentials only to matching server challenges for that origin on local
Chromium and Firefox. Do not put the password in
browser_evaluate or audit commentary. Safari and remote sessions return
unsupported_backend. Call operation: clear to drop live-session credentials
for later intercepted challenges; it does not revoke Authorization values the
browser already cached, so open a new panel for a clean unauthenticated
session.
browser_network operations are start, status, and stop.
For HTTP or WebSocket observation, first inspect the panel's
network_capture field from browser_list or browser_panel. When supported,
call browser_network with operation: start before navigation so open,
frames, errors, and close are all observed. Use URL filters and payload/file
limits for busy streams. To capture HTTP response content, set both
include_http: true and include_http_bodies: true, and check
http_response_body_transport first. Bodies appear as bounded
http_response_body records; they may contain sensitive page data and never
belong in the action audit. The result returns live connection counters and one
private NDJSON export path. Prefer browser_network_watch for event-driven
monitoring: filter by URL and event kind, leave payloads excluded unless needed,
then pass the returned capture_id and next_sequence into the next call. It
reports timeout, capture stop/replacement, gaps, drops, truncation, file limits,
and writer failure explicitly. For sustained local analysis, it is also safe to
inspect the exact path returned by browser_network with read-only tools such
as tail -f, jq, or rg; never infer or inspect another Horizon runtime
path. Call operation: status to inspect the active or last capture without restarting it.
Call operation: stop to flush the capture.
For page-pixel recording, inspect video_capture then call browser_video
with operation: start. Optional start-only knobs: quality (1-100),
compression_level (0-10, higher is slower/smaller), fps (1-30),
max_width (320-1920, caps the longest encoded side), max_file_bytes.
Omitted options keep the host browser.video settings. The host defaults are
quality 90 and source-frame sizing with codec-block alignment, bounded by a
3840-pixel longest side and 8,294,400 pixels (4K); larger frames are downscaled
proportionally. An explicit
host size cap remains active when a recording omits max_width. These
encoding settings do not resize the page viewport. Pause skips time in the file;
resume continues the same WebM; stop finalizes a private .webm path.
Use operation: status to inspect the active or last recording without changing it.
browser_video operations are start, pause, resume, status, and stop.
Page pixels never enter the action audit. The recording samples the existing
decoded frame slot on Chromium, Firefox, and Safari.
Chromium HTTP bodies and WebSocket frames are protocol-native, but CDP cannot
return a fetch() body the page drained with response.blob(); that
http_response_body record carries an error and no payload, so when the
bytes matter, read text() or arrayBuffer() or leave the body unread. A
top-level navigation to a PDF is different: it captures the viewer's HTML
shell as a normal successful body, never the PDF bytes. Firefox HTTP
bodies are native WebDriver BiDi, while WebSocket frames use page
instrumentation because standard BiDi does not expose them; the panel
advertises both distinctions. Safari network capture is currently unsupported.
Do not describe Firefox WebSocket instrumentation as undetectable.
When the user must steer, first check that the panel advertises handoff.
Remote sessions return unsupported_backend without starting a handoff or
wait. For supported local sessions, announce what the user needs to do in a
progress message, then call browser_handoff with a concise reason. Keep this turn active until
the user selects Done — hand back to agent. Omit timeout_millis for the
15-minute human wait; do not substitute a short page-action timeout such as
60000 ms. Leave wait true (the default) and stop issuing page actions while
the user steers. Set wait: false only for an explicitly nonblocking script.
A yielded or backgrounded tool invocation is still running: keep awaiting that same invocation using the client's wait mechanism until its result arrives. Do not send a final response saying you are waiting: ending the turn leaves no pending call for the Done button to resume.
If the handoff times out, call browser_panel once. If handoff_pending is
still true, call blocking browser_handoff again
with resume_request_id from the timeout and the default timeout. This resumes
that request without undoing a concurrent Done click; it renews an expired lease
only if the recorded owner and request still match. Keep waiting in this turn.
If handoff completed,
or the call returns handoff_pending: false, take a fresh snapshot and resume
the task without requiring another chat message. Stop on explicit cancellation,
panel closure, lost ownership, or an unrecoverable connection failure and report
the actual condition. Do not poll browser_list for hand-back.
Use browser_audit to review the
redacted ordered action history or to verify a specific action id. The default
page is the newest matching records (limit 1-500, default 100). To iterate
every retained record, call with from_start: true and reuse next_event_id
as after_event_id until has_more is false. Treat cursor_lost,
malformed_records, and older_records_dropped as explicit loss.
For remote devices, set orientation: portrait or orientation: landscape on
a configured target, or supply orientation with target in browser_create
for a session-only override. Configured and catalog targets use the same option.
An explicit configured or per-call orientation requires matching measured geometry
on the first committed document before readiness. A pending, failed or unmeasurable
first page is rejected with a typed orientation error and exact-session release
attempt; default creates without an explicit orientation keep the pending contract
above.
Check orientation_support (supported, unsupported, or unverified) and
remote_orientation, then call browser_orientation with panel_id and
orientation to rotate a supported session. The tool waits for the device and
measured page geometry and returns requested/applied orientation and CSS viewport
dimensions. Reacquire refs after rotation. An unsupported endpoint returns
orientation_unsupported; an ignored start request returns
remote_orientation_mismatch after Horizon attempts release. Inspect uncertain
release before creating again, and inspect the page before retrying a runtime
timeout because the device may already have rotated. Remote resize remains
remote_viewport_fixed; orientation does not emulate arbitrary dimensions.
For responsive layouts, inspect the panel's resize capability, then call
browser_resize with panel_id, width and height (320-8000 CSS pixels per
axis). Chromium and local Firefox support this; Safari returns
viewport_unsupported and remote devices return remote_viewport_fixed.
The result contains requested and browser-measured applied width/height.
The pin survives host layout, visibility changes and navigation in that live
session; the canvas panel letterboxes it. Call browser_resize with
reset: true and no dimensions to resume the latest host panel size; its
requested is null and applied is measured too. Session replacement/restart
clears the pin. A timeout/failure may follow a backend mutation: inspect the
page or retry rather than assuming no change. browser_video max_width and
codec alignment affect encoding only. Reacquire semantic refs after resizing.
browser_remote_allocations operations are list and reconcile.
For capacity retained after a remote panel disappears, use
browser_remote_allocations with operation: list, then operation: reconcile
and one returned reference. This checks only the exact retired allocation
at its original provider. Active, unidentified, or uncertain sessions retain
their holds. Repeated reconciliation is safe; never infer release from an
empty panel list or account-wide session counts. The user can also reconcile
in Settings > Remote browsers.
Call browser_provider_devices with a configured provider and optional search
words. Read at most 50 returned combinations per page, then use next_offset
for another page. Pass the returned target reference to browser_create with
backend omitted. A catalog entry proves neither entitlement nor capacity.
Call browser_provider_usage without a provider for all profiles, or with a
configured provider name. Read sample time, running/allowed counts, queues, and
per-profile errors. Profiles use their own credential bindings; names alone do
not provide isolation. Usage does not reserve a device. Never pass credentials
or raw provider capabilities.
browser_act operations are click, fill, scroll, reload, back, forward,
set_files, and drop_files. A click accepts count: 1..3, including a trusted
double-click with 2. Use a fresh ref or selector and examine the visible result.
For set_files, target the actual input[type=file], even when hidden.
Use its file_input metadata for accept and multiple-file policy.
For drop_files, target a visible drop element on local Chromium or Firefox.
Supply 1..32 absolute regular-file paths under the configured agent work root
or an explicitly permitted attachment root. These paths are on the server host.
Do not widen roots or upload private files without task authorization.
Read attached names and sizes for set_files, then examine page acceptance.
A dispatched drop does not prove that an application accepted the files.
browser_screenshot returns retained viewport pixels as a private PNG path and
original dimensions. It requires a ready panel and a live supporting Horizon
host. It takes no fresh navigation or full-page capture. Optional
copy_to_clipboard defaults false; clipboard_requested proves host dispatch,
not OS acknowledgement. Capture claims ownership and refuses another live owner,
human steering, or pending handoff. It changes no focus, visibility, or canvas.
Copy needed evidence before panel close or host exit; only eight exports remain.
Casting uses horizon-cast. Cloud offers and companions use horizon-cloud.
Native iOS and Android sessions use horizon-app-testing.
© peters, MIT. 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 assets/plugins/codex/skills/horizon-browser of peters/horizon.
Open the folder on GitHubat commit 39421a4
Horizon 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 |
|---|---|---|---|---|---|---|
| Horizon Browser this skillpeters/horizon | 716 | — | ~4.8k | Automated safety check: Pass | MIT | |
| Isolated Linux Agent Workspaceagent-sh/agent-workspace-linux | 186 | — | ~2.1k | Automated safety check: Pass | MIT | |
| Xiaohongshu Content Researchjumodada/Drissionpage-MCP-Server | 487 | — | ~768 | Automated safety check: Pass | Custom licence | |
| CLI Anything SafariHKUDS/CLI-Anything | 52k | — | ~3.4k | Automated safety check: Pass | Apache-2.0 | |
| Zerotoken OpenclawAMOS144/ZeroToken | 455 | 1 repos | ~2.9k | Automated safety check: Pass | MIT | |
| Unbrowseunbrowse-ai/unbrowse | 782 | — | ~3.3k | Automated safety check: Pass | MIT |
agent-sh/agent-workspace-linux
Drives a hidden, agent-owned Linux desktop and browser over MCP for GUI testing and web automation without touching the user's real desktop.
jumodada/Drissionpage-MCP-Server
A skill your agent uses for authorized, read-only research on public Xiaohongshu content or the local Xiaohongshu-like playground fixture.
HKUDS/CLI-Anything
Safari browser automation CLI on macOS via safari-mcp. An agent skill from HKUDS/CLI-Anything.
AMOS144/ZeroToken
A skill your agent uses when using ZeroToken MCP via OpenClaw for browser automation, trajectory recording and low-token replay, especially for recurring or scheduled browser tasks.
unbrowse-ai/unbrowse
Search and call websites through Unbrowse's hosted API or remote MCP, reuse indexed site tools, read pages, and learn missing routes in its cloud browser.
AIPexStudio/AIPex
Lets an agent drive Chrome through the AIPex extension and its MCP bridge: navigation, clicking, form filling, screenshots, tab management and downloads.
peters/horizon
Check that a microphone is usable for Horizon dictation and report which layer is at fault — no signal, bad level, or a genuine model/accent limit.
peters/horizon
Manage Horizon native VNC Device panels and drive isolated local desktops for simulators and native application tests through devicepanel and the horizon-device CLI/MCP.
peters/horizon
Run or inspect declared iOS and Android native app tests through Horizon devicetestrun and app MCP tools.
peters/horizon
Cast Horizon panels, workspaces, cloud cards, or its main window to Apple TV through the public cast MCP tool.
peters/horizon
Inspect Horizon cloud offers and companions, control explicitly authorized companion workers, use a worker Local Network Bridge, or ask for GitHub access from a cloud worker through public MCP tools.
Works with
Categories
Control, inspect, or audit Horizon browser panels through public browser MCP tools. Horizon Browser is an agent skill from peters/horizon. Control, inspect, or audit Horizon browser panels through public browser MCP tools.
Horizon Browser fits situations like: tasks that involve MCP servers; tasks that involve Browser automation.
Run `npx skills add peters/horizon --skill horizon-browser -a claude-code`. Or copy the skill folder (assets/plugins/codex/skills/horizon-browser in peters/horizon) into .claude/skills/horizon-browser in your project. Claude Code loads it when a task matches its description.
Run `npx skills add peters/horizon --skill horizon-browser -a codex`. Or copy the skill folder (assets/plugins/codex/skills/horizon-browser in peters/horizon) into .agents/skills/horizon-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 peters/horizon --skill horizon-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/horizon-browser, .gemini/skills/horizon-browser, .github/skills/horizon-browser and .opencode/skills/horizon-browser in your project.
SKILL.md names no scripts, command-line tools or credentials: Horizon 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.
Horizon Browser is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.
About 4.8k tokens (SKILL.md is roughly 19k 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 Horizon Browser: Isolated Linux Agent Workspace (agent-sh/agent-workspace-linux, 186 stars), Xiaohongshu Content Research (jumodada/Drissionpage-MCP-Server, 487 stars), CLI Anything Safari (HKUDS/CLI-Anything, 52k stars) and Zerotoken Openclaw (AMOS144/ZeroToken, 455 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
peters (a GitHub user) maintains it in peters/horizon, which has 716 GitHub stars. The repository holds 6 skills in this directory. The repository was last updated on October 10, 2026.
Source: peters/horizon on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.