# How to Create and Publish Custom OpenWork Skills to the Marketplace

> Learn to create and publish custom OpenWork skills to the marketplace. Transform your workflows with custom plugins and share them easily.

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

---

**OpenWork skills are first-class resources defined in [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md) files and published through built-in remote capabilities that create plugins on OpenWork Cloud, attach them to marketplaces, and optionally share access with specific users or teams.**

OpenWork provides a structured workflow for turning ideas into reusable agent capabilities. This guide walks through the complete lifecycle—from drafting a [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md) to publishing on the marketplace—using the built-in remote skills defined in [`ee/apps/den-api/src/mcp/builtin-skills.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/mcp/builtin-skills.ts).

---

## The Four-Step OpenWork Skill Lifecycle

Creating and publishing a custom OpenWork skill follows a predictable path. Each step maps to a specific built-in capability.

| Step | Built-in skill | What it does |
|------|---------------|--------------|
| 1. Draft | `skill:create-skill` | Validates and creates a plugin containing your [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md) |
| 2. Create | `skill:create-skill` | Instantiates the plugin on OpenWork Cloud (instantly usable by creator) |
| 3. Publish | `skill:add-to-marketplace` | Attaches the plugin to a marketplace catalog |
| 4. Share | `skill:share-plugin` | Grants scoped access to people, teams, or organizations |

---

## Step 1: Draft Your Skill in [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md)

Every OpenWork skill starts with a **front-matter block** followed by **execution instructions**. The `create-skill` capability validates this structure before accepting the payload.

### Required [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md) Structure

```markdown
---
name: weather-alert                    # kebab-case, unique within org

description: |
  Generate a concise weather alert for a given city.
---

# Weather Alert

Given a city name, fetch the current weather from a public API and return a short
summary in plain English. Use the following steps:

1. Call `fetch("https://api.weatherapi.com/v1/current.json?key=...&q={city}")`.
2. Parse the JSON and extract `temp_c`, `condition.text`.
3. Respond with: "`{city}` is currently `{temp_c}°C` with `{condition}`."

```

The `name` field becomes the skill's identifier. The `description` determines when the agent suggests this skill. The body contains the **full execution logic** the agent follows when invoked.

As implemented in `different-ai/openwork`, the `CREATE_SKILL_SOURCE` constant in [`builtin-skills.ts`](https://github.com/different-ai/openwork/blob/main/builtin-skills.ts) enforces that both front-matter and body are non-empty.

---

## Step 2: Create the Skill on OpenWork Cloud

The `create-skill` capability transforms your [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md) into a **plugin with a skill component**. This is a **remote-only** operation—no local files are created unless explicitly requested.

### API Flow (from [`builtin-skills.ts`](https://github.com/different-ai/openwork/blob/main/builtin-skills.ts))

```json
POST /v1/plugins
{
  "name": "My Awesome Plugin",
  "components": [
    { "type": "skill", "input": { "rawSourceText": "<SKILL.md content>" } }
  ]
}

```

On success, the call returns a `pluginId`. The capability then verifies creation:

```json
GET /v1/pluginsResolved/{pluginId}

```

If the plugin already exists (`409 duplicate_plugin`), the skill offers to update via `postConfigObjectsVersions` rather than failing.

---

## Step 3: Publish to the OpenWork Marketplace

Once created, your skill exists as a private plugin. To make it discoverable, use **`skill:add-to-marketplace`**.

### Marketplace Attachment Process

The `add-to-marketplace` capability performs these operations:

```typescript
// 1. Discover available marketplaces
const markets = await openworkCloudExecuteCapability({
  capability: "getMarketplaces"
});

// 2. Select target and attach plugin
await openworkCloudExecuteCapability({
  capability: "skill:add-to-marketplace",
  pathParams: [targetMarketplaceId],
  body: { pluginId: "<pluginId>" }
});

// 3. Verify attachment
GET /v1/marketplacesResolved/{marketplaceId}

```

This step **does not create a new skill**—it adds the existing plugin to a marketplace catalog you own or administer.

---

## Step 4: (Optional) Scope Access with `share-plugin`

By default, only the creator can use a skill. To grant access without publishing broadly, use **`skill:share-plugin`**.

### Sharing Configuration

```typescript
await openworkCloudExecuteCapability({
  capability: "skill:share-plugin",
  body: {
    pluginId: "<pluginId>",
    orgMembershipId: "om_9876",    // resolved via getOrg
    role: "viewer"                 // or "admin"
  }
});

```

The capability validates recipients through `getOrg` before granting access. Valid targets include:
- Individual users
- Teams
- Entire organizations

---

## Complete Publishing Example

Here's the full workflow from [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md) draft to marketplace publication:

```typescript
// Step 1-2: Create skill from markdown source
const skillMd = `---
name: changelog-generator
description: |
  Generate a formatted changelog from Git commits since last tag.
---

# Changelog Generator

1. Run \`git describe --tags --abbrev=0\` to find last tag.
2. Run \`git log {lastTag}..HEAD --oneline\`.
3. Group commits by type (feat, fix, docs).
4. Output Markdown changelog.`;

const createResult = await openworkCloudExecuteCapability({
  capability: "skill:create-skill",
  body: { rawSourceText: skillMd }
});

// Step 3: Publish to marketplace
await openworkCloudExecuteCapability({
  capability: "skill:add-to-marketplace",
  pathParams: ["mp_acme_public"],
  body: { pluginId: createResult.pluginId }
});

// Step 4: Share with engineering team
await openworkCloudExecuteCapability({
  capability: "skill:share-plugin",
  body: {
    pluginId: createResult.pluginId,
    orgMembershipId: "om_eng_team",
    role: "viewer"
  }
});

```

---

## Key Implementation Files

Understanding these source locations helps debug and extend the OpenWork skill system:

| File Path | Purpose |
|-----------|---------|
| [`ee/apps/den-api/src/mcp/builtin-skills.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/mcp/builtin-skills.ts) | Defines `create-skill`, `add-to-marketplace`, `add-user-to-marketplace`, and `share-plugin` with their capability schemas |
| [`ee/apps/den-api/src/mcp/agent.ts`](https://github.com/different-ai/openwork/blob/main/ee/apps/den-api/src/mcp/agent.ts) | Shows how the agent discovers and executes built-in remote skills |
| [`AGENTS.md`](https://github.com/different-ai/openwork/blob/main/AGENTS.md) ([`.opencode/skills/prd-conventions/SKILL.md`](https://github.com/different-ai/openwork/blob/main/.opencode/skills/prd-conventions/SKILL.md) section) | Documents the [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md) file format expected by `create-skill` |

---

## Summary

- **Skills are resources**, not standalone code—define them in [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md) with front-matter and execution body
- **Creation is remote** via `skill:create-skill`, which wraps your markdown in a plugin component
- **Publishing is attachment** via `skill:add-to-marketplace`, adding an existing plugin to a catalog
- **Sharing is granular** via `skill:share-plugin`, controlling access without marketplace exposure
- **All capabilities are discoverable** through the OpenWork skill index and executed by the agent against OpenWork Cloud APIs

---

## Frequently Asked Questions

### What format must my skill definition follow?

Your skill must be a valid [`SKILL.md`](https://github.com/different-ai/openwork/blob/main/SKILL.md) file with YAML front-matter containing at minimum `name` (kebab-case, unique within your organization) and `description` fields, followed by a Markdown body with execution instructions. The `create-skill` capability rejects files missing either component.

### Can I update a skill after publishing it?

Yes. If `create-skill` detects a duplicate plugin (HTTP 409), it offers to update via `postConfigObjectsVersions`. For marketplace-published skills, the updated version becomes available immediately to all users with access.

### Do I need to publish to a marketplace to use my skill?

No. Skills are instantly usable by their creator immediately after `create-skill` succeeds. Marketplace publication is only required to make the skill discoverable by other users or teams in your organization.

### How do I control who can see my marketplace skill?

Use `skill:share-plugin` to grant specific `orgMembershipId` values access with roles (`viewer`, `admin`). Alternatively, create a private marketplace and add your plugin only there—marketplace visibility acts as a first gate, with plugin-level sharing as a second layer.