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

Published: 2026-10-04 · By: Divy Chaurasia · Level: beginner · Time: 20 min · Tags: skills, codex, chatgpt

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](https://agentskills.io) 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:

| Scope | Location | Use for |
| --- | --- | --- |
| Repo | `.agents/skills/` in the current folder, any parent folder, or the repo root | Skills for one project, checked into Git |
| User | `$HOME/.agents/skills/` | Your personal skills, in every project |
| Admin | `/etc/codex/skills/` | Machine-wide defaults |
| System | Bundled with Codex | Built-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 type | Example | Expected |
| --- | --- | --- |
| Direct | "Draft release notes" | Skill runs |
| Indirect | "What shipped since v1.4?" | Skill runs |
| Missing input | Repo with no tags | Asks where to start |
| Negative | "Write a commit message for this diff" | Skill doesn't run |
| Edge case | Only CI changes since the tag | Says 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.

> **plugin:** [Plugin Eval](https://chatgptplugins.directory/plugins/plugin-eval): Start from chat, then evaluate or benchmark locally
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.

> **plugin:** [Google Drive](https://chatgptplugins.directory/plugins/google-drive): Drive, Docs, Sheets or Slides
Publishing it to the directory is covered in [Publish a ChatGPT plugin](/tutorials/publish-a-chatgpt-plugin).

## Troubleshooting

| Problem | Fix |
| --- | --- |
| Skill doesn't appear | Check the folder location and that `SKILL.md` has both `name` and `description`. Restart Codex. |
| Never triggers implicitly | Put trigger phrases at the start of the description, and check `allow_implicit_invocation`. |
| Triggers too often | Add "Do not use for…" boundaries to the description. |
| Two skills with the same name | Codex doesn't merge them; both appear. Rename one. |
| Too many skills installed | The 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

- Browse skill-based plugins in the [plugins directory](/plugins), such as Superpowers.
- Install plugins in Codex: [Use plugins and MCP servers in Codex](/tutorials/use-plugins-in-codex).
- Give your skill live data with an MCP server: [Build your first ChatGPT app](/tutorials/build-your-first-chatgpt-app).

> **plugin:** [Superpowers](https://chatgptplugins.directory/plugins/superpowers): Plan, develop, and debug code

## Listings in this tutorial

- [Google Drive](https://chatgptplugins.directory/plugins/google-drive.md): Drive, Docs, Sheets or Slides
- [Plugin Eval](https://chatgptplugins.directory/plugins/plugin-eval.md): Start from chat, then evaluate or benchmark locally
- [Superpowers](https://chatgptplugins.directory/plugins/superpowers.md): Plan, develop, and debug code

---
Source: https://chatgptplugins.directory/tutorials/write-a-skill-for-chatgpt-and-codex · Index: https://chatgptplugins.directory/llms.txt · Independent and community-run. Not affiliated with or endorsed by OpenAI. ChatGPT is a trademark of OpenAI.
