GitHub list of ChatGPT Plugin Directory

Write an Agent Skill for ChatGPT and Codex

Write a skill with SKILL.md, scripts and references, load it in Codex, test when it triggers, and bundle it in a plugin so it also works in ChatGPT.

Divy ChaurasiaBeginner 20 minFor builders

A skill is a folder of instructions (plus optional scripts and reference files) that teaches ChatGPT or Codex how to do one job your way: draft release notes, review a migration, prepare a weekly report. Skills follow the open Agent Skills standard, so a well-written skill can work across tools that support it.

The model doesn't read every skill all the time. It starts with each skill's name and description, and loads the full instructions only when it decides a skill fits the task. That makes the description the most important line you'll write.

This guide builds a release-notes skill, tests it in Codex, and packages it so it works in ChatGPT too.

Before you start#

  • Codex installed (npm install -g @openai/codex) and signed in, or the ChatGPT desktop app.
  • A task you repeat and already know how to do well. Skills capture a process; they don't invent one.

Tip: You don't have to write the files by hand. Run $skill-creator in Codex, or @skill-creator in a ChatGPT Work chat, and describe the workflow. It asks when the skill should trigger and whether it needs scripts, then drafts the folder. The steps below explain what it produces, so you can review and edit it.

1. Create the skill folder#

A skill is a directory with a required SKILL.md and optional extras:

text
release-notes/
├── SKILL.md            # required: front matter + instructions
├── scripts/            # optional: code the agent can run
├── references/         # optional: docs to read when needed
├── assets/             # optional: templates and other files
└── agents/
    └── openai.yaml     # optional: UI metadata, invocation policy, dependencies

Where you put it decides where Codex finds it:

ScopeLocationUse for
Repo.agents/skills/ in the current folder, any parent folder, or the repo rootSkills for one project, checked into Git
User$HOME/.agents/skills/Your personal skills, in every project
Admin/etc/codex/skills/Machine-wide defaults
SystemBundled with CodexBuilt-ins such as skill-creator

For this guide, create it in a repository:

bash
mkdir -p .agents/skills/release-notes/{scripts,references}

Codex follows symlinked skill folders, so you can keep skills in one place and link them into several repos.

2. Write SKILL.md#

.agents/skills/release-notes/SKILL.md:

md
---
name: release-notes
description: Draft release notes from commits merged since the last Git tag. Use when the user asks for release notes, a changelog entry or a "what shipped" summary. Do not use for writing commit messages or PR descriptions.
---

Draft release notes for the changes since the most recent tag.

1. Run `scripts/changes_since_tag.sh` from the repository root. It prints the
   last tag, then one line per commit since that tag.
2. If the script reports no tags, ask the user which commit to start from. Do
   not guess.
3. Group the changes under these headings, in this order: Added, Changed,
   Fixed, Removed. Skip empty headings.
4. Write each item as one sentence in plain language for users, not
   developers. Drop pure refactors, test-only and CI-only changes.
5. Follow the tone and formatting rules in `references/style.md`.
6. End with the version range, for example `v1.4.0...HEAD`.

Never invent changes that aren't in the script output. If an item is unclear,
list it under "Needs review" instead of guessing what it does.

The rules for the front matter:

  • name and description are both required.
  • Front-load the description. Put the job and the trigger phrases first. When many skills are installed, Codex shortens descriptions to fit its budget, so the start must stand on its own.
  • Say when not to use it. Boundaries stop the skill firing on nearby tasks.

For the body: write numbered, imperative steps with clear inputs and outputs. Say what to do when information is missing. Keep it to one job; split a skill when parts of it have different triggers.

3. Add a script and a reference file#

Use scripts/ when a step needs to be deterministic. Instructions are enough for most steps, so don't add code that the model could do reliably on its own.

.agents/skills/release-notes/scripts/changes_since_tag.sh:

bash
#!/usr/bin/env bash
set -euo pipefail

last_tag=$(git describe --tags --abbrev=0 2>/dev/null || true)
if [ -z "$last_tag" ]; then
  echo "NO_TAGS"
  exit 0
fi

echo "LAST_TAG=$last_tag"
git log --no-merges --pretty=format:'%h %s' "$last_tag"..HEAD
bash
chmod +x .agents/skills/release-notes/scripts/changes_since_tag.sh

Use references/ for longer material the agent should read only when it needs it, such as style guides, schemas and examples. SKILL.md stays short, and the reference loads only when the skill runs.

.agents/skills/release-notes/references/style.md:

md
# Release notes style

- Present tense: "Adds", "Fixes".
- No internal ticket numbers or author names.
- Link to docs pages when a feature has one.
- Maximum 12 items; group minor fixes as "Other fixes".

4. Optional: agents/openai.yaml#

This file controls how the skill appears in the ChatGPT desktop app, whether the model may pick it on its own, and which MCP tools it depends on:

yaml
interface:
  display_name: "Release notes"
  short_description: "Draft release notes since the last tag"
policy:
  allow_implicit_invocation: false

allow_implicit_invocation defaults to true. Set it to false for skills that should only run when you ask for them by name. If a skill relies on an MCP server, declare it under dependencies.tools with its type, value, transport and url, and still tell the model in SKILL.md which tools to call and in what order.

5. Run it in Codex#

Start Codex in the repository. New and changed skills are detected automatically; restart Codex if one doesn't show up.

There are two ways a skill runs:

  • Explicitly: type $release-notes, or run /skills to pick it from a list.
  • Implicitly: ask "Write release notes for this version" and Codex should choose the skill from its description.
text
$release-notes for everything since the last tag

Check that Codex ran the script, used the headings, and followed the style file.

6. Test when it triggers#

Run a small set of prompts and record what happens for each:

Prompt typeExampleExpected
Direct"Draft release notes"Skill runs
Indirect"What shipped since v1.4?"Skill runs
Missing inputRepo with no tagsAsks where to start
Negative"Write a commit message for this diff"Skill doesn't run
Edge caseOnly CI changes since the tagSays there's nothing user-facing

If it fires at the wrong times, fix the description. If it fires correctly but the output is off, fix the instructions. Re-run the set after every change.

The Plugin Eval plugin can help run this kind of evaluation locally, with reports that explain token budgets.

7. Use the skill in ChatGPT#

Where a skill works depends on how you install it:

  • Standalone skill folders work in the ChatGPT desktop app, the Codex CLI and the IDE extension. In the desktop app, open Skills in the sidebar to see skills from your projects.
  • Skills bundled in a plugin also work in Chat and Work in ChatGPT on the web, desktop and mobile.

In ChatGPT, type @ to pick a skill explicitly, or just describe the task and let ChatGPT match it.

8. Bundle it in a plugin#

To share a skill, or use it on ChatGPT web and mobile, package it as a plugin. A skills-only plugin needs just a manifest and a skills/ folder:

text
release-notes-plugin/
├── plugin.json
└── skills/
    └── release-notes/
        ├── SKILL.md
        ├── scripts/changes_since_tag.sh
        └── references/style.md
json
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "release-notes-plugin",
  "version": "1.0.0",
  "description": "Draft user-facing release notes from Git history."
}

Portable plugins find skills in skills/ automatically. Add the plugin to a local marketplace to install it, or run $plugin-creator to scaffold the manifest and marketplace entry for you. A plugin can also bundle several related skills, or skills alongside an MCP server, the way the Google Drive plugin combines Drive, Docs, Sheets and Slides skills with its connector.

Publishing it to the directory is covered in Publish a ChatGPT plugin.

Troubleshooting#

ProblemFix
Skill doesn't appearCheck the folder location and that SKILL.md has both name and description. Restart Codex.
Never triggers implicitlyPut trigger phrases at the start of the description, and check allow_implicit_invocation.
Triggers too oftenAdd "Do not use for…" boundaries to the description.
Two skills with the same nameCodex doesn't merge them; both appear. Rename one.
Too many skills installedThe initial skill list is capped at about 2% of the context window, so descriptions get shortened and some skills may be left out. Disable ones you don't use.

To turn a skill off without deleting it, add this to ~/.codex/config.toml and restart Codex:

toml
[[skills.config]]
path = "/path/to/skill/SKILL.md"
enabled = false

Next steps#

Keep reading