> ## Documentation Index
> Fetch the complete documentation index at: https://tbd-6fc993ce-hypeship-docs-ia-v2.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Hand setup to your coding agent, or create your first cloud browser yourself

export const CopyPromptButton = props => {
  const {label = 'copy prompt'} = props || ({});
  const [copied, setCopied] = useState(false);
  const prompt = props && props.prompt || `# Setup Kernel

## Prerequisites
- Read the kernel-cli skill at https://github.com/kernel/skills/blob/main/plugins/kernel-cli/skills/kernel-cli/SKILL.md for reference on commands and capabilities.

## Steps

1. **Check if Kernel CLI is installed:**
   - Run \`kernel --version\`.
   - If not found, install via \`brew install kernel/tap/kernel\`.
   - If found, run \`brew upgrade kernel/tap/kernel\` to ensure latest version.
   - Verify with \`kernel --version\` and confirm >= v0.16.0.

2. **Check authentication:**
   - Run \`kernel auth\`.
   - If authenticated, done.
   - If not, run \`kernel login\` and tell the user to complete the browser flow.
     Poll \`kernel auth\` every 5 seconds, up to 5 minutes.
     If it times out, stop and ask the user for help.

3. **Create a browser and open Live View:**
   - Run a Kernel CLI command that creates a browser session and goes to \`https://www.kernel.sh/docs/browsers/live-view\`
   - Capture the returned \`browser_live_view_url\`.
   - Open that URL in the user's browser.
   - Tell the user they can use the live view immediately.
   - If browser creation fails, stop and ask the user for help.`;
  const handleCopy = useCallback(async () => {
    try {
      await navigator.clipboard.writeText(prompt);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    } catch {
      const textarea = document.createElement('textarea');
      textarea.value = prompt;
      textarea.style.position = 'fixed';
      textarea.style.opacity = '0';
      document.body.appendChild(textarea);
      textarea.select();
      document.execCommand('copy');
      document.body.removeChild(textarea);
      setCopied(true);
      setTimeout(() => setCopied(false), 2000);
    }
  }, []);
  return <button onClick={handleCopy} style={{
    display: 'inline-flex',
    alignItems: 'center',
    justifyContent: 'center',
    gap: '0.5rem',
    width: '100%',
    maxWidth: '352px',
    height: '56px',
    padding: '0 32px',
    fontSize: '0.9375rem',
    fontWeight: 500,
    letterSpacing: '0.01em',
    color: '#fff',
    backgroundColor: '#111',
    border: '1px solid rgba(255, 255, 255, 0.08)',
    cursor: 'pointer',
    textDecoration: 'none',
    transition: 'text-decoration 0.15s ease',
    fontFamily: 'inherit'
  }} onMouseEnter={e => {
    e.currentTarget.style.textDecoration = 'underline';
  }} onMouseLeave={e => {
    e.currentTarget.style.textDecoration = 'none';
  }}>
      {copied ? <>
          <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <polyline points="3.5 8.5 6.5 11.5 12.5 4.5" />
          </svg>
          copied!
        </> : <>
          <svg width="16" height="16" viewBox="0 0 16 16" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
            <rect x="5.5" y="5.5" width="8" height="8" rx="1.5" />
            <path d="M10.5 5.5V3.5C10.5 2.67 9.83 2 9 2H3.5C2.67 2 2 2.67 2 3.5V9C2 9.83 2.67 10.5 3.5 10.5H5.5" />
          </svg>
          {label}
        </>}
    </button>;
};

Two paths. Start with the first if a coding agent is writing the code; use the second if you are.

## Path 1: hand it to your coding agent

Copy this prompt into Cursor, Claude Code, Codex, or whatever you use. It installs the Kernel CLI and skills, authenticates you, and opens a live browser session that you or your agent can drive.

<CopyPromptButton />

### Agent-readable surfaces

| Surface | What it's for |
| - | - |
| [`kernel.sh/llms.txt`](https://www.kernel.sh/llms.txt) | Hand-written. What Kernel is, when to use it, every machine endpoint. Start here. |
| [`kernel.sh/docs/llms.txt`](https://www.kernel.sh/docs/llms.txt) | Index of every docs page, for fetching the ones a task needs. |
| [`kernel.sh/docs/llms-full.txt`](https://www.kernel.sh/docs/llms-full.txt) | The whole docs corpus in one file, for agents with room for it. |
| [Agent Skills](/skills/overview) | Kernel know-how installed into the agent, so it doesn't re-read docs every session. |
| [MCP server](/reference/mcp-server) | Kernel's API as tools, for agents that call tools instead of writing code. |
| [OpenAPI 3.1](https://www.kernel.sh/openapi.json) | For generating a client or calling the REST API directly. |

## Path 2: write it yourself

<Note>
  You'll need an API key from the [dashboard](https://dashboard.onkernel.com). Set it as `KERNEL_API_KEY` — every SDK, the CLI, and the MCP server read it from the environment.
</Note>

<Steps>
  <Step title="Install an SDK">
    <CodeGroup>
      ```bash TypeScript theme={null}
      npm install @onkernel/sdk
      ```

      ```bash Python theme={null}
      pip install kernel
      ```

      ```bash Go theme={null}
      go get github.com/kernel/kernel-go-sdk
      ```
    </CodeGroup>
  </Step>

  <Step title="Create a browser and drive it">
    This creates a browser, runs Playwright code inside the browser's VM, returns the result, and cleans up. No local Chromium, no CDP connection to manage.

    <CodeGroup>
      ```typescript Typescript/Javascript theme={null}
      import Kernel from '@onkernel/sdk';

      const kernel = new Kernel();

      const browser = await kernel.browsers.create({ timeout_seconds: 300 });
      console.log('live view:', browser.browser_live_view_url);

      try {
        const { result } = await kernel.browsers.playwright.execute(browser.session_id, {
          code: `
            await page.goto('https://news.ycombinator.com');
            return await page.$$eval('.titleline > a', (as) => as.slice(0, 5).map((a) => a.textContent));
          `,
        });
        console.log(result);
      } finally {
        await kernel.browsers.deleteByID(browser.session_id);
      }
      ```

      ```python Python theme={null}
      from kernel import Kernel

      kernel = Kernel()

      browser = kernel.browsers.create(timeout_seconds=300)
      print("live view:", browser.browser_live_view_url)

      try:
          response = kernel.browsers.playwright.execute(
              browser.session_id,
              code="""
                await page.goto('https://news.ycombinator.com');
                return await page.$$eval('.titleline > a', (as) => as.slice(0, 5).map((a) => a.textContent));
              """,
          )
          print(response.result)
      finally:
          kernel.browsers.delete_by_id(browser.session_id)
      ```
    </CodeGroup>

    Open `browser_live_view_url` while it runs and you'll watch the page load.
  </Step>

  <Step title="Pick your next decision">
    Two things determine the shape of everything after this: which control surface you use, and where your loop runs. [How you drive the browser](/introduction/control) covers both.

    From there:

    * Getting blocked? [Stealth](/browsers/bot-detection/overview) and [proxies](/proxies/overview).
    * Behind a login? [Authentication](/auth/overview).
    * Need to pay? [Payments](/browsers/payments).
    * Worked examples: [cookbooks](/cookbooks).
  </Step>
</Steps>
