Skills System
Skills are on-demand knowledge documents the agent can load when needed. They follow a progressive disclosure pattern to minimize token usage and are compatible with the agentskills.io open standard.
All skills live in ~/.fabric/skills/ — the primary directory and source of truth. On fresh install, bundled skills are copied from the repo. Hub-installed and agent-created skills also go here. The agent can modify or delete any skill.
You can also point Fabric at external skill directories — additional folders scanned alongside the local one. See External Skill Directories below.
See also:
Validating Skills and Contracts
fabric skills validate performs a read-only check of SKILL.md and the
optional skill.contract.yaml governance contract. Pass an installed skill
name, a skill directory, a directory containing multiple skills, or no target
to check every skill in the active profile:
fabric skills validate github-pr-workflow
fabric skills validate ./skills/my-category/my-skill
fabric skills validate # active profile
fabric skills validate --require-contract # reject missing contracts
fabric skills validate --json # deterministic automation output
Results are classified as verified, legacy, or invalid. Legacy skills
without a contract remain usable during migration unless
--require-contract is set. A present contract is always checked strictly;
invalid YAML, conflicting identity, unsafe evaluation paths, or a missing evaluation
suite produces a non-zero exit status. See Creating Skills
for the canonical contract format.
Starting with a blank slate
By default every profile is seeded with the bundled skill catalog, and each fabric update adds any newly bundled skills. If you want a profile with no bundled skills — and that stays empty across updates — you have two paths:
At install time (applies to the default ~/.fabric profile):
curl -fsSL https://raw.githubusercontent.com/ObliviousOdin/fabric/main/scripts/install.sh | bash -s -- --no-skills
At profile-create time (named profiles):
fabric profile create research --no-skills
On an already-installed profile (default or named), toggle it at runtime:
fabric skills opt-out # stop future seeding — nothing on disk is touched
fabric skills opt-out --remove # also delete UNMODIFIED bundled skills (confirms first)
fabric skills opt-in --sync # undo: remove the marker and re-seed now
All three paths write a .no-bundled-skills marker into the profile directory. While the marker is present, the installer, fabric update, and any skill sync all skip bundled-skill seeding for that profile. Delete the marker (or run fabric skills opt-in) to re-enable.
fabric skills opt-out only stops future seeding — it never deletes anything already on disk. The optional --remove flag deletes bundled skills only when they are unmodified (byte-identical to the version Fabric installed). Skills you have edited, skills installed from the hub, and skills you wrote yourself are always kept.
Using Skills
Every installed skill is automatically available as a slash command:
# In the CLI or any messaging platform:
/gif-search funny cats
/axolotl help me fine-tune Llama 3 on my dataset
/github-pr-workflow create a PR for the auth refactor
/plan design a rollout for migrating our auth provider
# Just the skill name loads it and lets the agent ask what you need:
/excalidraw
Stacking multiple skills in one command
You can invoke several skills in a single message by chaining slash commands
at the start — every leading /skill token (up to 5) is loaded, and the rest
becomes your instruction:
/github-pr-workflow /test-driven-development fix issue #123 and open a PR
Parsing stops at the first token that isn't an installed skill, so arguments
that happen to start with / (like file paths) are never swallowed:
/ocr-and-documents /tmp/scan.pdf extract the tables # loads one skill; /tmp/scan.pdf is the argument
For combinations you use repeatedly, prefer a skill bundle — same effect under one short command.
The bundled plan skill is a good example. Running /plan [request] loads the skill's instructions, telling Fabric to inspect context if needed, write a markdown implementation plan instead of executing the task, and save the result under .fabric/plans/ relative to the active workspace/backend working directory.
You can also interact with skills through natural conversation:
fabric chat --toolsets skills -q "What skills do you have?"
fabric chat --toolsets skills -q "Show me the axolotl skill"
Learning a skill from sources (/learn)
/learn is the fast way to turn something you already know — or a pile of
reference material — into a reusable skill, without hand-writing the
SKILL.md. It is open-ended: point it at anything you can describe and the
agent gathers the material with a source-reading tool allowlist, then authors a skill
that follows the house authoring standards (≤60-char
description, the standard section order, Fabric-tool framing, no invented
commands).
# A local SDK or doc directory — read with read_file / search_files
/learn the REST client in ~/projects/acme-sdk, focus on auth + pagination
# An online doc page — fetched with web_extract
/learn https://docs.example.com/api/quickstart
# The workflow you just walked the agent through in this conversation
/learn how I just deployed the staging server
# Pasted notes / a described procedure
/learn filing an expense: open the portal, New > Expense, attach the receipt, submit
Because the live agent does the sourcing, /learn works the same in the CLI,
the messaging gateway, the TUI, and the dashboard — and on any terminal backend
(local, Docker, remote), since there is no separate ingestion engine. In the
dashboard, the Skills page has a Learn a skill button that opens a panel
with a directory field, a URL field, and an open-ended text box; it composes a
/learn request and runs it in chat.
There is no model-tool footprint: /learn builds a standards-guided prompt and
hands it to the agent as a normal turn. The agent submits the result with the
skill_manage tool as a quarantined draft outside the active skill tree. Review
it with /skills diff <id>, promote it with /skills approve <id>, or discard
it with /skills reject <id>. This review boundary always applies to /learn,
even when the optional foreground write-approval gate
is off.
/learn authoring is intentionally a single-turn sandbox. It can read files,
search/extract web sources, inspect conversations and existing skills, and use
skill_manage; terminal commands, generic file writers, code execution,
delegation, memory writes, MCP/plugin tools, and dynamic Tool Search execution
are denied at dispatch. If a required source is missing, the run stops without
writing and asks you to start a fresh /learn ... request containing that
source instead of carrying authoring authority into an ordinary follow-up turn.
As defense in depth, any skill_manage write attempted in the immediately
following chat turn is still routed to quarantine rather than the active tree.
Progressive Disclosure
Skills use a token-efficient loading pattern:
Level 0: prompt taxonomy → category counts only (bounded)
Level 1: skills_list(query="task") → ranked candidates (default max 8)
Level 2: skill_view(name) → full content + metadata (varies)
Level 3: skill_view(name, path) → one supporting file (varies)
For catalogs of 32 skills or fewer, Fabric keeps the compact name/description
index inline. Larger catalogs automatically switch to a top-level taxonomy;
the current 72-skill bundled catalog renders to about 372 bytes
instead of embedding every description. skills_list(query=...) ranks locally
and deterministically, gives verified contract triggers extra weight, and
removes a candidate when its declared non-trigger matches. The agent only
loads the strongest relevant candidate or smallest compatible stack.
Runtime permission leases
A verified skill.contract.yaml can constrain the existing tools while that
skill is active. Leases are process-local and turn-scoped; they never add tools
or change the cached system prompt. Slash commands and bundles bind to the next
turn, while session preloads receive a fresh lease and budget on every turn.
Roll enforcement out from config.yaml:
skills:
permissions:
mode: observe # observe | enforce_learned | enforce_all
observe(default) records privacy-safe decision/gap codes but never blocks.enforce_learnedenforces learned and unknown-provenance skills while observing distributed/external skills.enforce_allenforces verified contracts for every skill provenance.
In an enforced population, legacy or invalid contracts fail closed at load.
Verified leases enforce declared toolsets, tool-call and wall-clock budgets,
resolved workspace/skill/temp file containment, and exact hosts/methods
for inspectable web_extract and browser_navigate calls. Stacked approvals
use Fabric's normal approval UI; a prohibition always wins.
Raw terminal commands, arbitrary execute_code, web_search targets, and
navigation caused indirectly by browser clicks/typing cannot be safely inferred
from structured arguments. When their toolset is declared, these calls are
allowed and marked with stable observation-gap codes; existing sandbox,
network, and approval controls still apply. Context-token and secret-use
declarations are recorded for inspection, but runtime attribution is not
claimed as enforced.
Local skill receipts
Fabric records bounded, profile-local activation metadata so skill quality can
be measured without collecting conversation content. The journal lives at
~/.fabric/skills/.governance/skill-receipts.jsonl; it contains skill/version/
digest identity, selection source, governance lane, and HMAC-pseudonymous
session/task/turn references. Prompts, responses, tool arguments, file content,
error text, and secrets are not valid receipt fields, and nothing is sent over
the network.
skills:
receipts:
enabled: true
max_bytes: 1048576
max_files: 4
Slash commands, stacks, bundles, preloads, scheduled skills, and skill_view
write activation receipts. Terminal outcomes are recorded only through the
explicit structured outcome API; Fabric does not guess that a preloaded or
multi-skill turn belongs to one activation. This keeps completion coverage
separate from routing precision until an evaluator supplies an explicit
routing_relevant label.
SKILL.md Format
---
name: my-skill
description: Brief description of what this skill does
version: 1.0.0
platforms: [macos, linux] # Optional — restrict to specific OS platforms
metadata:
fabric:
tags: [python, automation]
category: devops
fallback_for_toolsets: [web] # Optional — conditional activation (see below)
requires_toolsets: [terminal] # Optional — conditional activation (see below)
config: # Optional — config.yaml settings
- key: my.setting
description: "What this controls"
default: "value"
prompt: "Prompt for setup"
---
# Skill Title
## When to Use
Trigger conditions for this skill.
## Procedure
1. Step one
2. Step two
## Pitfalls
- Known failure modes and fixes
## Verification
How to confirm it worked.
Platform-Specific Skills
Skills can restrict themselves to specific operating systems using the platforms field:
| Value | Matches |
|---|---|
macos | macOS (Darwin) |
linux | Linux |
windows | Windows |
platforms: [macos] # macOS only (e.g., iMessage, Apple Reminders, FindMy)
platforms: [macos, linux] # macOS and Linux
When set, the skill is automatically hidden from the system prompt, skills_list(), and slash commands on incompatible platforms. If omitted, the skill loads on all platforms.
Skill output and media delivery
When a skill response (or any agent response) includes a bare absolute path to a media file — for example /home/user/screenshots/diagram.png — the gateway auto-detects it, strips it from the visible text, and delivers the file natively to the user's chat (Telegram photo, Discord attachment, etc.) instead of leaving the raw path in the message.
For audio specifically, the [[audio_as_voice]] directive promotes audio files to native voice-message bubbles on platforms that support them (Telegram, WhatsApp).
Forcing document-style delivery: [[as_document]]
Sometimes you want the opposite of inline preview: you want the file delivered as a downloadable attachment, not a re-compressed image bubble. The classic example is a high-resolution screenshot or chart — Telegram's sendPhoto recompresses it to ~200 KB at 1280 px, destroying readability. A 1-2 MB PNG sent via sendDocument keeps the original bytes intact.
If a response (or any text inside it — typically the last line) contains the literal directive [[as_document]], every media path extracted from that response is delivered as a document/file attachment rather than an image bubble:
Here is your rendered chart:
/home/user/.fabric/cache/chart-q4-2025.png
[[as_document]]
The directive is stripped before delivery, so users never see it. Granularity is intentionally all-or-nothing per response: emit [[as_document]] once and every image path in the same response is delivered as a document. This mirrors the scope of [[audio_as_voice]].
Use it from a skill when:
- You produce screenshots or charts the user needs as files (for editing in another tool, archiving, sharing intact).
- The default lossy preview would obscure detail (small text, pixel-accurate diagrams, color-sensitive renders).
Platforms without a separate document path (e.g. SMS) fall back to whatever attachment mechanism they have.
Conditional Activation (Fallback Skills)
Skills can automatically show or hide themselves based on which tools are available in the current session. This is most useful for fallback skills — free or local alternatives that should only appear when a premium tool is unavailable.
metadata:
fabric:
fallback_for_toolsets: [web] # Show ONLY when these toolsets are unavailable
requires_toolsets: [terminal] # Show ONLY when these toolsets are available
fallback_for_tools: [web_search] # Show ONLY when these specific tools are unavailable
requires_tools: [terminal] # Show ONLY when these specific tools are available
| Field | Behavior |
|---|---|
fallback_for_toolsets | Skill is hidden when the listed toolsets are available. Shown when they're missing. |
fallback_for_tools | Same, but checks individual tools instead of toolsets. |
requires_toolsets | Skill is hidden when the listed toolsets are unavailable. Shown when they're present. |
requires_tools | Same, but checks individual tools. |
Example: The built-in duckduckgo-search skill uses fallback_for_toolsets: [web]. When you have FIRECRAWL_API_KEY set, the web toolset is available and the agent uses web_search — the DuckDuckGo skill stays hidden. If the API key is missing, the web toolset is unavailable and the DuckDuckGo skill automatically appears as a fallback.
Skills without any conditional fields behave exactly as before — they're always shown.
Secure Setup on Load
Skills can declare required environment variables without disappearing from discovery:
required_environment_variables:
- name: TENOR_API_KEY
prompt: Tenor API key
help: Get a key from https://developers.google.com/tenor
required_for: full functionality
When a missing value is encountered, Fabric asks for it securely only when the skill is actually loaded in the local CLI. You can skip setup and keep using the skill. Messaging surfaces never ask for secrets in chat — they tell you to use fabric setup or ~/.fabric/.env locally instead.
Once set, declared env vars are automatically passed through to execute_code and terminal sandboxes — the skill's scripts can use $TENOR_API_KEY directly. For non-skill env vars, use the terminal.env_passthrough config option. See Environment Variable Passthrough for details.
Skill Config Settings
Skills can also declare non-secret config settings (paths, preferences) stored in config.yaml:
metadata:
fabric:
config:
- key: myplugin.path
description: Path to the plugin data directory
default: "~/myplugin-data"
prompt: Plugin data directory path
Settings are stored under skills.config in your config.yaml. fabric config migrate prompts for unconfigured settings, and fabric config show displays them. When a skill loads, its resolved config values are injected into the context so the agent knows the configured values automatically.
See Skill Settings and Creating Skills — Config Settings for details.
Skill Directory Structure
~/.fabric/skills/ # Single source of truth
├── mlops/ # Category directory
│ ├── axolotl/
│ │ ├── SKILL.md # Main instructions (required)
│ │ ├── references/ # Additional docs
│ │ ├── templates/ # Output formats
│ │ ├── scripts/ # Helper scripts callable from the skill
│ │ └── assets/ # Supplementary files
│ └── vllm/
│ └── SKILL.md
├── devops/
│ └── deploy-k8s/ # Agent-created skill
│ ├── SKILL.md
│ └── references/
├── .hub/ # Skills Hub state
│ ├── lock.json
│ ├── quarantine/
│ └── audit.log
└── .bundled_manifest # Tracks seeded bundled skills
External Skill Directories
If you maintain skills outside of Fabric — for example, a shared ~/.agents/skills/ directory used by multiple AI tools — you can tell Fabric to scan those directories too.
Add external_dirs under the skills section in ~/.fabric/config.yaml:
skills:
external_dirs:
- ~/.agents/skills
- /home/shared/team-skills
- ${SKILLS_REPO}/skills
Paths support ~ expansion and ${VAR} environment variable substitution.
How it works
- Create locally, update in place: New agent-created skills are written to
~/.fabric/skills/. Existing skills are modified where they are found, including skills underexternal_dirs, when the agent usesskill_manageactions such aspatch,edit,write_file,remove_file, ordelete. - External dirs are not a write-protection boundary: If an external skill directory is writable by the Fabric process, agent-managed skill updates can change files in that directory. Use filesystem permissions or a separate profile/toolset setup if shared external skills must stay read-only.
- Local precedence: If the same skill name exists in both the local dir and an external dir, the local version wins.
- Full integration: External skills appear in the system prompt index,
skills_list,skill_view, and as/skill-nameslash commands — no different from local skills. - Non-existent paths are silently skipped: If a configured directory doesn't exist, Fabric ignores it without errors. Useful for optional shared directories that may not be present on every machine.
Example
~/.fabric/skills/ # Local (primary, read-write)
├── devops/deploy-k8s/
│ └── SKILL.md
└── mlops/axolotl/
└── SKILL.md
~/.agents/skills/ # External (shared, mutable if writable)
├── my-custom-workflow/
│ └── SKILL.md
└── team-conventions/
└── SKILL.md
All four skills appear in your skill index. If you create a new skill called my-custom-workflow locally, it shadows the external version.
Skill Bundles
Skill bundles are tiny YAML files that group several skills under a single slash command. When you run /<bundle-name>, every skill listed in the bundle loads at once — useful when a particular task always benefits from the same set of skills together.
Quick example
# Create a bundle for backend feature work
fabric bundles create backend-dev \
--skill github-code-review \
--skill test-driven-development \
--skill github-pr-workflow \
-d "Backend feature work — review, test, PR workflow"
Then in the CLI or any gateway platform:
/backend-dev refactor the auth middleware
The agent receives all three skills loaded into one user message, with any text after the slash command attached as a user instruction.
YAML schema
Bundles live in ~/.fabric/skill-bundles/<slug>.yaml and look like this:
name: backend-dev
description: Backend feature work — review, test, PR workflow.
skills:
- github-code-review
- test-driven-development
- github-pr-workflow
instruction: |
Always start by writing failing tests, then implement.
Open the PR through the standard workflow with co-author tags.
Fields:
name(optional — defaults to the filename stem) — the bundle's display name. Normalized to a hyphen slug for the slash command (Backend Dev→/backend-dev).description(optional) — short text shown in/bundlesandfabric bundles list.skills(required, non-empty list) — skill names or paths relative to your skills directory. Use the same identifier you'd pass to/<skill-name>.instruction(optional) — extra guidance prepended to the loaded skill content. Useful for codifying "how we always use these together."
Managing bundles
# List all installed bundles
fabric bundles list
# Inspect one bundle
fabric bundles show backend-dev
# Create a bundle interactively (omit --skill flags to enter them one per line)
fabric bundles create research
# Overwrite an existing bundle
fabric bundles create backend-dev --skill ... --force
# Delete a bundle
fabric bundles delete backend-dev
# Re-scan ~/.fabric/skill-bundles/ and report changes
fabric bundles reload
From inside a chat session, /bundles lists every installed bundle and its skills.
Behavior
- Bundles take precedence over individual skills when slugs collide. If you name a bundle
researchand you also have a skill calledresearch,/researchinvokes the bundle. This is intentional — you opted into the bundle by naming it. - Missing skills are skipped, not fatal. If a bundle lists
skill-fooand you haven't installed it, the bundle still loads the skills that do resolve, and the agent gets a note listing what was skipped. - Bundles work in every surface — interactive CLI, TUI, dashboard chat, and every gateway platform (Telegram, Discord, Slack, …) — because dispatch is centralized in the same place as individual skill commands.
- Bundles do not invalidate the prompt cache. They generate a fresh user message at invocation time, the same way
/<skill-name>does — no system prompt mutation.
When bundles beat installing each skill manually
Use a bundle when:
- You always pair the same skills for a recurring task (
/backend-dev,/release-prep,/incident-response). - You want a one-character-shorter mental model than typing several
/skillinvocations in a row. - You want to ship a team-wide "task profile" by checking the bundle YAML into a shared dotfiles repo and symlinking it into
~/.fabric/skill-bundles/.
A bundle is just a YAML alias — it doesn't install skills for you. The skills themselves must already be present (in ~/.fabric/skills/ or an external skill directory). Otherwise the bundle invocation just skips the missing ones.
Agent-Managed Skills (skill_manage tool)
The agent can create, update, and delete its own skills via the skill_manage tool. This is the agent's procedural memory — when it figures out a non-trivial workflow, it saves the approach as a skill for future reuse.
Skills and memory work together in the self-improvement loop: memory stores
small durable facts that should always be in context, while skills store longer
procedures that should load only when relevant. Background review and /learn
changes always enter quarantine as drafts and require explicit promotion. The
optional write-approval gate below extends that review boundary to ordinary
foreground skill edits as well.
When the Agent Creates Skills
- After completing a complex task (5+ tool calls) successfully
- When it hit errors or dead ends and found the working path
- When the user corrected its approach
- When it discovered a non-trivial workflow
Actions
| Action | Use for | Key params |
|---|---|---|
create | New skill from scratch | name, content (full SKILL.md), optional category |
patch | Targeted fixes (preferred) | name, old_string, new_string |
edit | Major structural rewrites | name, content (full SKILL.md replacement) |
delete | Remove a skill entirely | name |
write_file | Add/update supporting files | name, file_path, file_content |
remove_file | Remove a supporting file | name, file_path |
The patch action is preferred for updates — it's more token-efficient than edit because only the changed text appears in the tool call.
Gating agent skill writes (skills.write_approval)
By default, ordinary foreground skill_manage writes land immediately.
Background self-improvement review and /learn writes are different: they
always stage outside the active tree until you explicitly promote them. To
require the same approval step for every foreground skill write, turn on the
write-approval gate:
skills:
write_approval: false # false = foreground writes directly | true = stage all writes
When write_approval: true, every skill_manage write (create / edit /
patch / delete / write_file / remove_file) is staged instead of committed —
a SKILL.md is too large to review inline, so staging applies regardless of
origin. With the setting off, background-review and /learn writes still stage;
only ordinary foreground writes bypass review.
Staged writes survive restarts under ~/.fabric/pending/skills/ and are
reviewed with the same familiar approve/deny flow as dangerous commands:
/skills pending # list staged skill writes + a one-line gist each
/skills diff <id> # full unified diff (best viewed in CLI or dashboard)
/skills approve <id> # promote it (or 'all'); activates next session
/skills approve <id> --now # promote + refresh shared skill routing immediately
/skills reject <id> # drop it (or 'all')
/skills rollback <tx-id> # exact retained rollback; activates next session
/skills rollback <tx-id> --now # rollback + refresh routing immediately
/skills approval on # turn the gate on (or 'off') and persist it
Promotion is one crash-safe transaction bound to the reviewed records,
contract, evaluation, and active-tree preconditions. If a manual edit lands
after review but before replay, Fabric preserves that edit, retains the draft,
and asks you to review again. The default activation boundary preserves the
current conversation's cached system prompt; --now is explicit because the
next request can lose its prompt-cache hit.
The review surface works in the interactive CLI and on messaging platforms
(diff output is truncated for chat bubbles — read the full diff on the CLI or
in the pending JSON file). Memory writes have the same gate under
memory.write_approval — see Controlling memory writes.
The separate
skills.guard_agent_createdsetting is a content scanner (dangerous-pattern heuristics), not an approval gate — the two are independent. See Guard on agent-created skill writes.
Skills Hub
Browse, search, install, and manage skills from online registries, skills.sh, direct well-known skill endpoints, and official optional skills.
Common commands
fabric skills browse # Browse all hub skills (official first)
fabric skills browse --source official # Browse only official optional skills
fabric skills search kubernetes # Search all sources
fabric skills search react --source skills-sh # Search the skills.sh directory
fabric skills search https://mintlify.com/docs --source well-known
fabric skills inspect openai/skills/k8s # Preview before installing
fabric skills install openai/skills/k8s # Install with security scan
fabric skills validate k8s # Validate SKILL.md and optional contract
fabric skills install official/security/1password
fabric skills install skills-sh/vercel-labs/json-render/json-render-react --force
fabric skills install well-known:https://mintlify.com/docs/.well-known/skills/mintlify
fabric skills install https://sharethis.chat/SKILL.md # Direct URL (single-file SKILL.md)
fabric skills install https://example.com/SKILL.md --name my-skill # Override name when frontmatter has none
fabric skills list --source hub # List hub-installed skills
fabric skills check # Check installed hub skills for upstream updates
fabric skills update # Reinstall hub skills with upstream changes when needed
fabric skills audit # Re-scan all hub skills for security
fabric skills gc # Recover/prune a bounded batch of transaction artifacts
fabric skills uninstall k8s # Remove a hub skill
fabric skills reset google-workspace # Un-stick a bundled skill from "user-modified" (see below)
fabric skills reset google-workspace --restore # Also restore the bundled version, deleting your local edits
fabric skills publish skills/my-skill --to github --repo owner/repo
fabric skills snapshot export setup.json # Export skill config
fabric skills tap add myorg/skills-repo # Add a custom GitHub source
Supported hub sources
| Source | Example | Notes |
|---|---|---|
official | official/security/1password | Optional skills shipped with Fabric. |
skills-sh | skills-sh/vercel-labs/agent-skills/vercel-react-best-practices | Searchable via fabric skills search <query> --source skills-sh. Fabric resolves alias-style skills when the skills.sh slug differs from the repo folder. |
well-known | well-known:https://mintlify.com/docs/.well-known/skills/mintlify | Skills served directly from /.well-known/skills/index.json on a website. Search using the site or docs URL. |
url | https://sharethis.chat/SKILL.md | Direct HTTP(S) URL to a single-file SKILL.md. Name resolution: frontmatter → URL slug → interactive prompt → --name flag. |
github | openai/skills/k8s | Direct GitHub repo/path installs and custom taps. |
clawhub, lobehub, browse-sh | Source-specific identifiers | Community or marketplace integrations. |
Integrated hubs and registries
Fabric currently integrates with these skills ecosystems and discovery sources:
1. Official optional skills (official)
These are maintained in the Fabric repository itself and install with built-in trust.
- Catalog: Official Optional Skills Catalog
- Source in repo:
optional-skills/ - Example:
fabric skills browse --source official
fabric skills install official/security/1password
2. skills.sh (skills-sh)
This is Vercel's public skills directory. Fabric can search it directly, inspect skill detail pages, resolve alias-style slugs, and install from the underlying source repo.
- Directory: skills.sh
- CLI/tooling repo: vercel-labs/skills
- Official Vercel skills repo: vercel-labs/agent-skills
- Example:
fabric skills search react --source skills-sh
fabric skills inspect skills-sh/vercel-labs/json-render/json-render-react
fabric skills install skills-sh/vercel-labs/json-render/json-render-react --force
3. Well-known skill endpoints (well-known)
This is URL-based discovery from sites that publish /.well-known/skills/index.json. It is not a single centralized hub — it is a web discovery convention.
- Example live endpoint: Mintlify docs skills index
- Reference server implementation: vercel-labs/skills-handler
- Example:
fabric skills search https://mintlify.com/docs --source well-known
fabric skills inspect well-known:https://mintlify.com/docs/.well-known/skills/mintlify
fabric skills install well-known:https://mintlify.com/docs/.well-known/skills/mintlify
4. Direct GitHub skills (github)
Fabric can install directly from GitHub repositories and GitHub-based taps. This is useful when you already know the repo/path or want to add your own custom source repo.
Default taps (browsable without any setup):
-
NVIDIA/skills — NVIDIA-verified skills (signed
skill.oms.sig+ governanceskill-card.md) -
Example:
fabric skills install openai/skills/k8s
fabric skills tap add myorg/skills-repo
Category groupings (skills.sh.json). A GitHub tap may ship a
skills.sh.json file at its repo root following the
skills.sh schema. Its
groupings (each with a title and a list of skill names) are read at index
time and become the category labels shown in the
Skills Hub page — instead of a
tag-derived guess. This is generic: any tap that ships the file gets real
categorization, no Fabric-side changes required.
{
"$schema": "https://skills.sh/schemas/skills.sh.schema.json",
"groupings": [
{ "title": "Inference AI", "skills": ["dynamo-recipe-runner", "dynamo-router-sla"] },
{ "title": "Decision Optimization", "skills": ["cuopt-developer", "cuopt-install"] }
]
}
5. ClawHub (clawhub)
A third-party skills marketplace integrated as a community source.
- Site: clawhub.ai
- Fabric source id:
clawhub
6. Claude marketplace-style repos (claude-marketplace)
Fabric supports marketplace repos that publish Claude-compatible plugin/marketplace manifests.
Known integrated sources include:
Fabric source id: claude-marketplace
7. LobeHub (lobehub)
Fabric can search and convert agent entries from LobeHub's public catalog into installable Fabric skills.
- Site: LobeHub
- Public agents index: chat-agents.lobehub.com
- Backing repo: lobehub/lobe-chat-agents
- Fabric source id:
lobehub
8. browse.sh (browse-sh)
Fabric integrates with browse.sh, Browserbase's catalog of 200+ site-specific browser-automation SKILL.md files (Airbnb, Amazon, arXiv, 12306.cn, Etsy, Xero, and many more). Each skill describes how to drive one website end-to-end and is suitable for use with Fabric's browser tools and any browser-automation skills you already have installed.
- Site: browse.sh
- Catalog API:
https://browse.sh/api/skills - Fabric source id:
browse-sh - Trust level:
community
fabric skills search airbnb --source browse-sh
fabric skills inspect browse-sh/airbnb.com/search-listings-ddgioa
fabric skills install browse-sh/airbnb.com/search-listings-ddgioa
Identifiers use the form browse-sh/<hostname>/<task-id> and match the slug exposed by the browse.sh catalog. Content is resolved through the per-skill detail endpoint (/api/skills/<slug> → skillMdUrl), not through the catalog's GitHub sourceUrl.
9. Direct URL (url)
Install a single-file SKILL.md directly from any HTTP(S) URL — useful when an author hosts a skill on their own site (no hub listing, no GitHub path to type). Fabric fetches the URL, parses the YAML frontmatter, security-scans it, and installs.
- Fabric source id:
url - Identifier: the URL itself (no prefix needed)
- Scope: single-file
SKILL.mdonly. Multi-file skills withreferences/orscripts/need a manifest and should be published via one of the other sources above.
fabric skills install https://sharethis.chat/SKILL.md
fabric skills install https://example.com/my-skill/SKILL.md --category productivity
Name resolution, in order:
name:field in the SKILL.md YAML frontmatter (recommended — every well-formed skill has one).- Parent directory name from the URL path (e.g.
.../my-skill/SKILL.md→my-skill, or.../my-skill.md→my-skill), when it's a valid identifier (^[a-z][a-z0-9_-]*$). - Interactive prompt on a terminal with a TTY.
- On non-interactive surfaces (the
/skills installslash command inside the TUI, gateway platforms, scripts), a clean error pointing at the--nameoverride.
# Frontmatter has no name and the URL slug is unhelpful — supply one:
fabric skills install https://example.com/SKILL.md --name sharethis-chat
# Or inside a chat session:
/skills install https://example.com/SKILL.md --name sharethis-chat
Trust level is always community — the same security scan runs as for every other source. The URL is stored as the install identifier, so fabric skills update re-fetches from the same URL automatically when you want to refresh.
Security scanning and --force
All hub-installed skills go through a security scanner that checks for data exfiltration, prompt injection, destructive commands, supply-chain signals, and other threats.
fabric skills inspect ... now also surfaces upstream metadata when available:
- repo URL
- skills.sh detail page URL
- install command
- weekly installs
- upstream security audit statuses
- well-known index/endpoint URLs
Use --force when you have reviewed a third-party skill and want to override a non-dangerous policy block:
fabric skills install skills-sh/anthropics/skills/pdf --force
Important behavior:
--forcecan override policy blocks for caution/warn-style findings.--forcedoes not override adangerousscan verdict.- Official optional skills (
official/...) are treated as built-in trust and do not show the third-party warning panel.
Trust levels
| Level | Source | Policy |
|---|---|---|
builtin | Ships with Fabric | Always trusted |
official | optional-skills/ in the repo | Built-in trust, no third-party warning |
trusted | Trusted registries/repos such as openai/skills, anthropics/skills, huggingface/skills, NVIDIA/skills | More permissive policy than community sources |
community | Everything else (skills.sh, well-known endpoints, custom GitHub repos, most marketplaces) | Non-dangerous findings can be overridden with --force; dangerous verdicts stay blocked |
Update lifecycle
The hub now tracks enough provenance to re-check upstream copies of installed skills:
fabric skills check # Report which installed hub skills changed upstream
fabric skills update # Reinstall only the skills with updates available
fabric skills update react # Update one specific installed hub skill
fabric skills gc # Recover interrupted work and prune verified terminal artifacts
This uses the stored source identifier plus the current upstream bundle content hash to detect drift. GC is deliberately conservative: it removes only artifacts that still match their journaled digest and retains malformed or changed records for manual inspection. If the command reports that more records remain, run it again to process the next bounded batch.
Skills hub operations use the GitHub API, which has a rate limit of 60 requests/hour for unauthenticated users. If you see rate-limit errors during install or search, set GITHUB_TOKEN in your .env file to increase the limit to 5,000 requests/hour. The error message includes an actionable hint when this happens.
Publishing a custom skill tap
If you want to share a curated set of skills — for your team, your org, or publicly — you can publish them as a tap: a GitHub repository other Fabric users add with fabric skills tap add <owner/repo>. No server, no registry sign-up, no release pipeline. Just a directory of SKILL.md files.
Repo layout
A tap is any GitHub repo (public or private — private needs GITHUB_TOKEN) laid out like this:
owner/repo
├── skills/ # default path; configurable per-tap
│ ├── my-workflow/
│ │ ├── SKILL.md # required
│ │ ├── references/ # optional supporting files
│ │ ├── templates/
│ │ └── scripts/
│ ├── another-skill/
│ │ └── SKILL.md
│ └── third-skill/
│ └── SKILL.md
└── README.md # optional but helpful
Rules:
- Each skill lives in its own directory under the tap's root path (default
skills/). - The directory name becomes the skill's install slug.
- Each skill directory must contain a
SKILL.mdwith standard SKILL.md frontmatter (name,description, plus optionalmetadata.fabric.tags,version,author,platforms,metadata.fabric.config). - Subdirectories like
references/,templates/,scripts/,assets/are downloaded alongsideSKILL.mdat install time. - Skills whose directory name starts with
.or_are ignored.
Fabric discovers skills by listing every subdirectory of the tap path and probing each for SKILL.md.
Minimal tap example
my-org/fabric-skills
└── skills/
└── deploy-runbook/
└── SKILL.md
skills/deploy-runbook/SKILL.md:
---
name: deploy-runbook
description: Our deployment runbook — services, rollback, Slack channels
version: 1.0.0
author: My Org Platform Team
metadata:
fabric:
tags: [deployment, runbook, internal]
---
# Deploy Runbook
Step 1: ...
After pushing that to GitHub, any Fabric user can subscribe and install:
fabric skills tap add my-org/fabric-skills
fabric skills search deploy
fabric skills install my-org/fabric-skills/deploy-runbook
Non-default paths
If your skills don't live under skills/ (common when you're adding a skills/ subtree to an existing project), edit the tap entry in ~/.fabric/.hub/taps.json:
{
"taps": [
{"repo": "my-org/platform-docs", "path": "internal/skills/"}
]
}
The fabric skills tap add CLI defaults new taps to path: "skills/"; edit the file directly if you need a different path. fabric skills tap list shows the effective path per tap.
Installing individual skills directly (without adding a tap)
Users can also install a single skill from any public GitHub repo without adding the whole repo as a tap:
fabric skills install owner/repo/skills/my-workflow
Useful when you want to share one skill without asking the user to subscribe to your whole registry.
Trust levels for taps
New taps are assigned community trust by default. Skills installed from them run through the standard security scan and show the third-party warning panel on first install. If your org or a widely-trusted source should get higher trust, add its repo to TRUSTED_REPOS in tools/skills_hub.py (requires a Fabric core PR).
Tap management
fabric skills tap list # show all configured taps
fabric skills tap add myorg/skills-repo # add (default path: skills/)
fabric skills tap remove myorg/skills-repo # remove
Inside a running session:
/skills tap list
/skills tap add myorg/skills-repo
/skills tap remove myorg/skills-repo
Taps are stored in ~/.fabric/.hub/taps.json (created on demand).
Bundled skill updates (fabric skills reset)
Fabric ships with a set of bundled skills in skills/ inside the repo. On install and on every fabric update, a sync pass copies those into ~/.fabric/skills/ and records a manifest at ~/.fabric/skills/.bundled_manifest mapping each skill name to the content hash at the time it was synced (the origin hash).
On each sync, Fabric recomputes the hash of your local copy and compares it to the origin hash:
- Unchanged → safe to pull upstream changes, copy the new bundled version in, record the new origin hash.
- Changed → treated as user-modified and skipped forever, so your edits never get stomped.
The protection is good, but it has one sharp edge. If you edit a bundled skill and then later want to abandon your changes and go back to the bundled version by just copy-pasting from ~/.fabric/fabric-agent/skills/, the manifest still holds the old origin hash from whenever the last successful sync ran. Your fresh copy-paste contents (current bundled hash) won't match that stale origin hash, so sync keeps flagging it as user-modified.
fabric skills reset is the escape hatch:
# Safe: clears the manifest entry for this skill. Your current copy is preserved,
# but the next sync re-baselines against it so future updates work normally.
fabric skills reset google-workspace
# Full restore: also deletes your local copy and re-copies the current bundled
# version. Use this when you want the pristine upstream skill back.
fabric skills reset google-workspace --restore
# Non-interactive (e.g. in scripts or TUI mode) — skip the --restore confirmation.
fabric skills reset google-workspace --restore --yes
The same command works in chat as a slash command:
/skills reset google-workspace
/skills reset google-workspace --restore
Each profile has its own .bundled_manifest under its own FABRIC_HOME, so fabric -p coder skills reset <name> only affects that profile.
Slash commands (inside chat)
All the same commands work with /skills:
/skills browse
/skills search react --source skills-sh
/skills search https://mintlify.com/docs --source well-known
/skills inspect skills-sh/vercel-labs/json-render/json-render-react
/skills install openai/skills/skill-creator --force
/skills check
/skills update
/skills gc
/skills reset google-workspace
/skills list
Official optional skills still use identifiers like official/security/1password and official/migration/openclaw-migration.