WebHarness
Connects AI clients to files, terminals, and browsers on a personal workstation, with explicit controls over what each client can access.
Repository snapshot
WebHarness
Experimental public WSL MCP Personal Workstation reference.
- Domains
- 4
- Profiles
- 3
- Browser
- 2 surfaces
Work done
- Dev / Code / Terminal / Local
- browser-fast + browser-devtools
- OAuth + durable human handoff
WebHarness
Giving an AI agent a shell is easy. Turning a real development machine into an understandable workstation is the harder system.
- Problem: high-capability AI access becomes ambiguous when files, Bash, repository intelligence, long-lived terminals, and authenticated browser state all look like one generic permission.
- Decision: expose four capability domains—Dev, Code, Terminal, and Local—behind explicit trust profiles, with browser tools discovered through the Local broker instead of expanding the outer MCP catalog indefinitely.
- Proof: the public Personal Workstation reference combines OAuth + 1MCP, durable tmux PTYs, repository-rooted code intelligence, compact
browser-fastinteraction, fullbrowser-devtoolsdiagnostics, and explicit setup/startup boundaries on a qualified WSL2 environment. - Status: experimental public reference implementation;
personalis the maintained full workstation, whilerestrictedandtrusted-devdemonstrate narrower authority choices.
What it does
WebHarness turns a WSL development machine into a high-capability MCP workstation for ChatGPT and other MCP clients. Files, processes, repositories, terminal state, and browser profiles stay on the machine that owns them while the model sees a compact capability surface.
The point is not remote shell access by itself. The point is being able to answer: what can this session do, and where does that authority stop?
Four capability domains keep the workstation legible
Dev files · guarded edits · Bash · waits · host actions
Code repository-rooted search · context · symbols
Terminal durable PTYs · model/human handoff
Local tool discovery · schema lookup · invocation
-> browser-fast
-> browser-devtools
Dev owns ordinary machine work. Code owns repository intelligence. Terminal owns interactive process lifetime. Local is a broker for high-cardinality capabilities that should not bloat every client session.
That separation changes the routing question from “which of these dozens of tools might work?” to “which authority domain already owns this job?”
The trust profile is an explicit choice
There is no silent full-authority default:
restrictedkeeps ordinary file work workspace-bounded and uses a conservative shell surface.trusted-devdeliberately adds unrestricted Bash as the Linux service user on a dedicated host.personalis the maintained full Personal Workstation: broader WSL-user paths, Code, persistent Terminal, waits, Local/Browser, and optional Windows host sleep.
Those are different authority contracts, not cosmetic modes. A public checkout should not silently inherit the permissions of my own machine.
Durable terminals solved a different problem
Short MCP calls and long-running development processes have different lifetimes. A build, server, or interactive terminal should not disappear just because an MCP provider restarts or one HTTP request ends.
The bridge therefore keeps terminal PTYs under tmux and treats terminal ownership as a separate boundary. That lets a model start a real process, observe it later, and hand the same PTY to a human when input is required instead of inventing another shell path.
Browser control stays behind Local
The Personal Workstation does not publish a large browser catalog beside files and Bash. Local exposes only tool_list, tool_schema, and tool_call, then routes to two browser surfaces:
browser-fastuses Agent Browser for compact routine observation and interaction.browser-devtoolskeeps the fuller Chrome DevTools surface for network, console, performance, Lighthouse, heap, screenshots, and detailed debugging.
Both can target resource-local browser state without attaching everyday Chrome. The maintained Linux path can use managed Chrome or a persistent Clearcote profile under WSLg; Windows uses a dedicated MCP Chrome profile. Per-call browser targeting keeps that resource choice explicit.
The broker is intentionally boring. Adding or upgrading a downstream MCP does not force its whole schema into every outer session.
The public reference is deliberately qualified
WebHarness is a reproducible reference, not a claim of universal host support. The maintained environment is WSL2 + Ubuntu + x86_64 + Node.js 24+ + systemd user services, with WSLg for headed Linux browser capability.
doctor is non-mutating. setup qualifies dependencies and renders configuration. Persistent startup requires an explicit --enable-startup choice rather than being smuggled into bootstrap.
Cloudflare Tunnel is the current public HTTPS transport and 1MCP is the OAuth/MCP gateway. OpenAI Secure MCP Tunnel is documented only as a possible future connector path; WebHarness does not currently implement or supervise it.
Current state
The public reference now includes the four-domain Personal Workstation, durable terminal handoff, Local browser brokering, managed browser backends, and browser-fast / browser-devtools separation. It remains self-hosted workstation infrastructure, not a hosted multi-tenant agent service.
Note: WebHarness is an independent educational experiment exploring controlled AI-to-development-environment access. It is not designed or intended to bypass OpenAI safeguards or violate OpenAI’s Terms of Use or platform policies.
What I learned
The most valuable part of agent infrastructure is often not another capability. It is a clean answer to ownership, lifetime, and authority.
A tool surface becomes easier to trust when access is explicit, long-running state has one owner, and a private convenience does not quietly become a public default.