Awesome-omni-skill chatgpt-app:validate

Run validation suite on your ChatGPT App to check schemas, annotations, widgets, and UX compliance.

install
source · Clone the upstream repo
git clone https://github.com/diegosouzapw/awesome-omni-skill
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/diegosouzapw/awesome-omni-skill "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/ai-agents/chatgpt-app-validate" ~/.claude/skills/diegosouzapw-awesome-omni-skill-chatgpt-app-validate && rm -rf "$T"
manifest: skills/ai-agents/chatgpt-app-validate/SKILL.md
safety · automated scan (low risk)
This is a pattern-based risk scan, not a security review. Our crawler flagged:
  • references .env files
Always read a skill's source content before installing. Patterns alone don't mean the skill is malicious — but they warrant attention.
source content

Validate ChatGPT App

You are helping the user validate their ChatGPT App before testing and deployment.

Validation Checks

1. Required Files Check (RUN FIRST)

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.

2. Server Implementation Check

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>();

3. Widget Configuration Check

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 */ },
  },
];

4. Tool Response Check

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,
  },
};

5. Resource Handler Check

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": { ... },
  },
};

6. Widget HTML Check

Verify generateWidgetHtml includes:

  • window.PREVIEW_DATA
    support for local preview
  • window.openai.toolOutput
    data access
  • openai:set_globals
    event listener
  • Polling fallback with setInterval
  • rendered
    flag to prevent re-renders

7. Endpoint Check

Verify these endpoints exist:

  • GET /health
    - Health check
  • GET /preview
    - Widget preview index
  • GET /preview/:widgetId
    - Individual widget preview
  • ALL /mcp
    - MCP protocol handler
  • DELETE /mcp
    - Session cleanup

8. Package.json Scripts Check

{
  "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

9. Annotation Validation

  • Query tools have
    readOnlyHint: true
  • Delete tools have
    destructiveHint: true
  • External API tools have
    openWorldHint: true

10. Database Validation (if enabled)

  • All migrations are valid SQL
  • Tables have
    user_subject
    column
  • Indexes exist for user queries

Workflow

  1. Run file existence checks
  2. Read and analyze server/index.ts
  3. Verify patterns match requirements
  4. Collect errors and warnings
  5. Display results

Results Format

## 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**

Common Errors

ErrorFix
Uses McpServerChange to
Server
from
@modelcontextprotocol/sdk/server/index.js
Missing session managementAdd
Map<string, StreamableHTTPServerTransport>
Wrong widget URIUse
ui://widget/{id}.html
format
Wrong MIME typeUse
text/html+skybridge
Missing structuredContentAdd to tool response for widget data
Has web/ folderRemove - widgets are inline in server/index.ts