# Where Custom Skill Definitions Are Stored in Craft Agents

> Discover where custom skill definitions land in Craft Agents. Learn about SKILL.md files within workspace directories and how metadata is parsed from front-matter and markdown.

- Repository: [Craft Ai Agents/craft-agents-oss](https://github.com/craft-ai-agents/craft-agents-oss)
- Tags: how-to-guide
- Published: 2026-07-04

---

**Custom skill definitions in Craft Agents are stored as [`SKILL.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/SKILL.md) files inside workspace-specific subdirectories located at `<workspace-root>/skills/<skill-slug>/`, with metadata and content parsed from front-matter and markdown body.**

In the `craft-ai-agents/craft-agents-oss` repository, custom skills are persisted locally on the filesystem rather than in a centralized database. Each workspace maintains its own isolated `skills` directory containing sub-folders named after their respective skill slugs. Understanding this storage architecture is essential for debugging skill loading issues or implementing custom tooling around the Craft Agents platform.

## Workspace Skill Storage Location

Every workspace in Craft Agents has a dedicated root directory. Within that directory, custom skills reside in a predefined `skills` folder.

The absolute path convention follows this structure:

```text
<workspace-root>/skills/<skill-slug>/SKILL.md

```

According to the source code in [`packages/shared/src/workspaces/storage.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/workspaces/storage.ts), the function `getWorkspaceSkillsPath()` returns the absolute path to this `skills` directory by appending `/skills` to the workspace root【#84-L89】. This design ensures that skills are scoped per workspace, preventing namespace collisions between different projects.

## How Skills Are Structured on Disk

### The SKILL.md File Format

Each custom skill is a subdirectory containing a mandatory [`SKILL.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/SKILL.md) file. This file serves as the single source of truth for the skill's definition, combining YAML front-matter for metadata and markdown for the implementation body.

The `loadWorkspaceSkills()` function and related utilities in [`packages/shared/src/skills/storage.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/skills/storage.ts) read these files to populate the skill registry at runtime【#87-L90】. The metadata structure conforms to the `SkillMetadata` interface defined in [`packages/shared/src/skills/types.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/skills/types.ts), which standardizes fields like `name`, `description`, and configuration parameters.

### Supporting Assets

Skills may include additional assets such as icons. The `getSkillIconPath()` utility looks for `icon.*` files located alongside [`SKILL.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/SKILL.md) within the skill directory【#78-L86】. This colocation pattern keeps all skill-related assets bundled together for easy portability and version control.

## Programmatic Access to Skill Storage

The `@craft-agents/shared` package exports several utilities for interacting with custom skill storage without hardcoding file paths.

### Listing Available Skills

To retrieve all skill slugs within a workspace:

```typescript
import { listSkillSlugs } from '@craft-agents/shared/src/skills/storage';
import { getWorkspacePath } from '@craft-agents/shared/src/workspaces/storage';

const wsId = 'my-workspace';
const wsRoot = getWorkspacePath(wsId);

const slugs = listSkillSlugs(wsRoot);
console.log('Workspace skills:', slugs);

```

The `listSkillSlugs()` function scans the `<workspace-root>/skills` directory and returns an array of directory names representing each skill slug【#35-L40】.

### Loading Skill Metadata and Content

To load a specific skill's complete definition:

```typescript
import { loadSkill } from '@craft-agents/shared/src/skills/storage';
import { getWorkspacePath } from '@craft-agents/shared/src/workspaces/storage';

const wsRoot = getWorkspacePath('my-workspace');
const skill = loadSkill(wsRoot, 'my-custom-skill');

if (skill) {
  console.log('Skill name:', skill.metadata.name);
  console.log('Description:', skill.metadata.description);
  console.log('Body:', skill.content);
}

```

`loadSkill()` reads the [`SKILL.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/SKILL.md) file for the given slug and parses both the front-matter metadata and the markdown body【#78-L81】.

### Resolving Skill Asset Paths

To locate a skill's icon file:

```typescript
import { getSkillIconPath } from '@craft-agents/shared/src/skills/storage';
import { getWorkspacePath } from '@craft-agents/shared/src/workspaces/storage';

const iconPath = getSkillIconPath(getWorkspacePath('my-workspace'), 'my-custom-skill');
console.log('Icon location:', iconPath);

```

This utility checks for image files matching `icon.*` patterns within the skill's directory【#78-L86】.

## Key Source Files and Functions

The storage mechanism is implemented across several files in the `packages/shared` directory:

- **[`packages/shared/src/workspaces/storage.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/workspaces/storage.ts)** (lines 84-89): Contains `getWorkspaceSkillsPath()`, which resolves the absolute path to the `skills` directory for any given workspace.
- **[`packages/shared/src/skills/storage.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/skills/storage.ts)** (lines 78-90): Implements `loadWorkspaceSkills()`, `loadSkill()`, and `getSkillIconPath()`, handling the file system operations for reading skill definitions.
- **[`packages/shared/src/skills/types.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/skills/types.ts)**: Defines the `SkillMetadata` interface that governs the structure of data extracted from [`SKILL.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/SKILL.md) front-matter.
- **[`packages/shared/src/skills/__tests__/storage.test.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/skills/__tests__/storage.test.ts)**: Contains the test suite demonstrating expected directory structures and validation logic for [`SKILL.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/SKILL.md) files.

## Summary

- Custom skills are stored per workspace in `<workspace-root>/skills/<skill-slug>/SKILL.md`.
- The `getWorkspaceSkillsPath()` utility provides the canonical path resolution for skill directories.
- Each skill directory contains a [`SKILL.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/SKILL.md) file with front-matter metadata and optional assets like icons.
- Use `listSkillSlugs()` to enumerate skills and `loadSkill()` to read specific definitions.
- The storage layer is implemented in [`packages/shared/src/skills/storage.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/packages/shared/src/skills/storage.ts) with type definitions in [`types.ts`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/types.ts).

## Frequently Asked Questions

### What happens if a SKILL.md file is missing from a skill directory?

If the [`SKILL.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/SKILL.md) file is missing or malformed, the `loadSkill()` function will return `null` or throw a parsing error depending on the validation context. The `listSkillSlugs()` function only returns directory names, so it may list a slug that subsequently fails to load if the file is absent.

### Can I store other files in the skill directory besides SKILL.md?

Yes. The directory structure supports additional assets such as `icon.*` files, which are resolved via `getSkillIconPath()`. While the system primarily looks for [`SKILL.md`](https://github.com/craft-ai-agents/craft-agents-oss/blob/main/SKILL.md), you can include supplementary files like configuration JSON or documentation, though these require custom loading logic outside the standard skill storage utilities.

### How does Craft Agents handle skill name collisions between workspaces?

Since skills are stored within workspace-specific `skills` directories, collisions are naturally prevented at the storage level. Each workspace operates in isolation, and the `getWorkspacePath()` function ensures that skill lookups are scoped to the correct workspace root. Skills from different workspaces cannot interfere with each other unless explicitly shared through external synchronization mechanisms.