Complete workflow for building, testing, and deploying ChatGPT Apps from concept to production.
/chatgpt-apps new - Create a new ChatGPT App/chatgpt-apps add-tool - Add an MCP tool to your app/chatgpt-apps add-widget - Add a widget to your app/chatgpt-apps add-auth - Configure authentication/chatgpt-apps add-database - Set up database/chatgpt-apps validate - Validate your app/chatgpt-apps test - Run tests/chatgpt-apps deploy - Deploy to production/chatgpt-apps resume - Resume working on an appPurpose: Create a new ChatGPT App from concept to working code.
"What ChatGPT App would you like to build? Describe what it does and the problem it solves."
Create 3-5 primary use cases with user stories.
For each widget:
id - unique identifier (kebab-case)name - display namedescription - what it showsmockData - sample data for previewDesign entities and relationships.
Generate complete application with this structure:
{app-name}/
├── package.json
├── tsconfig.server.json
├── setup.sh
├── START.sh
├── .env.example
├── .gitignore
└── server/
└── index.ts
Critical Requirements:
Server class from @modelcontextprotocol/sdk/server/index.jsStreamableHTTPServerTransport for session managementui://widget/{widget-id}.htmltext/html+skybridgestructuredContent in tool responses_meta with openai/outputTemplate on tools./setup.sh./START.sh --devhttp://localhost:3000/previewPurpose: Add a new MCP tool to your ChatGPT App.
Create Zod schema with appropriate types and descriptions.
Use chatgpt-mcp-generator agent to create:
server/tools/ Update server/index.ts with metadata:
```typescript
{
name: "my-tool",
_meta: {
"openai/toolInvocation/invoking": "Loading...",
"openai/toolInvocation/invoked": "Done",
"openai/outputTemplate": "ui://widget/my-widget.html", // if widget
}
}
```
Add tool to .chatgpt-app/state.json.
Use kebab-case: list-items, create-task, show-recipe-detail
| Scenario | readOnlyHint | destructiveHint | openWorldHint |
|---|---|---|---|
| ---------- | -------------- | ----------------- | --------------- |
| List/Get | true | false | false |
| Create/Update | false | false | false |
| Delete | false | true | false |
| External API | varies | varies | true |
Purpose: Add inline HTML widgets with HTML/CSS/JS and Apps SDK integration.
Document expected structure with TypeScript interface.
```typescript
const widgets: WidgetConfig[] = [
{
id: "my-widget",
name: "My Widget",
description: "Displays data",
templateUri: "ui://widget/my-widget.html",
invoking: "Loading...",
invoked: "Ready",
mockData: { / sample / },
},
];
```
Generate HTML with:
window.PREVIEW_DATA)window.openai.toolOutput)openai:set_globals) Link tool to widget via widgetId.
Preview at /preview/{widget-id} with mock data.
(function() {
let rendered = false;
function render(data) {
if (rendered || !data) return;
rendered = true;
// Render logic
}
function tryRender() {
if (window.PREVIEW_DATA) { render(window.PREVIEW_DATA); return; }
if (window.openai?.toolOutput) { render(window.openai.toolOutput); }
}
window.addEventListener('openai:set_globals', tryRender);
const poll = setInterval(() => {
if (window.openai?.toolOutput || window.PREVIEW_DATA) {
tryRender();
clearInterval(poll);
}
}, 100);
setTimeout(() => clearInterval(poll), 10000);
tryRender();
})();
Purpose: Configure authentication using Auth0 or Supabase Auth.
Auth0:
Supabase Auth:
Ask user preference based on needs.
Use chatgpt-auth-generator agent to create:
Add auth middleware to protect routes.
```bash
# Auth0
AUTH0_DOMAIN=your-tenant.auth0.com
AUTH0_CLIENT_ID=...
AUTH0_CLIENT_SECRET=...
# Supabase (from database setup)
SUPABASE_URL=...
SUPABASE_ANON_KEY=...
```
Verify login flow and user isolation.
Purpose: Configure PostgreSQL database using Supabase.
Verify account and project exist.
For each entity, specify:
Use chatgpt-database-generator agent to create SQL with:
id (UUID primary key)user_subject (varchar, indexed)created_at (timestamptz)updated_at (timestamptz)```typescript
import { createClient } from '@supabase/supabase-js';
const supabase = createClient(
process.env.SUPABASE_URL!,
process.env.SUPABASE_SERVICE_ROLE_KEY!
);
```
Run SQL in Supabase dashboard or via migration tool.
Always filter by user_subject:
const { data } = await supabase
.from('tasks')
.select('*')
.eq('user_subject', userSubject);
Purpose: Generate test prompts to validate ChatGPT correctly invokes tools.
Review each tool's purpose and inputs.
For each tool, create:
Write to .chatgpt-app/golden-prompts.json:
```json
{
"toolName": {
"direct": ["prompt1", "prompt2"],
"indirect": ["prompt1", "prompt2"],
"negative": ["prompt1", "prompt2"],
"edge": ["prompt1", "prompt2"]
}
}
```
Purpose: Validation suite before deployment.
Server from MCP SDKStreamableHTTPServerTransportwidgets array existsui://widget/{id}.htmlstructuredContent (not just content)_meta with openai/outputTemplatetext/html+skybridge_meta with serialization and CSP/health - Health check/preview - Widget index/preview/:widgetId - Widget preview/mcp - MCP endpointbuild:serverstart with HTTP_MODE=truedev with watch mode| Error | Fix |
|---|---|
| ------- | ----- |
| Missing structuredContent | Add to tool response |
| Wrong widget URI | Use ui://widget/{id}.html |
| No session management | Add Map |
| Missing _meta | Add to tool definition and response |
| Wrong MIME type | Use text/html+skybridge |
Critical: Check file existence FIRST before other validations!
Purpose: Run automated tests using MCP Inspector and golden prompts.
```bash
HTTP_MODE=true NODE_ENV=test npm run dev
```
Test protocol compliance:
Verify schemas compile and match implementation.
Use ChatGPT to test prompts:
```json
{
"passed": 42,
"failed": 3,
"categories": {
"mcp": "✅",
"schema": "✅",
"widgets": "✅",
"prompts": "⚠️ 3 failures"
},
"timing": "2.3s"
}
```
For each failure, explain:
Purpose: Deploy ChatGPT App to Render with PostgreSQL and health checks.
```yaml
services:
name: {app-name}
runtime: docker
plan: free
healthCheckPath: /health
envVars:
value: 3000
value: true
value: production
generateValue: true
# Add auth/database vars if needed
```
```dockerfile
FROM node:20-slim
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY dist ./dist
EXPOSE 3000
CMD ["node", "dist/server/index.js"]
```
Option A: Automated (if Render MCP available)
Use Render MCP agent to deploy.
Option B: Manual
https://{app}.onrender.com/healthhttps://{app}.onrender.com/mcphttps://{app}.onrender.com/mcpPurpose: Resume building an in-progress ChatGPT App.
Read .chatgpt-app/state.json:
```json
{
"appName": "My Task Manager",
"phase": "Implementation",
"tools": ["list-tasks", "create-task"],
"widgets": ["task-list"],
"auth": false,
"database": true,
"validated": false,
"deployed": false
}
```
Show current status:
Based on phase:
Concept Phase:
Implementation Phase:
Testing Phase:
Deployment Phase:
Based on user's choice, invoke the appropriate workflow section.
The .chatgpt-app/state.json file tracks progress:
{
"appName": "string",
"description": "string",
"phase": "Concept" | "Implementation" | "Testing" | "Deployment",
"tools": ["tool-name"],
"widgets": ["widget-id"],
"auth": {
"enabled": boolean,
"provider": "auth0" | "supabase" | null
},
"database": {
"enabled": boolean,
"entities": ["entity-name"]
},
"validated": boolean,
"tested": boolean,
"deployed": boolean,
"deploymentUrl": "string | null",
"goldenPromptsGenerated": boolean,
"lastUpdated": "ISO timestamp"
}
# Setup
./setup.sh
# Development
./START.sh --dev # Dev mode with watch
./START.sh --preview # Open preview in browser
./START.sh --stdio # STDIO mode (testing)
./START.sh # Production mode
# Testing
npm run validate # Type checking
curl http://localhost:3000/health
# Deployment
git push origin main # Trigger Render deploy
When the user invokes any chatgpt-app command:
.chatgpt-app/state.json existsAlways guide users through the natural progression:
Concept → Implementation → Testing → Deployment
共 1 个版本