Integration details
Description
Charming is a hosted runtime for personal web apps that users and their agents can share. An agent creates an app, Charming gives it a URL, backend, and key-value storage, and the user keeps using the same app and data across ChatGPT, Claude, and other agents.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- AI App & Website Builders
- Secondary Subcategories
- None listed
- Brand
- Charming
- Access
- Account required
- First tracked
- 2026-08-22
- Tool count
- 32
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
ChatGPT Plugin Discovery Score
ChatGPT Plugin discovery is coming soon
ChatGPT can surface a Plugin when it matches a user's request.Your Plugin Discovery Score measures how often yours appears.
No spam. Unsubscribe any time.
What discovery looks like

Competing in ChatGPT AI App & Website Builders
View Category32 tools agents can invoke
Acknowledge feedback responses after the agent has processed them. Use this to stop processed responses from appearing in advisories and list_feedback_responses. Acknowledgement is durable and idempotent.
acknowledge_feedback_responses
Create a new interactive web app and render it inline. Use this to build a new app from a request. This tool call returns only after the app is live at the response URL. Do not wait or poll for deployment. If `module` reuses a `manifest.id` the caller already owns, the new app replaces the existing app module, UI, and styles in place; use update_app to edit a known app ID by UUID. Apps persist state through a backend `env.storage` (Workers KV) binding and call backend operations from the frontend via `window.charming.api`. The `module`, `ui`, and `description` parameter docs carry the authoring rules — including the fill-viewport outer-container rule on `ui`; the charming:app-guide prompt has the full guide and a canonical example. Read the public docs without a browser using read_docs({ path: "build-mcp.md" }); read_docs({}) lists available pages. If a request needs in-app AI calls, external integrations, native apps, scheduled jobs, SQL, notifications, or view-only sharing, do not fake support. Build the closest local-state version, then log the gap with `submit_feedback`. The charming:app-guide prompt has alternatives. The charming:design-guide prompt documents Charming's default visual style for generated `ui` (single accent, warm neutrals, real type hierarchy; no gradients or decorative emoji) — a default that yields to any user-requested aesthetic. When telling the user where to open or share the app, always give them `shareUrl` from the result — never the `url` field, which is machine-only and embeds a write-capable access token.
create_app
Use this when the user wants an app op to run on its own, on a timer — no chat needs to be open. Schedules one of an app's declared ops as a Routine. Interval is `hourly`, `daily`, or `weekly` (no cron syntax). The target op is invoked with empty input (`{}`), so it must not declare any required input fields. Rejects a duplicate Routine on the same (app, op) pair, and enforces a 3-per-app / 25-per-user cap.
create_routine
Permanently delete a Charming app the caller owns, optionally also purging its stored data. Use this to remove an app the caller no longer wants. Deletion is irreversible and requires confirmation: the host is asked to show a confirmation prompt, and when it cannot, the call fails closed until re-invoked with confirm: true.
delete_app
Use this to stop and remove a Routine.
delete_routine
Fetch an existing app by ID and render it inline. Use this to open, re-render, or continue working with an app the caller already has. Returns the live embedded UI plus its callable API operations, which another agent can invoke with query_app (read-only) or mutate_app (writes) to query or update saved app data. Unlike list_apps, which returns metadata including IDs and URLs, get_app renders the app; call list_apps first to find the ID. When telling the user where to open or share the app, always give them `shareUrl` from the result — never the `url` field, which is machine-only and embeds a write-capable access token.
get_app
Use this to inspect an accepted app build without running or publishing it. Use include_source to recover the exact submitted source. Status remains available after authoring access to the ESM cohort is removed.
get_app_build
Return an app's raw persisted source (module, frontend ui script, and styles) plus its current revision for optimistic-concurrency edits. Pass that revision through update_app's `expected_revision` input. Use this when you need the source to inspect, debug, or edit an app the caller owns.
get_app_source
List feedback rows for the caller's apps. Use this to review feedback previously recorded for an app. When `app_id` is set, returns rows for that one app (owner-checked); when omitted, returns rows across every app the caller owns. Paginate with `cursor` from a prior call's `cursor` field. Newest rows come first.
list_feedback
Use this to see who an app is shared with: lists every outstanding invitation and active grant, labeled by status (`pending` = invited, no access yet; `accepted` = active grantee; `invited` = email-only invite, no Charming account yet) and by role (`collaborator` = read + write; `end-user` = run + write data, not edit source; `viewer` = read only).
list_app_shares
List the caller's Charming apps — owned ones plus apps shared with them (accepted invites, marked `[shared with you]`; a read-only share also reads `(view-only)`). Use this to find an app's id before fetching, editing, or calling it. Returns per app: id, revision, role (owner | collaborator | end-user | viewer | team-admin | team-member), displayName, description (a search-friendly summary), url (machine API base), shareUrl (the link to give the user), lastUpdatedAt (ISO-8601 of the last write), claimed (always true for now — exposed for forward-compat), and capabilities (imports + exports). A `collaborator` can edit and run a shared app; an `end-user` can run it and write its data but cannot edit the app source; a `viewer` can only open and read it. The description disambiguates apps with similar display names; capabilities.exports lists each app's callable operations, exposing the cross-app integration surface without N+1 get_app_source calls. Paginate with `cursor` from a prior call's `nextCursor` line. Apps with `description: null` predate descriptions and have not yet been backfilled. When telling the user where to open or share an app, always give them `shareUrl` — never construct links for humans from the `url` field.
list_apps
Fetch unread Charming staff responses to feedback submitted by this authenticated account. Use this when a feedback-responses-available advisory appears. Responses are ordered oldest-first. Reading does not acknowledge them; call acknowledge_feedback_responses with the returned response IDs after processing them.
list_feedback_responses
Use this to see the caller's Routines across their apps.
list_routines
Make a public Charming app PRIVATE again. Use this to close anonymous access: visitors can no longer open the app without logging in (the URL requires login). Data already written by anonymous visitors is retained. Idempotent: calling on an already-private app is a no-op.
unset_public
Make a Charming app Public: anyone with the URL can open the live hosted App Viewer with no login and read its data. Public visitors cannot change data or source. Use this for a read-only public surface such as a dashboard, menu, schedule, or status page. Surface the returned `message` verbatim so the user understands the access granted. For write access, share with the `end-user` role or choose the signed-in audience setting. Template and Listed are separate settings. Idempotent: calling on an already-public app returns the same URL without re-firing analytics. Owner-only; anonymous apps must be claimed first.
set_public
Run a mutating backend operation on a Charming app and return its result, without editing code. Use this for operations that change state — including operations whose read/write safety can't be determined. For read-only operations, use query_app. If you don't know an operation's name or which tool it needs, call get_app — each operation lists its tool.
mutate_app
Enable a Charming Template for people who can already read the source App, and optionally publish it in Charming's public Template directory so anyone can discover and copy it. Listed grants no access to the live source App or its data. Use this when the user wants independent copies or a public Template listing, not access to the live App. Each copy belongs to the signed-in visitor from creation. Optional listing fields are a patch: `title`, `summary`, `content_markdown`, `category`, cover fields, and `gallery` change only when supplied. Publishing with `listed: true` requires a nonblank resulting title and summary; every cover or gallery image needs nonblank alt text and must reference an image asset from this App. Pass `listed: true` to also mark it for discovery, or `listed: false` to unlist it. Omitting `listed` is a patch, not a reset: it leaves the current listed state exactly as it is (an already-listed app stays listed; a never-listed app stays unlisted), so re-affirming that an app is a template never surprises the owner by delisting it. Idempotent: calling with the same effective `listed` state as the current one returns the same URL without re-firing analytics. Anonymous apps cannot be made into templates; the app must be claimed first.
set_template
Run a read-only backend operation on a Charming app and return its result, without editing code. Use this for operations that only read state. For operations that change state, use mutate_app. If you don't know an operation's name or which tool it needs, call get_app — each operation lists its tool.
query_app
Read Charming documentation without web access. Call without arguments to get the docs index, then pass a page path from that index (for example capabilities/data-storage.md). Use this when building an app or looking up the runtime, API, or capability reference. Returns Markdown in chunks of up to 20,000 characters; pass next_offset as offset with the same path to continue. For the full authoring reference, use llms-full.txt. Only public Charming docs can be read. Limited to 60 reads per caller per minute.
read_docs
Change a Charming app's URL slug — the human-readable, URL-safe name, distinct from its title/displayName and from its machine manifest id. Use this to give an app a different public URL. Titles and slugs are independent: editing the title with update_app does not change the slug; this tool does. Renaming changes the public URL, and the old URL keeps working by redirecting to the new one. Slug rules: lowercase letters, digits, and hyphens; 2-48 chars; may start with a letter or digit; no leading, trailing, or consecutive hyphens. When telling the user where to open or share the renamed app, always give them `shareUrl` from the result — never the `url` field, which is machine-only and embeds a write-capable access token.
rename_app
Revoke another user's access to one of your apps — removes a pending invitation or an accepted collaborator grant. Use this when the user wants to withdraw an invitation or remove a collaborator. Takes effect immediately for new requests. Idempotent: revoking a grant that does not exist is a no-op.
unshare_app
Search the public Charming Template directory by keyword. Use this to check for an existing Template before calling create_app, or when the user asks what Templates exist. Returns the resolved listing title, summary, Markdown detail, category, cover, starter prompt, creator, builder count, canonical Template page, and browser copy URL. The copy URL starts browser navigation where the user chooses to copy and signs in before owned creation; it is not an MCP or REST write. After browser creation, find the copy with list_apps or GET /app and read it with get_app_source or GET /app/:id/source.
search_templates
Set or clear an app's authored starter prompt — a short getting-started instruction prefilled in the chat host when a visitor clicks "Open in Claude" or "Open in ChatGPT" on the app, replacing the generic "I'm using this Charming app" body. Use this to frame a shared/remixable app's intended first action for visitors. Write a generic instruction — do NOT embed the app's URL: the app name, description, and URL (and, for unclaimed apps, an access token) are appended automatically at render time, so a hardcoded URL would point every remixer at the template instead of their own copy. Pass `starter_prompt: null` (or an empty string) to clear and revert to the generic default. Owner-only; anonymous apps must be claimed first. Idempotent (re-setting the same value is a no-op). Length cap: 2000 characters.
set_starter_prompt
Change the signed-in user's handle (their username) — the first segment of their friendly app URLs (`https://charm.ing/<handle>/<app-name>`), so changing it changes the prefix of every app URL they share. Use this to give the current user a different handle. The old handle keeps working by redirecting to the new one, so links already shared stay valid. Acts on the current signed-in user only and takes no user id. Handle rules: lowercase letters, digits, and hyphens; 3-32 chars; must start with a letter; no leading, trailing, or consecutive hyphens; some words are reserved. Rate-limited to 3 changes per rolling 30 days.
set_handle
Deprecated: use `set_template` instead. This metadata-blind alias accepts only `app_id`, enables Template for people who can already read the source App, and leaves listing metadata and Listed state unchanged. The original is never mutated. Use this when an older workflow requires the deprecated alias; use `set_template` for new work. Each copy belongs to the signed-in visitor from creation. Idempotent: calling on an already-remixable app returns the same URL without re-firing analytics. Anonymous apps cannot be made remixable; the app must be claimed first.
set_remixable
Invite someone (by Charming handle or email) to one of your apps, OR change the role of someone you already invited. Use this when the user wants to give a specific person access to an app, or to change what an existing collaborator/end-user/viewer can do. Creates a PENDING invitation: the invitee has no access until the eligible signed-in account chooses Open app from the email or Charming Home; that action creates the durable grant before entering the app. Pick a role: `collaborator` (default) can open, edit, and run the app (shared state, same data); `end-user` can open the app and write its data (record entries, save state) but cannot edit the app source; `viewer` can only open and use the read-only surface — viewers cannot edit, run mutating ops, or change anything. If the grantee already has a share, calling this again WITH a `role` changes their role in place (status `updated`, no new invitation, no second email) — this is how you flip a collaborator to an end-user and back; re-sharing WITHOUT a `role` leaves the existing role untouched. No share role can ever share, delete, or transfer the app. The invitee does NOT need a Charming account first — inviting an email with no account stores a pending invitation and emails them a sign-up link; the eligible grant appears after they register and verify that email (an unknown handle still errors, since there is no address to reach). Revoke anytime with `unshare_app`.
share_app
Deprecated: use `unset_template` instead (identical effect). Stop allowing remixes of a Charming app. Use this to stop offering copies to new visitors; existing copies survive untouched. Also clears any public template listing, since a listed app must stay copyable. Idempotent: calling on an already-non-remixable app is a no-op.
unset_remixable
Record agent-authored feedback about a Charming app. Use this to log observed bugs, suggested enhancements, caught crash reports, or qualitative notes. Source is server-enforced to "agent" — agents cannot impersonate user or auto-crash sources. The caller must have app:run access.
submit_feedback
Stop treating a Charming app as a template. Use this to turn off copying for new visitors and clear any public listing; existing copies survive untouched. Idempotent: calling on an app that is neither copyable nor listed is a no-op.
unset_template
Update an existing Charming app and render the fresh revision inline. Use this to edit an app the caller already owns, identified by UUID. This tool call is synchronous: when it returns, the updated app is already live — no process to wait for, no deployment queue. Two mutually exclusive input shapes: (A) full-source — pass module/ui/styles to replace those buckets, following the same authoring rules as create_app (documented on those parameters and in the charming:app-guide prompt); (B) edits[] — exact-string find/replace operations plus the revision carried by `expected_revision` from your last read, much cheaper for small changes. If the app's behavior changed materially (new operation, new data tracked, new use-case), also pass an updated `description` so list_apps stays accurate; backfill one if an older app has none. When telling the user where to open or share the app, always give them `shareUrl` from the result — never the `url` field, which is machine-only and embeds a write-capable access token.
update_app
Use this to change a Routine's `interval`, or enable/disable it. Re-enable is `{enabled: true}` — there is no separate re-enable action. Re-enabling also resets the consecutive-failure counter.
update_routine
UPLOAD A STATIC ASSET TO AN APP so app code stays small and the app reads it back same-origin. Use this when an app needs a large or static file — an image, PDF, audio clip, or a dataset bigger than a few KB — that would otherwise be inlined into `module`/`ui` and blow the 256 KiB source cap. Provide EXACTLY ONE of: `sourceUrl` (PREFERRED for any binary — the SERVER fetches the remote file, follows redirects, and the bytes never transit this tool call), `text` (UTF-8 dataset/JSON/CSV — no encoding needed), or `dataBase64` (LAST RESORT, tiny binaries only: large base64 arguments can stall inside some MCP clients before ever reaching the server, so keep it under ~16 KB and use `sourceUrl` for anything bigger). The app reads the asset via `window.charming.assets.getUrl(key)` (for <img>/<a>) or `env.assets.get(key)` in its backend (the app must declare `charming:storage/blob@1.0` in manifest.capabilities.imports to use env.assets). Caps: 10 MiB/asset, 50 assets/app, 100 MiB/app.
upload_asset
How do I improve a ChatGPT Plugin's discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Charming alternatives on ChatGPT?
As of 2026-09-13, Charming competes with Adalo, AI Roleplay Chat Simulator, AppDeploy, Base44, Buildfire, Craftian, Floot, FluxBuilder, FreakUI, GoodBarber, Hatchable, Hercules, Hostinger, Lovable, Macaly Cloud, MiniUp, ProductOS, Replit, Sticklight, Val Town, Zite in ChatGPT AI App & Website Builders, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.