# How ego‑browser Integrates With External Agent CLIs Like Claude Code

> Learn how ego-browser connects AI agent CLIs like Claude Code. It injects an SDK and bridges calls via CDP messages, enabling seamless browser control.

- Repository: [CitroLabs/ego-lite](https://github.com/citrolabs/ego-lite)
- Tags: how-to-guide
- Published: 2026-08-02

---

**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`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts), the binary reads this snippet from **STDIN**, wraps it in an async function, and executes it:

```typescript
// 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`](https://github.com/citrolabs/ego-lite/blob/main/src/helpers.ts) and re‑exported through [`src/index.ts`](https://github.com/citrolabs/ego-lite/blob/main/src/index.ts):

```typescript
// 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:

```typescript
// 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

```bash
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:

```javascript
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`](https://github.com/citrolabs/ego-lite/blob/main/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`](https://github.com/citrolabs/ego-lite/blob/main/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`](https://github.com/citrolabs/ego-lite/blob/main/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`](https://github.com/citrolabs/ego-lite/blob/main/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 native `ego‑lite` process.
- **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`](https://github.com/citrolabs/ego-lite/blob/main/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.