How ego‑browser Integrates With External Agent CLIs Like Claude Code
ego‑browser acts as a thin connection layer that lets any AI agent CLI drive the ego‑lite browser by accepting JavaScript via stdin, injecting a runtime SDK onto globalThis, and bridging calls to the native browser through CDP messages.
The ego‑lite project from citrolabs provides a headless browser stack built on Chrome DevTools Protocol (CDP). The ego-browser package specifically bridges external agent CLIs—such as Claude Code, Codex, or Cursor—to this browser engine. This article explains the three‑step integration pipeline, the key source files involved, and how to invoke the system from any shell‑capable agent.
The Three‑Step Integration Pipeline
Step 1: CLI → ego‑browser Binary
An external agent launches ego-browser as a Node.js executable and feeds it a JavaScript snippet through a heredoc. In src/index.ts, the binary reads this snippet from STDIN, wraps it in an async function, and executes it:
// package/ego-browser/src/index.ts#L56-L66
const code = fs.readFileSync(0, "utf-8"); // read from stdin
const wrapped = `(async () => { ${code} })();`;
await eval(wrapped);
The agent controls execution entirely through this stdin contract—no configuration files or persistent state required.
Step 2: ego‑browser → Runtime SDK
On startup, ego-browser installs the ego‑browser SDK onto globalThis via installEgoSdk(). This function, defined in the same entry file, exposes browser automation helpers such as click, goto, snapshotText, openOrReuseTab, and useOrCreateTaskSpace. The helpers themselves are collected in src/helpers.ts and re‑exported through src/index.ts:
// package/ego-browser/src/helpers.ts#L5-L30
export async function click(selector: string, opts?: ClickOpts): Promise<void> {
const node = await waitForSelector(selector, opts);
await ego.sendCDPMessage("Input.dispatchMouseEvent", {
type: "mousePressed",
x: node.center.x,
y: node.center.y,
button: "left"
});
// ... release, etc.
}
Because the SDK attaches to globalThis, the same helper surface is available whether the agent invokes ego-browser as a CLI or imports it programmatically as a Node module.
Step 3: SDK → ego‑lite Bridge
Each helper translates high‑level actions into CDP messages sent via ego.sendCDPMessage. The native ego‑lite process executes these commands in the browser, then marshals results back to the agent script. For example, snapshotText() calls Runtime.evaluate through the CDP bridge, parses the result, and returns clean text to the caller.
The CLI also redirects console.log to a dedicated output sink so agents can capture final results through stdout:
// package/ego-browser/src/index.ts#L75-L82
const originalLog = console.log;
console.log = (...args) => {
outputSink.write(args.map(a => String(a)).join(" ") + "\n");
originalLog.apply(console, args);
};
Invoking ego‑browser From Claude Code
Agents need only two operations: invoke the binary and supply a JavaScript heredoc.
Shell Invocation Via Claude Code
claude code --run '
ego-browser nodejs <<'"'"'EOF'"'"'
// Re-use a task space across heredoc rounds
const ts = await useOrCreateTaskSpace("demo-task")
cliLog(`task space id: ${ts.id}`)
// Open a page and take a screenshot
await openOrReuseTab("https://example.com", { wait: true })
await cliLog(await snapshotText())
EOF
'
The same pattern works with any CLI that executes shell commands—no vendor‑specific plugins required.
Direct Node Embedding
Agents that prefer in‑process integration can import the SDK directly:
import { installEgoSdk } from "ego-browser";
installEgoSdk(); // installs helpers on globalThis
await openOrReuseTab("https://example.com");
console.log(await snapshotText());
Key Source Files
Understanding these files clarifies how ego‑browser integration with external agent CLIs is implemented:
| File | Role |
|---|---|
package/ego-browser/src/index.ts |
CLI entry point; decides between runMain() (direct execution) or installEgoSdk() (SDK installation). Handles stdin reading, async wrapping, and output redirection. |
package/ego-browser/src/helpers.ts |
Defines and exports all public automation helpers that agents consume: click, goto, snapshot, openOrReuseTab, useOrCreateTaskSpace, and others. |
skills/ego-browser/SKILL.md |
Human‑readable specification of the agent‑facing API, intended for LLM consumption. Documents expected call patterns for Claude Code, Codex, Cursor, and custom agents. |
README.md |
States explicitly that ego‑browser is **"the connection layer between any agent CLI (Claude Code, Codex, Cursor, or a custom one) and ego‑lite"`. |
Summary
- ego‑browser exposes a stdin‑based contract: agents send JavaScript heredocs, the binary executes them in an async context.
- The SDK installs onto
globalThis, providing consistent helpers whether used via CLI or module import. - All browser operations route through CDP messages (
ego.sendCDPMessage) to the nativeego‑liteprocess. - Output redirection ensures agents capture results cleanly through stdout.
- No vendor lock‑in: any shell‑capable CLI can drive the system using the same heredoc pattern.
Frequently Asked Questions
What agent CLIs are compatible with ego‑browser?
Any CLI that can execute shell commands and pipe JavaScript to a binary. Verified patterns exist for Claude Code, OpenAI Codex, and Cursor, but the stdin‑based contract works with custom agents or CI pipelines without modification.
Does ego‑browser require persistent configuration between calls?
No. Each invocation is stateless. Agents that need persistence across commands use useOrCreateTaskSpace("name") to retrieve or initialize a task space, passing context through the heredoc rather than external files.
How does ego‑browser handle errors from the browser?
Errors thrown during CDP execution propagate through the SDK and surface as JavaScript exceptions in the agent script. The async wrapper in src/index.ts ensures uncaught rejections terminate the process with a non‑zero exit code, signaling failure to the calling CLI.
Can agents use TypeScript instead of plain JavaScript?
The stdin reader expects executable JavaScript. Agents using TypeScript should compile to JavaScript before piping to ego-browser, or invoke the SDK through Node's tsx or ts-node loader if running in a controlled environment where additional dependencies are acceptable.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →