How to Define Custom Skills for OpenMAIC Agents: A Complete Developer Guide
OpenMAIC agents can be extended by creating a self-contained directory containing a SKILL.md file under skills/agent-runtime/, which the skill loader automatically registers for invocation via slash commands or the create_skill tool.
OpenMAIC is an extensible agent framework that allows developers to tailor AI capabilities through modular, file-based skills. These skills require no manual registration code—according to the OpenMAIC source code, the system discovers and loads capabilities automatically by scanning the filesystem at startup.
Understanding the OpenMAIC Skill Architecture
A skill in OpenMAIC is a runtime capability defined by a combination of YAML front-matter metadata and an LLM prompt template. The architecture relies on four core components working together:
SKILL.mdfiles stored in subdirectories underskills/agent-runtime/lib/workbench/skill-load.tswhich implements the filesystem watcher and parserlib/workbench/agent-skills.tsproviding React hooks (useAgentSkills) and display helpers (skillTitle,skillDisplayLabel)- Server-side APIs at
/api/agent/skills/[skillId]for persisting runtime-created skills
The loader treats each skill directory as an isolated unit, parsing the SKILL.md file to extract the handle (the slash-command trigger), version, author, and the prompt template that the LLM will execute when invoked.
Creating Your First Custom Skill
Step 1: Set Up the Directory Structure
Create a new folder under the skills/agent-runtime/ directory. The folder name should be descriptive but does not affect the skill's runtime identity.
skills/
└─ agent-runtime/
└─ my-awesome-skill/
└─ SKILL.md
Step 2: Author the SKILL.md File
The SKILL.md file is the sole requirement for defining a skill. It must contain YAML front-matter delimited by --- followed by the prompt template body.
---
title: My Awesome Skill
handle: my-awesome-skill # used after the slash, e.g. `/my-awesome-skill`
author: Your Name
version: 0.1.0
description: |
Generates a short motivational quote based on the user's current mood.
---
You are a helpful assistant. When the user says they feel **{{mood}}**, respond with a short motivational quote that fits the mood. Keep the reply under 30 words.
Key fields in the front-matter:
handle– The unique identifier users type after the "/" character to invoke the skilltitle– The display name shown in the UI skill menuversion– Semantic versioning for tracking changes
The body content after the front-matter serves as the system prompt or template that the LLM receives when the skill is invoked. You can embed placeholders (e.g., {{mood}}) that the UI will replace with user-supplied arguments.
How the Skill Loader Works
When the OpenMAIC application initializes, the skill loader (lib/workbench/skill-load.ts) performs the following operations:
- Scans the
skills/agent-runtime/tree recursively - Parses each
SKILL.mdfile to extract front-matter metadata - Registers the skill in an in-memory registry accessible to the runtime
- Exposes the skill as a callable tool through the
create_skillfunction
This process requires no import statements or manual registration calls. Once the file exists on disk, the loader picks it up automatically on the next application start or when the file watcher detects changes.
Accessing Skills Programmatically
To interact with registered skills within React components, import the useAgentSkills hook from lib/workbench/agent-skills.ts:
import { useAgentSkills } from '@/lib/workbench/agent-skills';
// Inside a React component
const { skills, loading, error } = useAgentSkills();
const mySkill = skills.find(s => s.name === 'my-awesome-skill');
The hook returns an array of skill objects containing the parsed metadata from each SKILL.md file. Helper utilities like skillTitle() and skillDisplayLabel() provide formatted strings for UI rendering, ensuring consistent presentation across the application interface.
Runtime Invocation and Persistence
Users can invoke skills through two primary mechanisms:
Slash Commands: Typing /my-awesome-skill happy in the composer triggers the skill loader to generate a create_skill tool call with the parsed arguments.
Programmatic Creation: To register a skill dynamically via the server API:
// POST /api/agent/skills
await fetch('/api/agent/skills', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
name: 'my-awesome-skill',
title: 'My Awesome Skill',
content: /* the SKILL.md body */,
}),
});
The server persists the skill definition, making it available on subsequent application loads alongside filesystem-defined skills.
Summary
- Directory-based: Place custom skills in
skills/agent-runtime/<skill-name>/ - Single file definition: Each skill requires only a
SKILL.mdfile with YAML front-matter and prompt body - Automatic discovery:
lib/workbench/skill-load.tshandles scanning and registration without manual imports - UI integration: Access loaded skills via
useAgentSkills()fromlib/workbench/agent-skills.ts - Flexible invocation: Trigger skills using
/handlesyntax in the UI orcreate_skilltool calls
Frequently Asked Questions
What file format does OpenMAIC use for skill definitions?
OpenMAIC uses Markdown files named SKILL.md with YAML front-matter. The front-matter contains metadata like title, handle, author, and version, while the body contains the prompt template that the LLM executes when the skill is invoked.
How do I make my skill appear in the slash command menu?
Your skill appears automatically once you define the handle field in the SKILL.md front-matter and place the file in skills/agent-runtime/. The lib/workbench/skill-load.ts loader scans this directory at startup and registers the handle for the UI's slash-menu, which is rendered by components like skill-load-card.tsx and tool-presentation.tsx.
Can I pass dynamic arguments to a custom skill?
Yes. Include template variables in your SKILL.md body using double curly braces (e.g., {{mood}}). When users invoke the skill via /my-awesome-skill happy, the system maps "happy" to the {{mood}} placeholder, interpolating the value before sending the prompt to the LLM.
Where does OpenMAIC store custom skills added at runtime?
Runtime-created skills are persisted through the /api/agent/skills/[skillId] endpoint. While filesystem-based skills reside in skills/agent-runtime/, dynamically created skills are stored server-side and loaded alongside directory-based skills on subsequent application initialization.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →