---
title: Skill
kind: resource
slug: skill
summary: "A Claude Code recipe hosted on Drop. Stored as a Droplet with `appType: SKILL` + a `SKILL.md` markdown body."
---

# Skill

A Claude Code recipe hosted on Drop. Stored as a Droplet with `appType: SKILL` + a `SKILL.md` markdown body.

A **Skill** is a Claude Code recipe ([Anthropic Skills](https://docs.claude.com/en/docs/claude-code/skills)) hosted on Drop so any teammate can install it with one command. Skills are Droplets with `appType: SKILL` — they share the same versioning, access control, and asset story as Droplets, but are detected on deploy from a `SKILL.md` file with frontmatter (`name`, `description`) and rendered with a markdown preview instead of an iframe. Skills default to `internalAccess: EVERYONE` so they're discoverable across Hi Marley. Admins can **feature** skills to surface them on `/skills`.

## The Skill object

### Attributes

- **`slug`** `string` — URL-friendly identifier. Used in `drop skills install {slug}` and `/skills/{slug}`. Globally unique across all Droplets and Skills.
- **`name`** `string` — Display name. Auto-populated from the `name:` field in `SKILL.md` frontmatter at deploy time; can be overridden via `--name` on `drop skills create`.
- **`description`** `string · nullable` — One-line description Claude Code surfaces when picking which skill to use. Auto-populated from the `description:` field in `SKILL.md` frontmatter.
- **`appType`** `enum` (enum: `DROPLET` / `DROP` / `SKILL`) — Always `SKILL` for this resource. Determines that `/view/{slug}` renders a markdown preview and that the skill appears on `/skills`. Set automatically when a `.md` file with `SKILL.md` frontmatter is deployed.
- **`sourceFormat`** `enum` (enum: `HTML` / `MARKDOWN`) — Always `MARKDOWN` for skills. The raw markdown is what Claude Code installs; the preview at `/view/{slug}` is server-rendered HTML.
- **`internalAccess`** `enum` (enum: `PRIVATE` / `SPACE` / `SPECIFIC` / `EVERYONE`) — Skills default to **`EVERYONE`** so they're installable by any teammate. Tightening to `PRIVATE`/`SPACE`/`SPECIFIC` removes the skill from the `/api/skills` listing for non-permitted callers but keeps it installable via direct slug for those who can see it.
- **`featured`** `boolean` — Admin-curated flag. Featured skills appear on the `/skills` showcase page. Toggled via [Feature / unfeature](#feature). The system `drop` skill cannot be unfeatured.
- **`currentVersion`** `integer` — Latest version number. `drop skills install` pulls the current version by default; `drop skills install <slug> --version N` pins to a specific version.
- **`exampleOfSkill`** `string · nullable` — When this Droplet is wired up as an *example* of another skill, the parent skill's slug. Most skills leave this `null`; set via [Link example](#link-example) on the parent skill.
- **`tags`** `string[]` — Free-form tags. Useful for filtering the skills directory (`tag:claude`).
- **`id`** `string · less-common` — CUID primary key. Use `slug` in API paths.
- **`publishedVersion`** `integer · nullable · less-common` — The version currently published at the live URL. May lag `currentVersion` if a draft is in flight.
- **`fileSize`** `integer · less-common` — Size of the live `SKILL.md` in bytes.
- **`ownerId`** `string · less-common` — The User who created the Skill. Owner-only permissions: change access mode, transfer, delete.
- **`createdAt`** `timestamp · less-common` — ISO 8601 timestamp of first deploy.
- **`updatedAt`** `timestamp · less-common` — ISO 8601 timestamp of last deploy or metadata change.

### JSON example

```json
{
  "id": "clxskill1...",
  "slug": "pres",
  "name": "Presentations",
  "description": "Create Hi Marley branded presentations as 16:9 droplets",
  "appType": "SKILL",
  "sourceFormat": "MARKDOWN",
  "internalAccess": "EVERYONE",
  "currentVersion": 5,
  "publishedVersion": 5,
  "fileSize": 10212,
  "featured": true,
  "exampleOfSkill": null,
  "tags": ["claude", "presentations"],
  "ownerId": "usr_alex",
  "createdAt": "2026-04-14T12:00:00.000Z",
  "updatedAt": "2026-05-28T09:00:00.000Z"
}
```

## Methods

### Create a skill

`POST /api/cli/deploy`

Deploy a new skill from a `.md` (or `.html`) file. The CLI auto-detects the `SKILL.md` frontmatter (`name`, `description`) and sets `appType: SKILL`. Reuses the standard deploy flow — presigned upload + confirm. Subsequent re-deploys with `drop skill create` (or `drop deploy`) of the same slug bump `currentVersion`. Pass `--space <slug>` to publish the skill straight into a Space — mirroring `drop create --space`, it scopes the skill to that Space's members (`internalAccess: SPACE`); omit it and the skill defaults to `EVERYONE`.

**CLI**

```bash
drop skill create SKILL.md \
  --slug pres \
  --name "Presentations" \
  --description "Create Hi Marley branded presentations" \
  --space growth-academy \
  --notes "v5 — letterboxing support"
```

**HTTP**

```bash
# Step 1 — request presigned URL (skills go through the standard CLI deploy flow)
curl -X POST https://drop.himarley.ai/api/cli/deploy \
  -H "Authorization: Bearer $DROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"slug":"pres","name":"Presentations","appType":"SKILL"}'

# Step 2 — upload SKILL.md
curl -X PUT "$UPLOAD_URL" --data-binary @SKILL.md

# Step 3 — confirm
curl -X POST https://drop.himarley.ai/api/apps/pres/confirm \
  -H "Authorization: Bearer $DROP_TOKEN"
```

**Response** (201)

```json
{
  "app": {
    "id": "clxskill1...",
    "slug": "pres",
    "name": "Presentations",
    "description": "Create Hi Marley branded presentations",
    "appType": "SKILL",
    "sourceFormat": "MARKDOWN",
    "internalAccess": "EVERYONE",
    "status": "ACTIVE",
    "createdAt": "2026-04-14T12:00:00.000Z"
  },
  "uploadUrl": "https://drop-apps.s3.amazonaws.com/pres/v1/index.html?X-Amz-...",
  "isNew": true
}
```

### Install (Claude Code)

`GET /api/skills/{slug}/install`

Download a skill's `SKILL.md` (plus any attached assets) into `~/.claude/skills/{slug}/` so Claude Code picks it up immediately. The CLI and MCP tool both wrap this — there's rarely a reason to call the HTTP endpoint directly.

**CLI**

```bash
drop skills install pres              # latest version
drop skills install pres --version 4  # pin to v4
drop skills update pres               # bump to latest
drop skills outdated                  # which skills have updates available?
```

**MCP**

```json
{
  "tool": "drop_skills_install",
  "arguments": { "slug": "pres" }
}
```

**HTTP**

```bash
curl https://drop.himarley.ai/api/skills/pres/install \
  -H "Authorization: Bearer $DROP_TOKEN" \
  -o ~/.claude/skills/pres/SKILL.md
```

**Response** (200)

```json
---
name: pres
description: Create Hi Marley branded presentations
---

# Presentations

Step-by-step recipe for Claude Code to produce a 16:9 letterboxed deck...
```

### Get a skill

`GET /api/apps/{slug}`

Return the full Skill object by slug. Skills use the same `/api/apps/{slug}` endpoint as Droplets — `appType: SKILL` is just a discriminator. For the showcase-page-shaped subset (latest version, fileSize, hasAssets), use [List skills](#list) above.

**CLI**

```bash
drop skills info pres
drop skills info pres --json
```

**HTTP**

```bash
curl https://drop.himarley.ai/api/apps/pres \
  -H "Authorization: Bearer $DROP_TOKEN"
```

**Response** (200)

```json
{
  "app": {
    "id": "clxskill1...",
    "slug": "pres",
    "name": "Presentations",
    "description": "Create Hi Marley branded presentations as 16:9 droplets",
    "appType": "SKILL",
    "sourceFormat": "MARKDOWN",
    "internalAccess": "EVERYONE",
    "currentVersion": 5,
    "publishedVersion": 5,
    "fileSize": 10212,
    "featured": true,
    "tags": ["claude", "presentations"],
    "createdAt": "2026-04-14T12:00:00.000Z",
    "updatedAt": "2026-05-28T09:00:00.000Z"
  }
}
```

### List skills

`GET /api/skills`

Return every skill the caller can see, split into three tiers: `mySkills` (owned by the caller), `featured` (admin-curated and discoverable), and `shared` (skills shared with the caller — `EVERYONE`-access skills plus `SPACE`-scoped skills in Spaces the caller belongs to). Each row includes `currentVersion`, `fileSize`, and a `hasAssets` flag. Used by the `/skills` showcase, the CLI (`drop skills`), and `drop_skills_list`.

**CLI**

```bash
drop skills list
```

**MCP**

```json
{
  "tool": "drop_skills_list",
  "arguments": {}
}
```

**HTTP**

```bash
curl -X GET 'https://drop.himarley.ai/api/skills' \
  -H "Authorization: Bearer $DROP_TOKEN"
```

**Response** (200)

```json
{
  "mySkills": [
    {
      "slug": "pres",
      "name": "Presentations",
      "description": "Create Hi Marley branded presentations",
      "currentVersion": 5,
      "updatedAt": "2026-04-14T12:00:00.000Z",
      "fileSize": 10212,
      "hasAssets": false,
      "featured": true,
      "internalAccess": "EVERYONE"
    }
  ],
  "featured": [],
  "shared": []
}
```

### Feature / unfeature

`PATCH /api/apps/{slug}/feature`

Toggle whether a skill appears on the `/skills` showcase page. **Library Admin only.** Returns 400 if called on a non-SKILL app, 400 if attempting to unfeature the system `drop` skill, 403 if the caller is not a Library Admin, 404 if the slug does not exist.

**Parameters**

- **`slug`** _(string · path · required)_ — The skill slug.
- **`featured`** _(boolean · body · required)_ — Set true to feature, false to unfeature.

**CLI**

```bash
drop skills admin feature pres --featured
```

**MCP**

```json
{
  "tool": "drop_skill_feature",
  "arguments": {
    "slug": "pres",
    "featured": true
  }
}
```

**HTTP**

```bash
curl -X PATCH 'https://drop.himarley.ai/api/apps/pres/feature' \
  -H "Authorization: Bearer $DROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"featured":true}'
```

**Response** (200)

```json
{
  "slug": "pres",
  "featured": true
}
```

### Link an example

`POST /api/apps/{slug}/examples`

Link an existing Droplet as a worked example of what the skill produces. The linked Droplet shows up on the skill's `/view/{slug}` page and in skill cards. Sets the example Droplet's `exampleOfSkill` to this skill's slug. **Library Admin only.** Returns 404 if the skill or example Droplet does not exist.

**Parameters**

- **`slug`** _(string · path · required)_ — The skill slug.
- **`exampleSlug`** _(string · body · required)_ — The example Droplet slug to link.

**CLI**

```bash
drop skills admin examples add pres --example-slug q3-board-deck
```

**MCP**

```json
{
  "tool": "drop_skill_link_example",
  "arguments": {
    "slug": "pres",
    "exampleSlug": "q3-board-deck"
  }
}
```

**HTTP**

```bash
curl -X POST 'https://drop.himarley.ai/api/apps/pres/examples' \
  -H "Authorization: Bearer $DROP_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"exampleSlug":"q3-board-deck"}'
```

**Response** (200)

```json
{
  "linked": true,
  "exampleSlug": "q3-board-deck",
  "skillSlug": "pres"
}
```

### Unlink an example

`DELETE /api/apps/{slug}/examples`

Remove a Droplet as an example of this skill. The Droplet itself is preserved; only the `exampleOfSkill` pointer is cleared. **Library Admin only.** Idempotent — calling on a Droplet that isn't a current example still returns 200.

**Parameters**

- **`slug`** _(string · path · required)_ — The skill slug.
- **`exampleSlug`** _(string · query · required)_ — The example Droplet slug to unlink.

**CLI**

```bash
drop skills admin examples remove pres --example-slug q3-board-deck
```

**MCP**

```json
{
  "tool": "drop_skill_unlink_example",
  "arguments": {
    "slug": "pres",
    "exampleSlug": "q3-board-deck"
  }
}
```

**HTTP**

```bash
curl -X DELETE 'https://drop.himarley.ai/api/apps/pres/examples' \
  -H "Authorization: Bearer $DROP_TOKEN"
```

**Response** (200)

```json
{
  "unlinked": true,
  "exampleSlug": "q3-board-deck",
  "skillSlug": "pres"
}
```
