hooks — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited hooks (Hook) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
A local-first alternative to Context7 for Claude Code. Indexes your project's dependency documentation and source code locally with production-grade semantic search. Embeddings and reranking run via TEI (HuggingFace Text Embeddings Inference) Docker containers with auto GPU detection. Supports JS/TS, Vue, Svelte, and Astro with AST-aware chunking, JSDoc extraction, and git-diff incremental indexing.
Benchmark Results
Tested on a real-world TypeScript monorepo (957 files, 4,484 indexed code chunks) with 187 generic queries across 16 categories (authentication, database, caching, error handling, etc.).
How scores are computed:
top_relevance * 9.5 + result_count_bonus). Zero results = zero score.7.5 - 1.5 * log10(matching_files)). Few focused matches score high; hundreds of files score low. Capped at 7.5 since grep always requires manual review.max(Semantic, Grep) per query. Represents what Claude Code gets when both tools are available.How the benchmark was run:
search_code (this plugin's MCP tool) and rg (ripgrep, same as Claude Code's built-in Grep). The MCP tool returns a relevance score (0-1) and result count; grep returns a file count.A supported GPU is mandatory for embedding and reranking inference. CPU-only mode is not supported.
| Platform | GPU | Backend | VRAM needed |
|---|---|---|---|
| Windows / Linux | NVIDIA RTX 20x0+ (Turing or newer) | Docker with CUDA | ~5 GB |
| macOS | Apple Silicon (M1/M2/M3/M4) | Native Metal (no Docker) | Uses unified memory |
The three TEI models require approximately:
nomic-ai/nomic-embed-text-v1.5 — ~270 MBcross-encoder/ms-marco-MiniLM-L-6-v2 — ~90 MBQodo/Qodo-Embed-1-1.5B — ~3 GB (FP16)First run downloads all models (~3.4 GB total). Subsequent starts use cached models.
| Requirement | NVIDIA path | Apple Silicon path |
|---|---|---|
| Node.js 20+ | Required | Required |
| Docker Desktop | Required (install) | Not needed |
| NVIDIA Container Toolkit | Linux only — required for GPU passthrough (install). Not needed on Windows (Docker Desktop handles it via WSL2). | N/A |
| Rust | N/A | Required for first build (install) |
TEI uses three local ports (not exposed to the network):
| Port | Service | Configurable via |
|---|---|---|
39281 | Doc embeddings | TEI_EMBED_URL |
39282 | Cross-encoder reranker | TEI_RERANK_URL |
39283 | Code embeddings | TEI_CODE_EMBED_URL |
# Add the marketplace
/plugin marketplace add matteodante/claude-local-docs
# Install the plugin
/plugin install claude-local-docsThe plugin starts TEI containers automatically on session start via a SessionStart hook.
git clone https://github.com/matteodante/claude-local-docs.git
cd claude-local-docs
npm install
npm run build
# Start TEI (auto-detects GPU)
./start-tei.sh| claude-local-docs | Context7 | |
|---|---|---|
| Runs where | Your machine (TEI Docker) | Upstash cloud servers |
| Privacy | Docs never leave your machine | Queries sent to cloud API |
| Rate limits | None | API-dependent |
| Offline | Full search works offline | Requires internet |
| GPU accelerated | NVIDIA CUDA / Apple Metal | N/A |
| Search quality | 4-stage RAG (vector + BM25 + RRF + cross-encoder reranking) | Single-stage retrieval |
| Doc sources | Prefers llms.txt, falls back to official docs | Pre-indexed source repos |
| Code search | Semantic AST-level search via Qodo-Embed-1-1.5B | N/A |
| Framework support | JS, TS, Vue, Svelte, Astro (SFC script extraction) | N/A |
| Scope | Your project's actual dependencies + source code | Any library |
| Monorepo | Detects pnpm/npm/yarn workspaces, resolves catalogs | N/A |
| Resilience | Retry with exponential backoff + 30s timeout on TEI calls | N/A |
/fetch-docs search_docs("how to use useState")
| |
v v
Detect monorepo +--- Vector search (LanceDB) ---+
Scan all workspace pkgs | nomic-embed-text-v1.5 |
Resolve catalog: versions | |
| | +-> RRF Fusion
v | | (k=60)
For each runtime dep: +-- BM25 search (LanceDB FTS) --+
- Search for llms.txt | keyword + stemming |
- Raw fetch (no truncation)| v
- Chunk + embed + store | Cross-encoder rerank
| ms-marco-MiniLM-L-6-v2
| (via TEI :39282)
+----------------------------------+
|
v
Top-K results/index-codebase search_code("RRF fusion logic")
| |
v v
Walk project files +--- Vector search (LanceDB) -------+
Respect .gitignore | Qodo-Embed-1-1.5B (1536-dim) |
Git-diff incremental skip | |
| | +-> RRF Fusion
v | | (k=60)
For each JS/TS/Vue/ +-- BM25 search (LanceDB FTS) ------+
Svelte/Astro file: | camelCase split + stemming |
- Extract <script> (SFC) | |
- Parse AST (tree-sitter) +-- File-path boost (optional) -----+
- Extract functions/classes | v
- Extract JSDoc/decorators | Cross-encoder rerank
- Contextual headers | ms-marco-MiniLM-L-6-v2
- Embed with Qodo-Embed | (via TEI :39282)
- Store in LanceDB +--------------------------------------+
|
v
Function-level results
(file, lines, scope, score)
+ neighbor chunk expansion/fetch-docsClaude analyzes your project (including monorepo workspaces), finds all runtime dependencies, searches the web for the best documentation for each one (preferring llms-full.txt > llms.txt > official docs), and indexes everything locally.
/index-codebaseParses all JS/TS/Vue/Svelte/Astro files with tree-sitter, extracts JSDoc comments and decorators, generates Qodo-Embed-1-1.5B embeddings for function/class/method-level chunks, and stores them in LanceDB. Incremental via git-diff (falls back to SHA-256 hashing for non-git projects). Only changed files are re-indexed.
Ask Claude anything. It will automatically use the right search tool:
# Library documentation (search_docs)
How do I set up middleware in Express?
What are the options for useQuery in TanStack Query?
Show me the API for zod's .refine()
# Your codebase (search_code)
Where is the authentication middleware?
Find the database connection setup
How does the search pipeline work?ML inference runs in TEI (HuggingFace Text Embeddings Inference) containers:
| Container | Port | Model | Purpose |
|---|---|---|---|
| tei-embed | :39281 | nomic-ai/nomic-embed-text-v1.5 | Doc embeddings (384-dim Matryoshka) |
| tei-rerank | :39282 | cross-encoder/ms-marco-MiniLM-L-6-v2 | Cross-encoder reranking (docs + code) |
| tei-code-embed | :39283 | Qodo/Qodo-Embed-1-1.5B | Code embeddings (1536-dim, 68.5 CoIR) |
All TEI communication goes through a shared TeiClient class (src/tei-client.ts) with automatic retry (2 attempts, exponential backoff), 30s timeout, and batch splitting. TEI containers must be running for both indexing and search — there is no fallback mode.
./start-tei.sh # Auto-detect GPU
./start-tei.sh --metal # Force Apple Metal (native, no Docker)
./start-tei.sh --cpu # Force CPU Docker
./start-tei.sh --stop # Stop all TEIAuto-detection selects the optimal backend:
| Platform | Backend | Image tag |
|---|---|---|
| NVIDIA RTX 50x0 (Blackwell) | Docker CUDA | 120-1.9 |
| NVIDIA RTX 40x0 (Ada) | Docker CUDA | 89-1.9 |
| NVIDIA RTX 30x0 (Ampere) | Docker CUDA | 86-1.9 |
| NVIDIA RTX 20x0 (Turing) | Docker CUDA | turing-1.9 |
| Apple Silicon | Native Metal | cargo install --features metal |
GPU override for NVIDIA:
docker compose -f docker-compose.yml -f docker-compose.nvidia.yml up -dDoc search uses a 4-stage RAG pipeline. Code search adds a 5th file-path boost signal:
| Stage | Technology | Purpose |
|---|---|---|
| Vector search | LanceDB + nomic-embed / Qodo-Embed via TEI | Semantic similarity (understands meaning) |
| BM25 search | LanceDB native FTS (BM25, stemming, stop words) | Keyword matching (exact terms like useEffect) |
| RRF fusion | Reciprocal Rank Fusion (k=60) | Merges both ranked lists, handles different score scales |
| Cross-encoder rerank | ms-marco-MiniLM-L-6-v2 via TEI | Rescores top 50 candidates with deep relevance model |
exported, async, abstract tracked per entity<script>/<script setup>, Svelte <script>/<script context="module">, Astro --- frontmatter + <script> tagsAll data stays in your project directory:
your-project/.claude/docs/
├── lancedb/ # Vector database (docs + code tables)
├── .metadata.json # Doc fetch timestamps, source URLs per library
├── .code-metadata.json # File hashes, language, chunk counts, last index
└── raw/
├── react.md # Raw fetched documentation
├── next.md
└── tanstack__query.md| Tool | Description |
|---|---|
analyze_dependencies | Detect and list all npm dependencies (monorepo-aware, runtime/dev tagged) |
store_and_index_doc | Index documentation content you already have as a string |
fetch_and_store_doc | Fetch documentation from a URL and index it (raw HTTP, no truncation) |
discover_and_fetch_docs | Auto-discover and index docs for an npm package |
search_docs | Semantic search across indexed library documentation |
list_docs | List indexed libraries with version and fetch date |
get_doc_section | Retrieve specific doc sections by heading or chunk ID |
index_codebase | Index project source code for semantic search (incremental, .gitignore-aware) |
search_code | Semantic search across project source code (function/class-level) |
get_codebase_status | Check codebase index status, language breakdown, changed files |
| Package | License | Purpose |
|---|---|---|
@lancedb/lancedb | Apache 2.0 | Embedded vector database + native FTS |
@modelcontextprotocol/sdk | MIT | MCP server framework |
web-tree-sitter | MIT | WASM-based AST parsing for code chunking |
tree-sitter-wasms | MIT | Pre-built WASM grammars (JS/TS/Vue/Svelte) |
ignore | MIT | .gitignore pattern matching |
zod | MIT | Schema validation |
TEI containers (Docker):
| Image | Model | Purpose |
|---|---|---|
text-embeddings-inference:* | nomic-ai/nomic-embed-text-v1.5 | Doc embeddings |
text-embeddings-inference:* | cross-encoder/ms-marco-MiniLM-L-6-v2 | Cross-encoder reranking |
text-embeddings-inference:* | Qodo/Qodo-Embed-1-1.5B | Code embeddings (1536-dim) |
npm run dev # Watch mode — rebuilds on file changes
npm run build # One-time build
npm run test:unit # Unit tests (no TEI needed)
npm run test:docs # Doc search integration tests (requires TEI on :39281, :39282)
npm run test:code # Code search integration tests (requires TEI on :39281, :39282, :39283)claude-local-docs/
├── .claude-plugin/
│ ├── plugin.json # Plugin manifest
│ └── marketplace.json # Marketplace listing
├── .mcp.json # MCP server config (stdio transport)
├── commands/
│ ├── fetch-docs.md # /fetch-docs — Claude as research agent
│ └── index-codebase.md # /index-codebase — index source code
├── hooks/
│ └── hooks.json # SessionStart hook for TEI containers
├── scripts/
│ └── ensure-tei.sh # Idempotent TEI health check + start
├── docker-compose.yml # TEI containers (uses ${TEI_TAG})
├── docker-compose.nvidia.yml # NVIDIA GPU device passthrough
├── start-tei.sh # Auto-detect GPU, start TEI
├── src/
│ ├── index.ts # MCP server entry, 10 tool definitions
│ ├── tei-client.ts # Shared TEI HTTP client (retry, timeout, batching)
│ ├── indexer.ts # Doc chunking + nomic-embed-text embeddings
│ ├── search.ts # Doc search pipeline (vector + BM25 + RRF + rerank)
│ ├── rrf.ts # Shared Reciprocal Rank Fusion utility
│ ├── reranker.ts # TEI cross-encoder reranking
│ ├── store.ts # LanceDB "docs" table + metadata
│ ├── code-indexer.ts # AST chunking (tree-sitter) + Qodo-Embed embeddings
│ ├── code-search.ts # Code search pipeline (5-stage + neighbor expansion)
│ ├── code-store.ts # LanceDB "code" table + file hash tracking + schema migration
│ ├── file-walker.ts # Project file discovery + .gitignore + git-diff
│ ├── sfc-extractor.ts # Vue/Svelte/Astro <script> block extraction
│ ├── fetcher.ts # Raw HTTP fetch (no AI truncation)
│ ├── workspace.ts # Monorepo detection + pnpm catalog
│ ├── discovery.ts # npm registry + URL probing for docs
│ ├── types.ts # Shared TypeScript interfaces
│ ├── unit.test.ts # Unit tests (no TEI needed)
│ ├── docs.test.ts # Doc search integration tests
│ └── code.test.ts # Code search integration tests
├── LICENSE
├── package.json
└── tsconfig.json# Check Docker is running
docker info
# Check container logs
docker compose logs tei-embed
docker compose logs tei-rerank
docker compose logs tei-code-embed
# Restart
./start-tei.sh --stop && ./start-tei.shIf 39281/39282/39283 are in use, override via env vars:
TEI_EMBED_URL=http://localhost:49281 TEI_RERANK_URL=http://localhost:49282 TEI_CODE_EMBED_URL=http://localhost:49283 node dist/index.jsThe default Docker CPU image runs via Rosetta 2. Use native Metal instead:
./start-tei.sh --metalRequires Rust (curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh). First build takes a few minutes.
MIT
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.