원클릭으로
chatgpt-appvalidate
Run validation suite on your ChatGPT App to check schemas, annotations, widgets, and UX compliance.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Run validation suite on your ChatGPT App to check schemas, annotations, widgets, and UX compliance.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Configure authentication for your ChatGPT App using Auth0 or Supabase Auth for multi-user support.
Configure a PostgreSQL database for your ChatGPT App using Supabase for data persistence.
Add a new MCP tool to your ChatGPT App. Guides through tool design, schema creation, and code generation.
Add a new inline widget to your ChatGPT App with Tailwind CSS and Apps SDK integration.
Deploy your ChatGPT App to Render with PostgreSQL database and automatic health checks.
Generate test prompts to validate that ChatGPT will correctly invoke your app's tools.
| name | chatgpt-app:validate |
| description | Run validation suite on your ChatGPT App to check schemas, annotations, widgets, and UX compliance. |
You are helping the user validate their ChatGPT App before testing and deployment.
Check that ALL mandatory files exist:
ls package.json tsconfig.server.json setup.sh START.sh .env.example server/index.ts
Expected file structure:
{app-name}/
├── package.json
├── tsconfig.server.json
├── setup.sh
├── START.sh
├── .env.example
├── .gitignore
└── server/
└── index.ts
If ANY of the above are missing, report as CRITICAL ERROR.
Verify server/index.ts uses correct patterns:
MUST have:
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js";
MUST NOT have:
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; // WRONG
Session management MUST exist:
const transports = new Map<string, StreamableHTTPServerTransport>();
Verify widgets array structure:
const widgets: WidgetConfig[] = [
{
id: "widget-id", // kebab-case
name: "Widget Name",
description: "What it displays",
templateUri: "ui://widget/widget-id.html", // MUST match this format
invoking: "Loading...",
invoked: "Ready",
mockData: { /* sample data */ },
},
];
Widget tools MUST return:
return {
content: [{ type: "text", text: JSON.stringify(result) }],
structuredContent: result, // CRITICAL - becomes window.openai.toolOutput
_meta: {
"openai/outputTemplate": widget.templateUri,
"openai/toolInvocation/invoked": widget.invoked,
},
};
Verify ReadResource returns correct format:
return {
contents: [{
uri,
mimeType: "text/html+skybridge", // MUST be this exact value
text: generateWidgetHtml(widget.id),
}],
_meta: {
"openai/serialization": "markdown-encoded-html",
"openai/csp": { ... },
},
};
Verify generateWidgetHtml includes:
window.PREVIEW_DATA support for local previewwindow.openai.toolOutput data accessopenai:set_globals event listenerrendered flag to prevent re-rendersVerify these endpoints exist:
GET /health - Health checkGET /preview - Widget preview indexGET /preview/:widgetId - Individual widget previewALL /mcp - MCP protocol handlerDELETE /mcp - Session cleanup{
"scripts": {
"build": "npm run build:server",
"build:server": "tsc -p tsconfig.server.json",
"start": "HTTP_MODE=true node dist/server/index.js",
"dev": "HTTP_MODE=true NODE_ENV=development tsx watch --clear-screen=false server/index.ts"
}
}
MUST NOT have: dev:web, build:web, concurrently
readOnlyHint: truedestructiveHint: trueopenWorldHint: trueuser_subject column## Validation Results
### File Structure ✓
All required files present.
### Server Implementation ✓
Using correct Server class with session management.
### Widget Configuration ✓
2 widgets properly configured.
### Tool Responses ✓
All widget tools return structuredContent.
---
**Overall: PASS**
| Error | Fix |
|---|---|
| Uses McpServer | Change to Server from @modelcontextprotocol/sdk/server/index.js |
| Missing session management | Add Map<string, StreamableHTTPServerTransport> |
| Wrong widget URI | Use ui://widget/{id}.html format |
| Wrong MIME type | Use text/html+skybridge |
| Missing structuredContent | Add to tool response for widget data |
| Has web/ folder | Remove - widgets are inline in server/index.ts |