@@ -110,16 +112,23 @@ export const PricingCalculator = () => {
${(usagePrices * multiplier).toFixed(8)}/second
- {browserType === 'gpu' && (Startup tier required)}
+ {browserType === 'gpu' && (Start-Up or Enterprise plan required)}
-
- Base plan: ${planPrices[plan].toFixed(2)}
- Usage: +${usageCost.toFixed(2)}
- Free credits: -${includedUsageCredits.toFixed(2)}
- Total cost: ${price.toFixed(2)}
-
+ {isEnterprise ? (
+
+ Enterprise pricing is custom, with custom concurrency, rate limits, support, and compliance terms.
+ Contact the KERNEL team for a quote.
+
+ ) : (
+
+ Base plan: ${planPrices[plan].toFixed(2)}
+ Usage: +${usageCost.toFixed(2)}
+ Free credits: -${includedUsageCredits.toFixed(2)}
+ Total cost: ${price.toFixed(2)}
+
+ )}
);
};
diff --git a/start/quickstart.mdx b/start/quickstart.mdx
new file mode 100644
index 00000000..4528ccea
--- /dev/null
+++ b/start/quickstart.mdx
@@ -0,0 +1,197 @@
+---
+title: "Quickstart"
+description: "Hand setup to your coding agent, or create your first cloud browser yourself"
+mode: "wide"
+---
+
+import { CopyPromptButton } from '/snippets/copy-prompt-button.jsx';
+
+Pick the way in that matches how you work. The first two are walked through on this page; the rest open their own guides.
+
+
+
+ Copy one prompt into Cursor, Claude Code, or Codex and let it set up KERNEL.
+
+
+ Create and drive your first browser in TypeScript, Python, or Go.
+
+
+ Call KERNEL over HTTP from any language, starting with creating a browser.
+
+
+ Create, drive, and debug browsers from a terminal.
+
+
+ Give any MCP client, like Claude or Cursor, a cloud browser as a set of tools.
+
+
+ Teach your coding agent the KERNEL CLI, SDKs, and auth with one install.
+
+
+ Guides for the agent frameworks, models, and platforms you already use.
+
+
+ Clone an end-to-end recipe and adapt it to your task.
+
+
+
+## Path 1: hand it to your coding agent
+
+Copy this prompt into Claude Code, Codex, Cursor, or any agent that can run terminal commands. It installs the KERNEL CLI, signs you in, and opens a live view of a KERNEL browser that you or your agent can drive. From there, ask your agent to do a task on a site you care about.
+
+
+
+
+
+
+
+1. Checks for the KERNEL CLI and installs or upgrades it with Homebrew.
+2. Checks whether you're signed in, and if not, runs `kernel login` and waits for you to finish signing in.
+3. Creates a browser and opens its live view so you can watch it.
+
+It stops and asks you for help if any step fails.
+
+
+| 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 with an SDK
+
+
+
+Create an API key in the [dashboard](https://dashboard.onkernel.com) and set it as `KERNEL_API_KEY`. Every SDK, the CLI, and the MCP server read it from the environment.
+
+```bash
+export KERNEL_API_KEY=
+```
+
+
+
+
+```bash TypeScript
+npm install @onkernel/sdk
+```
+
+```bash Python
+pip install kernel
+```
+
+```bash Go
+go get github.com/kernel/kernel-go-sdk
+```
+
+
+
+
+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.
+
+
+```typescript TypeScript
+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
+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)
+```
+
+```go Go
+package main
+
+import (
+ "context"
+ "fmt"
+
+ "github.com/kernel/kernel-go-sdk"
+)
+
+func main() {
+ ctx := context.Background()
+ client := kernel.NewClient()
+
+ browser, err := client.Browsers.New(ctx, kernel.BrowserNewParams{
+ TimeoutSeconds: kernel.Int(300),
+ })
+ if err != nil {
+ panic(err)
+ }
+ defer client.Browsers.DeleteByID(ctx, browser.SessionID)
+ fmt.Println("live view:", browser.BrowserLiveViewURL)
+
+ res, err := client.Browsers.Playwright.Execute(ctx, browser.SessionID, kernel.BrowserPlaywrightExecuteParams{
+ Code: `
+ await page.goto('https://news.ycombinator.com');
+ return await page.$$eval('.titleline > a', (as) => as.slice(0, 5).map((a) => a.textContent));
+ `,
+ })
+ if err != nil {
+ panic(err)
+ }
+ fmt.Println(res.Result)
+}
+```
+
+
+Open `browser_live_view_url` while it runs and you'll watch the page load.
+
+
+
+## Next steps
+
+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.
+
+
+
+ Stealth and proxies to get past bot detection.
+
+
+ Fill credentials from a vault, or let managed auth log in.
+
+
+ Complete checkouts without exposing card data to your agent.
+
+
+ End-to-end recipes you can clone and run.
+
+
diff --git a/style.css b/style.css
index 9b8af45f..19f5385a 100644
--- a/style.css
+++ b/style.css
@@ -347,3 +347,8 @@ html.dark #navigation-items img[src*="/images/integration-icons/"] {
html.dark .cookbook-tag {
color: rgba(237, 238, 240, 0.7);
}
+
+.copy-prompt-full button {
+ width: 100% !important;
+ max-width: 100% !important;
+}
diff --git a/vaults/overview.mdx b/vaults/overview.mdx
index 68dab206..1071c22b 100644
--- a/vaults/overview.mdx
+++ b/vaults/overview.mdx
@@ -1,5 +1,6 @@
---
-title: "Overview"
+title: "Vaults"
+sidebarTitle: "Overview"
description: "Group credentials and payment items, collect values, and control their use by attached browsers"
---
@@ -27,6 +28,17 @@ navigation and submission, start with [Fill from Vault](/auth/fill-from-vault).
see [wallet integrations](/integrations/wallets/overview).
+## Choose where credentials come from
+
+a `credential` item can get its values from three places. all three end with the browser filling the login without your agent reading the values.
+
+| | [KERNEL-hosted collection](/vaults/credentials) | [an existing vault](/vaults/existing-credential-vault) | [1Password](/vaults/1password) |
+| --- | --- | --- | --- |
+| where the secret lives | encrypted in a KERNEL `credential` item | an encrypted copy in a KERNEL `credential` item | in the user's 1Password account |
+| how it gets there | the user enters it in a KERNEL-hosted form, or your backend writes it | your backend copies it from the vault you already use and keeps it in sync | the user links their 1Password account once |
+| who approves each use | your application or agent, when it calls `fill` | your application or agent, when it calls `fill` | the user, in the 1Password app |
+| pick it when | you're collecting credentials from users for the first time | your credentials already live in another secrets manager | your users keep logins in a private 1Password vault |
+
## How vaults work
### Sensitive values do not come back through the api
@@ -72,7 +84,7 @@ availability.
-### Inject values with KERNEL's fill api
+### Inject values with KERNEL's fill API
retrieve the item and require `fill` in `available_operations`. your controller authorizes the destination and supplies field names and selectors, not the stored values. KERNEL checks the browser attachment and item lifecycle, validates the target inputs, and writes values into the attached browser.