# How to Define Custom Skills for OpenMAIC Agents: A Complete Developer Guide

> Learn how to define custom skills for OpenMAIC agents. This developer guide shows you how to create and register new skills for your agents, extending their capabilities.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: how-to-guide
- Published: 2026-09-09

---

**OpenMAIC agents can be extended by creating a self-contained directory containing a [`SKILL.md`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.md`](https://github.com/THU-MAIC/OpenMAIC/blob/main/SKILL.md) files** stored in subdirectories under `skills/agent-runtime/`
- **[`lib/workbench/skill-load.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/skill-load.ts)** which implements the filesystem watcher and parser
- **[`lib/workbench/agent-skills.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/agent-skills.ts)** providing 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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.

```text
skills/
└─ agent-runtime/
   └─ my-awesome-skill/
      └─ SKILL.md

```

### Step 2: Author the SKILL.md File

The [`SKILL.md`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.

```markdown
---
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 skill
- **`title`** – The display name shown in the UI skill menu
- **`version`** – 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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/skill-load.ts)) performs the following operations:

1. **Scans** the `skills/agent-runtime/` tree recursively
2. **Parses** each [`SKILL.md`](https://github.com/THU-MAIC/OpenMAIC/blob/main/SKILL.md) file to extract front-matter metadata
3. **Registers** the skill in an in-memory registry accessible to the runtime
4. **Exposes** the skill as a callable tool through the `create_skill` function

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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/agent-skills.ts):

```typescript
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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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:

```typescript
// 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.md`](https://github.com/THU-MAIC/OpenMAIC/blob/main/SKILL.md) file with YAML front-matter and prompt body
- **Automatic discovery:** [`lib/workbench/skill-load.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/skill-load.ts) handles scanning and registration without manual imports
- **UI integration:** Access loaded skills via `useAgentSkills()` from [`lib/workbench/agent-skills.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/lib/workbench/agent-skills.ts)
- **Flexible invocation:** Trigger skills using `/handle` syntax in the UI or `create_skill` tool calls

## Frequently Asked Questions

### What file format does OpenMAIC use for skill definitions?

OpenMAIC uses **Markdown files named [`SKILL.md`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/SKILL.md) front-matter and place the file in `skills/agent-runtime/`. The [`lib/workbench/skill-load.ts`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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`](https://github.com/THU-MAIC/OpenMAIC/blob/main/skill-load-card.tsx) and [`tool-presentation.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tool-presentation.tsx).

### Can I pass dynamic arguments to a custom skill?

Yes. Include **template variables** in your [`SKILL.md`](https://github.com/THU-MAIC/OpenMAIC/blob/main/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.