Blog
/
Editorial

Start building ChatGPT apps

Published
October 8, 2025
Last updated
October 9, 2025
Learn how you can start building ChatGPT apps with Gadget, using our forkable starter template, OpenAI's Apps SDK, and MCP.

OpenAI announced a new Apps SDK during their recent OpenAI DevDay 2025, allowing developers to build apps and widgets directly embedded into ChatGPT.

And while getting access to MCP capabilities in ChatGPT post DevDay has been a bit of a rollercoaster ride, their example pizza app does indeed work: I can see a (hardcoded) map and list of pizza places, right in ChatGPT. And we were even able to build everyone's favourite app, a todo list, that makes use of Gadget's auto-generated CRUD API and Postgres db:

Our goal at Gadget is to handle the boilerplate so devs can focus on building the things that make their apps unique. So we built a forkable ChatGPT starter template that handles all the infrastructure, auth, and MCP setup required so you can focus on building out the widgets, tool calls, data models, and backend logic that power your app.

Note: Building ChatGPT apps requires a Plus or Pro plan.

An extremely brief intro to OpenAI’s Apps SDK

The Apps SDK is built on top of MCP, the model-context protocol. It extends MCP’s tool calling capabilities by enabling devs to define HTML, CSS, and JS resources and embed them inside ChatGPT using a tool call. If you’re new to MCP or need a refresher, check out the MCP docs.

Getting a basic, unauthenticated ChatGPT app running can be done with a couple of HTTP routes, a tool call, and some HTML. Things get trickier when you want to include authentication and multi-tenancy in your app. ChatGPT apps use OAuth 2.1 and need to conform to the MCP authorization spec.

ChatGPT apps run inside an iframe in a chat. OpenAI also provides some helpful <inline-code>window<inline-code> dressing: helper functions and options that allow you to do things like make additional tool calls from within your widget or store widget state so that it persists between refreshes.

Using the Apps SDK (in Gadget)

To start, fork our app template.

Even though this is just a hello world app, OAuth is handled, <inline-code>/mcp<inline-code> HTTP routes that stand up a new MCP server have been defined.

Every app built on Gadget also gets a hosted and scaled Postgres database, a serverless Node backend with an autogenerated, yet extensible, CRUD API, and a React frontend. Not to mention, there is a built-in background jobs system powered by Temporal and every read API comes with a full text <inline-code>search<inline-code> powered by Elasticsearch. You build on production-grade infrastructure, live on the web, and avoid any time spent doing any setup. (Not to mention, we handle deployment to production for you as well.)

Setup steps

To get started with this template, follow these instructions (which are also included in the template’s <inline-code>README.md<inline-code> file):

  1. Once you have forked the template, Gadget will spin up a new app instance for you with all the infrastructure needed to run your app. No additional setup required!
  2. Because OAuth and the necessary HTTP routes have already been created for you (in <inline-code>api/routes<inline-code>) and the MCP server is stood up, you can connect to ChatGPT right away. Follow OpenAI’s instructions for creating a connector and set your app URL to <inline-code>https://<your-app-name>--development.gadget.app/mcp<inline-code>.
  3. When an app is created, you should also see the available Actions. Now you can enable your connector in a conversation and prompt the model to power a tool call! For this starter template, something like “Can you say hello!” is a good way to kick off the tool call and render “Hello, world” as a widget inside ChatGPT.

Customizing your app

Here’s a quick overview of what we include in the ChatGPT app template:

  • Auth is handled in <inline-code>api/routes/.well-known/*<inline-code> and makes use of the data models in the <inline-code>oauth<inline-code> namespace at <inline-code>api/models/oauth/*<inline-code>. A <inline-code>user<inline-code> model is also included by default.
  • An MCP server is stood up as part of HTTP route calls to <inline-code>/mcp<inline-code>. Gadget’s backend is powered by Fastify, so these are Fastify HTTP routes. The actual server is set up in <inline-code>api/mcp.ts<inline-code>.
  • A simple HTML file <inline-code>api/widget.html<inline-code> defines the app that is rendered in ChatGPT.

Note: HTTP routes are a nice escape hatch for handling things like OAuth callbacks, but most backend logic should be added to Gadget actions.

You can use <inline-code>ggt<inline-code>, the Gadget CLI, to build locally. While <inline-code>ggt dev<inline-code> runs, any changes you make to your app locally are synced to the web environment (and vice versa). This means you can build using your favourite local tools and IDEs like Claude Code, Codex, or Cursor.

Start adding tool calls and widgets to customize your app’s functionality. If you need to store custom data, define one or more data models and use the autogenerated <inline-code>api<inline-code> client to read or write data as part of your MCP actions.

What’s next?

We’re continuing to work on tooling to better support building ChatGPT apps in Gadget. To start, we have a Vite plugin <inline-code>vite-plugin-chatgpt-widgets<inline-code> to help compile your React components and widgets down into plain ole HTML, JS, and CSS.

We’ve also put together a video that covers the basics of building ChatGPT apps.

Have questions?

If you have any questions about getting started building ChatGPT apps using OpenAI’s App SDK on Gadget, reach out to us on our developer Discord. We’re always happy to help!

Riley Draward
Author
Reviewer
Try Gadget
See the difference a full-stack development platform can make.
Create app
No items found.

Start building ChatGPT apps

Learn how you can start building ChatGPT apps with Gadget, using our forkable starter template, OpenAI's Apps SDK, and MCP.
Problem
Solution
Result

OpenAI announced a new Apps SDK during their recent OpenAI DevDay 2025, allowing developers to build apps and widgets directly embedded into ChatGPT.

And while getting access to MCP capabilities in ChatGPT post DevDay has been a bit of a rollercoaster ride, their example pizza app does indeed work: I can see a (hardcoded) map and list of pizza places, right in ChatGPT. And we were even able to build everyone's favourite app, a todo list, that makes use of Gadget's auto-generated CRUD API and Postgres db:

Our goal at Gadget is to handle the boilerplate so devs can focus on building the things that make their apps unique. So we built a forkable ChatGPT starter template that handles all the infrastructure, auth, and MCP setup required so you can focus on building out the widgets, tool calls, data models, and backend logic that power your app.

Note: Building ChatGPT apps requires a Plus or Pro plan.

An extremely brief intro to OpenAI’s Apps SDK

The Apps SDK is built on top of MCP, the model-context protocol. It extends MCP’s tool calling capabilities by enabling devs to define HTML, CSS, and JS resources and embed them inside ChatGPT using a tool call. If you’re new to MCP or need a refresher, check out the MCP docs.

Getting a basic, unauthenticated ChatGPT app running can be done with a couple of HTTP routes, a tool call, and some HTML. Things get trickier when you want to include authentication and multi-tenancy in your app. ChatGPT apps use OAuth 2.1 and need to conform to the MCP authorization spec.

ChatGPT apps run inside an iframe in a chat. OpenAI also provides some helpful <inline-code>window<inline-code> dressing: helper functions and options that allow you to do things like make additional tool calls from within your widget or store widget state so that it persists between refreshes.

Using the Apps SDK (in Gadget)

To start, fork our app template.

Even though this is just a hello world app, OAuth is handled, <inline-code>/mcp<inline-code> HTTP routes that stand up a new MCP server have been defined.

Every app built on Gadget also gets a hosted and scaled Postgres database, a serverless Node backend with an autogenerated, yet extensible, CRUD API, and a React frontend. Not to mention, there is a built-in background jobs system powered by Temporal and every read API comes with a full text <inline-code>search<inline-code> powered by Elasticsearch. You build on production-grade infrastructure, live on the web, and avoid any time spent doing any setup. (Not to mention, we handle deployment to production for you as well.)

Setup steps

To get started with this template, follow these instructions (which are also included in the template’s <inline-code>README.md<inline-code> file):

  1. Once you have forked the template, Gadget will spin up a new app instance for you with all the infrastructure needed to run your app. No additional setup required!
  2. Because OAuth and the necessary HTTP routes have already been created for you (in <inline-code>api/routes<inline-code>) and the MCP server is stood up, you can connect to ChatGPT right away. Follow OpenAI’s instructions for creating a connector and set your app URL to <inline-code>https://<your-app-name>--development.gadget.app/mcp<inline-code>.
  3. When an app is created, you should also see the available Actions. Now you can enable your connector in a conversation and prompt the model to power a tool call! For this starter template, something like “Can you say hello!” is a good way to kick off the tool call and render “Hello, world” as a widget inside ChatGPT.

Customizing your app

Here’s a quick overview of what we include in the ChatGPT app template:

  • Auth is handled in <inline-code>api/routes/.well-known/*<inline-code> and makes use of the data models in the <inline-code>oauth<inline-code> namespace at <inline-code>api/models/oauth/*<inline-code>. A <inline-code>user<inline-code> model is also included by default.
  • An MCP server is stood up as part of HTTP route calls to <inline-code>/mcp<inline-code>. Gadget’s backend is powered by Fastify, so these are Fastify HTTP routes. The actual server is set up in <inline-code>api/mcp.ts<inline-code>.
  • A simple HTML file <inline-code>api/widget.html<inline-code> defines the app that is rendered in ChatGPT.

Note: HTTP routes are a nice escape hatch for handling things like OAuth callbacks, but most backend logic should be added to Gadget actions.

You can use <inline-code>ggt<inline-code>, the Gadget CLI, to build locally. While <inline-code>ggt dev<inline-code> runs, any changes you make to your app locally are synced to the web environment (and vice versa). This means you can build using your favourite local tools and IDEs like Claude Code, Codex, or Cursor.

Start adding tool calls and widgets to customize your app’s functionality. If you need to store custom data, define one or more data models and use the autogenerated <inline-code>api<inline-code> client to read or write data as part of your MCP actions.

What’s next?

We’re continuing to work on tooling to better support building ChatGPT apps in Gadget. To start, we have a Vite plugin <inline-code>vite-plugin-chatgpt-widgets<inline-code> to help compile your React components and widgets down into plain ole HTML, JS, and CSS.

We’ve also put together a video that covers the basics of building ChatGPT apps.

Have questions?

If you have any questions about getting started building ChatGPT apps using OpenAI’s App SDK on Gadget, reach out to us on our developer Discord. We’re always happy to help!

Interested in learning more about Gadget?

Join leading agencies making the switch to Gadget and experience the difference a full-stack platform can make.