> ## Documentation Index
> Fetch the complete documentation index at: https://docs.animam.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Site actions (WebMCP)

> Let your Animam agent perform real actions on your website — add to cart, book, filter, start a flow — running in the visitor's browser, with confirmation on writes.

Your agent doesn't just answer — it can **act on your site**. You declare actions with the standard [WebMCP](https://webmachinelearning.github.io/webmcp/) API (`navigator.modelContext.registerTool`); the agent calls them, and they run **in the visitor's browser**, with the visitor's session on your site.

<Note>
  Site actions are available on **Builder** plans and higher (the `externalMcp` capability). On lower plans, declared tools are simply ignored.
</Note>

## How it works

1. **You declare your actions** — standard WebMCP, reusing your own front-end APIs. The agent only ever sees the **schema**, never your code or secrets.
2. **The agent calls them** — during a conversation, the Animam agent decides to call an action. Read-only actions run immediately; write actions ask the visitor to confirm first.
3. **It runs in the browser** — `execute()` uses the visitor's existing session on your site (cookies, CSRF), so your normal auth applies.

## Declare a tool

The Animam widget installs a `navigator.modelContext` polyfill on load, so you can use the **standard WebMCP API** — it works with the Animam agent today, and with browser-native agents (Chrome) when they ship.

```js theme={null}
// A read-only tool — runs without confirmation
navigator.modelContext.registerTool({
  name: 'get_cart',
  description: 'Returns the visitor cart (items and total).',
  inputSchema: { type: 'object', properties: {} },
  annotations: { readOnlyHint: true },
  execute: async () => {
    const res = await fetch('/api/cart')
    return await res.json() // return structured data, not HTML
  },
})

// A mutating tool — the agent asks the visitor to confirm before running
navigator.modelContext.registerTool({
  name: 'add_to_cart',
  description: 'Add a product to the visitor cart.',
  inputSchema: {
    type: 'object',
    properties: { sku: { type: 'string' }, qty: { type: 'integer' } },
    required: ['sku'],
  },
  // no readOnlyHint => mutating => confirmation required
  execute: async ({ sku, qty }) => {
    const res = await fetch('/api/cart', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ sku, qty }),
    })
    return await res.json()
  },
})
```

You can also use the convenience alias `AnimamChat.registerTool(tool)` if you prefer not to touch `navigator`. Register after the widget is ready:

```js theme={null}
window.addEventListener('animam:ready', () => {
  AnimamChat.registerTool({ /* … */ })
})
```

### Read-only vs mutating

|                                   | `readOnlyHint`    | Confirmation                                                    |
| --------------------------------- | ----------------- | --------------------------------------------------------------- |
| Read-only (lookup, search, get)   | `true`            | none — runs immediately                                         |
| Mutating (add, book, pay, delete) | omitted / `false` | the widget shows a **Confirm / Cancel** card before `execute()` |

Confirmation is enforced by the widget — which owns your `execute()` function and the tool's annotation — so the model **cannot bypass it**. A declined action returns `{ status: 'cancelled' }` to the agent.

## Tool design

* **Reuse your real APIs.** Tools call your existing endpoints, not duplicated logic.
* **Return structured data** (objects/arrays), summarized — never large HTML blobs.
* **Write clear descriptions.** The agent decides when to call a tool purely from its `description` and `inputSchema`.
* **Validate server-side.** Treat the agent's input as untrusted form input — your endpoints enforce the rules.
* **Action-oriented names**: `add_to_cart`, `search_inventory`, `go_to_step`.

## Security

* The agent receives only the tool **schema** — never your secrets or your `execute()` code.
* Mutating actions require **explicit visitor confirmation**, enforced in the browser.
* Tools run with the **visitor's own session** on your site, so your existing auth / CSRF / rate-limit protections apply.
* Site actions are gated to **Builder+**.

## Standard, no lock-in

WebMCP is a neutral [W3C](https://webmachinelearning.github.io/webmcp/) standard. The same registration serves the Animam agent (every browser, today) and browser-native agents (Chrome) when they ship — you're additive, not locked into a proprietary API.

<Card title="See it live" href="https://animam.ai/site-actions" icon="arrow-up-right">
  The site-actions overview page.
</Card>
