# Notte - Browser Automation Skill

> If you are an AI coding agent (Claude Code, Cursor, Windsurf, Copilot, etc.), follow the instructions below to automate browser tasks using Notte.

## Install

### Option A: CLI (recommended for coding agents)

```bash
brew tap nottelabs/notte-cli https://github.com/nottelabs/notte-cli.git
brew install notte
```

Or via Go:

```bash
go install github.com/nottelabs/notte-cli/cmd/notte@latest
```

Or register as a skill for AI coding assistants:

```bash
npx skills add nottelabs/notte-cli
```

### Option B: Python SDK

```bash
pip install notte-sdk
```

### Option C: Node.js SDK

```bash
npm install notte-sdk
```

## Authenticate

Get an API key from [console.notte.cc](https://console.notte.cc), then Settings, then API Keys.

```bash
# Via environment variable (recommended for CI/CD)
export NOTTE_API_KEY="your-api-key"  # pragma: allowlist secret

# Via system keyring (recommended for local dev)
notte auth login

# Check auth status
notte auth status
```

## Use the CLI

Run `notte --help` for the full command reference.

### Core workflow

```bash
# Start a cloud browser session
notte sessions start

# Navigate to a URL
notte page goto "https://example.com"

# See what's on the page (returns interactive elements with IDs like @B1, @I1)
notte page observe

# Interact with elements
notte page click "@B1"
notte page fill "@I1" "hello@example.com"

# Extract structured data
notte page scrape --instructions "Extract all product names and prices"

# Take a screenshot
notte page screenshot

# Clean up
notte sessions stop
```

### Session start options

```bash
notte sessions start \
  --browser-type chromium|chrome|firefox \
  --headless \
  --proxy \
  --proxy-country us \
  --solve-captchas \
  --viewport-width 1920 \
  --viewport-height 1080 \
  --profile-id <id> \
  --profile-persist \
  --use-file-storage \
  --idle-timeout-minutes 5 \
  --max-duration-minutes 30
```

### All page actions

```bash
notte page observe                      # Get page state and available actions
notte page scrape --instructions "..."  # Scrape content
notte page click "@B3"                  # Click an element by ID
notte page fill "@I1" "text"            # Fill an input field
notte page goto "https://example.com"   # Navigate to a URL
notte page back                         # Go back in history
notte page forward                      # Go forward in history
notte page scroll-down [amount]         # Scroll down
notte page scroll-up [amount]           # Scroll up
notte page press "Enter"                # Press a key
notte page screenshot                   # Take a screenshot
notte page select <id> "option"         # Select dropdown option
notte page check <id>                   # Check/uncheck checkbox
notte page upload <id> <file>           # Upload a file
notte page download <id>                # Download file by clicking element
notte page new-tab <url>                # Open URL in new tab
notte page switch-tab <index>           # Switch to tab by index
notte page close-tab                    # Close current tab
notte page reload                       # Reload page
notte page wait <seconds>               # Wait for duration
notte page captcha-solve                # Solve captcha
```

### AI Agents via CLI

```bash
notte agents start --task "Find pricing information on this page"
notte agents status
notte agents stop
notte agents replay
```

### Functions, Vaults, Personas, Files

```bash
notte functions list                    # List automation functions
notte functions run                     # Run current function
notte vaults list                       # List credential vaults
notte personas list                     # List digital identities
notte files upload <path>               # Upload a file
notte files download <id>               # Download a file
```

### Tips

- Sessions output a `ViewerUrl`. Open it to watch the browser live.
- If element IDs (`@B1`) fail, use Playwright selectors: `#id`, `.class`, `button:has-text('Submit')`.
- For multiple matches, add `>> nth=0` to select the first: `button:has-text('OK') >> nth=0`.
- Dismiss modals with `notte page press "Escape"`.
- Use `--output json` on any command for machine-readable output.

## Use the Python SDK

### Browser Session (Playwright over CDP)

```python
from playwright.sync_api import sync_playwright
from notte_sdk import NotteClient

client = NotteClient()

with client.Session(open_viewer=True) as session:
    cdp_url = session.cdp_url()

    with sync_playwright() as p:
        browser = p.chromium.connect_over_cdp(cdp_url)
        page = browser.contexts[0].pages[0]
        page.goto("https://www.google.com")
        page.screenshot(path="screenshot.png")
```

### AI Agent (autonomous task execution)

```python
from notte_sdk import NotteClient

client = NotteClient()

with client.Session(open_viewer=True) as session:
    agent = client.Agent(session=session, max_steps=5)

    response = agent.run(
        task="Go to Hacker News and find the top 3 posts about AI",
        url="https://news.ycombinator.com"
    )
    print(response)
```

### Structured Scraping (typed output)

```python
from pydantic import BaseModel
from notte_sdk import NotteClient

class Product(BaseModel):
    name: str
    price: float
    url: str

class ProductList(BaseModel):
    products: list[Product]

client = NotteClient()

result = client.scrape(
    url="https://example.com/products",
    response_format=ProductList,
    instructions="Extract all products with their prices"
)

for p in result.data.products:
    print(f"{p.name}: ${p.price}")
```

## Use the MCP Server

First, install and start the Notte MCP server locally:

```bash
pip install notte-sdk
notte-mcp  # Starts the MCP server on http://localhost:8001/sse
```

Then add this to your Claude Desktop or MCP-compatible tool config:

```json
{
  "mcpServers": {
    "notte-mcp": {
      "command": "npx",
      "args": ["mcp-remote", "http://localhost:8001/sse"],
      "env": {
        "NOTTE_API_KEY": "<your-notte-api-key>"
      }
    }
  }
}
```

Available MCP tools:
- `notte_operator`: run an AI agent on a website
- `notte_observe`: list interactive elements on the page
- `notte_screenshot`: capture the current page
- `notte_scrape`: extract structured data
- `notte_step`: perform a single action
- `notte_start_session`: start a cloud browser
- `notte_list_sessions`: list active sessions
- `notte_stop_session`: stop a session

## Key Capabilities

| Capability | How |
|-----------|-----|
| Navigate websites | `notte page goto <url>` or `page.goto()` via CDP |
| Fill forms | `notte page fill "@I1" "value"` or SDK `session.execute()` |
| Click buttons | `notte page click "@B1"` |
| Extract data | `notte page scrape --instructions "..."` or `client.scrape()` |
| Handle CAPTCHAs | `--solve-captchas` flag or `notte page captcha-solve` |
| Anti-detection | `--proxy` flag enables residential proxy rotation |
| Upload/download files | `notte page upload` / `notte page download` or SDK `session.files` |
| Persistent auth | `--profile-id <id> --profile-persist` to save browser state |
| Run autonomously | `notte agents start --task "..."` or SDK `client.Agent(...)` |
| Deploy as API | Convert agents to Functions via `notte functions create` |
| Manage credentials | `notte vaults credentials add` for secure password storage |

## Links

- Documentation: https://docs.notte.cc
- API Reference: https://docs.notte.cc/api-reference/authentication
- Python SDK: `pip install notte-sdk` ([PyPI](https://pypi.org/project/notte-sdk/))
- Node SDK: `npm install notte-sdk` ([npm](https://www.npmjs.com/package/notte-sdk))
- GitHub: https://github.com/nottelabs/notte
- CLI: https://github.com/nottelabs/notte-cli
- MCP Server: https://docs.notte.cc/integrations/mcp
