# Capabilities

By default, the script-tag widget lets the agent perform a small set of page actions on your behalf — clicking links, scrolling, programmatically clicking buttons. The `capabilities` attribute lets you tighten this allowlist on a per-page basis.

```html
<livelayer-widget
  agent-id="agt_abc123"
  capabilities="navigate,scroll,click">
</livelayer-widget>
```

## Available capabilities

<!-- omitted: ParamsTable -->

> [!WARNING]
> The script-tag widget cannot fill or submit forms in your page. That's a deliberate security boundary — form filling requires React-state coherence and lives only in the [NPM](/docs/develop/npm/overview) package.

## Examples

**All actions allowed (default):**

```html
<livelayer-widget agent-id="agt_abc123"></livelayer-widget>
```

When `capabilities` is omitted, all actions are allowed. This preserves backward compatibility for existing embeds.

**Read-only / observation:**

```html
<livelayer-widget
  agent-id="agt_abc123"
  capabilities="">
</livelayer-widget>
```

Empty list = no actions. The agent can talk and answer but can't move the page. Best for content-heavy pages where you don't want the agent surprising the visitor with navigation.

**Tour-style (scroll only):**

```html
<livelayer-widget
  agent-id="agt_abc123"
  capabilities="scroll">
</livelayer-widget>
```

The agent can scroll to highlight sections, but can't click or navigate away. Common for product walkthroughs.

**Sales widget (navigate only):**

```html
<livelayer-widget
  agent-id="agt_abc123"
  capabilities="navigate">
</livelayer-widget>
```

The agent can hand off to specific URLs (pricing, signup, contact) but doesn't auto-scroll or click. Predictable for conversion-focused experiences.

## JSON array form

You can also pass capabilities as a JSON array — useful when generating the embed in code:

```html title="json-form.html"
<livelayer-widget
  agent-id="agt_abc123"
  capabilities='["navigate","scroll"]'>
</livelayer-widget>
```

Both comma-separated and JSON-array forms produce the same result.

## How enforcement works

The widget enforces capabilities **client-side** by ignoring agent commands that aren't in the allowlist. The agent server can still emit any command — the widget just no-ops the disallowed ones.

This means:

- **Capabilities are not authentication.** A determined visitor with browser dev tools can override them. They're a UX guardrail, not a security boundary.
- **The agent doesn't know it's being restricted.** It will keep trying actions you've disallowed. To get smarter behavior, also restrict the agent prompt at the dashboard level (e.g., "Don't offer to navigate anywhere on this page").

For server-side enforcement, use [NPM](/docs/develop/npm/overview) — your `onAgentCommand` callback can validate against your auth context before executing.

## Read next

- [Events](/docs/develop/script-tag/events) — listen for what the agent does
- [NPM capabilities](/docs/develop/npm/react/avatar-widget#capabilities) — fine-grained, type-safe restriction in React
