skills/bayramannakov/chatgpt-app-builder/SKILL.md
Build ChatGPT Apps using the Apps SDK and MCP. Use when users want to: (1) Evaluate if their product should become a ChatGPT App (2) Design and implement MCP servers with widgets (3) Test apps locally and in ChatGPT (4) Prepare for App Store submission Triggers: "ChatGPT app", "Apps SDK", "build for ChatGPT", "ChatGPT integration", "MCP server for ChatGPT", "submit to ChatGPT"
npx skillsauth add aiskillstore/marketplace chatgpt-app-builderInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Build production-ready ChatGPT Apps from concept to App Store submission.
New app? → Start at Phase 1 (Fit Evaluation)
Have app-spec.md? → Start at Phase 3 (Implementation)
App built? → Start at Phase 4 (Testing)
Ready to ship? → Start at Phase 5 (Deployment)
Goal: Determine if a ChatGPT App is right for this product.
Ask the user:
Evaluate against three value pillars (see fit_evaluation.md):
| Pillar | Question | Strong Signal | |--------|----------|---------------| | Know | Does it provide data ChatGPT lacks? | Live prices, user-specific data, internal metrics | | Do | Can it take real actions? | Create, update, delete, send, schedule | | Show | Can it display better than text? | Lists, charts, maps, media galleries |
Minimum requirement: At least one pillar must be strong.
Review fit_evaluation.md for:
Draft prompts for discovery testing:
Create the specification file:
# [Product Name] ChatGPT App Spec
## Product Context
- Name: [Product name]
- API Base: [API URL]
- Auth: [Bearer token / OAuth / None]
## Value Proposition
- Know: [What data does it provide?]
- Do: [What actions can it take?]
- Show: [What UI is needed?]
## Golden Prompts
### Direct (should trigger)
1. ...
### Indirect (should trigger)
1. ...
### Negative (should NOT trigger)
1. ...
Output: app-spec.md in project directory
Goal: Define complete technical specification.
Follow one-job-per-tool principle. See chatgpt_app_best_practices.md.
For each tool, specify:
name: service_verb_noun # e.g., taskflow_get_tasks
title: Human Readable Name
description: Use this when the user wants to... [be specific]
annotations:
readOnlyHint: true/false
destructiveHint: true/false
openWorldHint: true/false
inputSchema:
param1: type (required/optional)
param2: enum["a", "b", "c"]
outputStructure:
content: [text summary for model]
structuredContent: {machine-readable data}
_meta: {widget-only data}
Does the app need custom UI?
| Use Case | Widget Needed? | Component Type | |----------|----------------|----------------| | Task list with checkboxes | Yes | List with actions | | Data display only | Maybe | Could use text | | Maps, charts, media | Yes | Specialized | | Multi-step workflow | Yes | Stateful widget |
See widget_development.md for patterns.
If accessing user-specific data or write operations, auth is required.
See oauth_integration.md for:
Add technical specification:
## Tools
### 1. service_get_items
- **Annotations**: readOnlyHint: true
- **Input**: { status?: "active" | "completed", limit?: number }
- **Output**:
- content: "Found N items"
- structuredContent: { items: [...] }
- _meta: { fullData: [...] }
### 2. service_create_item
- **Annotations**: openWorldHint: true
- **Input**: { title: string, description?: string }
- **Output**: { id, title, created_at }
## Widget
- Type: List with action buttons
- Display modes: inline, fullscreen
- State: { selectedId, filter }
## Authentication
- Required: Yes
- Provider: Auth0
- Scopes: read:items, write:items
Output: Updated app-spec.md with full technical spec
Goal: Generate complete working project.
Copy from assets and customize:
# Project structure
myapp-chatgpt/
├── package.json
├── tsconfig.json
├── src/
│ ├── index.ts # MCP server entry
│ ├── tools/ # Tool handlers
│ ├── widget/ # Widget source
│ └── types/ # TypeScript types
└── scripts/
└── build-widget.ts # Widget bundler
See node_chatgpt_app.md for complete patterns.
Key components (from assets/server/):
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
import { SSEServerTransport } from "@modelcontextprotocol/sdk/server/sse.js";
// GET /mcp - SSE stream connection
// POST /mcp/messages - Message handling
const tools: Tool[] = [{
name: "service_get_items",
title: "Get Items",
description: "Use this when the user wants to see items...",
inputSchema: { type: "object", properties: {...} },
_meta: {
"openai/outputTemplate": "ui://widget/app.html",
"openai/widgetAccessible": true
},
annotations: { readOnlyHint: true, destructiveHint: false, openWorldHint: false }
}];
server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools }));
server.setRequestHandler(CallToolRequestSchema, async (request) => {
const { name, arguments: args } = request.params;
// Handle tool calls...
return {
content: [{ type: "text", text: `Found ${items.length} items` }],
structuredContent: { items: items.slice(0, 10) },
_meta: { fullItems: items }
};
});
Key patterns (from assets/widget/):
// Access data
const output = window.openai.toolOutput;
const meta = window.openai.toolResponseMetadata;
// Invoke tools
await window.openai.callTool("service_action", { id: "123" });
// Persist state
window.openai.setWidgetState({ selectedId: "123" });
// Layout control
window.openai.notifyIntrinsicHeight(400);
await window.openai.requestDisplayMode({ mode: "fullscreen" });
See widget_development.md for React hooks and patterns.
npm install
npm run build # Compiles server + bundles widget
Before moving to testing, verify:
notifyIntrinsicHeight() after all DOM changes.style property, not setAttribute() (see widget_development.md)/.well-known/openai-apps-challenge endpoint returns challenge token/privacy endpoint returns HTML privacy policy/terms endpoint returns HTML terms of service/mcp endpoint handles SSE connections/health or / returns health check JSONOutput: Complete project in working directory
Goal: Verify the app works correctly.
# Terminal 1: Start server
npm run dev
# Server runs at http://localhost:8000
# Terminal 2: Run inspector
npx @modelcontextprotocol/inspector@latest http://localhost:8000/mcp
Verify:
ngrok http 8000
# Copy the https://xxx.ngrok.app URL
https://xxx.ngrok.app/mcpIn a new ChatGPT conversation:
If issues found:
npm run buildSee troubleshooting.md for common issues and solutions.
Output: Working app tested in ChatGPT
Goal: Ship to production and App Store.
Generate deployment configs from assets/deploy/:
Fly.io (recommended):
fly launch
fly deploy
Vercel/Cloudflare: Ensure streaming HTTP support.
See submission_requirements.md:
Required:
If auth required:
Output: App live in ChatGPT App Store
development
Apple Human Interface Guidelines for content display components. Use this skill when the user asks about charts component, collection view, image view, web view, color well, image well, activity view, lockup, data visualization, content display, displaying images, rendering web content, color pickers, or presenting collections of items in Apple apps. Also use when the user says how should I display charts, what's the best way to show images, should I use a web view, how do I build a grid of items, what component shows media, or how do I present a share sheet. Cross-references: hig-foundations for color/typography/accessibility, hig-patterns for data visualization patterns, hig-components-layout for structural containers, hig-platforms for platform-specific component behavior.
tools
Automate HelpDesk tasks via Rube MCP (Composio): list tickets, manage views, use canned responses, and configure custom fields. Always search tools first for current schemas.
testing
Expert Haskell engineer specializing in advanced type systems, pure functional design, and high-reliability software. Use PROACTIVELY for type-level programming, concurrency, and architecture guidance.
tools
GraphQL gives clients exactly the data they need - no more, no less. One endpoint, typed schema, introspection. But the flexibility that makes it powerful also makes it dangerous. Without proper controls, clients can craft queries that bring down your server. This skill covers schema design, resolvers, DataLoader for N+1 prevention, federation for microservices, and client integration with Apollo/urql. Key insight: GraphQL is a contract. The schema is the API documentation. Design it carefully.