Charming

by tambo-labs

SSE
1 stars
251 downloads
Not rated
GitHub Website

About

Charming MCP server - generate and host interactive web apps via MCP

Details

Author
tambo-labs
GitHub stars
1
Downloads
251
Transport
SSE
Categories
Developer Tools, AI

- Full authoring guide: usecharming.com/llms-full.txt
- OpenAPI spec: charm.ing/openapi.json
- Docs: usecharming.com/docs

Setting up with Highlight

This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:

  1. Download and install Highlight from highlightai.com/download
  2. Navigate to the plugins tab and select "Add Custom Plugin"
  3. Configure the plugin with the settings below
    Plugin Name Charming
    Command (node, npx, python, etc.)

    Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.

  4. Enable "Start Automatically" if you want the plugin to start when Highlight launches

From the repository

{
  "mcpServers": {
    "charming-mcp": {
      "command": "npx",
      "args": [
        "skills",
        "add",
        "tambo-labs/charming-mcp"
      ]
    }
  }
}

create_app

Create a new interactive web app and render it inline. Use this to build a new app from a request. This tool call is synchronous: when it returns, the app is already live at the URL in the response. There is no Charming process to wait for, no deployment queue, and no polling step — success means the app is immediately accessible. 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. If a request needs something Charming can't do yet (AI calls, external integrations, a native app, scheduled jobs, SQL, notifications, view-only sharing), don't fake it — build the closest local-state version and log the gap with submit_feedback; the charming:app-guide prompt lists each case and what to build instead. 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.

update_app

Update an existing Charming app and render the fresh version 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 `expected_version` 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.

get_app

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_source

Return an app's raw persisted source (module, frontend ui script, and styles) plus its current version for optimistic-concurrency edits. Use this when you need the source to inspect, debug, or edit an app the caller owns.

list_apps

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, 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.

delete_app

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.

upload_asset

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.

rename_app

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.

set_remixable

Mark a Charming app as remixable. Use this to let anyone who opens the app's URL get their own brand-new editable copy, while the original is never mutated by visitors. Each remix is an independent app the visitor can keep and later claim by signing up. 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.

unset_remixable

Stop allowing remixes of a Charming app. Use this to turn off auto-forking for new visitors; existing remixes survive untouched. Idempotent: calling on an already-non-remixable app is a no-op.

set_public

Make a Charming app PUBLIC: anyone who opens its URL can use it with no login and read AND write its SHARED data. Use this for a totally-open surface (a poll, an RSVP list, a guestbook) where requiring sign-in or per-person invites is not worth it. WARNING — this is a shared, unauthenticated write surface: every anonymous visitor reads and writes the SAME data pool with no per-visitor isolation, so anyone with the URL can overwrite or wipe the data. Surface the returned `message` verbatim so the user understands that before sharing. For per-person access that keeps an audit trail and write control, share with the `end-user` role instead (it requires login). Idempotent: calling on an already-public app returns the same URL without re-firing analytics. Owner-only; anonymous apps must be claimed first.

unset_public

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.

set_starter_prompt

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.

share_app

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 gets no access and sees nothing in their workspace until they accept. 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; it activates once they register and verify that email (an unknown handle still errors, since there is no address to reach). Revoke anytime with `unshare_app`.

unshare_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.

list_app_shares

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).

query_app

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.

mutate_app

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.

submit_feedback

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 own the app.

list_feedback

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.

set_handle

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.

Claude Desktop / Cursor

Paste into your MCP client config file to install this server.

{
    "mcpServers": {
        "charming": {
            "charming-mcp": {
                "command": "npx",
                "args": [
                    "skills",
                    "add",
                    "tambo-labs/charming-mcp"
                ]
            }
        }
    }
}

McpServers

{
    "charming-mcp": {
        "command": "npx",
        "args": [
            "skills",
            "add",
            "tambo-labs/charming-mcp"
        ]
    }
}
Charming is a hosted MCP server that generates, hosts, and updates interactive web apps. Connect it to any MCP-compatible AI client and ask it to build an app. You get back a live URL in seconds. Most MCP clients can use this remote configuration: ``` `{ "mcpServers": { "charming": { "url": "https://charm.ing/mcp", "type": "streamableHttp" } } }` ``` The MCP endpoints require a bearer token, and OAuth with Dynamic Client Registration bootstraps one automatically: clients that support it show a one-time consent screen, with no API key to paste. Anonymous creation with no token is available on the HTTP path only. Auth guide:[usecharming.com/auth.md. For per-client paste-strings and setup steps, see](https://usecharming.com/auth.md)[usecharming.com/clients.txt. Once Charming is connected, paste this to start a build session: ``` `Help me figure out what to build. Look at what you know about me and suggest 2-3 apps that fit, or ask me up to 3 short questions to find an idea. Read https://usecharming.com/start.md then help me create my first app.` ``` Charming exposes 24 tools. Connected clients discover them automatically via`tools/list`. Working in Codex, Claude Code, Cursor, or another AI coding agent? Install the optional Charming authoring skill from](https://usecharming.com/clients.txt)[skills.shwith`npx skills add tambo-labs/charming-mcp`. This installs authoring guidance; it does not connect the MCP server. It teaches the agent Charming's build contract and workflow. The skill itself is](https://www.skills.sh)[`SKILL.md`;](https://github.com/tambo-labs/charming-mcp/blob/HEAD/SKILL.md)[`AGENTS.md`has connect and authoring instructions for any AI coding agent. Codex users can instead install the bundled](https://github.com/tambo-labs/charming-mcp/blob/HEAD/AGENTS.md)[Charming Codex plugin. Cursor reads project rules from`.cursor/rules/`. Drop](https://github.com/tambo-labs/charming-codex-plugin)[`.cursor/rules/charming.mdc`into your project (or copy its body into a legacy root`.cursorrules`) and Cursor's agent will reach for Charming (real URL, storage, and inline rendering) whenever you ask for an app you want to keep. The rule points at the served docs; it does not duplicate the contract. This repository is the canonical source for every public Charming integration package. Platform-neutral artifacts are hand-edited; platform adapters are generated from them, so a fact lives in exactly one file. ``` `npm ci # install ajv, the schema validator node scripts/build-packages.mjs # regenerate every adapter node scripts/build-packages.mjs --check # fail on drift (runs in CI)` ``` The adapters are not published yet; publishing each one is tracked separately. See](https://github.com/tambo-labs/charming-mcp/blob/HEAD/.cursor/rules/charming.mdc)[`DISTRIBUTION.md`for the layout, the drift checks, and how the Charming monorepo proposes changes here. - Agent skill:](https://github.com/tambo-labs/charming-mcp/blob/HEAD/DISTRIBUTION.md)[`SKILL.md`· coding-agent guide:](https://github.com/tambo-labs/charming-mcp/blob/HEAD/SKILL.md)[`AGENTS.md`· Cursor rule:](https://github.com/tambo-labs/charming-mcp/blob/HEAD/AGENTS.md)[`.cursor/rules/charming.mdc` - Full authoring guide:](https://github.com/tambo-labs/charming-mcp/blob/HEAD/.cursor/rules/charming.mdc)[usecharming.com/llms-full.txt - Auth and pairing:](https://usecharming.com/llms-full.txt)[usecharming.com/auth.md· limits:](https://usecharming.com/auth.md)[usecharming.com/pricing.md - OpenAPI spec:](https://usecharming.com/pricing.md)[charm.ing/.well-known/openapi.json - Docs:](https://charm.ing/.well-known/openapi.json)[usecharming.com/docs This is a web browser that enables your coding agent, such as Claude Code, to visit websites on your behalf and assist you in identifying bugs or creating UI test cases. Create crafted UI components inspired by the best 21st.dev design engineers. Bring agent evaluations, observability, and synthetic test set generation directly into your IDE for free with Galileo's new MCP server An MCP server to help AI assistants to answer questions and generate AccelByte Extend SDK code more effectively . MCP server for AI Diagram Maker — generate beautiful software engineering diagrams directly inside Cursor, Claude Desktop, Claude Code, or any MCP-compatible AI agent ALAPI MCP Tools,Call hundreds of API interfaces via MCP AI-powered SVG animation generator that transforms static files into animated SVG components using the Allyson platform MCP server that gives AI assistants on-demand access to 1,500+ amCharts docs, ~300 code examples, and 1000+ class API references. APIMatic MCP Server is used to validate OpenAPI specifications using APIMatic. The server processes OpenAPI files and returns validation summaries by leveraging APIMatic’s API. One shared context layer for AI agents and humans — live API specs, DB schemas, and versioned contracts across repos so every agent and teammate works from the same source of truth. Build and deploy full-stack Next.js apps with 98 tools for React, AWS, and MongoDB](https://usecharming.com/docs)
No reviews yet — be the first

Sign in to leave a review

Use Google, GitHub, or an email account so ratings stay tied to real people.

Email sign in

No reviews posted yet.