/mcp-local-rag
Searches, saves, and maintains a local document index through a local RAG MCP server. Use when user says "search my docs", "save this page", "read around that chunk", "sync my index", or invokes `npx mcp-local-rag`.
$ npx -y skills add shinpr/mcp-local-rag --skill mcp-local-rag --agent claude-codeHow 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
/mcp-local-rag
Context preview
The summary Claude sees to decide when to auto-load this skill.
Searches, saves, and maintains a local document index through a local RAG MCP server. Use when user says "search my docs", "save this page", "read around that chunk", "sync my index", or invokes `npx mcp-local-rag`.
SKILL.md
mcp-local-rag.SKILL.mdname: mcp-local-rag
description: Searches, saves, and maintains a local document index through a local RAG MCP server. Use when user says "search my docs", "save this page", "read around that chunk", "sync my index", or invokes `npx mcp-local-rag`.
MCP Local RAG Skills
Tools
| MCP Tool | CLI Equivalent | Use When | |----------|---------------|----------| | `ingest_file` | `npx mcp-local-rag ingest <path> [--visual]` | Local files (PDF, DOCX, TXT, MD). CLI for bulk/directory. PDF visual mode: see [Visual content (PDFs)](#visual-content-pdfs). | | `ingest_data` | — | Raw content (HTML, text) with source URL | | `query_documents` | `npx mcp-local-rag query <text>` | Semantic + keyword hybrid search; optional `scope` to limit to a path prefix | | `delete_file` | `npx mcp-local-rag delete <path>` | Remove ingested content | | `list_files` | `npx mcp-local-rag list [--scope <prefix>]` | File ingestion status; optional `scope` to limit to a path prefix (reachable scan path) | | `status` | `npx mcp-local-rag status` | Database stats | | `read_chunk_neighbors` | `npx mcp-local-rag read-neighbors` | Read N chunks adjacent to a known chunkIndex (context expansion; call after `query_documents` or grep) | | `sync_start` | `npx mcp-local-rag sync [path]` | Reconcile the index with disk after files changed outside this session. See [Index sync](#index-sync) | | `sync_status` | — | Poll a `sync_start` job for progress and its final outcome |
Workflow
1. Search: query, then filter by score **and** topical relevance. Expand a hit with `read_chunk_neighbors` only when it alone cannot ground the answer. 2. Ingest: `ingest_file` for local files, `ingest_data` for raw or web content. 3. Reconcile: `sync_start` once, then poll `sync_status`, instead of re-running `ingest_file` file by file.
Search: Core Rules
Hybrid search combines vector (semantic) and keyword (BM25).
Score Interpretation
Lower = better match.
| Score | Action | |-------|--------| | < 0.3 | Use directly | | 0.3-0.5 | Include if it mentions the same concept/entity | | 0.5-0.7 | Include only if directly relevant to the question | | > 0.7 | Skip unless no better results |
Score ranks lexical and semantic proximity, not usefulness: drop a hit that shares keywords with the query but not its intent, whatever it scored.
When two hits contradict each other, settle it on source, stated version, and surrounding context — not on score, which says nothing about which one is current or correct — and report the discrepancy when that does not settle it. When a query returns nothing, check `list_files` before answering that the corpus has no such content — an empty result also means never ingested.
Limit Selection
| Intent | Limit | |--------|-------| | Specific answer (function, error) | 5 | | General understanding | 10 | | Comprehensive survey | 20 |
Scope (Optional)
Use `scope` when one database mixes multiple corpora and you want results from only one. Pass an absolute path prefix, or a list (results are unioned); it matches a `filePath` equal to or under the prefix.
| Intent | scope | |--------|-------| | Search everything | omit | | One corpus/folder | absolute prefix, e.g. `/Users/me/docs/api` | | Several corpora | list of absolute prefixes |
Prefixes must be absolute, in the server's OS path style — relative prefixes match nothing. If the user gives a relative path, derive an absolute prefix from a `filePath` in an earlier `query_documents`/`list_files` result, or omit `scope` when no absolute prefix is known.
Query Formulation
The BM25 half matches literally, so carry the user's exact identifiers, error strings, and API names into the query rather than paraphrasing them. The vector half needs enough words to have a topic, so a bare term gains from surrounding context.
When results are few or all score above 0.5, add 2-4 variants after the original term. More than that drifts off topic.
fileTitle
Each result carries `fileTitle`, the title extracted from the document, or `null` when extraction failed — so group and attribute chunks by `filePath`/`source` rather than by title alone.
Stored images
PDF and DOCX query results may include stored image attachments independently of PDF visual ingest. Treat each image and its chunk text as one evidence unit. For CLI results, decode each `data` value according to `mimeType` and pass the bytes as image input alongside that result's text. See the [CLI reference](references/cli-reference.md) for CLI image ingestion, output, and sync behavior.
Context Expansion (read_chunk_neighbors)
`read_chunk_neighbors` (CLI: `read-neighbors`) is an **on-demand context expansion utility**. Use it when a `query_documents` hit lacks enough surrounding context for a grounded answer. Chunks in this index are **semantic units** — sentences or paragraphs grouped by topic via Max-Min semantic chunking, not fixed-size text slices. Reading the chunks immediately before and after a target chunk yields coherent surrounding context, not arbitrary fragments.
Each `query_documents` result item includes `chunkIndex` plus either `filePath` or `source`. Pass `filePath` for files ingested with `ingest_file`, or `source` for content ingested with `ingest_data`.
Use this tool when one of these signals is present:
- **Insufficient context for your answer**: during response generation, the target chunk alone is not enough to reach a grounded conclusion (e.g., it references "this approach" or "as shown above" without the referent).
- **Explicit user request for more context**: the user asks for surrounding detail ("what comes before that?", "read more around that section", "show me the full explanation").
Otherwise, answer from the existing `query_documents` results.
Typical workflow when triggered: 1. Identify the specific chunk to expand (from a prior `query_documents` hit or `grep`). 2. Take that chunk's `filePath` and `chunkIndex`. 3. Call `read_chunk_neighbors` with `ch
Read more
name: mcp-local-rag description: Searches, saves, and maintains a local document index through a local RAG MCP server. Use when user says "search my docs", "save this page", "read around that chunk", "sync my index", or invokes `npx mcp-local-rag`.
MCP Local RAG Skills
Tools
| MCP Tool | CLI Equivalent | Use When | |----------|---------------|----------| | `ingest_file` | `npx mcp-local-rag ingest <path> [--visual]` | Local files (PDF, DOCX, TXT, MD). CLI for bulk/directory. PDF visual mode: see [Visual content (PDFs)](#visual-content-pdfs). | | `ingest_data` | — | Raw content (HTML, text) with source URL | | `query_documents` | `npx mcp-local-rag query <text>` | Semantic + keyword hybrid search; optional `scope` to limit to a path prefix | | `delete_file` | `npx mcp-local-rag delete <path>` | Remove ingested content | | `list_files` | `npx mcp-local-rag list [--scope <prefix>]` | File ingestion status; optional `scope` to limit to a path prefix (reachable scan path) | | `status` | `npx mcp-local-rag status` | Database stats | | `read_chunk_neighbors` | `npx mcp-local-rag read-neighbors` | Read N chunks adjacent to a known chunkIndex (context expansion; call after `query_documents` or grep) | | `sync_start` | `npx mcp-local-rag sync [path]` | Reconcile the index with disk after files changed outside this session. See [Index sync](#index-sync) | | `sync_status` | — | Poll a `sync_start` job for progress and its final outcome |
Workflow
1. Search: query, then filter by score **and** topical relevance. Expand a hit with `read_chunk_neighbors` only when it alone cannot ground the answer. 2. Ingest: `ingest_file` for local files, `ingest_data` for raw or web content. 3. Reconcile: `sync_start` once, then poll `sync_status`, instead of re-running `ingest_file` file by file.
Search: Core Rules
Hybrid search combines vector (semantic) and keyword (BM25).
Score Interpretation
Lower = better match.
| Score | Action | |-------|--------| | < 0.3 | Use directly | | 0.3-0.5 | Include if it mentions the same concept/entity | | 0.5-0.7 | Include only if directly relevant to the question | | > 0.7 | Skip unless no better results |
Score ranks lexical and semantic proximity, not usefulness: drop a hit that shares keywords with the query but not its intent, whatever it scored.
When two hits contradict each other, settle it on source, stated version, and surrounding context — not on score, which says nothing about which one is current or correct — and report the discrepancy when that does not settle it. When a query returns nothing, check `list_files` before answering that the corpus has no such content — an empty result also means never ingested.
Limit Selection
| Intent | Limit | |--------|-------| | Specific answer (function, error) | 5 | | General understanding | 10 | | Comprehensive survey | 20 |
Scope (Optional)
Use `scope` when one database mixes multiple corpora and you want results from only one. Pass an absolute path prefix, or a list (results are unioned); it matches a `filePath` equal to or under the prefix.
| Intent | scope | |--------|-------| | Search everything | omit | | One corpus/folder | absolute prefix, e.g. `/Users/me/docs/api` | | Several corpora | list of absolute prefixes |
Prefixes must be absolute, in the server's OS path style — relative prefixes match nothing. If the user gives a relative path, derive an absolute prefix from a `filePath` in an earlier `query_documents`/`list_files` result, or omit `scope` when no absolute prefix is known.
Query Formulation
The BM25 half matches literally, so carry the user's exact identifiers, error strings, and API names into the query rather than paraphrasing them. The vector half needs enough words to have a topic, so a bare term gains from surrounding context.
When results are few or all score above 0.5, add 2-4 variants after the original term. More than that drifts off topic.
fileTitle
Each result carries `fileTitle`, the title extracted from the document, or `null` when extraction failed — so group and attribute chunks by `filePath`/`source` rather than by title alone.
Stored images
PDF and DOCX query results may include stored image attachments independently of PDF visual ingest. Treat each image and its chunk text as one evidence unit. For CLI results, decode each `data` value according to `mimeType` and pass the bytes as image input alongside that result's text. See the [CLI reference](references/cli-reference.md) for CLI image ingestion, output, and sync behavior.
Context Expansion (read_chunk_neighbors)
`read_chunk_neighbors` (CLI: `read-neighbors`) is an **on-demand context expansion utility**. Use it when a `query_documents` hit lacks enough surrounding context for a grounded answer. Chunks in this index are **semantic units** — sentences or paragraphs grouped by topic via Max-Min semantic chunking, not fixed-size text slices. Reading the chunks immediately before and after a target chunk yields coherent surrounding context, not arbitrary fragments.
Each `query_documents` result item includes `chunkIndex` plus either `filePath` or `source`. Pass `filePath` for files ingested with `ingest_file`, or `source` for content ingested with `ingest_data`.
Use this tool when one of these signals is present:
- **Insufficient context for your answer**: during response generation, the target chunk alone is not enough to reach a grounded conclusion (e.g., it references "this approach" or "as shown above" without the referent).
- **Explicit user request for more context**: the user asks for surrounding detail ("what comes before that?", "read more around that section", "show me the full explanation").
Otherwise, answer from the existing `query_documents` results.
Typical workflow when triggered: 1. Identify the specific chunk to expand (from a prior `query_documents` hit or `grep`). 2. Take that chunk's `filePath` and `chunkIndex`. 3. Call `read_chunk_neighbors` with `ch
English | 简体中文 | Deutsch | Español | Português (Brasil) | Français Search private documents from an MCP client or the terminal without sending them to an embedding API. mcp-local-rag indexes PDF, DOCX, Markdown, and text files on your machine.
Repo: shinpr/mcp-local-rag

