How to host an app your AI built with its own URL and saved data Charming, a hosting platform, enables developers to turn apps built inside AI chats like Claude into permanently hosted applications with their own URLs and persistent data storage. The platform uses an MCP connector to let Claude write and deploy ES modules with key-value storage, allowing apps to survive beyond the chat session and be accessed by multiple agents. Claude can write a working app right inside a chat. Close the chat and it's gone: no URL, no saved data, nothing to open tomorrow. This is how you turn that throwaway app into a hosted one with its own URL and a database behind it. The example is a reading list, live at charm.ing/avi/reading-list https://charm.ing/avi/reading-list . The thing doing the hosting is Charming https://usecharming.com . Claude writes the code, Charming runs it. You keep using Claude, or whatever agent you already pay for. Charming is just where the app lives once the conversation ends. The canonical guide https://usecharming.com/blog/how-to-host-an-app-built-with-claude has the full walkthrough and screenshots. This version is for developers: how the connector hooks up, what the published module looks like, and how other agents reach it afterward. Charming plugs into Claude as a custom MCP connector. One-time setup: https://charm.ing/mcp .Screenshots and troubleshooting: usecharming.com/setup/claude https://usecharming.com/setup/claude/ . In a normal Claude chat: Build me a reading list app. I want to add books with a title and author, move each one between to-read, reading, and read, and give finished books a star rating. Claude writes it and previews it inline. So far it's just like any other in-chat app. Then: Create this on Charming so it has its own URL and saves my data. Claude calls the connector and hands back a live URL. That's your hosted app, with storage behind it and an API other agents can call later. Under the connector, Claude authors and ships one ES module with two named exports: js export const manifest = { id: 'reading-list', version: '0.0.1', displayName: 'Reading list', capabilities: { imports: 'buildy:storage/kv@1.0' , // gives the handlers env.storage exports: , }, }; export const routes = { op: 'list', method: 'GET', handler: async input, { env } = await env.storage.get 'books' ?? , }, { op: 'add', method: 'POST', handler: async input, { env } = { const books = await env.storage.get 'books' ?? ; books.push { ...input, status: 'to-read' } ; await env.storage.put 'books', books ; return books; }, }, ; No server to stand up, no database to provision. env.storage is per-app key/value storage that survives every later update, and each declared route becomes a discoverable operation at /app/