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

# Updating a published app

> Safely roll out changes to your workloads on ChatGPT and Claude.ai

## Why versioning matters

Most hosts cache some of your MCP workload responses when your submission is accepted.
Knowing which response is cached and which isn't tells you whether a change ships immediately or needs a new submission.

**Cached at submission (frozen until you submit a new version):**

* **`tools/list` response**: tool descriptions, annotations and input/output schemas, on all workloads.
* **`resources/read` response**: the views entrypoint HTML, on MCP apps specifically.

Everything else reaches your server on every user interaction (an actual `tools/call`, for example) and runs your latest deployment.

This split is what makes versioning tricky: say you deploy an update that adds a required input parameter to a tool.
The host still sources its input schema from the cached `tools/list`, so it fires a `tools/call` without the new parameter.
However, your freshly deployed handler now expects it and rejects the request with a validation error.

All calls to this tool now fail, with no possible recovery other than reverting your deployment.

You just broke your production workload.

In order to avoid this scenario, the following table summarizes how to handle the most common operations safely.
All recommended migration paths keep host knowledge of your server and your actual service deployment compatible.

## Operation-specific migration paths

### For all workloads

| Operation                           | How to prepare                                                                                                                             | How to release       | Notes                                                                                                                                                                                                                                          |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Add a new tool                      | Add the tool                                                                                                                               | Submit a new version | The tool stays invisible to the host until you submit.                                                                                                                                                                                         |
| Remove a tool                       | Add `_meta.ui.visibility: ["app"]` on your tool description                                                                                | Submit a new version | Do not remove your tool altogether. It is still referenced in the cached `tools/list` on hosts and will keep being called by the model until you submit a new version. You can safely remove it after this revised version has been submitted. |
| Add a new param in an existing tool | Add the param in the input schema, but make it optional                                                                                    | Submit a new version | Do not add a required param. Your handler is updated right away with the new requirement, but hosts won't be aware of it until a new release is made and will fail all input validation on your tool.                                          |
| Update a param in an existing tool  | Keep changes backward compatible: relax validation, don't tighten it, and avoid renaming. Widen accepted values rather than narrowing them | Submit a new version | Hosts validate inputs against the cached schema. If you tighten validation (e.g. make an optional param required, add new constraints) before resubmitting, the host keeps sending values your handler now rejects.                            |
| Remove a param in an existing tool  | Stop reading the param in your handler, but keep accepting it (leave it optional in the input schema)                                      | Submit a new version | The model keeps sending the param while the host references the cached `tools/list`. Removing it from the input schema before resubmitting can cause input validation to fail.                                                                 |

### For MCP apps specifically

| Operation      | How to prepare                                                                                                                                   | How to release                                                                               | Notes                                                                                                                                                                                                                                                                                                            |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Add a new view | Add the view resource and reference it from the relevant tool's `_meta.ui.resourceUri`                                                           | Submit a new version                                                                         | Both `tools/list` and `resources/read` are cached, so the host won't discover the new view until you submit.                                                                                                                                                                                                     |
| Update a view  | To change view behavior or styling only, ship new assets under stable, deterministic names (see [Asset naming strategy](#asset-naming-strategy)) | Update the assets content. You only need a new submission to change the view entrypoint HTML | The `resources/read` entrypoint HTML is cached. With deterministic asset names you can ship updated assets without resubmitting, because the cached HTML keeps pointing at the same asset URLs.                                                                                                                  |
| Remove a view  | Remove the view and stop referencing it from your tools' `_meta`. Keep the referenced static assets available.                                   | Submit a new version                                                                         | The view is still referenced by the cached `tools/list` content, and the view content itself is still cached by the host. Removing them from your workload before you submit a new version therefore has no effect on the host. Just make sure the external public assets referenced by the view stay available. |

## Recommended release workflow

We recommend using a **dedicated [environment](/build-deploy/environments)** for each version you submit to a host store.

Because hosts freeze a snapshot of your workload at submission time, a dedicated environment with its dedicated URL gives you a stable, immutable target for each published version:

* Your ongoing development on other environments never affects an already-submitted version.
* You can keep shipping fixes to a submitted version (within the limits described above) without disturbing your next release.
* When you want a clean break, you cut a new release against a new environment and submit it as a new version.

<Tip>
  Name your environments after the released version (for example `v1`, `v2`) so it stays obvious which environment backs
  which submission on each host.
</Tip>

## Asset naming strategy

For MCP apps, the `resources/read` response serves as the views entrypoint HTML.
How your build pipeline bundles and references built assets directly determines your release strategy.

<Tip>
  TL;DR: Use **deterministic asset names within a released version and its fixes**. This lets you ship small updates to
  your views by simply redeploying, while the host serves the latest asset content from the stable URL it already
  cached. Next and previous versions use version-specific asset names and aren't affected.
</Tip>

### Inline assets in HTML

All CSS and JS content is included in the `resources/read` content.
You can't update the view behavior without a new submission.

### Assets bundled separately with unique names per build

Your build pipeline produces content-hashed names that change on every build (`assets-fdsiucv7384.js` on the first build, then `assets-ytiroiu4253.js` on the next one).
The cached entrypoint HTML keeps pointing at the old name, so a new deployment exposes assets the host will never download, and the old assets keep being served.
You can't update the view behavior without a new submission.

### Assets bundled separately with deterministic, stable names

Your build pipeline produces assets with names that stay the same across builds (always `assets.js`).
The cached entrypoint HTML keeps pointing at the same URL, and a redeploy replaces the content served at that URL.
Updated assets ship without resubmission: you control the application lifecycle through deployment, not submission.

However, your changes then impact all existing views across all conversations.

<Warning>
  If you use a single environment for all your workload versions, make sure to keep deterministic names only **within**
  a single released version scope. You would otherwise risk breaking all existing views. See details below.
</Warning>

Hosts don't just render a view once. To rebuild the conversation as the user scrolls, they persist the view's tool input, output, metadata and — depending on the host's capabilities — its view state in the conversation history. When an old view re-enters the viewport (for example, the user scrolls back in time or reopens an old conversation), the host **re-renders it by re-fetching the asset referenced in that turn's entrypoint HTML**.

If you keep the same asset name across versions, that re-render pulls your **latest** asset code, but feeds it the **old** turn's input/output/metadata. The new asset expects the updated sidecar tool input/output schemas, so it ends up rendering against data shaped for a previous version — breaking or corrupting views in past conversations that were perfectly valid when they were created.

Giving each released version its own asset names keeps every historical turn pinned to the asset it was built against, so old views keep rendering correctly while new views get the new code.
