Mermaid App is an example project that uses ChatGPT Apps SDK to render Mermaid diagrams. It uses Hono and Cloudflare Workers for deployment but can be used an a simple example of what it takes to build a ChatGPT App.
- Remote tool powered by the Apps SDK metadata:
src/tools.tsregisters therender-mermaidMCP tool. - Custom widget for ChatGPT: The HTML resource returned at
ui://widget/mermaid.htmllistens foropenai:set_globalsevents and uses Mermaid.js to draw the diagram supplied by the model. - Cloudflare Worker deployment:
src/index.tsuses the standard Typescript MCP SDK with Hono that you can run locally with Wrangler or deploy globally to Cloudflare. - Validation guard-rails: The helper in
src/tools.tschecks that the submitted text looks like a Mermaid diagram before returning it to ChatGPT, giving you a pattern for returning graceful tool errors.
- Node.js 20+ and npm
- A paid ChatGPT account for testing
- Install dependencies
npm install
- Run locally
Wrangler exposes a local Worker URL. The MCP endpoint lives at
npm run dev
/mcp; the UI preview page is available at/. - Setup a tunnel
Your service needs to run on a publicly accessible URL. The easiest way to do this is with Cloudflare tunnels or ngrok.
cloudflared tunnel --url http://localhost:8787
- Connect the tool to ChatGPT
- Put ChatGPT in Developer mode (Apps & Connectors -> Advanced Settings)
- In ChatGPT, create a new App. (Apps & Connectors -> Create)
- Add the tunnel URL you just created along with
/mcp. Set a name and "No Authentication" - ChatGPT will discover the
render-mermaidtool and automatically load theui://widget/mermaid.htmlwidget whenever the tool returns Mermaid text.
I found debugging issues to be difficult since the events and event structures are not well documented. And my favorite debugging technique console.log is blocked in the environment. So add this little DOM logger to the script if you want to get details on what events occur and what data is available on them.
let log = "";
function writeLog(newLog) {
log = log + newLog;
document.getElementById("debug").innerHTML = "<pre>" + log + "</pre>\\n";
}
}
...
writeLog("event: " + JSON.stringify(event, null, 2));
...
<div id="debug"></div>Deploy the Worker:
npm run deployAfter deployment, update your ChatGPT App to reference the deployed Worker’s /mcp endpoint.
src/index.ts: Hono app that binds the MCP server to Cloudflare Worker routes.src/tools.ts: Registersrender-mermaid, defines its Zod schema, validation logic, and the HTML widget resource.src/readme.ts: Serves a lightweight landing page that links to your MCP endpoint.wrangler.jsonc: Worker configuration and environment variables.public/: Static assets.
- If ChatGPT reports that it cannot reach the tool, verify the
/mcpendpoint is accessible over HTTPS and that your Cloudflare Worker is running. - If the widget loads but no diagram appears, check the console logs for errors. The errors might be vague and stack traces are unlikely to be useful.
- ChatGPT caches widget resources. After updating the HTML, use the "Refresh" button in the Apps settings to force it to refetch.
Distributed under the MIT License. See LICENSE for details.