This project demonstrates an end-to-end ChatGPT app built with the OpenAI Apps SDK and the Apps SDK quickstart patterns. The app connects ChatGPT to a headless CMS, renders a custom vehicle search experience inside ChatGPT via an iframe widget, and exposes a tool that streams structured inventory results to both the LLM and the user interface.
- Headless CMS integration: Queries vehicle inventory from a headless CMS with optional engine-type filtering.
- Custom UX in ChatGPT: Renders a responsive widget visually inspired by avemo-group.de/fahrzeugsuche inside ChatGPT.
- React-powered widget: Uses a React component (bundled on-demand with esbuild) to manage form state and render the iframe UI.
- Apps SDK + MCP server: Implements an MCP server that exposes the widget resource and a
search_inventorytool, keeping UI and structured content in sync throughwindow.openai. - Local mock data: Provides high-quality fallback inventory data so the widget can be previewed without live CMS credentials.
- 🆕 Lead Capture Form: Users can book test drives directly from vehicle detail pages with a comprehensive contact form.
Users can now contact dealers/companies by clicking the "Book Test Drive" button on any vehicle detail page. The feature includes:
- ✅ Professional contact form with validation
- ✅ Real-time input validation
- ✅ Success confirmation with animation
- ✅ MCP tool for backend integration
- ✅ Ready for CRM integration
Documentation:
- Lead Form Feature Guide - Complete feature overview
- Flow Diagrams - Visual architecture and user journey
- Production Integration - Backend setup guide
- Quick Summary - Implementation summary
- Node.js 18 or newer.
- A headless CMS with a
carcontent type that includes fields forname,model,engineType,description,heroImage, optionalprice,ctaUrl,ctaLabel, andstatusBadge. - API access credentials for your headless CMS.
- Install dependencies:
pnpm install
- Copy the environment template and populate it:
Fill in your headless CMS credentials. Adjust the CMS configuration variables based on your CMS provider.
cp .env.example .env
- Run the MCP server locally (the React widget is bundled automatically on the first request in development):
To work on the iframe UI in isolation, run:
pnpm dev
Then open the printed preview URL (defaults topnpm run widget:dev
http://localhost:4173/index.html). - (Optional) Test locally with the MCP Inspector:
npx @modelcontextprotocol/inspector@latest http://localhost:8787/mcp
- Expose the server to ChatGPT using a tunnel such as ngrok:
Use the public URL (e.g.
ngrok http 8787
https://your-subdomain.ngrok.app/mcp) when adding the connector in ChatGPT. - In ChatGPT:
- Enable developer mode (Settings → Apps & Connectors → Advanced).
- Add a new connector pointing to the tunneled
/mcpURL. - Start a new chat, attach the connector, and ask something like “Find an electric SUV in stock.”
apps/search-server/src/server.js– MCP server that registers the widget resource and thesearch_inventorytool.apps/search-server/public/– HTML/CSS shell and static assets served with the widget bundle.packages/search-data/src/– Headless CMS integration and demo data shared across packages.packages/search-widget/src/– React sources compiled on-demand into the widget iframe.scripts/widget-dev-server.js– esbuild-powered preview server for developing the widget locally..env.example– Template for required environment variables.
- Update the widget styling in
public/car-widget.htmlto further match brand guidelines or add additional filters (price range, body style, etc.). - Extend
searchVehiclesinpackages/search-data/src/data-provider.jsto integrate with your CMS and map additional fields such as mileage or availability dates. - When you change tools or metadata, refresh the connector in ChatGPT (Settings → Connectors → Refresh) so the new schema is picked up.
When ready, deploy apps/search-server/src/server.js (or package the @drive-scout/search-server workspace) to a public environment that supports Node.js (e.g., Vercel, Fly.io, Azure). Ensure the /mcp endpoint remains reachable over HTTPS and keep your CMS API credentials secure via environment variables.