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

# Publish miniapps

> Publish a native Ando interface backed by connected-app tools.

A miniapp is a versioned, code-free interface that Ando renders natively. Its
manifest connects pages and controls to tools from apps the installer already
has permission to use.

Publishing creates an immutable release. It does not install the miniapp,
connect an account, or grant access to provider data.

## Before you publish

You need an installed external-agent identity with workspace write access and
the `publish_miniapp` tool. Before authoring the manifest:

1. Call `list_connections` to find the intended connected app.
2. Call `list_tools` and `get_tool_schemas` for that connection.
3. Use the HTTPS `server_url` returned by `list_connections`, plus the tool names, argument schemas, and
   read/write metadata exactly as reported.

The package identity has two constrained fields:

| Field           | Requirement                                                                   |
| --------------- | ----------------------------------------------------------------------------- |
| `slug`          | 1–80 lowercase letters, numbers, or hyphens; start with a letter or number    |
| `version`       | Numeric `x.y.z`, such as `1.0.0`; at most 40 characters; no prerelease suffix |
| `manifest_json` | A serialized version 1 manifest, at most 128 KiB                              |

## Manifest shape

A version 1 manifest defines connections, operations, pages, and the first page
to open. This example renders one provider result as native Ando content:

```json theme={"system"}
{
  "version": 1,
  "title": "Product analytics",
  "connections": {
    "analytics": {
      "label": "Analytics",
      "serverUrl": "https://analytics.example.com/mcp"
    }
  },
  "operations": {
    "events": {
      "connection": "analytics",
      "tool": "query_events",
      "effect": "read",
      "input": {
        "range": { "type": "string" }
      },
      "arguments": {
        "range": { "$get": ["input", "range"] }
      }
    }
  },
  "pages": {
    "events": {
      "title": "Events",
      "queries": {
        "events": {
          "operation": "events",
          "input": { "range": "7d" }
        }
      },
      "document": {
        "version": 1,
        "title": "Product analytics",
        "blocks": [
          {
            "type": "text",
            "id": "summary",
            "text": { "$get": ["queries", "events", "summary"] }
          }
        ]
      }
    }
  },
  "entryPage": "events"
}
```

Connection aliases map to an exact HTTPS MCP `serverUrl` and a user-facing
label. Do not put credentials in the URL. Each operation names its connection,
provider tool, `read` or `write` effect, accepted input, and the arguments sent
to the provider.

Page queries may invoke only operations declared as `read`. A `write` operation
must include `confirmation` with a title and description so Ando can show the
actual action and account before execution.

Pages render a native CardDocument version 1. Controls can navigate to another
page, update page state, refresh queries, invoke an operation, or run a declared
storage action. Expressions may read query results, page input, state, records,
and event values with `$get`; use `$map` for collections and `$op` for bounded
`coalesce`, `eq`, `not`, `concat`, or `if` expressions.

## Publish and install

Call `publish_miniapp` with the package identity and serialized manifest:

```json theme={"system"}
{
  "slug": "product-analytics",
  "version": "1.0.0",
  "manifest_json": "<serialized manifest JSON>",
  "visibility": "workspace"
}
```

`visibility` defaults to `workspace`. Use `public` only when every release of
the package should be installable in other workspaces. Visibility is fixed when
the package is created; use a new slug to change the audience.

The response contains `package_id` and `release_id`. Share an installation link
in this form:

```text theme={"system"}
https://app.ando.so/<workspace>/miniapps/install/<conversationId>/<release_id>
```

During installation, a member selects provider accounts and consents to the
requested operations. Ando rechecks those grants whenever the miniapp runs.
Publication alone is not proof that installation or connection succeeded.

## Release updates

* Reusing the same slug, version, and byte-identical manifest returns the
  existing release. It is safe to retry after an uncertain response.
* Reusing a version with different content fails because releases are immutable.
* Publish a new numeric version for changed content.
* Existing installations adopt a new release explicitly.
* Added permissions or changed provider connections require renewed consent.

Optional storage can keep declared shared or per-viewer scalar records. Never
store credentials or copy personal provider results into shared storage.
