Open Markdown text in a new tab

Creating a skill

A skill is a small package of instructions for a repeatable task. Start with one SKILL.md file and add supporting files only when they help the assistant do the work. Skills can describe a review method, a writing style, or a workflow without requiring a plugin or a running service. The Skills guide explains how to import, select, and use the result in Chat. For an inference engine or provider integration, follow Creating a new plugin instead.

Write the instructions

Create a UTF-8 file named SKILL.md. Its opening block gives the skill a name and description; the Markdown below it contains the instructions the assistant follows after loading it.

---
name: review-notes
description: Review meeting notes for missing decisions, unclear ownership, and follow-up tasks. Use when turning rough notes into a reviewable summary.
---
# Review meeting notes

Read the notes before editing them. Preserve the meaning of decisions and
attribute statements only when the notes identify the speaker.

Group the result into decisions, open questions, and follow-up tasks.
For each task, include its owner and due date when supplied.
Mark missing information as unspecified; do not invent it.

Finish with questions that need an answer before the notes can be shared.

Choose a name of at most 64 characters using lowercase letters, digits, and single hyphens between words. The name must be unique in the account that imports it. Keep the description within 2,048 characters and explain when the skill is useful, because the assistant uses that description to decide whether to load it. The manifest's name is the name used in an explicit request, such as $review-notes. A ZIP's filename does not change it.

Write instructions that a reader can follow: what input to inspect, what steps matter, what the output should contain, and how to handle missing information. Include a short example when it clarifies the result. Avoid claims that the skill can override the user's request, grant permissions, or install tools.

Choose how the skill is loaded

By default, an enabled skill can be loaded by the assistant or requested by the user. Add disable-model-invocation: true to require an explicit user request such as $review-notes. Add user-invocable: false to prevent requests by name while leaving automatic loading available. The flags accept YAML booleans, not quoted strings.

disable-model-invocationuser-invocableAvailable loading methods
false, the defaulttrue, the defaultAutomatic loading or an explicit user request.
truetrueAn explicit user request only.
falsefalseAutomatic loading only; a request by name is rejected.
truefalseNeither method; the skill cannot be enabled for a conversation.

For a minimal skill, the name and description above are enough. Optional fields include license, compatibility (up to 500 characters), and metadata, a JSON-compatible object that can contain nested objects, arrays, booleans, numbers, and text.

Advanced compatibility declarations include argument-hint, arguments, allowed-tools, disallowed-tools, tools, context, agent, background, paths, shell, model, effort, and hooks. Origin, homepage, author, repo, tags, category, and version fields remain descriptive data. Unknown fields outside metadata are rejected. Use a plain YAML mapping without duplicate keys, anchors, aliases, tags, or merge keys.

Tool declarations do not enable tools or bypass approvals. Supported restrictive tool declarations limit the active execution; unsupported patterns require correction before activation. Model and effort fields are preferences and do not change the chat's provider or billing settings. Hooks and dynamic shell snippets are retained instructions; any required command runs as a visible, authorized tool action. An optional agents/openai.yaml sidecar can describe the interface and required MCP services, and policy.allow_implicit_invocation: false requires an explicit invocation.

Arguments are captured when the invocation is admitted. $ARGUMENTS denotes the full original string; $0 and $ARGUMENTS[0] refer to the first shell-quoted argument. A supported arguments list maps named placeholders to positions. Values remain literal input data rather than commands or recursively expanded placeholders. Forked workflows delegate explicitly through subagent_spawn with the intended skill_ids, task, workspace, and permitted tools.

Add supporting files

Reference examples or templates by their relative paths, such as references/example.md or assets/report-template.csv. The assistant can read UTF-8 supporting text through skill_read after activating the skill. Keep each reference relevant to the instructions; long material can be read in portions. Binary resources return metadata rather than content, so provide a text alternative when the assistant needs to inspect them directly.

A collection can retain a referenced file outside an individual skill directory. Read its exact captured source path with skill_read and source_relative: true. The read remains limited to that skill's admitted supporting files. For execution, materialization preserves those files at their source-relative positions.

Imported supporting files are not installed in the conversation's workspace. If your workflow needs complete supporting files, describe how to activate the skill and copy the package with the separately selected skill_materialize tool in Execute mode. Use the returned workspace-relative path for later file or execution tools. For scripts, identify the runtime, inputs, expected output, and cleanup steps. Downloads are available from Chat configuration > Skills > View by selecting a filename. Running or modifying files still follows the file and shell tool permissions and the conversation's approval policy.

Import SKILL.md directly when it is the only file. Otherwise, create a ZIP with the manifest and its supporting files at the root, or wrap them in one folder named exactly like the skill. Include only regular files and directories. Leave out links, credentials, caches, local environments, and unrelated project files. Use portable filenames that work across supported operating systems. Paths use forward slashes and must remain inside the package; absolute paths, parent traversal, conflicting names, and symbolic links are rejected.

Keep the upload within 250 MiB and the limit configured by API.OPENAI.MAX_FILE_UPLOAD_MB, its expanded contents within 20 MiB per skill, and each package within 256 regular files and 512 entries, including directories. A path may contain at most 16 segments and use at most 1,024 UTF-8 bytes. The manifest has a 256 KiB limit and must fit the conversation's remaining context. Longer reference material belongs in supporting files that the assistant can read when needed. See Imports and limits for account capacity.

Create a skill with an AI coding agent

Give the agent the current SoAI documentation, examples of the desired result, and a disposable chat for testing. Keep private source material and credentials out of a package you plan to share. As with the plugin-creation prompt, the brief below asks the agent to check the public contract and test the final package before calling it complete.

Fill in the bracketed fields, leaving a field blank when it does not apply. The Copy button copies the whole prompt. An untested package is a draft; report which checks actually ran.

You are building and verifying a reusable SoAI skill for ordinary WebUI conversations.

SKILL BRIEF

Skill name: [LOWERCASE NAME WITH SINGLE HYPHENS, FOR EXAMPLE review-notes]
Intended user and task: [ONE CONCRETE PARAGRAPH]
When to use it: [TRIGGERS AND RELEVANT REQUESTS]
When not to use it: [OUT-OF-SCOPE REQUESTS]
Input: [TEXT, FILES, OR OTHER INFORMATION THE USER WILL SUPPLY]
Expected result: [FORMAT, REQUIRED CONTENT, AND AN EXAMPLE]
Required steps and constraints: [WORKFLOW, STYLE, AND FACTS TO PRESERVE]
Supporting material: [EXAMPLES, REFERENCES, TEMPLATES, SCRIPTS, OR NONE]
Required tools or runtime: [DEPENDENCIES AND WORKSPACE NEEDS, OR NONE]
Loading method: [AUTOMATIC AND EXPLICIT / EXPLICIT ONLY / AUTOMATIC ONLY]
License for shared material: [LICENSE OR NONE; PRESERVE REQUIRED ATTRIBUTION]
Acceptance test: [THE REQUEST AND RESULT THAT PROVE THE SKILL WORKS]

Create the skill source, package checks, realistic test requests, and the final SKILL.md file or ZIP. Test the final package in a disposable SoAI chat before treating it as complete.

Public contract

1. Read Skills, Creating a skill, Agent tools overview, File and shell tools, and Conversation context, compaction, and history in the documentation for the SoAI installation that will import the package. Treat its published manifest fields, import limits, loading behavior, and tool boundaries as authoritative. Do not assume another application's skill format is accepted by SoAI.

2. Ask for a missing task-specific fact only when it cannot be determined from the brief, supplied examples, or those public pages. Preserve supplied facts and identify missing information instead of inventing it. Never request or package production credentials or confidential source material that the user has not authorized for sharing.

Package contract

3. Create a UTF-8 file named exactly SKILL.md. Begin with YAML frontmatter between --- delimiters. Supply a non-empty name of at most 64 characters using lowercase ASCII letters, digits, and single hyphens, and a non-empty description of at most 2,048 characters that explains when to load the skill. The name must be unique in the importing account.

4. Use documented manifest fields. Optional compatibility text is limited to 500 characters; metadata is a JSON-compatible object. Compatibility declarations can include argument-hint, arguments, allowed-tools, disallowed-tools, tools, context, agent, background, paths, shell, model, effort, and hooks. Tool restrictions never grant permissions or approval exemptions; unsupported restrictive syntax prevents activation. Loading flags are unquoted YAML booleans. Use false/true for automatic and explicit loading, true/true for explicit-only loading, and false/false for automatic-only loading, in disable-model-invocation/user-invocable order. Do not use duplicate keys, anchors, aliases, tags, or merge keys.

5. Deliver SKILL.md alone when no supporting files are needed. Otherwise build a ZIP with SKILL.md at its root, or with every entry inside one folder named exactly like the manifest's name. Include only intended regular files and directories. Use package-relative forward-slash paths without traversal or name conflicts. Exclude links, credentials, caches, local environments, and unrelated project files.

6. Keep the upload within 250 MiB and the ceiling set by API.OPENAI.MAX_FILE_UPLOAD_MB, expanded content within 20 MiB per skill, SKILL.md within 256 KiB, regular files within 256 per skill, and resulting files and directories within 512 per skill. A collection can inspect at most 65,536 repository entries and 1 GiB of declared expanded repository data. The installed library holds at most 500 skills and 256 MiB of retained content per account. Paths have at most 16 segments and 1,024 UTF-8 bytes. Keep package checks and test results outside the deliverable, while retaining examples the skill needs at runtime. For reproducible distribution, optionally sort ZIP paths and normalize timestamps and file modes; import does not require this.

Instructions and tools

7. Write actionable Markdown instructions below the frontmatter. Explain which input to inspect, the required steps, expected output, verification, missing-input handling, and conditions for asking the user a question. Use examples where they resolve ambiguity. Keep the main instructions small enough for conversation context and put longer reference material in supporting files.

8. Refer to supporting files by exact relative paths and say when to read each one. skill_read reads supporting UTF-8 text in bounded portions after activation; binary files return metadata only. Provide a text alternative when the model must inspect a binary resource. Imported files are not placed in the workspace automatically. When the workflow needs complete files, describe how to use the separately selected skill_materialize write tool in Execute mode and follow the returned workspace-relative path. For a script, describe its runtime and how to run it through ordinary permitted tools and clean up its outputs.

9. Describe required tools, runtimes, and permissions accurately. WebUI imports require MCP_USE. Automatic loading also needs TOOLS.MCP.ENABLED, tools enabled with at least one tool selected for the active mode, and model tool-calling support. A skill does not install dependencies, enable tools, grant access, or bypass approval. Its instructions remain subordinate to the user's direct request and system or developer instructions. Do not claim personal skill selection applies to automations, messaging integrations, external inference API calls, or external MCP clients.

Import and acceptance

10. Inspect the final file or archive for its layout, manifest, allowed fields, UTF-8 content, path safety, sizes, and intended resources. Import it through Chat configuration > Skills > Add skill in a disposable chat, inspect View, enable the skill, and select Save. Do not change SoAI or weaken validation to make the package import. Confirm a rejected test package leaves the existing library and selection intact.

11. Run the acceptance request on the intended model. For a directly invocable skill, test a $name request after saving the selection, including Chat mode with tools disabled when only instructions are needed. For an automatically loadable skill, enable tools and test a relevant request without naming it. Check unrelated requests and incomplete input. Read every supporting file required by the acceptance task; test script preparation and execution when applicable, with the normal permissions and approvals.

12. Confirm forbidden loading methods are rejected or unavailable as documented. Check that a name in inline code or a quoted block does not count as an explicit invocation. Test a saved Skills preset, then replace only your own test skill and update its conversation and preset selections. Record any model-dependent behavior, missing runtime, permission restriction, or context limit that prevents a test from completing.

Deliver the final file or ZIP, the checks actually performed, the import and acceptance results, and any unsupported or untested paths. A SHA-256 digest is optional distribution information. If SoAI testing is unavailable, label the package as unverified.

Try it in a chat

Your account needs MCP usage (MCP_USE) to import the package. Automatic loading also requires an enabled tool runtime (TOOLS.MCP.ENABLED) and a model with tool-calling support. In Chat configuration > Tools, enable tools, select at least one for the active mode, and select Save.

Import the package from Chat configuration > Skills > Add skill, enable it, and select Save. If the skill allows explicit requests, first request it by name to check the instructions themselves. If it allows automatic loading, try a relevant request without naming it to check whether the description helps the model discover it. Use the models you expect to work with; instruction following and tool selection can differ between models.

Test incomplete input and a request outside the skill's purpose. Confirm that the assistant asks useful questions, preserves supplied facts, and reads the intended supporting files. When revising a package, import the replacement and update its conversation and preset selections before testing again.

Related documentation