Skip to main content
skill CX Codex

kernel-typescript-sdk — Claude Code skill: Kernel browser automation

A skill for driving Kernel browser sessions from TypeScript: server-side Playwright or CDP, profiles, proxies, and session cleanup.

Install into Claude Code · Skills CLI (Vercel) All methods and platforms ↓
npx skills add kernel/skills --skill kernel-typescript-sdk -a claude-code
Open on GitHub

What kernel-typescript-sdk does

This skill covers writing TypeScript against @onkernel/sdk: creating browser sessions, running them through server-side Playwright or attaching over CDP, persisting state in profiles, and routing traffic through proxies. It fits server-side automation work where you would rather not babysit a local browser.

There are two paths. Server-side Playwright via kernel.browsers.playwright.execute() runs your code next to the browser, so no local Playwright install is needed. Reach for CDP when a local library has to drive Playwright itself or when you are debugging by hand. Every execute call gets a fresh context, so keep dependent steps in one call or return the state the next call needs.

The cleanup rule is the point of the skill: delete a session in finally. The idle timeout is a safety net, not the normal path. With CDP, close the local client first and delete the Kernel session after — browser.close() does not free Kernel resources. Create profiles before attaching them, and set save_changes: true only when this session's changes should survive. You need KERNEL_API_KEY in the environment, and playwright-core if you go the CDP route. Do not rename a profile while a browser references it by name; session changes may fail to save.

For one-off kernel ... commands, use the separate kernel-cli skill.

What it helps with

  • create a Kernel browser session from TypeScript and tear it down cleanly
  • run a flow through server-side Playwright without installing it locally
  • attach over CDP and reuse the browser's existing context
  • keep a login across runs with a profile
  • check a proxy before automation depends on it

Example prompts for the agent

  • write a TypeScript script that creates a Kernel session, navigates with server-side Playwright and returns the page title
  • connect to the session over cdp_ws_url with playwright-core, then close the client before deleting the session
  • create an example-login profile with save_changes: true and attach it to a new session

How to install kernel-typescript-sdk

1Skills CLI (Vercel)

npx skills add kernel/skills --skill kernel-typescript-sdk -a claude-code

2Manually: put the files in place

~/.claude/skills/kernel-typescript-sdk/SKILL.md

Copy the whole skill folder; for one project use .claude/skills/kernel-typescript-sdk/

Step by step, with commands for each platform: How to install skills in Claude Code: five ways

Questions about kernel-typescript-sdk

How do I install kernel-typescript-sdk in Claude?

Run npx skills add kernel/skills --skill kernel-typescript-sdk -a claude-code. The skill lands at ~/.claude/skills/kernel-typescript-sdk/SKILL.md.

What does kernel-typescript-sdk do?

It guides TypeScript browser automation on Kernel: session creation, server-side Playwright or CDP, profiles, proxies, and session deletion.

What do I need for this skill to work?

The @onkernel/sdk package and a KERNEL_API_KEY in your environment. The CDP path also needs playwright-core.

Source text

SKILL.md · MIT
---
name: kernel-typescript-sdk
description: Build Kernel browser automation in TypeScript with server-side Playwright or CDP, including profiles, proxies, and reliable session cleanup.
context: fork
---

# Kernel TypeScript SDK

## When to Use This Skill

Use this skill to create and automate Kernel browser sessions from TypeScript, persist browser state with profiles, route sessions through proxies, or package automation as Kernel actions.

For one-off `kernel ...` commands, use the `kernel-cli` skill instead.

## Install and Initialize

```bash
npm install @onkernel/sdk
# Only CDP-based automation also needs a local Playwright client:
npm install playwright-core
```

```typescript
import { Kernel } from "@onkernel/sdk";

const kernel = new Kernel(); // Reads KERNEL_API_KEY from the environment.
```

Request and response fields use `snake_case` (`timeout_seconds`, `session_id`, `cdp_ws_url`). SDK methods use JavaScript casing (`deleteByID`, `captureScreenshot`).

## Choose an Automation Path

Prefer **server-side Playwright** with `kernel.browsers.playwright.execute()` for most automation. Code runs beside the browser with low latency and does not require a local Playwright installation.

Use a **CDP connection** when a local library must control Playwright directly or when debugging interactively. Connect with `browser.cdp_ws_url` and reuse the browser's existing context.

## Server-Side Playwright Lifecycle

Always delete a created session in `finally`. The idle timeout is a safety net, not the normal cleanup path.

```typescript
import { Kernel } from "@onkernel/sdk";

const kernel = new Kernel();
const session = await kernel.browsers.create({
  stealth: true,
  timeout_seconds: 300,
});

try {
  const response = await kernel.browsers.playwright.execute(session.session_id, {
    code: `
      await page.goto("https://example.com", { waitUntil: "domcontentloaded" });
      return { title: await page.title(), url: page.url() };
    `,
    timeout_sec: 60,
  });

  if (!response.success) {
    throw new Error(response.error ?? response.stderr ?? "Playwright execution failed");
  }

  console.log(response.result);
} finally {
  await kernel.browsers.deleteByID(session.session_id);
}
```

Use `return` inside `code` to populate `response.result`. Each call uses a fresh execution context, so keep dependent steps in one call or return the state needed by the next call.

## CDP Lifecycle

Close the local CDP client, then delete the Kernel session even if connection or automation fails.

```typescript
import { Kernel } from "@onkernel/sdk";
import { chromium } from "playwright-core";

const kernel = new Kernel();
const session = await kernel.browsers.create({ stealth: true, timeout_seconds: 300 });

try {
  const browser = await chromium.connectOverCDP(session.cdp_ws_url);
  try {
    const context = browser.contexts()[0];
    if (!context) throw new Error("Kernel browser has no default context");

    const page = context.pages()[0] ?? (await context.newPage());
    await page.goto("https://example.com", { waitUntil: "domcontentloaded" });
    console.log(await page.title());
  } finally {
    await browser.close();
  }
} finally {
  await kernel.browsers.deleteByID(session.session_id);
}
```

Do not treat `browser.close()` as Kernel resource cleanup; always call `deleteByID()`.

## Profiles

Create profiles before attaching them. Set `save_changes: true` only when changes from this session should persist when the session ends.

```typescript
const profile = await kernel.profiles.create({ name: "example-login" });
const session = await kernel.browsers.create({
  profile: { id: profile.id, save_changes: true },
  stealth: true,
});

try {
  // Authenticate or automate with playwright.execute or CDP.
} finally {
  await kernel.browsers.deleteByID(session.session_id);
}
```

Prefer profile IDs for long-running work. Do not rename a profile while a browser references it by name; that can prevent session changes from saving. Delete a profile only when it was created as temporary test data, and only after deleting its browser sessions:

```typescript
await kernel.profiles.delete(profile.id);
```

## Proxies and Direct Connections

Attach an existing proxy by ID at creation:

```typescript
const session = await kernel.browsers.create({
  stealth: true,
  proxy_id: process.env.KERNEL_PROXY_ID!,
});
```

Check a configured proxy against a public HTTP(S) target before use when target reachability matters:

```typescript
const checked = await kernel.proxies.check(process.env.KERNEL_PROXY_ID!, {
  url: "https://example.com",
});
if (checked.status === "unavailable") throw new Error("Proxy is unavailable");
```

For a running stealth session, clear an explicit proxy and disable Kernel's default stealth proxy to connect directly:

```typescript
await kernel.browsers.update(session.session_id, {
  proxy_id: "",
  disable_default_proxy: true,
});
```

Set `disable_default_proxy: false` to re-enable the default stealth proxy. `kernel.proxies.update(id, { name })` only renames a proxy; recreate it to change its type or configuration. Delete temporary proxies only after all sessions using them are deleted.

## Binary Data

Do not return screenshots or file bytes from `playwright.execute`. Use the dedicated response endpoints:

```typescript
const screenshot = await kernel.browsers.computer.captureScreenshot(session.session_id);
const screenshotBuffer = Buffer.from(await screenshot.arrayBuffer());

const file = await kernel.browsers.fs.readFile(session.session_id, {
  path: "/tmp/output.pdf",
});
const fileBuffer = Buffer.from(await file.arrayBuffer());
```

## Cleanup Rules

1. Wrap every created browser session in `try/finally` immediately after creation.
2. Delete sessions with `kernel.browsers.deleteByID(session_id)` on success and failure.
3. For CDP, close the local client before deleting the session.
4. Delete temporary profiles and proxies only after dependent sessions are gone.
5. Keep credentials and proxy passwords in environment variables; never embed them in source or logs.

## References

- **Kernel Documentation**: https://www.kernel.sh/docs
- **Quickstart Guide**: https://www.kernel.sh/docs/quickstart
- **TypeScript Types**: Use the declarations and hover docs shipped with `@onkernel/sdk`
- **Additional integration examples**: [examples](./examples/examples.md)

© kernel · MIT · kernel/skills

Similar skills

All skills for Browser and scraping →

From the same set3

Project sponsors

Companies that keep this analytics open
Gold sponsor

Impressions, clicks and code copies — open statistics. We keep the numbers public for the same reason NeBlask itself is public. Become a sponsor