# How to Implement Custom Skills in OpenWork: A Complete Developer's Guide

> Learn to implement custom skills in OpenWork with this developer's guide. Discover how to create and register your own MCP capabilities for seamless integration.

- Repository: [Different AI/openwork](https://github.com/different-ai/openwork)
- Tags: how-to-guide
- Published: 2026-08-21

---

**To implement custom skills in OpenWork, create markdown files with YAML front-matter in the `.warden/skills` directory, which the server automatically parses via [`skill-markdown.ts`](https://github.com/different-ai/openwork/blob/main/skill-markdown.ts) and registers as MCP capabilities accessible through the `/execute_capability` endpoint.**

OpenWork is an open-source AI agent platform that treats **skills** as reusable playbooks—structured instructions that agents invoke when tasks match their descriptions. To implement custom skills in OpenWork, you author markdown definitions with structured front-matter specifying input and output schemas, store them in the repository's skill store, and let the MCP gateway handle discovery and execution.

## What Are OpenWork Skills?

In the OpenWork architecture, a **skill** is a capability definition that translates natural language tasks into executable actions. Skills are not compiled code but rather declarative markdown files stored under the repository's **`.warden/skills`** folder. Each file contains metadata in YAML front-matter that describes the skill's interface, including its title, description, parameters, and return type.

The system watches this directory for changes, enabling hot-reloading without server restarts. When a file is added or modified, the **Skill Loader** parses the front-matter and registers the skill with the MCP (Model Context Protocol) runtime.

## Architecture of the Skill System

### The Skill Store

The **`.warden/skills`** directory serves as the canonical storage location for user-defined skills. This folder is monitored by the file system watcher, ensuring that any new markdown file immediately becomes available to the runtime. Place all custom skill definitions in this location to ensure automatic loading.

### The Skill Loader

Located at [`ee/packages/utils/src/skill-markdown.ts`](https://github.com/different-ai/openwork/blob/main/ee/packages/utils/src/skill-markdown.ts), the **Skill Loader** reads each markdown file in the skill store and extracts the front-matter. It converts the YAML metadata—specifically the `input` and `output` JSON Schema definitions—into a structured **capability** object that the MCP understands. The loader handles validation and registration, surfacing any schema errors during the parsing phase.

### Server Integration

The server-side endpoint in [`apps/server/src/skills.ts`](https://github.com/different-ai/openwork/blob/main/apps/server/src/skills.ts) exposes loaded skills via the MCP API. It provides two critical methods: `/search_capabilities` for discovery and `/execute_capability` for invocation. This file acts as the bridge between the file-based skill definitions and the agent runtime, ensuring that custom skills appear alongside built-in capabilities.

### User Interface Components

For visual authoring, the Den web application provides dedicated components:
- **[`skill-editor-screen.tsx`](https://github.com/different-ai/openwork/blob/main/skill-editor-screen.tsx)** (`ee/apps/den-web/app/(den)/dashboard/_components/`): A graphical editor for creating and modifying skill markdown with live preview.
- **[`skill-detail-screen.tsx`](https://github.com/different-ai/openwork/blob/main/skill-detail-screen.tsx)** (same directory): Displays skill metadata, permission settings, and version history for managing published skills.

## Step-by-Step Implementation Guide

### 1. Create the Skill Markdown File

Navigate to the `.warden/skills` directory and create a new `.md` file. The filename becomes the skill's identifier. Structure the file with YAML front-matter delimited by triple dashes:

```markdown
---
title: "Summarize Ticket"
description: "Generate a concise summary of a ticket given its ID."
input:
  type: object
  properties:
    ticketId:
      type: string
      description: "The unique identifier of the ticket."
output:
  type: string
  description: "A short, human-readable summary."
tags: [ticketing, summary]
---
Use the ticketing connector to fetch the ticket data, then produce a summary that includes the title, priority, and current status.

```

The content below the front-matter contains the implementation instructions or prompt template that guides the agent's behavior.

### 2. Define Input and Output Schemas

The `input` and `output` fields in the front-matter use **JSON Schema** syntax to enforce type safety. The [`skill-markdown.ts`](https://github.com/different-ai/openwork/blob/main/skill-markdown.ts) parser validates these schemas during loading. Ensure your `input` object defines all required parameters under `properties`, and specify the expected `output` type (string, object, or array) to help agents understand return values.

### 3. Validate Your Implementation

Run the local development server with `pnpm dev`. The system automatically loads your new skill. To verify functionality, execute the end-to-end test suite located at [`evals/specs/skill-created-mcp-app.e2e.test.ts`](https://github.com/different-ai/openwork/blob/main/evals/specs/skill-created-mcp-app.e2e.test.ts). This test validates that the skill is discoverable via `/search_capabilities` and executable via `/execute_capability` with the defined parameters.

### 4. Edit via the Den Web UI (Optional)

Instead of editing markdown directly, open the Den web interface and navigate to **Settings → Library → Add Custom App**. The **Skill Editor** ([`skill-editor-screen.tsx`](https://github.com/different-ai/openwork/blob/main/skill-editor-screen.tsx)) provides a form-based interface for editing front-matter fields and the prompt body, reducing syntax errors and providing immediate validation feedback.

### 5. Package as a Plugin (Optional)

To distribute skills across teams or publish to the Den marketplace, bundle them into a plugin. Reference [`packages/types/src/skill-created-app.tsx`](https://github.com/different-ai/openwork/blob/main/packages/types/src/skill-created-app.tsx) for the plugin manifest structure. This file demonstrates how to package a skill with versioning and metadata, enabling installation through the OpenWork plugin system rather than manual file placement.

## Invoking Custom Skills via MCP

Once loaded, agents interact with your skill through the MCP gateway. The agent calls the `execute_capability` tool with the skill name and arguments:

```json
{
  "tool": "execute_capability",
  "capability": "Summarize Ticket",
  "args": { "ticketId": "ABC-1234" }
}

```

The server routes this request to the appropriate handler based on the capability name registered by [`skill-markdown.ts`](https://github.com/different-ai/openwork/blob/main/skill-markdown.ts). For discovery, agents query `/search_capabilities` to retrieve the full catalog including custom skills, their descriptions, and input schemas.

## Summary

- Store custom skill markdown files in the **`.warden/skills`** directory for automatic loading.
- Define interfaces using **JSON Schema** in the YAML front-matter parsed by [`ee/packages/utils/src/skill-markdown.ts`](https://github.com/different-ai/openwork/blob/main/ee/packages/utils/src/skill-markdown.ts).
- Access skills through the MCP endpoints defined in [`apps/server/src/skills.ts`](https://github.com/different-ai/openwork/blob/main/apps/server/src/skills.ts), specifically `/search_capabilities` and `/execute_capability`.
- Validate implementations using the [`evals/specs/skill-created-mcp-app.e2e.test.ts`](https://github.com/different-ai/openwork/blob/main/evals/specs/skill-created-mcp-app.e2e.test.ts) test suite.
- Use the **Skill Editor** UI components for visual authoring when direct markdown editing is impractical.
- Bundle related skills into distributable plugins using the structure defined in [`packages/types/src/skill-created-app.tsx`](https://github.com/different-ai/openwork/blob/main/packages/types/src/skill-created-app.tsx).

## Frequently Asked Questions

### Where are custom skills stored in OpenWork?

Custom skills reside in the **`.warden/skills`** folder at the repository root. This directory is watched by the server; any markdown file placed here is automatically parsed and loaded into the MCP runtime without requiring a server restart.

### What file format is used for OpenWork skills?

Skills are authored as **markdown files with YAML front-matter**. The front-matter contains metadata fields including `title`, `description`, `input` schema, `output` schema, and `tags`, while the markdown body contains the implementation instructions or prompt templates.

### How do AI agents discover custom skills?

Agents discover skills through the MCP gateway's `/search_capabilities` endpoint, which aggregates both built-in and custom capabilities. The [`skills.ts`](https://github.com/different-ai/openwork/blob/main/skills.ts) server file serves the loaded skills, allowing agents to query available functions and their schemas before calling `execute_capability` with the specific skill name.

### Can I bundle multiple skills together for distribution?

Yes. You can package skills into plugins using the manifest structure shown in [`packages/types/src/skill-created-app.tsx`](https://github.com/different-ai/openwork/blob/main/packages/types/src/skill-created-app.tsx). This approach allows you to version, permission, and distribute collections of related skills through the Den marketplace or private registries, rather than managing individual markdown files in `.warden/skills`.