(function(){const posthogKey = "phc\_oMfVwfGjzwkE5n7cCaDf25rTm7WaYn8rH4FnvsVq57Zb"; const posthogHost = "https://i.buildy.so"; const forceAnalytics = false; const analyticsHosts = \["buildy.so","www.buildy.so","usecharming.com","www.usecharming.com"\]; const analyticsIdCookie = "buildy\_marketing\_identity\_seen"; const analyticsIdCookieMaxAgeSeconds = 31536000; !function(t,e){var o,n,p,r;e.\_\_SV||(window.posthog && window.posthog.\_\_loaded)||(window.posthog=e,e.\_i=\[\],e.init=function(i,s,a){function g(t,e){var o=e.split(".");2==o.length&&(t=t\[o\[0\]\],e=o\[1\]),t\[e\]=function(){t.push(\[e\].concat(Array.prototype.slice.call(arguments,0)))}}(p=t.createElement("script")).type="text/javascript",p.crossOrigin="anonymous",p.async=!0,p.src=s.api\_host.replace(".i.posthog.com","-assets.i.posthog.com")+"/static/array.js",(r=t.getElementsByTagName("script")\[0\]).parentNode.insertBefore(p,r);var u=e;for(void 0!==a?u=e\[a\]=\[\]:a="posthog",u.people=u.people||\[\],u.toString=function(t){var e="posthog";return"posthog"!==a&&(e+="."+a),t||(e+=" (stub)"),e},u.people.toString=function(){return u.toString(1)+".people (stub)"},o="init os ds Ie us vs ss ls capture calculateEventProperties register register\_once register\_for\_session unregister unregister\_for\_session ws getFeatureFlag getFeatureFlagPayload getFeatureFlagResult isFeatureEnabled reloadFeatureFlags updateFlags updateEarlyAccessFeatureEnrollment getEarlyAccessFeatures on onFeatureFlags onSurveysLoaded onSessionId getSurveys getActiveMatchingSurveys renderSurvey displaySurvey cancelPendingSurvey canRenderSurvey canRenderSurveyAsync identify setPersonProperties group resetGroups setPersonPropertiesForFlags resetPersonPropertiesForFlags setGroupPropertiesForFlags resetGroupPropertiesForFlags reset get\_distinct\_id getGroups get\_session\_id get\_session\_replay\_url alias set\_config startSessionRecording stopSessionRecording sessionRecordingStarted captureException startExceptionAutocapture stopExceptionAutocapture loadToolbar get\_property getSessionProperty bs ps createPersonProfile setInternalOrTestUser ys es $s opt\_in\_capturing opt\_out\_capturing has\_opted\_in\_capturing has\_opted\_out\_capturing get\_explicit\_consent\_status is\_capturing clear\_opt\_in\_out\_capturing cs debug M gs getPageViewId captureTraceFeedback captureTraceMetric Qr".split(" "),n=0;n<o.length;n++)g(u,o\[n\]);e.\_i.push(\[i,s,a\])},e.\_\_SV=1)}(document,window.posthog||\[\]); var h = window.location.hostname; if (forceAnalytics || analyticsHosts.indexOf(h) !== -1) { const hashParams = new URLSearchParams(window.location.hash.substring(1)); const productDistinctId = hashParams.get('distinct\_id'); const productSessionId = hashParams.get('session\_id'); const productBootstrap = productDistinctId && productSessionId ? { distinctID: productDistinctId, sessionID: productSessionId } : null; let markerDistinctId = null; if (!productBootstrap) { const markerIdPattern = /^\[0-9a-f\]{8}-\[0-9a-f\]{4}-\[0-9a-f\]{4}-\[0-9a-f\]{4}-\[0-9a-f\]{12}$/i; const markerPrefix = analyticsIdCookie + '='; const markerCookie = document.cookie .split(';') .map(function (part) { return part.trim(); }) .find(function (part) { return part.startsWith(markerPrefix); }); if (markerCookie) { try { const value = decodeURIComponent(markerCookie.slice(markerPrefix.length)); if (markerIdPattern.test(value)) markerDistinctId = value; } catch {} } } const bootstrap = productBootstrap ?? (markerDistinctId ? { distinctID: markerDistinctId } : null); posthog.init(posthogKey, { api\_host: posthogHost, defaults: '2026-01-30', ...(bootstrap ? { bootstrap } : {}), loaded: function (ph) { const distinctId = ph.get\_distinct\_id(); if (typeof distinctId !== 'string') return; try { localStorage.setItem(analyticsIdCookie, distinctId); } catch {} document.cookie = analyticsIdCookie + '=' + encodeURIComponent(distinctId) + '; Path=/; Max-Age=' + analyticsIdCookieMaxAgeSeconds + '; SameSite=Lax' + (window.location.protocol === 'https:' ? '; Secure' : ''); }, }); } })();(function(){const ga4Id = "G-XG5Q0M59CD"; const forceAnalytics = false; const analyticsHosts = \["buildy.so","www.buildy.so","usecharming.com","www.usecharming.com"\]; var h = window.location.hostname; if (forceAnalytics || analyticsHosts.indexOf(h) !== -1) { window.dataLayer = window.dataLayer || \[\]; function gtag() { window.dataLayer.push(arguments); } window.gtag = gtag; gtag('consent', 'default', { ad\_storage: 'denied', ad\_user\_data: 'denied', ad\_personalization: 'denied', analytics\_storage: 'granted', }); gtag('js', new Date()); gtag('config', ga4Id); var s = document.createElement('script'); s.async = true; s.src = 'https://www.googletagmanager.com/gtag/js?id=' + ga4Id; document.head.appendChild(s); } })();How to host an app built with Claude | Charming{"@context":"https://schema.org","@type":"BlogPosting","headline":"How to host an app built with Claude","description":"Claude builds an app inside a chat, but it vanishes when you close the tab. Publish it through Charming and it gets its own URL and a real database.","datePublished":"2026-07-21T00:00:00.000Z","author":{"@type":"Person","name":"Akhilesh Rangani"},"publisher":{"@type":"Organization","name":"Charming","url":"https://usecharming.com/","logo":"https://usecharming.com/charming-mark.svg"},"mainEntityOfPage":"https://usecharming.com/blog/how-to-host-an-app-built-with-claude","url":"https://usecharming.com/blog/how-to-host-an-app-built-with-claude"}{"@context":"https://schema.org","@type":"HowTo","name":"Host an app built with Claude","description":"Claude builds an app inside a chat, but it vanishes when you close the tab. Publish it through Charming and it gets its own URL and a real database.","step":\[{"@type":"HowToStep","position":1,"name":"Build the app with Claude","text":"Tell Claude what you want and let it write the app."},{"@type":"HowToStep","position":2,"name":"Connect Charming to Claude","text":"Add https://charm.ing/mcp as a custom connector in Claude so it can publish and update hosted apps."},{"@type":"HowToStep","position":3,"name":"Publish it through Charming","text":"Ask Claude to create the app on Charming. You get back a live URL with a database behind it."},{"@type":"HowToStep","position":4,"name":"Save your data","text":"Add entries in the hosted app. The data lives on the server, not in the chat."},{"@type":"HowToStep","position":5,"name":"Reopen it after the chat","text":"Close the conversation, open the URL later, and your data is still there."},{"@type":"HowToStep","position":6,"name":"Read or update it from another AI","text":"Point another agent at the same app over MCP or HTTP and let it read or change the same data."}\]}.blog-prose{color:var(--color-ink-light);font-size:1.125rem;line-height:1.8}.blog-prose>\*+\*{margin-top:1.5rem}.blog-prose h2,.blog-prose h3{color:var(--color-ink);letter-spacing:-.02em;font-weight:600;line-height:1.2}.blog-prose h2{margin-top:3.5rem;font-size:1.75rem}.blog-prose h3{margin-top:2.5rem;font-size:1.35rem}.blog-prose a{color:var(--color-ink);text-decoration:underline;text-decoration-color:var(--color-ink-lighter);text-underline-offset:.2em}.blog-prose ul,.blog-prose ol{padding-left:1.4rem}.blog-prose ul{list-style:outside}.blog-prose ol{list-style:decimal}.blog-prose li+li{margin-top:.5rem}.blog-prose blockquote{border-left:2px solid var(--color-rule);color:var(--color-ink-lighter);padding-left:1.25rem;font-style:italic}.blog-prose pre{border:1px solid var(--color-rule);background:var(--color-muted);padding:1rem;font-size:.85rem;line-height:1.6;overflow-x:auto}.blog-prose :not(pre)>code{background:var(--color-muted);padding:.12em .3em;font-size:.88em}.blog-prose img,.blog-prose iframe,.blog-prose video{border:1px solid var(--color-rule);width:100%}.blog-prose figure{margin-top:2.5rem}.blog-prose .brand-comparison{border:1px solid var(--color-rule);background:var(--color-rule);grid-template-columns:repeat(2,minmax(0,1fr));gap:1px;display:grid;overflow:hidden}.blog-prose .brand-comparison\_\_item{flex-direction:column;justify-content:center;align-items:center;gap:1.5rem;min-height:18rem;padding:2.5rem;display:flex}.blog-prose .brand-comparison\_\_item--old{color:var(--color-ink);background:#fff}.blog-prose .brand-comparison\_\_item--new{color:var(--color-ink);background:#f7f7f5}.blog-prose .brand-comparison\_\_item img{object-fit:contain;border:0;width:auto;height:10rem}.blog-prose .brand-comparison\_\_item span{letter-spacing:.12em;text-transform:uppercase;font-family:IBM Plex Mono,monospace;font-size:.75rem;line-height:1}.blog-prose .brand-comparison figcaption{background:#fff;grid-column:1/-1;margin:0;padding:.75rem 1rem}.blog-prose .launch-video{margin-top:0;margin-bottom:3rem}.blog-prose figcaption{color:var(--color-ink-lighter);margin-top:.75rem;font-family:IBM Plex Mono,monospace;font-size:.75rem;line-height:1.6}@media (width<=639px){.blog-prose .brand-comparison{grid-template-columns:1fr}.blog-prose .brand-comparison\_\_item{min-height:14rem;padding:2rem}.blog-prose .brand-comparison\_\_item img{height:8rem}.blog-prose .brand-comparison figcaption{grid-column:auto}}

[![Charming](/charming-lockup.svg)](/)

[Ideas](/#apps)[Pricing](/#pricing)[For Work](/work/)[Blog](/blog/)[Docs](/docs/)

[Sign up / Login](https://charm.ing/auth/login)

[Ideas](/#apps)[Pricing](/#pricing)[For Work](/work/)[Blog](/blog/)[Docs](/docs/)

var e=document.querySelector(\`\[data-nav-menu\]\`);e&&(e.querySelectorAll(\`a\`).forEach(t=>{t.addEventListener(\`click\`,()=>{e.open=!1})}),document.addEventListener(\`pointerdown\`,t=>{e.open&&!e.contains(t.target)&&(e.open=!1)}),document.addEventListener(\`keydown\`,t=>{t.key===\`Escape\`&&e.open&&(e.open=!1,e.querySelector(\`summary\`)?.focus())}));

[← All stories](/blog/)

# How to host an app built with Claude

Claude builds an app inside a chat, but it vanishes when you close the tab. Publish it through Charming and it gets its own URL and a real database.

By Akhilesh Rangani·July 21, 2026

Short version: have Claude build the app, then publish it through [Charming](/). You connect Charming to Claude once, ask Claude to create the app, and you get back a hosted app with its own URL and a database behind it. Close the chat and the app is still there. Any AI you use can read or update the same data over MCP or plain HTTP.

The rest of this is the long version, with an example you can open right now: [a reading list](https://charm.ing/avi/reading-list). It tracks books through to-read, reading, and read, and it saves every change.

## Where Claude stops and Charming starts

Search around and you will see the same complaint in thread after thread: it is fun, but with “no persistent storage” an app built this way stays “just a toy.” You add real data, close the tab, and the next time you open it the thing has started over. So once the demo works, the question is always some version of the same one, the one people keep asking on Hacker News and dev.to: how do I turn this into a real app, with its own URL and a database, that does not vanish when the chat ends?

Claude is good at turning a sentence into working code while you are still chatting. What it cannot do is keep that app around after you close the tab. That gap is the reason Charming exists.

Claude writes the code, and Charming runs it. Charming gives the app a URL, stores its data, and exposes an API your agents can call, so you never stand up a server or a login system yourself. You keep the AI you already pay for. Charming is where the result lives.

## What you’ll build

A reading list. You add a book with its title and author, move it from to-read to reading to read, and give the ones you finish a star rating. Nothing private, nothing to sign in for. It remembers your books.

![A hosted reading list app showing four books grouped by status: The Pragmatic Programmer under to-read, Project Hail Mary under reading, and Dune and The Left Hand of Darkness under read with star ratings.](/blog/host-app-built-with-claude/reading-list-app.png)

The finished app, hosted on Charming with its own URL and saved data.

Open the live one here: [charm.ing/avi/reading-list](https://charm.ing/avi/reading-list).

## Step 1: Build it with Claude

Open a normal Claude chat and say what you want:

> 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 shows you a preview. Up to here it is the same as a Claude Artifact: a live thing running inside the chat. The next steps give it a permanent URL and storage that outlives the chat.

## Step 2: Connect Charming to Claude

You do this once. Charming plugs into Claude as a custom MCP connector, which is how Claude gets to publish and update hosted apps.

1.  Copy the connector URL: `https://charm.ing/mcp`
2.  Open Claude’s connector settings at [claude.ai/customize/connectors](https://claude.ai/customize/connectors).
3.  Choose **Add custom connector**, name it Charming, paste the URL, and click **Add**.
4.  Approve it once so Claude can use Charming’s tools.

The [Claude setup page](https://charm.ing/docs/guides/setup-claude) has the same steps with screenshots.

## Step 3: Publish it

Back in the chat, ask Claude to make it live:

> Create this on Charming so it has its own URL and saves my data.

Claude calls Charming and hands back a live link. That link is the hosted app: a public URL with a database behind it and an API other agents can hit. You did not make a repo or deploy anything.

## Step 4: Save some data

Open the URL and add a few books. Mark one as reading, finish another and give it four stars. What you type gets stored on Charming’s server, not buried in the chat transcript.

The example list has four books, one in each state, so you can see reading and read next to each other:

*   The Pragmatic Programmer, still to-read
*   Project Hail Mary, currently reading
*   Dune, read, five stars
*   The Left Hand of Darkness, read, four stars

## Step 5: Close the chat, come back later

Close the Claude conversation. Open a new tab and go straight to the app’s URL. The books are still there, same states, same ratings. The app does not need the chat that built it.

## Step 6: Use it from another AI

The app has an agent-readable API, so you are not stuck with Claude. Point another agent at the same Charming app over MCP, or hit its HTTP API, and it reads and writes the same data.

I asked Claude to add the Harry Potter series to the same list. It loaded the app to see what was already on there, then added all seven books as to-read:

![Claude using the Charming connector to open the hosted reading list app inline and add the seven Harry Potter books to it as to-read.](/blog/host-app-built-with-claude/claude-adds-books.png)

Another agent working on the same hosted app. Claude reads the list, then adds the Harry Potter series to it.

Open the app again and the new books are there. Two different chats wrote to the same app.

## About Claude Artifacts

Artifacts are a good way to get something interactive inside a chat, and a published Artifact on a paid plan can even save text and be shared by link. If that covers what you need, use it. We went through exactly what an Artifact keeps in [do Claude Artifacts save data](/do-claude-artifacts-save-data/).

Charming is a different thing. The app lives at a neutral URL that is not tied to Claude, the data is a real database instead of text capped inside one product, and any agent that speaks MCP or HTTP can read and change it. Claude can build it either way. Charming is for when you want the result to stand on its own.

If you are weighing this against other options in general, we wrote up [where to host an app you built with AI](/where-to-host-an-app-you-built-with-ai/).

## Frequently asked questions

**Can Claude publish an artifact as a standalone app?** A published Artifact gets a shareable link and lives inside Claude. If you want an app with its own URL and a database other agents can reach, publish it through Charming instead. Claude writes the code; Charming runs the app.

**How do I turn a Claude artifact into an app?** Connect Charming to Claude as a custom connector, then ask Claude to create the app on Charming. You get a hosted app with a database behind it that does not reset when you close the chat.

**Where should I host an app I built with Claude?** Charming is built for this. It hosts an app your AI made and handles storage, the API, and sharing for you. If you are comparing hosting options more broadly, we cover that in [where to host an app you built with AI](/where-to-host-an-app-you-built-with-ai/).

**Does the app keep working after the chat ends?** Yes. The app and its data live on Charming, so losing or closing the chat does not touch it. Open the URL later and everything is still there.

Related reading: [do Claude Artifacts save data](/do-claude-artifacts-save-data/), [where to host an app you built with AI](/where-to-host-an-app-you-built-with-ai/), [can you build an app inside ChatGPT](/can-you-build-an-app-inside-chatgpt/), [does ChatGPT Canvas persist](/does-chatgpt-canvas-persist/), and [personal app ideas](/personal-app-ideas/).

## Get The Daily Charmer by email.

astro-island,astro-slot,astro-static-slot{display:contents}(()=>{var e=async t=>{await(await t())()};(self.Astro||(self.Astro={})).load=e;window.dispatchEvent(new Event("astro:load"));})();(()=>{var g=Object.defineProperty;var w=(a,s,c)=>s in a?g(a,s,{enumerable:!0,configurable:!0,writable:!0,value:c}):a\[s\]=c;var l=(a,s,c)=>w(a,typeof s!="symbol"?s+"":s,c);var E=new Set(\["\_\_proto\_\_","constructor","prototype"\]);{let a={0:t=>y(t),1:t=>c(t),2:t=>new RegExp(t),3:t=>new Date(t),4:t=>new Map(c(t)),5:t=>new Set(c(t)),6:t=>BigInt(t),7:t=>new URL(t),8:t=>new Uint8Array(t),9:t=>new Uint16Array(t),10:t=>new Uint32Array(t),11:t=>Number.POSITIVE\_INFINITY\*t},s=t=>{let\[p,e\]=t;return p in a?a\[p\](e):void 0},c=t=>t.map(s),y=t=>typeof t!="object"||t===null?t:Object.fromEntries(Object.entries(t).map((\[p,e\])=>\[p,s(e)\]));class f extends HTMLElement{constructor(){super(...arguments);l(this,"Component");l(this,"hydrator");l(this,"hydrate",async()=>{var b;if(!this.hydrator||!this.isConnected)return;let e=(b=this.parentElement)==null?void 0:b.closest("astro-island\[ssr\]");if(e){e.addEventListener("astro:hydrate",this.hydrate,{once:!0});return}let r=this.querySelectorAll("astro-slot"),n={},d=this.querySelectorAll("template\[data-astro-template\]");for(let o of d){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(n\[o.getAttribute("data-astro-template")||"default"\]=o.innerHTML,o.remove())}for(let o of r){let i=o.closest(this.tagName);i!=null&&i.isSameNode(this)&&(n\[o.getAttribute("name")||"default"\]=o.innerHTML)}let u;try{u=this.hasAttribute("props")?y(JSON.parse(this.getAttribute("props"))):{}}catch(o){let i=this.getAttribute("component-url")||"<unknown>",v=this.getAttribute("component-export");throw v&&(i+=\` (export ${v})\`),console.error(\`\[hydrate\] Error parsing props for component ${i}\`,this.getAttribute("props"),o),o}let h;await this.hydrator(this)(this.Component,u,n,{client:this.getAttribute("client")}),this.removeAttribute("ssr"),this.dispatchEvent(new CustomEvent("astro:hydrate"))});l(this,"unmount",()=>{this.isConnected||this.dispatchEvent(new CustomEvent("astro:unmount"))})}disconnectedCallback(){document.removeEventListener("astro:after-swap",this.unmount),document.addEventListener("astro:after-swap",this.unmount,{once:!0})}connectedCallback(){if(!this.hasAttribute("await-children")||document.readyState==="interactive"||document.readyState==="complete")this.childrenConnectedCallback();else{let e=()=>{document.removeEventListener("DOMContentLoaded",e),r.disconnect(),this.childrenConnectedCallback()},r=new MutationObserver(()=>{var n;((n=this.lastChild)==null?void 0:n.nodeType)===Node.COMMENT\_NODE&&this.lastChild.nodeValue==="astro:end"&&(this.lastChild.remove(),e())});r.observe(this,{childList:!0}),document.addEventListener("DOMContentLoaded",e)}}async childrenConnectedCallback(){let e=this.getAttribute("before-hydration-url");e&&await import(e),this.start()}getRetryImportUrl(e){let r=new URL(e,document.baseURI);return r.searchParams.set("astro-retry",Date.now().toString()),r.toString()}async importWithRetry(e){try{return await import(e)}catch(r){return await new Promise(n=>setTimeout(n,1e3)),import(this.getRetryImportUrl(e))}}handleHydrationError(e){let r=this.getAttribute("component-url"),n=new CustomEvent("astro:hydration-error",{cancelable:!0,bubbles:!0,composed:!0,detail:{error:e,componentUrl:r}});this.dispatchEvent(n)&&console.error(\`\[astro-island\] Error hydrating ${r}\`,e)}async start(){let e=JSON.parse(this.getAttribute("opts")),r=this.getAttribute("client");if(Astro\[r\]===void 0){window.addEventListener(\`astro:${r}\`,()=>this.start(),{once:!0});return}try{await Astro\[r\](async()=>{let n=this.getAttribute("renderer-url");try{let\[d,{default:u}\]=await Promise.all(\[this.importWithRetry(this.getAttribute("component-url")),n?this.importWithRetry(n):Promise.resolve({default:()=>()=>{}})\]),h=this.getAttribute("component-export")||"default";if(h.includes(".")){this.Component=d;for(let m of h.split(".")){if(E.has(m)||!this.Component||typeof this.Component!="object"&&typeof this.Component!="function"||!Object.hasOwn(this.Component,m))throw new Error(\`Invalid component export path: ${h}\`);this.Component=this.Component\[m\]}}else{if(E.has(h))throw new Error(\`Invalid component export path: ${h}\`);this.Component=d\[h\]}return this.hydrator=u,this.hydrate}catch(d){return this.handleHydrationError(d),()=>{}}},e,this)}catch(n){this.handleHydrationError(n)}}attributeChangedCallback(){this.hydrate()}}l(f,"observedAttributes",\["props"\]),customElements.get("astro-island")||customElements.define("astro-island",f)}})();

Email addressSubscribe

Occasional emails from Charming. Unsubscribe anytime.

## Give your agent somewhere to build.

Your first app takes one sentence.

(()=>{var a=(s,i,o)=>{let r=async()=>{await(await s())()},t=typeof i.value=="object"?i.value:void 0,c={rootMargin:t==null?void 0:t.rootMargin},n=new IntersectionObserver(e=>{for(let l of e)if(l.isIntersecting){n.disconnect(),r();break}},c);for(let e of o.children)n.observe(e)};(self.Astro||(self.Astro={})).visible=a;window.dispatchEvent(new Event("astro:visible"));})();

Add to an AI Chat

![](/logos/claude-code.png)![](/logos/codex.svg)![](/logos/cursor.svg)Copy Prompt

[![Charming](/charming-lockup.svg)](/)

Software that's finally yours.

[Operational](https://status.buildy.so "System status. Opens status.buildy.so")

© 2026 Charming

## Product

*   [Overview](/)
*   [Pricing](/#pricing)
*   [For Work](/work/)
*   [Blog](/blog/)

## Works with

*   [ChatGPT](https://chatgpt.com/apps/buildy/asdk_app_69f9215e800881919f3d96d79200a35a)
*   [Claude](https://charm.ing/docs/guides/setup-claude)
*   [Gemini](https://charm.ing/docs/guides/setup-gemini)
*   [Grok](https://charm.ing/docs/guides/setup-grok)
*   [Perplexity](https://charm.ing/docs/guides/setup-perplexity)

## Resources

*   [Docs](/docs/)
*   [Guides](/guides/)
*   [Contact](/contact-us/)
*   [llms.txt](/llms.txt)
*   [Email us](mailto:support@usecharming.com)

## Legal

*   [Privacy](/privacy/)
*   [Terms](/terms/)
*   [Fair use](/fair-use/)
*   [Subprocessors](/subprocessors/)