If you've been iterating on Claude skills and want a way to share them — with your team, with your future self, or with future Claude instances — this skill publishes them as stories on a Distro newslode. It produces a single artifact that serves two audiences: humans who want to read about what the skill does, and agents who want to install it programmatically.

distro-skill-publish takes a canonical SKILL.md, wraps it in a human-readable story (intro, features, install instructions, scope notes), embeds the SKILL.md verbatim in a four-backtick fenced code block, and files a draft on whatever Distro newslode you point it at. Future Claudes can retrieve the story via distro_content_to_markdown, extract the fenced block, and install the skill — while humans browsing the newslode get context, feature bullets, and install steps.

The always-draft default means nothing goes live without your review. You can publish from the Tiptap editor when ready, or ask this skill to flip the status.

What you'll need

To actually use this skill (after installing it), your Claude needs one connector turned on:

  • Distro Publisher MCP — to create the draft story on your newslode

If you're missing it, Claude will tell you when you try to use the skill. It's a one-time setup in your Claude settings.

What it does

  • Takes a canonical SKILL.md from your current conversation, a file on disk, or a previously published Distro story

  • Validates the frontmatter (checks for name: and description: fields)

  • Composes a six-section story: intro, runtime prerequisites, feature list, install instructions, the canonical SKILL.md in a four-backtick fenced block, scope notes, and a feedback line

  • Publishes as a draft on the newslode of your choice with a reader-friendly title ("Distro email ingest skill") and a short preview

  • Returns the Tiptap editor link so you can review before going live

  • Supports updates in place (no new stories for version bumps) via distro_content_update with significantUpdate: true

Install the skill

Ask Claude:

"Please fetch the distro-skill-publish skill from Distro Skills and give me a .skill file I can install."

Claude will pull this story, extract the SKILL.md from the fenced block below, and package it as distro-skill-publish.skill. The file will appear in your chat with a Save skill button — click it to install directly. That registers the skill with your Claude app so it shows up in your skills list and triggers on matching requests.

Requires the Distro Reader or Distro Publisher MCP connected so Claude can pull the story. While Distro Skills is private, this works for account holders with access. Public read access is coming.

Claude Code users: you have a direct path — ask Claude to drop the unzipped folder into ~/.claude/skills/distro-skill-publish/ and restart the session. No packaging step needed.

No Distro MCP connected? Copy the SKILL.md contents from the fenced block below into a file called SKILL.md inside a folder called distro-skill-publish, zip it (folder as zip root), and upload through Settings → Capabilities → Skills → Upload skill.

The skill source

This is the canonical SKILL.md:

---
name: distro-skill-publish
description: Use this skill whenever the user asks to publish, post, file, register, or upload a Claude skill (a SKILL.md file, a .skill package, or a skill the user has written or is iterating on) to a Distro newslode. Triggers on requests like "publish this skill to [newslode]", "file the [name] skill on Distro", "post this SKILL.md to my skill registry newslode", or any request that pairs a skill source file with a Distro publishing action. Publishes a unified story that serves both humans (intro, features, install instructions) and agents (canonical SKILL.md in a fenced code block, retrievable via distro_content_to_markdown). Always drafts by default.
---

# Distro skill-publish skill

Publish a Claude skill to a Distro newslode as a draft story, structured so that both humans reading the newslode and future Claude instances retrieving it can get what they need from the same artifact.

## Core design principle

**One story per skill, serving two audiences.**

The story has a human-readable intro and install guide at the top and bottom, with the canonical `SKILL.md` embedded verbatim in a four-backtick fenced code block in the middle. Humans get context; agents extract the SKILL.md. The four-backtick fence is important because SKILL.md files commonly contain their own triple-backtick blocks — the outer four-backtick fence prevents ambiguous parsing.

This replaces an earlier "body IS the SKILL.md, no wrappers" approach, which had two problems: (1) the HTML round-trip through Distro's Tiptap converter mangled YAML frontmatter (`---` sentinels got converted to `* * *`); (2) humans browsing the newslode saw a wall of YAML and technical prose rather than a readable intro. Wrapping the SKILL.md in a fenced code block protects it from the converter and keeps the rest of the story human-friendly.

## Default behavior

- **Status:** Always `draft` by default. The user can override by explicitly saying "publish live" or "go live immediately." After the draft is filed, the user can review in the Tiptap editor and then either publish it themselves or ask this skill to flip the status.
- **Newslode:** The user must specify. Do not default to a newslode — ask if not provided.

## Workflow

### Step 1 — Locate the skill source

The skill source might come from several places. In order of likelihood:

1. **The current conversation** — the user has been drafting/iterating on a SKILL.md, and the latest version is visible in context. Use that.
2. **A file on disk** — e.g., `/mnt/skills/user/some-skill/SKILL.md` (if the skill is installed in the user's Claude Desktop, it's mirrored here read-only) or `/home/claude/some-skill/SKILL.md`. Read it.
3. **A file the user uploaded** — e.g., `/mnt/user-data/uploads/SKILL.md` or a `.skill` package. Read it.
4. **A previously published story on another Distro newslode** — the user wants to republish or fork. Fetch via `distro_content_to_markdown`, then extract the fenced SKILL.md block (see extraction note at the bottom of this file).

If it's ambiguous, ask which source to use. Do not guess.

### Step 2 — Validate the SKILL.md

Before publishing, do a structural sanity check:

- Must start with YAML frontmatter delimited by `---` lines
- Frontmatter must contain a `name:` field (kebab-case skill identifier)
- Frontmatter must contain a `description:` field (the triggering text)
- Body must exist after the frontmatter

Extract for later use:
- `name:` value from frontmatter → used in folder names, install instructions, and the canonical title
- `description:` value → can inform the preview text

If any required piece is missing, flag it to the user before publishing. Don't silently publish broken skills.

### Step 3 — Resolve the destination newslode

If the user named the newslode by title (e.g., "Distro Skills"), call `distro_publication_list` to resolve it to a `publicationId`. (`publication_list` is the only tool that surfaces private newslodes.)

If the user gave an ID directly, use it.

If the user didn't specify a newslode at all, **ask**. Do not default to any particular newslode.

### Step 4 — Compose the story

The story has six sections in this order:

**1. Intro** — 2–3 paragraphs explaining what the skill does in plain language. Lead with the user problem, not the feature list. Name the skill in **bold** on first reference using its kebab-case identifier.

**2. What you'll need** — runtime prerequisites for *using* the skill (not installing it). If the skill calls MCP tools, name them — "Distro Publisher MCP" or "Gmail connector," using plain terms. Skip this section if the skill has no runtime prereqs beyond a vanilla Claude.

**3. What it does** — bulleted feature list, written for humans. Draw the material from the SKILL.md body but rewrite for reader-friendliness — the frontmatter `description:` field is keyword-optimized for triggering, not for reading.

**4. Install the skill** — use this exact structure:

> Ask Claude:
>
> > "Please fetch the [skill-name] skill from Distro Skills and give me a `.skill` file I can install."
>
> Claude will pull this story, extract the SKILL.md from the fenced block below, and package it as `[skill-name].skill`. The file will appear in your chat with a **Save skill** button — click it to install directly. That registers the skill with your Claude app so it shows up in your skills list and triggers on matching requests.
>
> *Requires the Distro Reader or Distro Publisher MCP connected so Claude can pull the story. While Distro Skills is private, this works for account holders with access. Public read access is coming.*
>
> **Claude Code users:** you have a direct path — ask Claude to drop the unzipped folder into `~/.claude/skills/[skill-name]/` and restart the session. No packaging step needed.
>
> **No Distro MCP connected?** Copy the SKILL.md contents from the fenced block below into a file called `SKILL.md` inside a folder called `[skill-name]`, zip it (folder as zip root), and upload through Settings → Capabilities → Skills → *Upload skill*.

**Important:** the ".skill + Save skill button" path is the cleanest one-click install on Claude Desktop and Claude.ai. Writes to `/mnt/skills/user/` from a chat sandbox do NOT register as installed skills — the file may appear in the mirror but won't be indexed by the app, won't show in the Settings UI, and won't trigger in future sessions. The `.skill` package flowing through `present_files` is what surfaces Claude Desktop's native "Save skill" affordance; that's the reliable install path for non-Code clients.

**5. The skill source** — heading says exactly "The skill source" so agents can locate it. Preceded by one sentence: "This is the canonical `SKILL.md`:". Then a four-backtick fenced code block containing the raw SKILL.md verbatim, with `markdown` as the language hint. The extra backticks matter because SKILL.md files often contain their own triple-backtick code blocks (shell examples, code snippets) — a four-backtick outer fence prevents those from prematurely closing the wrapper.

Nothing else inside the fence. No commentary, no wrappers, no sentinels — just the raw SKILL.md. The fence itself is the wrapper.

Note: Distro's Tiptap converter may normalize a four-backtick fence down to three backticks if the inner content contains no triple-backtick blocks. This is safe — without inner triple-backticks, a three-backtick fence can't be prematurely closed. The extraction-side regex (documented below) tolerates both fence widths.

**6. When to use / When not to use** — short bullet lists, written for humans. Restates the scope from the SKILL.md body but in reader-friendly language.

**7. Feedback** — one line: "This is v<version>. Edge cases or suggestions → reply or ping [author]."

### Step 5 — Publish as draft

Call `distro_content_publish` with:
- `publicationId`: resolved from Step 3
- `title`: human-readable form of the skill name. Examples:
  - `distro-email-ingest` → "Distro email ingest skill"
  - `distro-link-post` → "Distro link post skill"
  - `brads-voice` → "Brad's voice skill"
  The word "skill" at the end aids feed readability. If the user gives a preferred title, use that.
- `content`: the full composed story from Step 4, as markdown
- `contentFormat: "markdown"` — explicit, not auto-detected
- `preview`: 150–250 chars. Reader-friendly summary of what the skill does. Do not lead with version numbers — lead with the user-facing value.
- `author`: the user's name or the authenticated default
- `status: "draft"` — always draft unless user explicitly says go live

Capture the returned `contentId` for the edit link.

### Step 6 — Return the edit link and next steps

Tell the user concisely:
- That the draft was filed (content ID, newslode name)
- The Tiptap editor URL: `https://app.distro.media/stories/<contentId>`
- That it's a draft — they can review before publishing, or tell you to flip status to live

## Updating an existing skill story

If the user asks to update a skill already published on a newslode (e.g., "bump distro-email-ingest to v1.1.0 with this change"):

1. Locate the existing story via `distro_content_list` filtered to the destination newslode. Match by title or by searching for the kebab-case `name:` in the fenced block.
2. Call `distro_content_update` with:
   - `contentId`: the existing story's ID
   - `content`: the updated full story body
   - `contentFormat: "markdown"`
   - `preview`: updated if needed
   - `significantUpdate: true` — sets `contentUpdatedAt` so readers see the update timestamp
   - Leave `status` unchanged unless the user asks to flip it

Do **not** create a new story for an updated version of the same skill — that fragments the registry. One canonical story per skill; update the body in place.

## Extracting the SKILL.md from a published story

If a future Claude is installing a skill from a Distro story (the "easy way" install path), the workflow is:

1. `distro_content_to_markdown` on the contentId → returns the full story body
2. Find the first outer fenced code block with `markdown` as the language hint. **The fence may be three or four backticks** — Distro's Tiptap converter normalizes fence length based on whether the inner content contains triple-backtick blocks. Use a regex that tolerates both.
3. Extract everything between that fence and the matching closing fence (same backtick count)
4. The extracted content is the canonical SKILL.md, ready to write to `~/.claude/skills/<n>/SKILL.md`
5. Parse the frontmatter `name:` field to determine the folder name

A resilient Python regex that works for both cases:

```python
re.compile(r"^(`{3,})(markdown)?\n(.*?)\n\1\s*$", re.DOTALL | re.MULTILINE)
```

The captured content (group 3) is the SKILL.md. The backreference `\1` ensures the closing fence has the same length as the opening fence.

## Distro tool quirks to remember

- `distro_content_publish` and `distro_content_update` both accept `contentFormat: "markdown"`. Always pass it explicitly rather than relying on `"auto"` — the YAML frontmatter inside the fenced block could confuse the auto-detector.
- `distro_publication_list` is the only tool that surfaces private newslodes.
- `distro_content_to_markdown` returns the story body as markdown. The four-backtick fence survives the HTML → markdown round-trip cleanly, but raw frontmatter at the top level of a story body does not — another reason the fence is essential.
- **Newly created publications may hit a permissions cache**: if the user just created a new newslode via `distro_publication_create` and a subsequent publish to it fails with "API key does not have access to this publication," the fix is to disconnect/reconnect the Distro MCP to force a fresh permissions fetch. Start a new chat after reconnecting.
- **`distro_content_delete` had a server-side bug as of April 2026** (returning "Cannot read properties of undefined (reading 'id')"). If a delete fails, don't loop — flag to the user and leave the story as a draft.

## What Claude can and cannot do for skill installation

- **Can:** draft the SKILL.md, package it as a `.skill` file via `skill-creator`'s `package_skill.py`, and present it via `present_files`. Claude Desktop's UI recognizes `.skill` files in chat and surfaces a one-click **Save skill** button — that's the cleanest install path for non-Code clients.
- **Cannot:** write directly into the user's installed skills registry by dropping files into `/mnt/skills/user/`. That path looks writable from inside the sandbox, but writes land in a sandbox-local overlay and are NOT indexed by Claude Desktop's skill engine. The files won't show in Settings → Capabilities → Skills and won't trigger in future sessions.
- **Can (Claude Code only):** write directly to `~/.claude/skills/` on the user's actual filesystem. Claude Code's skill engine reads that path at session start, so a write + session restart is a real install.

In install instructions, lead with the `.skill` + Save skill path for Claude Desktop and Claude.ai users. Mention the direct filesystem path only for Claude Code. Do not claim any form of "automatic install" for Claude Desktop — the Save skill button is still a user click, even if it's a simpler click than going through Settings.

## Examples

### Example 1 — first publish of a new skill

**User:** "Publish the distro-email-ingest skill we just drafted to Distro Skills."

**Claude:**
1. Uses the SKILL.md draft from the current conversation context
2. Validates: has frontmatter, `name: distro-email-ingest`, has `description:`, has body ✓
3. Resolves "Distro Skills" → `publicationId: 114`
4. Composes the six-section story (intro, prereqs, features, install, source in four-backtick fence, when to use / not use, feedback)
5. Title: "Distro email ingest skill"; preview: short human summary of value
6. `distro_content_publish` with `contentFormat: "markdown"`, `status: "draft"`
7. Returns content ID, edit link, notes draft status

### Example 2 — user explicitly wants live

**User:** "File the distro-link-post skill on Distro Skills — publish it live, not draft."

**Claude:** Same workflow, but `status: "published"`. Confirms in the response that it's live.

### Example 3 — update existing skill

**User:** "Update the distro-email-ingest skill story on Distro Skills — here's v1.1.0 with the new image-upload tweaks."

**Claude:**
1. `distro_content_list` on pub 114, finds existing story
2. Composes the updated full story (intro, prereqs, etc. — not just a SKILL.md swap) with the new SKILL.md in the fenced block
3. `distro_content_update` with `significantUpdate: true`
4. Returns edit link; notes what changed

## When not to use this skill

- **Publishing a regular story** (article, essay, newsletter) to a newslode — just use `distro_content_publish` directly.
- **Publishing a link-style post** (a URL with a hot take) — use `distro-link-post` instead.
- **Publishing an ingested email as a story** — use `distro-email-ingest` instead.
- **Creating the newslode itself** — use `distro_publication_create` directly; this skill only publishes stories into existing newslodes.

When to use

  • You've built a Claude skill and want to share it with collaborators or future Claude sessions

  • You want one artifact that works as both documentation (for humans) and an install source (for agents)

  • You want version history, draft review, and an edit URL — all the things a newslode already gives you

When not to use

  • You want to publish a regular essay or article → just use distro_content_publish directly; no skill publishing machinery needed

  • You're posting a link with a hot take → use distro-link-post instead

  • You're ingesting an email as a story → use distro-email-ingest instead

  • You need to create the newslode itself → use distro_publication_create directly; this skill only files stories into existing newslodes

Feedback

This is v1.2.0. Edge cases or suggestions → reply or ping Brad.