Skip to content
SKILLS
Documentation menu

Publish

Publishing your first artifact

Namespaces, the agent-registry.json manifest, limits, what blocks a release and what is only advisory.

Before you start

  1. An account and a namespace. In this first version the operator creates both. Write to contact@spboucher.ai with the namespace you would like. Self-service sign-up is planned.
  2. A token, if you publish from the command line or an agent. Create one in the dashboard under Tokens (you will be asked for your password again), or see Publishing from Claude Code.
  3. A package directory containing only what you intend to make public.

The package

A package is a directory. The registry adds one file to whatever your artifact already is: agent-registry.json at the root. It does not replace SKILL.md, package.json, pyproject.toml or an MCP configuration; those stay as they are.

citation-check/
├── agent-registry.json    registry manifest (required)
├── SKILL.md               required for type "skill"
├── README.md              required for every type except "skill"
├── LICENSE                recommended
├── CHANGELOG.md           recommended
├── references/…
└── scripts/…

Create a skeleton with skills init ./citation-check --type skill --name @yourns/citation-check.

Manifest reference

{
  "schemaVersion": "1.0",
  "name": "@yourns/citation-check",
  "version": "1.0.0",
  "type": "skill",
  "description": "Checks that every citation in a manuscript resolves to a reference.",
  "license": "MIT",
  "repository": "https://example.org/you/citation-check",
  "entrypoint": "SKILL.md",
  "keywords": ["academic-writing", "citations"],
  "compatibility": ["claude-code", "generic-agent-skills"],
  "permissions": ["filesystem:read"],
  "dependencies": []
}

Unknown keys are rejected. The file is limited to 64 KiB.

FieldRequiredRules
schemaVersionyes"1.0"
nameyes@namespace/slug. Namespace: up to 39 lowercase letters, digits and single hyphens. Slug: up to 64, same alphabet
versionyesStrict semantic version, no build metadata: 1.2.0, 2.0.0-rc.1
typeyesskill, mcp-server, agent, prompt-pack, workflow, connector, hook, bundle, eval-kit, template
descriptionyes10–300 characters. Becomes the listing summary
licenseyesSPDX identifier preferred (MIT, Apache-2.0, CC-BY-4.0, …). An unrecognised value is accepted with a note
repository, homepage, issuesnohttp(s) URLs, up to 500 characters
entrypointnoRelative path that must exist in the package. For a skill it must be SKILL.md
keywordsnoUp to 12 tags, lowercase letters, digits, hyphens, up to 32 characters each
compatibilitynoUp to 16 entries. Each is a client id (claude-code, codex, cursor, generic-agent-skills, generic-mcp) or an object { "client", "minVersion"?, "platform"?: "any"|"macos"|"linux"|"windows", "installStrategy"?: "copy-directory"|"mcp-config"|"manual" }
permissionsnoAny of filesystem:read, filesystem:write, network, shell, env, mcp, browser, credentials
dependenciesnoUp to 64 entries { "name": "@ns/slug", "version": "<semver range>", "optional"?: true }
capabilitiesnoOverride the derived labels: downloadable, installable, remote-endpoint, documentation-only, source-linked, executable
mcpfor mcp-serverSee below
sourceCommitnoHexadecimal commit id, 7–64 characters

Compatibility entries are your claims. They are displayed as unverified.

The mcp block

{
  "type": "mcp-server",
  "mcp": {
    "transport": "stdio",
    "command": "node",
    "args": ["server.mjs"],
    "env": [{ "name": "ECHO_PREFIX", "description": "Text prepended to replies", "required": false, "secret": false }],
    "tools": [{ "name": "echo", "description": "Returns its input" }]
  }
}
FieldRules
transportstdio or streamable-http
command, argsRequired for stdio. The command users run locally. Up to 32 arguments
urlRequired for streamable-http. The endpoint you operate
envUp to 32 variables: name (uppercase, digits, underscore), optional description, required (default true), secret
toolsUp to 200 { name, description? } entries for display

Never put a secret value in the manifest. Declare the variable name; users set the value locally.

Rules by type

TypeAdditional requirements
skillSKILL.md at the root with valid frontmatter; its name must equal the slug; description 1–1024 characters
mcp-serverAn mcp block and a README.md
bundleAt least one dependency, each pinned to an exact version
all othersA README.md

Limits

LimitValue
Archive (compressed)20 MiB
Unpacked total64 MiB
Single file16 MiB
Files2000
Path length / depth240 characters / 16 levels
In-browser preview per file256 KiB (larger or binary files are listed but not previewed)

Validate, pack, publish

skills validate ./citation-check                 # same checks the server runs, locally
skills publish ./citation-check --visibility public --dry-run   # full report, uploads nothing
skills publish ./citation-check --visibility public

skills pack and skills publish skip .git, node_modules, .DS_Store, __pycache__, .venv, .idea, .vscode and anything matched by a .skillsignore file. Symbolic links are never followed or published. The archive is deterministic: packing the same files twice gives the same SHA-256.

The dry-run report lists the target, version, visibility, every file with its size, skipped files, declared permissions, findings, and the archive checksum. Read it. Then publish.

Making an artifact public for the first time asks for explicit confirmation. So does any later change of visibility.

What happens on the server

uploaded ──> validating ──> rejected            nothing is stored or published
                       └──> security review ──> published
                                            └──> quarantined ──> published (moderator approves)
                                                             └──> revoked   (moderator rejects)

The archive is parsed in memory and inspected statically. It is never extracted to disk and nothing in it is executed.

Blocking: the release is refused

  • Unsafe paths: absolute, .., backslashes, control characters, case-insensitive duplicates.
  • Links, devices or other special entries in the archive; corrupt or oversized archives.
  • Forbidden files: .git/, node_modules/, .env and variants (except .env.example, .env.sample, .env.template), .npmrc, .netrc, .ssh/, .aws/, private keys, *.pem, *.p12, *.pfx.
  • Manifest errors; a manifest whose name, version or type differs from the artifact and version you are publishing to.
  • Type rules above.
  • A required dependency that does not exist, or has no published version satisfying the range.
  • Recognisable credentials: private keys, AWS, GitHub, Anthropic, OpenAI, Slack, Google, Stripe, registry tokens, JSON Web Tokens. Remove the secret and rotate it; it has already left your machine.

The response lists each finding with a code, file and line. Secrets are never echoed back.

Advisory: published, and shown on the release page

Hidden files, executables, scripts, compiled binaries, scripts that use the network or spawn processes, sudo, hard-coded credential-looking values, undeclared network or shell permissions, an unrecognised licence, a missing LICENSE, CHANGELOG or repository link, frontmatter fields outside the open specification.

Quarantine: held for a moderator

Download-and-execute pipelines (curl … | sh), decoded-and-executed payloads, recursive deletion of home or root paths, evaluation of remotely fetched code, reads of local credential stores, text that tells an agent to override its instructions, hide behaviour from the user or transmit credentials, and bidirectional control characters. A quarantined release is invisible to the public until a moderator approves or rejects it. If your package legitimately needs one of these, explain it in the README; it speeds up review.

After publishing

  • The release is immutable. To fix something, publish a new version.
  • You can edit release notes and listing metadata (summary, links, keywords, visibility). Listing metadata is refreshed from the manifest each time a new latest version is published.
  • You can deprecate an artifact with a reason, and revoke a version that turned out to be harmful. See Versioning.

Responsible publication

Publish only what you have the right to publish, under a licence you state. Do not include private data, other people's proprietary material or credentials. Declare the permissions your package needs. See the Acceptable use policy.

↑↓ to navigate · enter to open · esc to close