ChatGPT Skill Architecture Specification Version: 1.0 Research cutoff: September 21, 2026 Scope: Native Agent Skills used by ChatGPT and Codex, plus portable plugin packaging for ChatGPT Chat/Work and Claude-compatible hosts. 1. Executive decision Build the workflow as an Agent Skills standard skill, then add an OpenAI-specific agents/openai.yaml file. When the skill needs distribution across ChatGPT web, desktop, and mobile, or must bring an MCP server with it, package the skill as a portable Agent Plugin. This is the most compatible architecture available: The portable core is skills//SKILL.md plus optional scripts/, references/, and assets/. ChatGPT presentation, dependency, and invocation policy live in agents/openai.yaml. Cross-product distribution lives in root plugin.json. Remote tool connections live in root mcp.json. A minimal .claude-plugin/plugin.json may be included as a Claude compatibility overlay. Do not convert a Claude skill into a Custom GPT unless the user explicitly asks for a Custom GPT. Native Agent Skills are now the correct ChatGPT target. 2. Source hierarchy Use these sources in this order: OpenAI: Build skills OpenAI: Package your plugin OpenAI: Plugins quickstart OpenAI: Plugins and skills walkthrough Agent Skills specification, the open standard linked by OpenAI OpenAI states that ChatGPT and Codex load skill names and descriptions first, load the full SKILL.md only after activation, support explicit ChatGPT invocation through @, and support implicit invocation through description matching. 3. Canonical directory structures 3.1 Standalone skill skill-name/ ├── SKILL.md ├── agents/ │ └── openai.yaml ├── scripts/ ├── references/ └── assets/ Use this for personal authoring, local Codex use, and direct skill installation when the host supports standalone skills. 3.2 Installable portable plugin plugin-name/ ├── plugin.json ├── mcp.json # only when bundling MCP ├── skills/ │ └── skill-name/ │ ├── SKILL.md │ ├── agents/ │ │ └── openai.yaml │ ├── scripts/ │ ├── references/ │ └── assets/ ├── assets/ └── .claude-plugin/ └── plugin.json # compatibility overlay Use this for reliable installation and @ discovery across supported ChatGPT surfaces. OpenAI says standalone skills are available in the desktop app, Codex CLI, and IDE extension, while plugin-bundled skills are available in Chat and Work across web, desktop, and mobile. 4. SKILL.md contract 4.1 Required frontmatter --- name: skill-name description: Do the job. Use when the user says the primary trigger phrases or requests the bounded workflow. Do not use for adjacent but materially different work. --- Rules: name: 1–64 characters, lowercase letters, digits, and hyphens only. The directory name must match name. description: 1–1024 characters. Front-load the job and strongest trigger phrases. State both positive scope and the nearest exclusion. Keep the portable frontmatter minimal. Put host-specific UI fields elsewhere. The open Agent Skills standard permits optional license, compatibility, metadata, and experimental allowed-tools. For maximum ChatGPT/Claude portability, use only name and description unless an optional portable field changes runtime behavior and both target hosts have been tested. 4.2 Description design The description is the implicit invocation classifier. It should answer: What outcome does the skill produce? What user language should activate it? What adjacent requests should not activate it? Good: description: Deep-save the current conversation by extracting durable decisions, rules, person notes, references, and open tasks; deduplicate and persist them to Open Brain; then create a continuation brief. Use when the user says deep save, save this conversation, capture this session, or prepare a fresh-context handoff. Do not use for a short summary or ordinary note-taking. Bad: description: Helps save chats. 4.3 Body design Use imperative instructions. Put inputs, outputs, completion criteria, and failure boundaries near the top. Keep one skill focused on one job. Keep SKILL.md under 500 lines and preferably under 5,000 tokens. Move detailed schemas, examples, and reference material into references/. Keep references one hop from SKILL.md; avoid chains of references pointing to more references. Prefer instructions over scripts. Use scripts for deterministic, repeated, or fragile operations. Refer to tools by capability or declared tool name, not a host-specific namespace, unless the branch is explicitly host-specific. Never claim success from an attempted write. Read back the durable result. 5. ChatGPT metadata: agents/openai.yaml interface: display_name: "Skill Name" short_description: "One clear 25–64 character UI description" icon_small: "./assets/icon.svg" icon_large: "./assets/icon.svg" brand_color: "#10A37F" default_prompt: "Use $skill-name to perform the bounded workflow." policy: allow_implicit_invocation: true dependencies: tools: - type: "mcp" value: "registered-server-id" description: "What the server provides" transport: "streamable_http" url: "https://example.com/mcp" Requirements: Quote string values. Keep short_description between 25 and 64 characters. Make display_name the exact label users should search after typing @. Make default_prompt one short example and explicitly mention $skill-name. Set allow_implicit_invocation: true when natural-language activation is desired. Declare every required MCP dependency. Installation of instructions alone does not install capabilities. Paths must be relative to the skill root and begin with ./. Do not place Claude-only user-invocable metadata here. This file improves presentation and dependency attachment. It does not rescue a vague description, a disabled installation, or an unsupported ChatGPT surface. 6. Portable plugin manifest { "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json", "name": "plugin-name", "version": "1.0.0", "description": "One bounded reusable workflow.", "extensions": { "com.openai": { "interface": { "displayName": "Plugin Name", "shortDescription": "Short install-surface description", "longDescription": "What the plugin does, requires, and produces.", "developerName": "full/REFIT", "category": "Productivity", "capabilities": ["Read", "Write"], "defaultPrompt": ["Use @skill-name to perform the workflow."], "brandColor": "#10A37F" } } } } Rules: Use the portable root plugin.json for new packages. Put skills only under root skills/. Do not add a redundant skills list to the manifest. Put OpenAI-only install-surface data inside extensions.com.openai. Treat extensions.com.openai as a full replacement for a .codex-plugin/plugin.json overlay, not an additive merge. Keep referenced paths relative to the plugin root and prefix them with ./. 7. MCP packaging If the workflow requires MCP, bundle a root mcp.json: { "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json", "mcpServers": { "server-name": { "type": "streamable-http", "url": "https://example.com/mcp" } } } Do not confuse the workflow with the capability: SKILL.md tells the agent how to work. mcp.json or a connected plugin gives the agent tools. agents/openai.yaml declares the dependency and improves host behavior. If the server exposes SSE rather than streamable HTTP, use the transport actually supported by both the server and target host. Do not relabel an SSE endpoint as streamable HTTP. 8. Claude compatibility The shared portable layer is the Agent Skills standard: SKILL.md scripts/ references/ assets/ Keep Claude-specific packaging outside that core: optional .claude-plugin/plugin.json Claude-only hooks or commands in Claude-specific paths Claude-only environment variables in explicitly labeled fallback branches Do not put user-invocable, argument-hint, Claude tool namespaces, or Claude filesystem assumptions into the shared core unless they are namespaced metadata or guarded by an explicit host branch. A single portable core plus thin host overlays is more reliable than one blended file full of mutually ignored fields. 9. Reliable ChatGPT @ invocation All of the following must be true: The skill or containing plugin is installed and enabled. The active ChatGPT surface supports that installation type. The skill exists at skills//SKILL.md for a plugin, or at the root of a valid standalone skill. The folder and frontmatter names match. agents/openai.yaml contains a clean display name and short description. The user starts a new ChatGPT Work chat after installation or refresh. The user types @ and selects the skill. Slash commands are not the ChatGPT skill picker. Required connectors are installed and authenticated. Exact acceptance test: 1. Install the package. 2. Refresh ChatGPT. 3. Open a new Work chat. 4. Type @. 5. Search the exact display_name. 6. Select the skill and confirm the composer adds its chip. 7. Send the default prompt. 8. Confirm the response follows a detail found only in SKILL.md. 9. For MCP skills, confirm one harmless read-only tool call. Passing YAML validation is insufficient. The @ picker and a real workflow invocation are the user-visible acceptance tests. 10. Validation gates Structural Required files exist. Folder name equals skill name. YAML and JSON parse. Relative paths resolve. No required reference is more than one hop away. Discovery Explicit @ selection works in a new Work chat. The chip displays the intended name and icon. A natural-language trigger activates the skill when implicit invocation is enabled. A negative control does not activate it. Execution Every required capability is installed. Tool names match the connected server. Writes are read back. Missing capabilities produce a precise boundary, never a fabricated completion. Portability Core instructions contain no unguarded host-specific assumptions. Claude can load the core skill. ChatGPT can display and invoke it. Plugin installation brings required remote tools where supported. 11. Common failure modes Custom GPT conversion used as the default ChatGPT target. Native Agent Skills have replaced that workaround. Skill appears in the catalog but not under @. Usually an installation cache, unsupported surface, broken UI metadata, or packaging-path problem. user-invocable: true assumed to control ChatGPT. That is not ChatGPT’s primary invocation mechanism. Long UI description. The skill may validate but render or index poorly. No default prompt. Catalog launch behavior becomes generic. Undeclared MCP dependency. The instructions load without the tools needed to finish. Claude path hardcoded. The skill fails on ChatGPT/Codex even though its reasoning is portable. Plugin root contains only a root SKILL.md. Portable plugins discover skills from skills/. Duplicate portable and host-specific manifests disagree. One package yields different names, versions, or descriptions. Validation declared from static files alone. Actual @ invocation remains untested. 12. Recommended release checklist Portable SKILL.md validated. description includes triggers and exclusions. agents/openai.yaml validated and UI copy within limits. plugin.json present for distributable packages. mcp.json present when the skill requires remote tools. Claude overlay isolated from the portable core. References and scripts use relative paths. No secrets in files, URLs, logs, or examples. Positive, negative, missing-tool, and long-context tests pass. ChatGPT @ picker test passes in a fresh Work chat. Claude invocation test passes on the intended Claude surface. Version and changelog updated only after runtime verification. 13. Confidence and unresolved boundary The file structure, invocation methods, progressive-disclosure model, plugin layout, and optional OpenAI metadata are verified from the sources above as of September 21, 2026. No static architecture can guarantee universal @ availability across every account, workspace policy, rollout, or client version. “Consistently invocable” therefore means the package passes the documented installation and fresh-Work-chat acceptance test on each supported target account. Anything stronger would be marketing dressed as a test result.