Skip to main content

toolery

A searchable, self-maintaining catalog over any corpus of tools, skills, agents, and components.

For humans: you have better things to do than read a README. Point your coding agent at toolery's skill — gh skill install thorwhalen/toolery toolery — and say "catalog my stuff and find me X." It takes it from there.

For agents, engineers, and control freaks: welcome, the rest of this README is yours — and there's an AGENTS.md with the canonical brief + module map.

Point toolery at a collection of heterogeneous assets — Claude skills, agent specs, MCP tools, docs, or packages — and get one searchable catalog: ask "what do I already have for X?" and get a ranked answer, not fifty schemas.

pip install toolery

Quick start

Search a folder of notes/docs from the command line:

toolery search "dedupe a csv" ~/my/notes

Or from Python — the simplest thing that works, with zero configuration:

import toolery

cat = toolery.catalog("~/my/notes")        # harvest a folder of markdown
for card, score in cat.search("parse pdf"):
    print(score, card.name, card.source_uri)

Out of the box the search is a fast, dependency-free lexical scorer, so nothing to install, no models, no API keys.

Any corpus, any asset kind

A catalog is built from sources. A source is a folder, a built-in harvester, or bare cards:

import toolery

cat = toolery.catalog(
    toolery.skills("~/.claude/skills"),     # Claude Agent Skills (SKILL.md)
    toolery.agents("~/.claude"),            # subagent specs (.claude/agents/*.md)
    toolery.packages("~/my/projects"),      # Python packages (pyproject.toml)
    toolery.mcp("~/my/project"),            # configured MCP servers (.mcp.json)
    "~/my/notes",                           # a folder of docs
    [toolery.Card("grep", "tool", "grep", "search text with patterns")],
)
cat.search("find text in files")
cat.by_kind("skill")
cat.kinds                                   # {'skill': 42, 'agent': 9, 'package': 210, ...}

Built-in harvesters: folder, skills, agents, packages, mcp — each just a generator of Cards, so adding a new asset kind is one small function. The CLI mirrors them: toolery skills|agents|packages <root> (add --query to search).

Everything is projected onto one uniform record, the Card (id, kind, name, description, tags, source_uri, content_ref). Supporting a new asset kind (agent specs, MCP tool schemas, packages) is just another generator that yields Cards — nothing else changes.

Bring your own search

catalog(...) and Catalog(...) accept a search_backend — any callable (query, cards, *, limit) -> [(card, score), ...]. The default, toolery.lexical_search, needs no dependencies. A semantic backend built on the ir retrieval substrate drops into the same seam, so you can start lexical and upgrade to embeddings without changing your calling code.

from toolery import Catalog, lexical_search, IrBackend

cat = Catalog(cards, search_backend=lexical_search)   # zero-dependency default
cat = Catalog(cards, search_backend=IrBackend())      # embeddings — pip install 'toolery[ir]'

IrBackend embeds each card and answers by vector similarity, rebuilding only when the cards change. Pass embedder="light" for a hermetic, no-download hashing embedder, or the default MiniLM for real semantic matching. From the CLI: add --semantic to toolery search.

For a multi-kind catalog, IrFederatedBackend builds one ir corpus per kind and searches them together via ir.discover([...]) — per-kind abstention floors + Reciprocal Rank Fusion, so skills, packages, and docs (whose similarity scores live on different scales) compare fairly:

from toolery import Catalog, IrFederatedBackend

cat = Catalog(mixed_kind_cards, search_backend=IrFederatedBackend())

The CLI exposes it as toolery discover "<query>" <root> --kinds skill,agent,doc,package.

Catalog your whole ecosystem

toolery.contrib builds a catalog over your usual asset locations in one call:

from toolery import contrib

cat = contrib.everything(package_roots=["~/proj/mine"])   # + your ~/.claude skills & agents
cat.search("thing I half-remember writing")

Keep your locations in ~/.config/toolery/sources.toml and search them all from the CLI:

[claude]
roots = ["~/.claude", "~/work/project"]
[packages]
roots = ["~/proj/mine", "~/proj/theirs"]
[harvesters]
refs = ["mymod:my_cards"]   # "module:function" -> your own Card/dict source (e.g. a private index)
toolery mine "which of my tools parses pdfs?"              # lexical
toolery mine "which of my tools parses pdfs?" --semantic   # ir federated (toolery[ir])

For a large corpus, warm a persistent on-disk index once (incremental via ir's ledger, so only changed assets are re-embedded) and reuse it across runs:

toolery index                                   # build/refresh the on-disk index
toolery mine "…" --semantic --persist           # reuse it — fast

Your paths and any private-source refs live in that local file — nothing personal is baked into the package.

Give an agent one search tool (MCP)

Instead of exposing a schema per asset, serve your whole catalog as a single MCP search tool (needs pip install 'toolery[mcp]'):

toolery serve            # stdio MCP server over your ~/.config/toolery/sources.toml
toolery serve --http     # or Streamable HTTP

Point your agent host's MCP config at that command and the agent gets one search tool over everything — the "one search tool, not fifty schemas" idea, made concrete. In Python:

from toolery import make_server, contrib

make_server(contrib.everything(package_roots=["~/proj"])).run(transport="stdio")

Skills (this package is AI-enabled)

toolery ships agent skills — install into any agent host with gh skill:

gh skill install thorwhalen/toolery toolery        # consumer: drive toolery to find your assets
gh skill install thorwhalen/toolery toolery-dev    # developer: extend & maintain toolery

They also ride along inside the wheel (toolery/data/skills/) and mirror to .claude/skills/ for Claude Code. Canonical agent instructions live in AGENTS.md (CLAUDE.md is a thin shim over it).

Status

Early (0.x). In place: the Card/catalog model; harvesters for folders, skills, agents, packages, and MCP servers; a zero-dependency lexical backend; an optional ir-backed semantic backend (toolery[ir]), plus federated multi-kind discovery (IrFederatedBackend / toolery discover); a contrib ecosystem preset (toolery mine); persistent incremental indexing (toolery index / --persist); MCP exposure as a single search tool (toolery serve); and the CLI. Also integrated into opsward (opsward find). Next: progressive-disclosure loading.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

toolery-0.0.10.tar.gz (26.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

toolery-0.0.10-py3-none-any.whl (21.6 kB view details)

Uploaded Python 3

File details

Details for the file toolery-0.0.10.tar.gz.

File metadata

  • Download URL: toolery-0.0.10.tar.gz
  • Upload date:
  • Size: 26.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for toolery-0.0.10.tar.gz
Algorithm Hash digest
SHA256 e5bb61e9af3e249e237812e32b819bddad83394e045aee158e73c8ce30a67d9c
MD5 2e5785721da6b886ace79a9f32874f77
BLAKE2b-256 fdd4572b6a9c2bb504be565345b43c1aa4904060ca0c51aa91d69c5dc7d450c5

See more details on using hashes here.

File details

Details for the file toolery-0.0.10-py3-none-any.whl.

File metadata

  • Download URL: toolery-0.0.10-py3-none-any.whl
  • Upload date:
  • Size: 21.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.26 {"installer":{"name":"uv","version":"0.11.26","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for toolery-0.0.10-py3-none-any.whl
Algorithm Hash digest
SHA256 e5362b429523b2530d7ac860d9f41dc8f7f8224000279ffa8034bd4f4369ffd0
MD5 5efe99c31c503f9b1240c753aea09b5e
BLAKE2b-256 d6adddcdaaacad986b854ccfb4a4f7394683770d4b40675fbf3c9521b1417c6e

See more details on using hashes here.

Release history Release notifications | RSS feed

This release

0.0.10 This release

2 files

0.0.9

2 files

0.0.8

2 files

0.0.7

2 files

0.0.6

2 files

0.0.5

2 files

0.0.4

2 files

0.0.3

2 files

0.0.2

2 files

0.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page