Skip to content
Skill Authoring
Skill

/creating-kb

Builds a portable, embedding-free knowledgebase from a set of files and delivers it as a self-contained `.skill` bundle (BM25 index + bundled searcher + query protocol). Use when a user wants to turn uploaded files, a folder, or a corpus into a searchable knowledgebase they can

BOOST
From plugin
claude-skills
15498 skills1 agent
Install
$ npx -y skills add oaustegard/claude-skills --skill creating-kb --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/creating-kb

Context preview

The summary Claude sees to decide when to auto-load this skill.

Builds a portable, embedding-free knowledgebase from a set of files and delivers it as a self-contained `.skill` bundle (BM25 index + bundled searcher + query protocol). Use when a user wants to turn uploaded files, a folder, or a corpus into a searchable knowledgebase they can

SKILL.md

creating-kb.SKILL.md
name: creating-kb
description: Builds a portable, embedding-free knowledgebase from a set of files and delivers it as a self-contained `.skill` bundle (BM25 index + bundled searcher + query protocol). Use when a user wants to turn uploaded files, a folder, or a corpus into a searchable knowledgebase they can hand to any agent — phrased as "make a knowledgebase", "build a KB skill", "package these docs for retrieval", "create a searchable bundle", or references to a `.skill` KB. The output runs anywhere with Node or Python — no model, no install, no network. Distinct from `bm25` (ephemeral in-session search) and `building-github-index` (markdown project-knowledge index).
metadata:
  version: 0.2.0

creating-kb

Turn a pile of files into a **portable, deployable knowledgebase**. The output is a `.skill` bundle — an ordinary zip — containing a BM25 inverted index, the chunk text, a pure-Node searcher, and a query protocol. It has no embedding model and no semantic search: retrieval is lexical, and the consuming agent supplies the semantic layer by expanding the query at search time. That is what makes the bundle portable — any agent that can run `node` can query it with no `npm install`, no model download, and no network.

The whole toolchain is JavaScript so one implementation serves both this builder and the in-browser packer. Build with the bundled script; do not hand-roll the index.

SCRIPTS=/mnt/skills/user/creating-kb/scripts
node $SCRIPTS/build_lexkb.js CORPUS_DIR --out /tmp/kb --name my-kb --zip

Workflow

1. Gather the sources

Collect the files into one directory. In a Claude.ai chat, uploads land in `/mnt/user-data/uploads/` — point the builder there. Otherwise use any path the user names. Supported extensions default to `txt,md,html,htm`; pass `--ext` to change them.

This MVP interface is bounded by how many files a chat can accept. For a large corpus, stage the files in a directory first, or use the browser packer (built from the same scripts) that runs entirely client-side.

2. Build the bundle

SCRIPTS=/mnt/skills/user/creating-kb/scripts
node $SCRIPTS/build_lexkb.js /mnt/user-data/uploads \
  --out /tmp/kb --name my-kb --zip \
  --source "human description of the corpus"

The script chunks each file, builds the BM25 index, writes the bundle dir (`SKILL.md` + `search.js` + `index.json` + `chunks.jsonl`), and — with `--zip` — emits `my-kb.skill` next to `--out`.

3. Deliver

Move the `.skill` to the outputs directory and give the user a download link:

cp /tmp/my-kb.skill /mnt/user-data/outputs/
[Download my-kb.skill](computer:///mnt/user-data/outputs/my-kb.skill)

Tell the user how to deploy it: unzip into an agent's skill directory (or upload it as a skill). The bundle's own `SKILL.md` then drives querying — the consuming agent reads it, expands each question into search terms, and runs the bundled `search.js`. No further setup.

Choosing chunk size

The retrieval unit and the reasoning unit are decoupled, which makes chunk size a low-stakes choice. `search.py`/`search.js` **rank** on the whole chunk (best recall) but **return** only the query-densest passage of it by default (`--snippet`, ~1200 chars), so a big chunk does not flood the consuming agent's context with surrounding noise. Index for recall; the searcher handles signal.

`--target-chars` controls chunk size (whole paragraphs are packed up to the target; `--target-chars 0` makes each file one chunk). Lexical BM25 tolerates — and on a real-corpus sweep slightly *preferred* — larger chunks than embedding-based retrieval, because there is no vector to dilute: BM25 scores individual term presence with length normalization, so a big chunk still ranks on the exact terms it contains.

  • **Default: `--target-chars 0` (whole document).** Best recall, fewest chunks;

the snippet return keeps reasoning context focused.

  • Long, multi-topic files where you want tighter citation units: `1500`–`4000`.
  • `500` only if you need very fine-grained chunk ids and accept more chunks.

Verifying the bundle

Test before delivering. Run a query against the freshly built bundle and confirm it returns sensible hits:

node /tmp/kb/search.js --query "a representative question" \
  --core "key term" --expand "synonym" --k 3

Each hit's `text` is the query-focused passage by default; add `--snippet 0` to inspect a full chunk.

`search.js` prints JSON `{"hits": [...]}`. Confirm the right chunks surface.

What ships in the bundle

| File | Role | |---|---| | `SKILL.md` | the query protocol the consuming agent follows (expand → search → cite) | | `search.js` / `search.py` | equivalent BM25 + RM3 + metadata-filter searchers; return query-focused passages (matched sentences kept in neighbour context, merged); the agent runs whichever runtime it has | | `index.json` | precomputed inverted index (postings, df, doc lengths, BM25 params) | | `chunks.jsonl` | chunk text + structured metadata |

Both searchers are thin readers of the same neutral JSON index, so the bundle runs in a Node-only or a Python-only consumer. Metadata stays structured (not folded into the indexed text), which lets the consuming agent filter on it (`--filter section=blog`, `--filter date>=2025`).

Scripts

  • `scripts/build_lexkb.js` — chunker + BM25 index builder + `.skill` writer.
  • `scripts/search.js` — the JS runtime searcher, copied verbatim into every

bundle. It owns the tokenizer; the builder imports it so index and queries tokenize identically.

  • `scripts/search.py` — the Python runtime searcher, copied verbatim into every

bundle; a thin reader of the same neutral JSON index, parity-pinned to `search.js` (identical results on a shared index).

  • `scripts/zipstore.js` — pure-JS ZIP-STORED writer (used by the builder; shared

with the in-browser packer).

  • `scripts/bundle_SKILL.md` — the query-side SKILL.md template written into each

bundle.

Read more
Ships withclaude-skills

A collection of Claude skills distributed as a Claude Code plugin marketplace. Skills are primarily designed for the Claude.ai PaaS skill compute environment; mileage will vary if used as Claude Code Agent Skills.

Get the whole plugin

Other skills on claude-skills.