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

# App Tool

> Renders an **interactive UI artifact** in the task feed: a versioned HTML/JS bundle loaded from a CDN inside a sandboxed iframe.

Renders an **interactive UI artifact** in the task feed: a versioned HTML/JS bundle loaded from a CDN inside a sandboxed iframe. Runtime reads/writes go through `/api/app-runtime`, gated by the configured tool's allowlist. Display name **"App Tool"**. Off by default.

## When to use it (vs `custom_interface` vs `python_code_tool` vs `generate_file`)

| Need                                                                      | Tool               |
| ------------------------------------------------------------------------- | ------------------ |
| Interactive mini-app in the task feed (filters, actions, persisted edits) | `app_tool`         |
| Read-only HTML view of prior step data (cards, tables, citations)         | `custom_interface` |
| Compute in Python; feed shows **markdown**, not HTML                      | `python_code_tool` |
| A downloadable static file, including an `.html` document                 | `generate_file`    |

`generate_file` with `format: html` produces a **file**, not a live feed widget. `python_code_tool` cannot "signal HTML" — its contract is markdown. For a task-feed scorecard the user can click, this is the tool.

## Authentication and enablement

Configured tool: each instance has a bundle + data-source binding + action allowlist. The LLM does not pick the bundle. Off by default; add and configure per agent.

## Inputs

* `configured_tool_id` — injected by the worker from context (`x-exclude-from-llm`). Never pass a display name here.
* `params` — bundle-specific payload forwarded as `runtime.params`. Shape comes from the configured tool's `input_schema` override (e.g. `{report_id: 59137}`).

## Output

An artifact descriptor (CDN bundle URL, scoped session token, initial data). The frontend mounts the iframe; edits persist via App Runtime and show up as `agent_action` feed events.

## Limits and side effects

* Iframe is sandboxed; runtime calls must match the binding allowlist.
* Writes go through `/api/app-runtime` (and the db/http gateways behind it), not the worker.

## Expected errors

* Missing `configured_tool_id` (not injected) — step cannot resolve the bundle.
* `configured_tool_id` that is not a UUID — validation error.
* Runtime action not on the allowlist — denied by the gateway.
