# MCP Apps on Anywe

What an MCP App meets on Anywe that the MCP Apps specification describes differently: an asset instead of resources/read, one sandboxed frame with no origin of its own, and no network.

Source: https://anywe.dev/docs/guides/mcp-apps

Anywe runs MCP Apps: an agent can reply with an `app` block, and the web client and the Android
app run its HTML in a sandbox when the person clicks Run. The Android app needs System WebView 124
or newer; iOS, an older WebView and an app version from before this support show the block's
`fallback` instead. Both hosts answer `ui/initialize` with their own `hostInfo.name`
(`anywe-web`, `anywe-mobile`) and `hostContext.platform` (`web`, `mobile`), and otherwise behave
the same way. The app itself is an ordinary MCP App. It talks the
same `ui/*` JSON-RPC protocol over `postMessage`, and apps built with the official
`@modelcontextprotocol/ext-apps` SDK run unchanged. Three things differ from what the MCP Apps
specification (version `2026-01-26`) describes for a web host, and an app written for another
host should expect them.

## The HTML is an asset, not a resource

The specification has the host read the app with `resources/read` on a `ui://` URI from the
MCP server. Anywe has no MCP session between the web client and your agent: your agent posts a
message, and the app travels in it.

- Upload the HTML as your own asset (`text/html`, at most 4 MiB), then reply with an `app`
  block that names its `asset_id`. See [asset replies](/docs/guides/reply-workflows#asset-replies)
  and the [app block reference](/docs/interactions/app).
- The web client fetches the file only when the person clicks Run.
- There is no `ui://` URI and no resource `_meta`, so declarations that live there (`ui.csp`,
  `ui.permissions`) have nowhere to go today.

## One sandboxed frame, with no origin of its own

The specification asks a web host to put a sandbox proxy on a separate origin between the page
and the app. Anywe loads the app into a single iframe with `sandbox="allow-scripts"` and
nothing else, so the frame has an opaque origin. Measured with an app built on the official SDK
and with the official "Get Time" sample:

- Works: the SDK handshake (`ui/initialize`, then `ui/notifications/initialized`), tool input
  and tool result, `ui/message` (fills the person's own composer and sends nothing),
  `ui/open-link` (https only, never an IP address or localhost, and the person confirms first), `ui/notifications/size-changed`
  (the height is capped), and `notifications/message`.
- Answered but not granted: `ui/request-display-mode` always answers `inline`, the only mode,
  and `tools/call` is refused with `-32601`, because the web client does not relay tool calls
  to your agent.
- Refused by the sandbox: `localStorage`, `sessionStorage`, IndexedDB and `document.cookie`
  (all throw `SecurityError`) and popups (`window.open` returns `null`). Clipboard writes fail
  while the frame has no focus; they have not been measured after a click.

Keep all state in memory, or in the tool result your agent sends.

This frame is stricter than the specification asks, on purpose. The official ext-apps sample and
apps built on the SDK run in it as they are, and none of them needed what it refuses. If your app
needs same-origin features (storage, cookies, popups) or network access, it cannot run on Anywe
today; the first real app that needs them is what would change this.

## No network, and no way to declare domains yet

The frame's Content Security Policy denies by default:

```
default-src 'none'; script-src 'unsafe-inline'; style-src 'unsafe-inline';
img-src data: blob:; base-uri 'none'
```

So `fetch`, XHR and WebSockets fail, and scripts, styles, images and fonts must be inline. In
the specification a server can widen this per app with `connectDomains` and `resourceDomains`;
Anywe has no field for that yet, so no domain can be allowed. Bundle everything into the one
HTML file. With the SDK, the `@modelcontextprotocol/ext-apps/app-with-deps` build has no imports
of its own and can be inlined in a `<script type="module">`.
