Publishing Skills and Plugins to ClawHub
Learn how to publish skills and plugins to ClawHub, including owner selection, validation, versioning, and review. Essential for developers and org owners.
Read this when
- Publishing a skill or plugin
- Debugging owner or package scope errors
- Adding publish UI, CLI, or backend behavior
Publishing
When you publish, a skill folder or plugin package is sent to ClawHub under an owner you select. ClawHub verifies that your token is authorized to publish for that owner, checks the metadata, name, version, files, and source details, then saves the release and kicks off automated security scans.
If any validation step fails, the publish is blocked. New releases might also be kept out of standard install and download surfaces until the review process wraps up.
Skills
The CLI offers the most straightforward way to publish. After signing in, you can publish a local skill folder:
clawhub login
clawhub skill publish ./my-skill \
--slug my-skill \
--name "My Skill" \
--owner <owner>
For publishing to an org owner, include --owner <handle>. Leave it out to publish as the currently authenticated user. Content that hasn't changed is skipped during publishing. A brand-new skill starts at 1.0.0, and subsequent changes automatically push out the next patch version. Only pass --version when you need to specify a version explicitly.
Skill catalog metadata
Categories determine where a skill shows up in the category filters on the ClawHub skills browse page. Topics become the filter chips that appear within a selected category. Set both when publishing:
clawhub skill publish ./my-skill \
--categories development,operations \
--topics "git,worktree,cleanup"
Both flags accept comma-separated values. Categories must be slugs from the list below, matched exactly, so Development gets rejected. Topics are free-form labels; ClawHub stores whatever you pass and shows the normalized version, so Git Worktree displays as #git-worktree.
| Slug | Description |
|---|---|
integrations | Connect services, fetch data, reconcile records, and operate APIs. |
automation | Build repeatable processes, scheduled jobs, pipelines, and orchestration. |
research | Search, browse, scrape, summarize, monitor, and extract web information. |
development | Inspect, edit, test, build, debug, and operate codebases. |
productivity | Manage tasks, calendars, email, meetings, projects, and business work. |
communication | Message, publish, and operate social or communication services. |
creative | Create and edit images, video, audio, music, design, and writing. |
knowledge | Work with documents, notes, knowledge bases, teaching, and learning. |
agents | Change how an agent plans, reflects, learns, remembers, or collaborates. |
operations | Inspect, monitor, deploy, and operate local systems or infrastructure. |
security | Audit, scan, authenticate, and protect systems or data. |
finance | Work with payments, budgets, banking, shopping, markets, and commerce. |
lifestyle | Travel, health, fitness, cooking, sports, home, and daily-life utilities. |
other | Skills that do not yet fit another browse category. |
ClawHub enforces these rules on both fields:
- A skill is limited to 3 categories and 5 topics at most.
- An invalid category slug causes the publish to fail.
--dry-rundoes not validate slugs; the registry performs that check when the publish runs. - When
otheris passed together with a specific category, it gets discarded. The 3-category cap is then applied, soother,development,operationsends up storing two categories instead of failing. - Duplicates are removed rather than causing errors, and they are matched after normalization, so
git,Gitcounts as a single topic. Both limits apply to what remains after that, not to what you originally passed. - Each topic is capped at 48 characters, and topics may not include invisible formatting characters.
- ClawHub reserves these topic names and rejects them:
approved,audited,certified,clawhub,community,curated,endorsed,featured,official,officials,openclaw,recommended,staff-pick,trusted,trusted-publisher,verified. The check runs on the normalized form, soOfficialandstaff pickare rejected as well. - A skill published initially without
--categoriesis saved asother, so it only shows up under the Other category. - On a subsequent publish, leaving out
--categoriesor--topicspreserves the values that are already stored. Passing the flag again changes them. An empty value clears the field:--categories ""returns the skill toother, and--topics ""removes its topics. - Passing either flag triggers a publish even if the files haven't changed, so correcting metadata this way produces a new patch version.
Skill owners can also adjust categories and topics from the skill's settings page on ClawHub. That's the fastest remedy for a skill that was already published into other.
Publishing from a catalog repo
For catalog repositories, the reusable
skill-publish.yml workflow provided by ClawHub is the recommended approach.
For every immediate skill directory located under root (which defaults to
skills), it invokes skill publish; alternatively, only the directory passed as
skill_path is processed.
jobs:
publish:
uses: openclaw/clawhub/.github/workflows/skill-publish.yml@main
with:
owner: <owner>
dry_run: false
secrets:
clawhub_token: ${{ secrets.CLAWHUB_TOKEN }}
To preview new or modified skills without triggering a publish, use dry_run: true.
Optional inputs changelog, categories, and topics are forwarded by the workflow to
skill publish, along with clear_categories and clear_topics for stripping metadata that a skill
already contains. When a skill is first published without categories, it is saved
as other, matching the behavior of clawhub sync; catalog metadata can
also be configured later via the skill's settings page.
Just like tags, both categories and topics affect every skill published in
a run, and providing them disables the skip for unchanged skills, meaning a new
patch version gets released for each chosen skill, even those whose files are
untouched. To restrict that to a single skill, pass skill_path. The complete
details are covered in the workflow notes.
Plugins
Plugins follow npm-style naming conventions. Scoped package names place the owner in the leading segment:
@owner/package-name
The scope and the chosen publish owner must align. A package named @openclaw/dronzer can
only be published under @openclaw. Publishing as @vintageayu requires renaming the
package to @vintageayu/dronzer.
This rule stops a package from taking an org namespace that the publisher has no authority over.
If you legitimately own an org, brand, package scope, owner handle, or namespace that is already taken or reserved on ClawHub, submit an Org / Namespace Claim issue with public, non-sensitive evidence. Refer to Org and Namespace Claims for guidance on what belongs in public issues and what should stay out.
Before Publishing a Plugin
- Choose an owner that corresponds to the package scope.
- Add
openclaw.plugin.json. For code plugins,package.jsonis also required, includingopenclaw.compat.pluginApiandopenclaw.build.openclawVersion. - To display a custom plugin catalog icon on the homepage and plugin list pages,
set
iconinsideopenclaw.plugin.jsonto any HTTPS image URL. - Provide source repository and exact commit metadata, or run the CLI from a GitHub-backed checkout so it can identify them automatically.
- Execute
clawhub package validate <source>prior to publishing. For issues with the package, manifest, SDK import, or artifacts, consult Plugin validation fixes. - Run
clawhub package publish <source> --dry-runbefore creating a release. - Expect new releases to remain hidden from public install surfaces until automated security checks and verification are complete.
Trusted Publishing for Packages
Trusted publishing for packages requires two configuration steps:
- Publish the package once using the normal manual or token-authenticated
clawhub package publishprocess. This creates the package row and defines which package managers are allowed to modify its trusted publisher configuration. - A package manager then configures the GitHub Actions trusted publisher settings:
clawhub package trusted-publisher set @owner/package-name \
--repository owner/repo \
--workflow-filename package-publish.yml
Once configured, future supported GitHub Actions publishes can rely on
OIDC/trusted publishing without keeping a long-lived ClawHub token in the
repository. The configured repository and workflow filename must align with the
GitHub Actions OIDC claim. If --environment <name> is also supplied, the GitHub Actions
environment claim must match that name exactly.
When trusted publisher configuration is set, ClawHub verifies the configured GitHub repository. Public repositories can be verified via public GitHub metadata. For private repositories, ClawHub needs GitHub access to that repository, such as through a future ClawHub GitHub App installation or another authorized GitHub integration.
The current reusable package publish workflow supports secretless trusted
publishing for workflow_dispatch publishes when id-token: write is present. Tag-push real
publishes still depend on clawhub_token, so keep CLAWHUB_TOKEN available for tag releases,
first publishes, untrusted packages, or break-glass scenarios.
By default, real publishes through the reusable workflow wait for the staged
attempt to become public. The workflow fails if security checks block or fail
the attempt, the attempt expires, or the 30-minute publication deadline is hit.
Callers can modify the deadline using publication_timeout_minutes. The upper limit is 40 minutes,
leaving 35 minutes of reusable job time for setup, upload, and output capture.
Only set wait_for_publication: false for an intentional asynchronous publish.
To inspect or remove the configuration:
clawhub package trusted-publisher get @owner/package-name
clawhub package trusted-publisher delete @owner/package-name
Deleting the trusted publisher configuration serves as the rollback mechanism. It stops future trusted publish token minting until a package manager re-establishes the configuration.
FAQ
Package scope must match selected owner
If the package scope and selected owner are mismatched, ClawHub rejects the publish:
Package scope "@openclaw" must match selected owner "@vintageayu".
Publish as "@openclaw" or rename this package to "@vintageayu/dronzer".
To resolve this, either pick the owner indicated by the package scope, or rename the package so its scope matches the owner you are able to publish as.
If the package name already has the correct scope but the package belongs to the wrong publisher, transfer ownership:
clawhub package transfer @opik/opik-openclaw --to opik
Only use package or skill transfer when you have admin rights to both the current owner and the destination publisher. Package transfer does not permit publishing into a scope you lack management access to.
If you lack access to the current owner but believe your org, project, or brand is the rightful namespace owner, file an Org / Namespace Claim issue with public, non-sensitive proof for staff review. Before filing, check Org and Namespace Claims.
This safeguards organization namespaces. By claiming the @openclaw namespace, a package called @openclaw/dronzer ensures that only publishers authorized for the @openclaw owner are able to release it.