SKILL.md files, and the registry’s read surface is public. You never need the Python SDK — or an account — to find a skill, judge its evidence, and get it onto disk where your runtime (Claude Code, Cursor, Copilot, Cline, …) auto-discovers it.
If you are starting a new agent, the public Support builder can export a complete frozen Python/OpenAI project, including skill bodies and required text companions, without a DecimalAI account or SDK. Its runtime uses your OpenAI key locally and uploads no traces. The optional CLI equivalent is decimalai starter support --project ./support-agent (0.13.8+). See the Support tutorial for local checks and the separate authenticated hosted-trial choice.
Five routes, one file. The registry renders every SKILL.md itself, frontmatter included, and checks it before serving it. Each route below writes those bytes unchanged, so a file from the Copy button, from curl, from skills pull and from the plugin is the same file, and the identity stamp in it means the same thing whichever route you took.
“Bundled files” are a skill’s
scripts/, references/, templates/ and assets/. A route that writes SKILL.md alone is enough for a skill that has none; the skill’s page lists its files.
Whatever the route, do the two trust checks first: the verified lift (with-vs-without benchmark, with model + case count + date) and the safety band (Passed / Caution / Blocked / Not yet reviewed). Both are on every skill’s public page — see How skills are vetted. The registry enforces part of the second one on every route that fetches a file: it never serves a Blocked skill, a skill withheld while its review is pending, or a version that failed its safety scan. When a skill’s newest version failed its scan, the routes that don’t name a version get the newest version that passed. A Caution or Not yet reviewed skill is served, and of the routes on this page only the Claude Code plugin asks you before writing one — a prompt in your own session, not a boundary the model can’t cross, so treat it as a convenience rather than a control (why that distinction matters). Blocked skills are still listed on every route, deliberately, so you can see that a skill exists and why it’s unsafe — the band on the page is the check, not the tooling.
The folder is the install name
Every skill has an install name: the name of the folder its files go in, and thename: its SKILL.md declares. Loaders compare the two, and some refuse a skill whose folder and name: disagree, so keep them equal.
The registry derives it from the skill’s registry name: acme/refund-policy installs as acme-refund-policy. It is not always the url_slug — a slug can keep _ or ., which loaders refuse in name: — and a name that doesn’t convert cleanly (one written in a non-Latin script, say, or longer than 64 characters) gets a short hash suffix instead, such as skill-3f9a1c. You never have to work it out:
- the commands on the skill’s page already use it;
- the
name:line of the servedSKILL.mdstates it; /s/<url_slug>.jsoncarries it asinstall_name, and the raw file’s response carries it in theX-Decimalai-Install-Nameheader.
decimalai skills add picks a name inside a project that already uses it, are in Skills on disk.
Provenance: the identity stamp
EverySKILL.md the registry serves records which skill and version it is, under metadata, the frontmatter map the agentskills.io format leaves for tools’ own keys. Loaders accept the file as served; the stamp needs no editing and no stripping. A public skill’s frontmatter looks like this (illustrative values; license, compatibility, allowed-tools and decimalai-category appear only when the skill sets them):
The top-level
source: and source_sha256: keys that files fetched before this format carried are gone: some strict loaders refused a skill with keys the format does not define.
The stamp answers two questions six months from now.
Have we edited it? Hash the body and compare it with the stamp. Run this from the project root:
ETag and compare it with the stamp:
metadata.decimalai-body-sha256, and -v<version> is its decimalai-version. When both match your stamp, you have the current version’s body. The -r part names the rendering of the frontmatter: description, license, compatibility, allowed-tools and invocation. An author can edit those without making a new version, so a changed -r with the same hash and version means only the frontmatter moved. Your file does not record the -r part; fetch the current file and compare the frontmatter if you need to know what changed.
decimalai-source keeps serving the version it names, so it never tells you that a newer one has shipped: compare against the URL without @<version>. No stamp, no answer — a file someone retyped by hand carries none.
Web copy-paste
Open any skill atapp.decimal.ai/skills/<url_slug> — for example playwright-cli. In the Use this skill card, Copy SKILL.md (under Claude Code or CLI & files) copies the file the registry serves for that skill, byte for byte: the same file /s/<url_slug>/SKILL.md returns, name, description and stamp included. There is nothing to add. Paste it into a folder named by the install name:
.agents/skills/ is also where decimalai skills add keeps the skills it manages; in a project that uses it, add the skill that way rather than pasting it. A folder you paste there stays yours: decimalai skills commands never change a folder their lock does not list, and adding the same skill later stops (exit 5) rather than overwrite your copy, until you pass --force.
CLI pull (decimalai skills pull)
The DecimalAI CLI ships with the Python package, and skills pull is anonymous — no API key, no signup, even when one is set:
<out>/<install_name>/: SKILL.md with its stamp, its bundled files with their modes (0755 for scripts the skill marks executable), plus the skill’s eval.yaml test suite when the author published one — so you can re-run the with-vs-without benchmark yourself with the open runner. It prints any bundled file the registry could not include, and any allowed-tools entry it dropped. Other forms:
--force; files that are not part of the skill stay in place either way. A Blocked or withheld skill is refused (exit 7).
Read-only by design: no fork is created, and the copy is loose — no lock records it and nothing updates it. To keep a skill in a project, pinned and updatable, use decimalai skills add instead. (decimalai skills export and the positional decimalai skills install <ref> are deprecated aliases of skills add and stop working in 0.17.)
Raw URLs (scripts, CI, and LLM agents)
Every published skill is fetchable as plain text — no HTML scraping, no auth:SKILL.md alone; for a skill with bundled files, use skills pull or the plugin.
The SKILL.md response is text/markdown with these headers:
An agent can poll cheaply: send the ETag back as
If-None-Match and an unchanged file answers 304 Not Modified. A plain curl sees the ETag as written above. A client that accepts compressed responses, a browser for instance, may see the same value marked weak, W/"…", because the edge re-encodes the body in transit; the hash inside is unchanged. The ETag is also the am-I-behind check, with no local hashing.
The @<version> form is a version archive, not a currency check — it serves whichever version you ask for, so the unpinned URL’s ETag is what carries the current version. A pinned file’s body never changes; its frontmatter follows the skill’s current license and tool list, so the -r part of its ETag can.
When there is no file to serve: 404 for an unknown skill, a version that never existed, or a malformed version token; 410 for a Blocked skill, a skill withheld pending review, or a version that failed its safety scan, with a body that says which; 429 when you are rate limited.
The
/s/ files are cached at the edge for up to two days, so a version published in that window, or a skill blocked in it, can take that long to show there. The API serves the same bytes and headers from the origin, checked on every request: https://api.decimal.ai/api/v1/registry/skills/<url_slug>/skill-md, with ?version=<n> for one version. A plain curl of that URL sees its ETag marked weak (W/"…"); curl --compressed sees it as written.MCP server
decimalai-mcp gives any MCP client — Claude Code, Claude Desktop, Cursor — three read-only registry tools: search_skills, get_skill (full record: trust bands, verified lift, SKILL.md body), and get_leaderboard. No API key required:
uvx fetches and runs it without installing anything permanently (uv required). Then ask your agent things like:
“find me a measured skill for enterprise customer onboarding, and show its verified lift, case count, and safety band”Today that returns
gtm-enterprise-onboarding first — +78.3 points over 23 cases, safety Passed — with the evidence inline, so you can judge it without opening a browser.
This is the discovery route — it answers “which skill should I use, and what’s the evidence?” without leaving your editor. It is deliberately read-only: it searches and inspects, it never writes files. The body get_skill returns is the skill’s text without the frontmatter, and a long one is cut short, so don’t save it as SKILL.md; pair the server with any route above to put the registry’s file on disk — or, in Claude Code, the plugin below does both halves in one place.
Optional: set
DECIMAL_API_KEY to also see which skills your org has already installed.Claude Code plugin
Full guide: Claude Code plugin. In short — two commands and the registry moves inside the session — nothing tocurl, no directory to pick, no pip install:
claude plugin details decimalai@decimalai shows what you took on: three slash commands (check, install, search), no agents, no hooks, no MCP or LSP servers, and about a hundred tokens added to every session. Nothing runs until you type a command. Search and install need python3 and curl.
/decimalai:search <query> ranks the public registry by measured effectiveness rather than downloads: each row carries the exact /decimalai:install line, the folder it lands in, a SkillScore, the verified lift with its model and case count, the safety band, and how many agents currently have the skill installed. Searching for sql injection surfaces detecting-sql-injection-via-waf-logs — +54.6 points over 22 cases on gemini-3.6-flash, safety Passed.
/decimalai:install <url_slug> writes the skill’s folder exactly as the registry renders it — SKILL.md plus its bundled files — into .claude/skills/<install_name>/. It reads the skill’s record first and prints its safety band and benchmark line. Then it fetches the folder, GET /api/v1/registry/skills/<id>/bundle, labelled channel=plugin, which lists every file with its text, SHA-256 and mode. Before anything touches disk it refuses a folder name loaders don’t accept, a path outside scripts/, references/, templates/ or assets/, a second SKILL.md anywhere in the tree, and any file whose bytes don’t hash to the SHA-256 the registry declared. It writes into a staging folder, reads every file back, and only then moves the folder into place. Because the bytes are the registry’s, the file carries the same identity stamp as every other route, and the ETag comparison under Raw URLs answers “am I behind?” for it too.
Pass the url_slug that search printed (or the skill’s id), not the name — a registry name may be namespaced (owner/skill), and a / is neither a URL path segment nor a directory name. An existing folder that holds exactly these bytes is left alone; one that differs is replaced only after you say yes, and is moved to .claude/decimalai-backup/ first.
/decimalai:check writes the two files behind the regression-check Action: the manifest-extraction entry point scripts/init_for_decimal.py and the workflow .github/workflows/decimal-regression-check.yml, with your repo’s real agent_name filled in. The workflow it writes needs a DECIMAL_API_KEY repo secret — the check runs against your own production traces — and adding that secret is still yours to do.
The route that refuses
The registry already declines to serve a Blocked skill’s files on every route above that fetches them. The plugin moves that decision one step earlier and adds a second one: it reads the band before it fetches anything, refuses Blocked, and asks you before writing anything that is not Passed. The registry returns blocked skills in ordinary search responses, so keeping one out of your results is the plugin’s job rather than the API’s. Searchsql injection and one of the matches is performing-second-order-sql-injection. Its safety scan is clean — the pattern checks for live secrets, reverse shells and data exfiltration all came back empty — and the intent review rejects it anyway, for walking a reader through extracting credentials out of a database. Pattern scanning was never going to catch that one; reading the file for purpose did.
The plugin still shows it, but not as a result: it comes last under a Blocked, will not install heading, with the reason and no install line, and /decimalai:install performing-second-order-sql-injection stops before fetching a file. Dropping the row silently would be the worse failure — you searched for something, a match exists, and you are entitled to know why it is withheld.
When you do want the SDK
Everything above is a loose copy: the file lands on disk and your runtime takes it from there, but nothing records what you took or moves it forward.decimalai skills add is the managed version of the same file. It needs no API key for a public skill:
.agents/skills/<install_name>/, records the skill in .decimal/skills.toml, and pins the exact files in .decimal/skills.lock. Commit all three; decimalai skills install --frozen then reproduces the folder in CI, decimalai skills update moves it forward, and decimalai skills verify checks it the way the loaders will. Claude Code loads that root as a plugin, from the repository’s absolute path: claude --plugin-dir "$(git rev-parse --show-toplevel)/.agents". Skills on disk covers the layout, CI and Docker, and pointing each framework at the folder; the CLI page has every command.
Moving a skill from a loose copy to a managed one: delete the .claude/skills/<install_name>/ copy, or Claude Code loads the skill twice. A copy you pasted into .agents/skills/<install_name>/ is replaced by decimalai skills add <url_slug> --force, which keeps a backup under .decimal/backup/ first.
The SDK also adds the feedback loop — forking skills into your org, routing them per-turn, and measuring which ones actually help your agent on your traffic. When you’re ready for that: Quickstart and the registry guide.
What the registry records
Each route that fetches a file is counted as one fetch of that skill for the day, labelled by route (web, raw, cli, plugin) and with no account attached, so nothing in the count identifies you. The Copy button also records one anonymous copy event. A fetch is not a delivery to a model: it never moves a skill’s usage numbers or its SkillScore, so the evidence you read before installing is not inflated by installs. Requests also appear in server logs, as described in §1.4 of the privacy policy.
Related
- Install a Skill in 5 Minutes — the tutorial version of this page: one skill, end to end
- Claude Code plugin — the plugin’s three commands, and the other ways into Claude Code
- Trust & exit — open formats, graceful degradation, and what leaving looks like
- How skills are vetted — what the safety bands mean
- skillevaluation — the open spec + runner behind every verified lift number