Show HN: An open-source framework for building "Apps in ChatGPT"

1 month ago 5

The ChatGPT apps framework. Make components, define schemas - everything else is automated.

Note: This project is a fork of OpenAI's Apps SDK Examples, enhanced with an automated framework to reduce boilerplate and simplify widget creation.

For AI Coding Tools: If you're using an AI coding tool like Cursor, Claude Code, or Codex, try prompting:

"Read the /docs/AGENTS.md and help me use this chatjs framework."

npx create-chatgpt-app my-app cd my-app

Or clone this repository to use as a starting point.

pnpm install pnpm run build

Terminal 1 - Frontend assets server:

Terminal 2 - MCP server:

Terminal 3 - Expose to internet:

From the ngrok command, You will get a public URL.

For example: https://<custom_endpoint>.ngrok-free.app/mcp

💡 Tip: If you used npx create-chatgpt-app, your project already includes 6 example widgets (pizzaz map, albums, carousel, list, solar-system, and todo) ready to try!

To add these apps to ChatGPT, enable developer mode, and add your apps in Settings > Connectors.

Add your local public URL from ngrok(like 'https://<custom_endpoint>.ngrok-free.app/mcp') to ChatGPT in Settings > Connectors.

Adding a New Widget (Component)

Create src/components/my-widget/index.jsx:

import React from 'react'; import { createRoot } from 'react-dom/client'; function MyWidget() { return <div>My Widget Content</div>; } const rootElement = document.getElementById('my-widget-root'); if (rootElement) { const root = createRoot(rootElement); root.render(<MyWidget />); }

Step 2: Add Widget Definition (Schema)

Edit server/src/server.ts:

const widgets = [ // ... existing widgets { component: "my-widget", // matches folder name title: "My Widget", schema: z.object({ param: z.string().describe("Parameter description") }), handler: async (args) => ({ text: "Widget rendered!", data: args }) } ];

Step 3: Rebuild & Restart

# Terminal 1: Rebuild pnpm run build # Terminal 2: Restart server cd server pnpm start

Done.

  • component: "my-widget" maps to src/components/my-widget/
  • Build script auto-discovers all components
  • Server auto-syncs version from package.json for asset hashing
  • Framework auto-generates MCP tools, resources, and handlers

404 on widget assets:

pnpm run build # Rebuild cd server && pnpm start # Restart server

Component not found:

  • Check src/components/your-widget/index.jsx exists
  • Check widget definition in server/src/server.ts
chatjs/ ├── src/components/ # React components (add here) │ └── my-widget/ │ └── index.jsx ├── assets/ # Built assets (generated) ├── server/src/ │ ├── framework/ # MCP framework │ └── server.ts # Widget definitions (edit here) └── package.json # Version (auto-synced)
{ component: string; // Component folder name (required) title: string; // Display name (required) description?: string; schema: ZodType; // Input schema (required) handler: (args) => Promise<{ // Handler (required) text: string; data?: Record<string, any>; }>; meta?: { invoking?: string; // "Loading..." invoked?: string; // "Loaded!" widgetDescription?: string; // For AI model understanding }; }

This project is built upon OpenAI's Apps SDK Examples, which provides the foundation for creating ChatGPT apps using the Model Context Protocol (MCP).

Key enhancements in Chat.js:

  • Automated MCP framework that eliminates 300+ lines of boilerplate
  • Convention-based widget registration
  • Automatic asset URL generation with version syncing
  • Simplified API for creating widgets
  • npm initializer (create-chatgpt-app) for instant project setup

Credits to OpenAI for the original Apps SDK implementation and example widgets.

MIT

Read Entire Article