Skip to main content

Lazy-loading skill discovery for Claude Code via MCP โ€” mirrors Anthropic's Tool Search Tool pattern for Skills.

Project description

๐Ÿ“ก skills-radar

Lazy-loading skill discovery for Claude Code (and other MCP clients). Stop bleeding context tokens on skills you might never use.

skills-radar is a local MCP server that mirrors Anthropic's MCP Tool Search Tool pattern โ€” but for Skills. Instead of preloading every skill's metadata into the system prompt at session start (default Claude Code behavior), skills-radar exposes two tools (search_skills, load_skill) so the agent fetches only what's relevant to the current task.

Why this exists: Anthropic shipped Tool Search for MCP tools in late 2025 (85% token reduction, +8.6% accuracy on Opus 4.5). They haven't shipped the equivalent for Skills yet. With 80+ skills across personal, project, and plugin scopes, your /doctor is probably bleeding 5โ€“10k tokens before you type a word. This fixes that.

Status: ๐Ÿšง v0.1 in active development. Spec: SPEC.md. MVP target: ~3-4h after spec approval.


Two deployment modes

Pick one based on your workflow:

Mode A โ€” Docker Desktop running 24/7 (recommended for shared / cross-platform / Linux / Windows)

One container, every Claude Code session in every project connects to the same http://localhost:6580/mcp. Container has persistent ChromaDB volume + bind-mounted skill paths read-only + watcher on (baked config). Healthy in ~1 second after docker compose up.

git clone https://github.com/darco81/skills-radar
cd skills-radar
docker compose up -d --build

claude mcp add --transport http skills-radar http://localhost:6580/mcp
# Restart Claude Code โ€” /mcp shows skills-radar connected.

Pros: one moving piece, recoverable via docker compose restart, runs on Linux/Windows/macOS, isolated. Limitation on macOS: no MLX inside the container (Linux container can't reach the Apple GPU). Use Mode B for the full MLX stack.

Mode B โ€” Native install (recommended for the 100% local Apple Silicon MLX stack)

stdio subprocess per Claude Code session, OR a long-running HTTP server.

pip install 'skills-radar[mlx]'                # MLX extras for Apple Silicon
skills-radar config-init
skills-radar index

# stdio (auto-starts per CC session):
claude mcp add skills-radar -- skills-radar serve --transport stdio --watch

# OR HTTP, long-running (Mode A behavior natively, with MLX):
skills-radar serve --transport http --watch &
claude mcp add --transport http skills-radar http://localhost:6580/mcp

Pros: full MLX rewriter + reranker on Apple Silicon (4096-dim Qwen3 embedder, MoE Qwen3-Coder for rerank), zero Ollama, zero network. Mac arm64 only.

Recovering token budget (both modes)

{ "skillOverrides": { "*": "name-only" } }

Now Claude only sees skill names in the prompt (~1k tokens for 80 skills), and queries skills-radar for full descriptions when needed.


How it works โ€” Two-Tier Discovery

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ Claude Code session                                    โ”‚
โ”‚  System prompt: mini-index (~1k tokens, names only)    โ”‚
โ”‚  MCP tools: search_skills, load_skill                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
           โ”‚
           โ–ผ  intent: clear?
   โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
   โ”‚ obvious name?         โ”‚
   โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”˜
        โ”‚ yes         โ”‚ no/ambiguous
        โ–ผ             โ–ผ
 load_skill(name)  search_skills(query)
                       โ”‚
                       โ–ผ
              top-k matches w/ score
                       โ”‚
                       โ–ผ agent picks best
                  load_skill(best.name)
        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
        โ”‚ Full SKILL.md content    โ”‚
        โ”‚ + trust tier + warnings  โ”‚
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Tier 1 (always, ~1k tokens): mini-index of skill names + 1-line summaries. Tier 2 (on demand): full SKILL.md body, fetched only when agent commits to using it.

Result: from ~6k tokens loaded upfront to ~1k tokens + on-demand. ~83% savings, and you can scale to 500 skills without your prompt suffering.


Features

  • ๐Ÿ” Hybrid retrieval โ€” BM25 (lexical) + dense embeddings (semantic), 70/30 by default
  • ๐Ÿ”ฅ Hot reload โ€” drop a SKILL.md, indexed in <1s via watchdog (no Claude restart)
  • ๐Ÿ›ก๏ธ Threat model day-one โ€” trust tiers (TRUSTED / VERIFIED / USER / UNTRUSTED), prompt-injection scanning, size limits, XML-injection stripping
  • ๐Ÿชถ Light by default โ€” sentence-transformers (90MB) + ChromaDB (zero deps)
  • ๐Ÿ”Œ Pluggable โ€” swap embedder (sentence-transformers, MLX [planned], Voyage [planned], OpenAI [planned]); swap store (ChromaDB default, Qdrant [planned])
  • ๐ŸŒ Multi-client โ€” Claude Code, Cursor, Claude Desktop, custom MCP agents
  • ๐Ÿ“ก Streamable HTTP transport (stateless_http=True, json_response=True) for production; stdio for local dev
  • ๐Ÿค– Optional local-LLM query rewriter (Ollama) โ€” rewrites ambiguous queries into richer keyword phrases before embedding
  • โœˆ๏ธ Air-gapped friendly โ€” pre-baked Docker image, offline HF Hub flags
  • ๐Ÿงช 2-tool MCP surface โ€” search_skills + load_skill. Mirrors Anthropic's Tool Search Tool pattern. Eats own dogfood: tool descriptions stay under 200 chars.

Production deployment

For shared / multi-client / Docker deployments, run the Streamable HTTP transport instead of stdio.

Bare-metal

skills-radar serve --transport http --host 0.0.0.0 --port 6580 --watch

Defaults match MCP Python SDK guidance: stateless_http=True, json_response=True โ€” pair both for horizontal scaling behind a load balancer.

Docker

docker compose up -d --build

The bundled Dockerfile pre-bakes the embedding model so containers start in ~2s instead of doing a 30-60s first-run download. Defaults to non-root uid 1000, offline HF Hub flags, strict sanitization (UNTRUSTED tier + strip_live_exec=true) โ€” community skills mounted via Docker shouldn't be allowed to run host-level commands.

docker-compose.yml mounts your ~/.claude/skills and plugin cache read-only and persists the ChromaDB store as a named volume.

Verify

curl -X POST http://127.0.0.1:6580/mcp \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json,text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"client","version":"0.1.0"}}}'

Should return 200 OK with the server capabilities + tool list.


Local-LLM query rewriter (optional, opt-in)

If you have Ollama running locally, you can have it rewrite ambiguous queries (especially multi-language ones) into richer English keyword phrases before they hit the embedder. Big quality boost for free.

# ~/.config/skills-radar/config.yaml
retrieval:
  rewriter:
    enabled: true
    backend: ollama
    model: gemma4:e4b      # or any small local model with low latency
    url: http://localhost:11434
    timeout: 5.0

Resilient by design: any HTTP error, timeout, or parse failure falls back to the raw query. Off by default โ€” search works exactly as before unless you opt in.


Project status

Phase Status Tag
Spec & architecture โœ… Done โ€”
F1 โ€” MVP (search + load, in-mem) โœ… Done v0.1.0a0
F2 โ€” Production (hot-reload, HTTP, threat model, Docker, integration tests) โœ… Done v0.2.0
F3 โ€” Public release (PyPI, GitHub Actions, FtF post) ๐Ÿ”„ In progress โ€”
F4 โ€” Polish (MLX backend, telemetry, TUI, more backends) โณ Backlog post-1.0

See SPEC.md for full PRD. See docs/ for architecture deep dive, threat model, writing-skills guide, context engineering rationale, and onboarding.


Acknowledgments / Prior art

This project stands on shoulders. Worth checking out:

What skills-radar does differently: 2-tool surface (mirroring Anthropic's pattern), Anthropic-aligned defaults, air-gapped friendly, multi-client by design.


License

MIT (planned). See LICENSE once published.


Author

Built by Dariusz Kowalski โ€” SDET, accessibility advocate, context-engineering enthusiast.

Part of the SDET ecosystem: sdet.it ยท cdat.sdet.it ยท brain.sdet.it (soon)

Project details


Download files

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

Source Distribution

skills_radar-0.4.0a2.tar.gz (102.9 kB view details)

Uploaded Source

Built Distribution

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

skills_radar-0.4.0a2-py3-none-any.whl (60.2 kB view details)

Uploaded Python 3

File details

Details for the file skills_radar-0.4.0a2.tar.gz.

File metadata

  • Download URL: skills_radar-0.4.0a2.tar.gz
  • Upload date:
  • Size: 102.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for skills_radar-0.4.0a2.tar.gz
Algorithm Hash digest
SHA256 a1528c89e8563eb95c4c6caa38b7ee7e900e7e59c61e73fc6e2c21977d9692a7
MD5 7c85d7a52ab0ab256ae9f3897aa56d01
BLAKE2b-256 003ed311346467fb7d95417b4bb23426b9d1b1967f217df845b174d35e334118

See more details on using hashes here.

Provenance

The following attestation bundles were made for skills_radar-0.4.0a2.tar.gz:

Publisher: publish.yml on darco81/skills-radar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file skills_radar-0.4.0a2-py3-none-any.whl.

File metadata

  • Download URL: skills_radar-0.4.0a2-py3-none-any.whl
  • Upload date:
  • Size: 60.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for skills_radar-0.4.0a2-py3-none-any.whl
Algorithm Hash digest
SHA256 1d905dcb5ba05ab64c2815721899f056ac52282be1b8e2dfc18d8ee1cb7904dd
MD5 f14bbeca1f8bd44b18dd721788dfb1d0
BLAKE2b-256 cd71b2ee790c6bef58bc033d35df592533519d7335be5b6c5abdfb6d75b9e7ca

See more details on using hashes here.

Provenance

The following attestation bundles were made for skills_radar-0.4.0a2-py3-none-any.whl:

Publisher: publish.yml on darco81/skills-radar

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page