Skip to main content

Skills written in Bike4Mind now install into Claude Code as plugins

engineering
open-source
skills
claude-code

October 29, 2026

By Bike4Mind Engineering · also on app.bike4mind.com


Skills written in Bike4Mind now install into Claude Code as plugins

Someone on your team writes a skill for reviewing pull requests: a SKILL.md that says how your team likes a review structured, a scripts/ folder with a small linter wrapper, and a references/ folder holding the style guide. A teammate reviews and approves it in Bike4Mind. Then you start Claude Code, type /plugin install, and the skill is there, scripts and style guide included, with the same text everyone else on the team got.

No folder was zipped and passed around. This post covers how that path works, what we built to make shipping scripts acceptable, and which parts you can use today.

Where skills used to get stuck

A skill is a good unit of team knowledge, and teams write them wherever their agent happens to be running. One person drafts in a chat window, another keeps a folder in a repository, a third pastes a body into a settings page. When the skill needs a script, the only way to move it is to copy the directory. Nothing records who looked at the script, and nothing tells the person who copied it last month that the original changed.

We already had a place for a team's skills: the Skill Market, where a skill is published, scanned, reviewed and listed for an organization. What was missing was the last hop, from an approved listing to the agent that runs it. Claude Code has its own plugin system, so we made the market speak that.

What a skill is in Bike4Mind

A skill is a named instruction document. It has a description that says when to use it, a body, an optional argument hint, and a flag for whether the model may invoke it on its own. It can declare the tools it is allowed to use. It can also carry supporting files.

Supporting files live in two directories only: scripts/ and references/. The limits are the same in the server, the web folder import and the desktop reader, because they share one validator:

  • At most 20 files per skill, 100 KB each, 512 KB in total.
  • Paths up to 200 characters. Each segment may use letters, digits, dot, underscore and hyphen, and may not start with a dot, which rules out .. and hidden files.
  • Text only. A file containing a NUL byte is refused.
  • No two paths that differ only by case, so the archive extracts the same on macOS and Windows as on Linux.

Skills also keep two separate tool lists. allowedTools names Bike4Mind's own tools. claudeCodeAllowedTools holds the value of Claude Code's allowed-tools frontmatter, for example Read, Grep. When we write a SKILL.md for Claude Code we emit only the second list, since Bike4Mind tool names mean nothing to Claude Code. A skill imported from a SKILL.md keeps its allowed-tools through publish and re-publish.

One listing, one plugin; or a bundle of them

Publishing a skill to the market copies it into an immutable version snapshot: name, description, body, tool lists and the supporting files, sorted by path. Approval points the listing at its current approved version. Everything downstream reads that snapshot, never the live skill, so editing your draft does not change what your teammates have installed.

The organization's feed is a Claude Code marketplace file. Each approved listing becomes one plugin entry whose source is an archive URL plus a sha256 of the zip. Because the feed pins the hash, the zip has to be byte-identical on every build. We store entries uncompressed, use a fixed timestamp, sort files by path, and keep anything per-request out of the SKILL.md. The zip route and the feed share one builder, so the hash and the bytes cannot drift.

The archive is small. For a single listing:

skills/review-pr/SKILL.md
skills/review-pr/scripts/lint.sh        (mode 0755)
skills/review-pr/references/style.md

The SKILL.md begins with frontmatter generated from the snapshot, along with a comment line marking it as third-party content and pointing back to the listing:

---
# Version: 3
name: review-pr
description: Review a pull request the way our team does
allowed-tools: Read, Grep
---

Our zip contains no plugin.json. The plugin's name, description and version come from the marketplace entry, and the skill files sit in the skills/ layout Claude Code reads. Scripts get an executable mode in case the extractor keeps unix permissions, but the SKILL.md should still call them through an interpreter, so the skill does not depend on that.

Org admins can also group approved listings into a bundle, up to 50 of them, and the feed serves the bundle as one plugin with each member under its own directory. The bundle's version is the first 12 characters of its content hash, which changes exactly when the bytes do: a member gets approved, delisted, or the membership is edited. A member that is delisted or no longer approved drops out of the next build. Bundles hold only approved Organization listings, each reviewed on its own, so building a bundle needs no extra review.

A skill moves from its author through review and the market into Claude Code An author or an API key with skills:write publishes a skill. The scan and the review queue hold anything risky. Approval creates a version snapshot in the Skill Market. The feed turns snapshots into a plugin zip or a bundle, which Claude Code installs. author person, or an API key: skills:write publish a skill scan + review clean: auto-approved else held in queue skills:review Skill Market approved version snapshot, with files per organization plugin feed marketplace.json zip, pinned by sha256 listing or bundle Claude Code /plugin install skills/ + scripts
Only approved versions reach the feed. Everything to the right of the review step reads a frozen snapshot.

Installing it

The install path is a settings entry, not a download. In the "Use in Claude Code" dialog, the Team marketplace tab mints an API key with the skills:read scope and writes the snippet for you. You merge it into your own ~/.claude/settings.json:

{
  "extraKnownMarketplaces": {
    "b4m-org-<org id>": {
      "source": {
        "source": "url",
        "url": ".../api/v1/skills/market/claude-marketplace.json?orgId=<org id>",
        "headers": { "Authorization": "Bearer <key>" }
      },
      "autoUpdate": true
    }
  }
}

Claude Code registers the marketplace after it has started once with those settings, and then /plugin install <name>@<marketplace> works. The marketplace name is derived from the organization id, so renaming the org never renames an install. The key goes in plain text in that file, so the dialog tells you to keep it in your user settings and never in a project's committed one. Membership is checked on every request, so someone who leaves the organization loses the feed and the zips even though their key still works for other organizations.

Why a script needs a person

A SKILL.md is text the model reads. A script is code that runs on the machine of whoever installed the skill, outside the model's view. That difference is why shipping scripts needed the review gate to grow before the feature could.

Every version is scanned before it is listed. The scan applies the same text rules to the body and to each supporting file, with the path attached to any finding. At a high level the rules look for attempts to override or extract instructions, forged system or tool delimiters, requests for credentials, markup that should not be in a skill, encoded payloads, links outside an allowlist, and instructions to send conversation data elsewhere. They run over normalized copies of the text as well as the original, so formatting tricks do not buy a way around them. Declared tools are checked too: for Claude Code tools, only a short read-only set (such as Read, Glob and Grep) is treated as low risk, and anything else, Bash with a command prefix included, counts as high risk.

A separate finding fires for any file under scripts/, any file whose extension is not plain prose, and any file that starts with a shebang. It is a medium finding, which places the version in review even when every other rule is quiet. A classifier also compares the description with what the body does. It can push a version toward review or rejection, never toward clean.

The outcome is a tier. Only a clean version goes live without a person, at every visibility. A review or high tier is held as pending. A critical finding fails the version outright.

Acknowledgements

A reviewer approving a held version has to acknowledge what the scan found. Approving a high-risk version requires an explicit high-risk acknowledgement, and approving one whose description does not match its behavior requires a mismatch acknowledgement. The two flags are stored on the version with the reviewer and the time. This used to be enforced only for Public listings, which meant an admin could approve a high-risk Organization listing, their own included, without confirming anything. It now applies at every visibility. Reviewing your own Public listing is refused outright.

The same thinking applies to skills shared across the whole instance. A non-admin can no longer edit the scanned fields of such a skill directly. The update is routed through the Skill Market so it gets scanned and reviewed like any other version.

Agents can write and review skills too

The market's authoring routes are available under /api/v1/skills/market with two scopes beyond skills:read:

  • skills:write lets a key publish a listing from a skill you own, submit a new version, list your own listings, withdraw one, rescan a version, and browse and import listings. It is not a confined scope, so it also reaches routes that declare none, and the key dialog keeps it out of the read-and-write preset because publishing is outward-facing.
  • skills:review lets a key list the held queue and approve or reject a version. It is limited to organization admins and to the Organization listings of orgs they administer. It cannot touch Public or unlisted listings.

The v1 listing snapshot returns the declared Claude Code tools and the supporting files, so an agent reading the review queue sees the same scripts a human reviewer would. The review route enforces the same acknowledgements, with ack_high_risk and ack_mismatch in the request body. An agent that writes a skill, submits it, and reviews the queue is bound by the same rules as a person, including the one about your own Public listings.

Whether you want an agent holding a review key is a decision for your organization. The scope exists so that decision can be made per key, and the scan runs whoever submits.

Where this stands today

All of the above is merged to main: the file limits and scan rules, the per-listing plugin zips, bundles, the Team marketplace dialog, and the write and review routes with their scopes. We have not verified here that a given deployment is running it, so treat your own instance's release as the source of truth.

What you need to use it: a Bike4Mind organization, an API key from the Team marketplace dialog, and a Claude Code version that supports URL marketplaces with request headers. The dialog notes that a headersHelper command, which keeps the key out of the settings file, needs Claude Code 2.1.238 or later.

The limits are real ones. Supporting files are text only and small. There is no binary asset support. Updates arrive when Claude Code refreshes the marketplace, not instantly, and the dialog shows the commands to refresh by hand. The feed builds every zip to compute its hash on each fetch, which is fine for a team's worth of skills and is a known cost for an organization with hundreds. We describe Claude Code's plugin and skill formats only as far as our code depends on them, so check Claude Code's own documentation for anything beyond what we generate.