# Guide: publish your AI's skills (https://systemhub.com/docs/guides/publishing-ai-skills)

> Part of systemHUB Docs · Connect: Settings → AI Gateway in systemHUB · Auth: OAuth (scoping is workspace-level today — see Getting started) · MCP tools: 48 · Full corpus: https://systemhub.com/llms-full.txt

Somewhere in your business, someone has taught an AI to do something well. They wrote it down — a skill file, a custom instruction set, an agent playbook, a prompt that finally worked — and saved it in a folder on their laptop. It runs beautifully. Nobody else knows it exists.

That is the same problem systemHUB exists to solve for processes, arriving in new clothing. A skill is a procedure a machine runs. It has an owner, it goes stale, it should be reviewable, and it is worth nothing to the business while it lives in one person's home directory.

This guide covers the pattern for giving those skills a visible home: an index grouped by business function, a page per skill with the file actually attached, and a hard split between the skills you can share and the ones you can't. Request bodies are **abridged and illustrative** — full contracts in the [tool reference](/docs/tool-reference).

## Which section should skills live in?

Any of the three works, and consistency matters more than the choice. A defensible default is **Policies**: a skill is a standard your team agrees to use, and the Policies section carries the agreement machinery (`get_document_agreement_status`) if you later want to know who has actually adopted it.

Examples below use `create_policy` / `create_policy_folder` / `publish_policy`. The Systems and Trainings equivalents (`create_system`, `create_training`, and their folder and publish tools) take the same shape — pick one section and put every skill there.

## 1. The index page

One page that answers "what can our AI already do?" — the thing a new starter or a curious manager reads first.

**Group by business function, not by technology.** Sales, Marketing, Finance, Client Delivery, Operations. Nobody browses by "things that call an API"; they browse by the part of the business they work in.

**Describe each skill by its outcome, not its mechanics.** This is the difference between an index people use and one they skim past:

| Don't write | Write |
|---|---|
| "Queries the CRM API, joins to the billing export, writes a formatted sheet." | "Turns a month of raw sales data into the board pack — about ten minutes instead of half a day." |
| "Multi-step agent with web search and a scoring rubric." | "Researches a prospect before a first call and tells you what they actually care about." |
| "Parses transcripts and extracts action items." | "Reads a client call and writes the follow-up email, with nothing missed." |

The reader is deciding whether they need this thing, not maintaining it. Lead with the hours saved or the job done.

```
→ create_policy_folder { "title": "AI Skills" }
→ create_policy {
    "parent": "8c1f4a20-…",
    "title": "AI Skills — what our AI can already do",
    "description": "The index of skills our team has built for AI assistants: what each one does, who owns it, and how to install it.",
    "content": "<p><strong>Start here.</strong> Each skill below links to its own page, where you'll find the file itself and what you need before running it.</p><h3>Sales</h3><ul><li><a href=\"…\">Research a prospect before a first call</a> — 20 minutes of background in about two.</li></ul><h3>Finance</h3><ul><li><a href=\"…\">Build the monthly board pack</a> — half a day down to ten minutes.</li></ul>",
    "state": 1
  }
```

Build the index last, once the individual pages exist and you have their URLs — otherwise you write it twice.

## 2. A page per skill, with the file attached

**A page describing a skill is a brochure. A page carrying the file is something the reader can actually install.** This is the step that makes the difference, and it is one tool call.

Skill files are usually markdown, and `.md` is a supported attachment type — so they go up natively:

```
→ add_document_attachments {
    "documentId": "7d4f2a90-…",
    "files": [{ "fileUrl": "https://…/research-a-prospect.md", "fileName": "research-a-prospect.md" }]
  }
```

Prefer `fileUrl` over `contentBase64` — see [Authoring content](/docs/concepts/authoring-content#attachments-use-fileurl-not-base64) for why, and for the full supported-type list.

### The multi-file problem, stated honestly

Plenty of skills aren't one file. They're a folder: an instruction file, a helper script, a couple of reference documents. That doesn't round-trip cleanly today:

- **`.zip` is rejected** (`skipped`, `reason: "invalid_type"`), so you can't attach the folder as an archive.
- **Only document types attach** — PDF, Office formats, `.txt`, `.csv`, `.rtf`, `.md`. A `.py` or `.sh` helper won't upload.

Three workable options, best first:

1. **Flatten to a single markdown file** where you can — inline short scripts in fenced code blocks. Most skills survive this fine, and the result is more readable anyway.
2. **Attach the instruction file, link the rest.** Put the repository or Drive URL in the body for the code. The page still carries the part that matters most.
3. **Rename to `.txt`** for a stubborn helper file. It works, but the reader has to know to rename it back, so say so on the page.

### What each skill page should carry

Follow the same discipline as any [good system](/docs/concepts/authoring-content#the-anatomy-of-a-good-system-the-systemology-house-format) — trigger, steps, definition of done — plus four things specific to skills:

- **What it needs before it runs.** Accounts, logins, access, other tools it calls. This is the single most common reason a skill works for its author and fails for everyone else.
- **How to install it.** One or two lines, and name the AI client — "drop this in your `.claude/skills/` folder", "paste into custom instructions". Different clients, different answers.
- **What it deliberately doesn't do.** The limits the author already knows about, so nobody rediscovers them in front of a client.
- **An owner and a review date.** Skills rot faster than SOPs, because the tools they call keep changing underneath them.

Yellow-highlight anything the reader must supply themselves rather than inventing it:

```html
<p><mark class="marker-yellow">[Add your own API key here — the skill will not run without it]</mark></p>
```

First drafts go up as `state: 1` (ORANGE, needs review), same as any other document.

## 3. Two folders, not one

This is the part most teams skip, and it is the part that bites.

Split your skills into **business-wired** and **generic**, in two separate folders, from the first document you create:

```
AI Skills
├── Internal          ← business-wired. Documented, never shared outside.
└── Shareable         ← genuinely generic. Safe to hand to anyone.
```

**Business-wired** means the skill carries identifiers from your business: CRM owner IDs, project or board IDs, spreadsheet IDs, internal file paths, account aliases, named staff, your pricing, your client list. These skills are usually the good ones — they're valuable *because* they're wired into your actual systems.

**Generic** means it would work unchanged for a business you've never met.

> **Be blunt with yourself about the ratio: the genuinely generic set is usually a small minority.** Teams tend to assume it's about half. In practice, if a skill is useful enough that people run it weekly, it is probably wired into something specific. Expect closer to one in five, and treat "shareable" as the exception you deliberately build, not the default you assume.

### Why this is a security decision, not a tidiness one

Two systemHUB behaviours make the folder split consequential:

- **Attachment download URLs are public and unauthenticated.** The `downloadUrl` returned for an attachment is a plain object anyone with the link can fetch, with no login. The path is unguessable, but that is obscurity, not access control — treat a leaked URL as permanent public read. Full detail in [Authoring content](/docs/concepts/authoring-content#attachments-use-fileurl-not-base64).
- **A share link serves the document to anyone who has it** — no login, and you cannot un-share it selectively. See [Sharing & links](/docs/concepts/sharing-and-links).

So the moment you attach a business-wired skill file, you've created a public URL to a document containing your internal identifiers. That's fine while the page stays inside your workspace. It stops being fine the first time someone shares the page "just to show them what we built".

Decide the folder up front, and adopt one rule: **generate share links only from the Shareable folder.** Never on a document in Internal, not even briefly.

> ⚠️ **The `note` field is not a private scratchpad.** It renders at the bottom of the document and travels with a share link, same as the body. Internal context — which client this was built for, which credentials it uses, what still needs fixing — belongs in your task tracker, not in `note`.

### The test

*Could you hand this file to a competitor, unchanged, with no harm done?*

If you have to think about it, it's business-wired. Put it in Internal.

## 4. Publish and index

```
→ publish_policy { "id": "7d4f2a90-…", "title": "v1.0 - First published" }
```

Then write the index page (step 1) linking to each skill, and you're done.

## Keeping it alive

- **Set a `reviewDate`.** Skills break silently when an upstream tool changes. A quarterly review is not excessive.
- **Version by filename, not by re-upload.** Attachments cannot be replaced — uploading a file whose name already exists returns `skipped` with `reason: "duplicate"` and **leaves the old content in place**. It is not an error, and nothing warns you that readers are still downloading v1. Name the new file `research-a-prospect-v2.md`, or delete the old attachment in the app first.
- **Retire, don't delete.** The MCP can't delete anyway. Move superseded skills to `state: 4` (PURPLE, archived) so the index stays honest.
- **Tag across the folder split** with `add_document_tags` — by the tool a skill drives, or the role that uses it — so people can find things the folder structure doesn't express.

## The checklist

- [ ] One section chosen for skills, used consistently
- [ ] Two folders from day one: business-wired vs genuinely generic
- [ ] Every skill page carries the **file**, not just a description of it
- [ ] `fileUrl` used rather than base64; multi-file skills flattened or linked
- [ ] Each page states what it needs, how to install it, and what it doesn't do
- [ ] Owner and `reviewDate` set on every skill
- [ ] Share links generated **only** from the shareable folder
- [ ] No internal context in `note` — it travels with the document
- [ ] Index page written last, grouped by business function, described by outcome
