Context Service¶
The context tool provides a Context-as-a-Service persistent index of your files using a local SQLite database. It supports two search strategies:
- Lexical search (FTS5) — fast keyword matching via SQLite Full-Text Search.
- Semantic search (sqlite-vec + @xenova/transformers) — vector embeddings for meaning-based retrieval.
Both strategies are local-first — no cloud API key is required. Embeddings are generated on-device using the all-MiniLM-L6-v2 model via @xenova/transformers.
It helps AI agents quickly answer where specific concepts, terms, API endpoints, or configurations are defined in the workspace, bypassing the need to search or read all files.
Workflow¶
Using the context tool is a two-step process:
index: Scan and index all text files in the directory. This builds both the FTS5 keyword index and the vector embeddings table.query: Run search queries against the created index inlexical,semantic, orhybridmode.
graph TD
A[Start] --> B[Call context with operation: index]
B --> C[Recursively scans directory]
C --> D[Creates .context.db with FTS5 + vector tables]
D --> E[Ready to Query]
E --> F{Choose mode}
F -->|lexical| G[FTS5 keyword MATCH]
F -->|semantic| H[Vector cosine similarity]
F -->|hybrid| I[FTS5 + vector combined]
G --> J[Returns ranked matches with snippets]
H --> J
I --> J Parameters¶
| Parameter | Type | Required | Description |
|---|---|---|---|
directory | string | ✅ | Absolute path to the directory to index or query. |
operation | string | ❌ | Operation to perform: "index" or "query" (default: "query"). |
query | string | ❌ | The term, phrase, or MATCH expression to search for (required for "query"). |
mode | string | ❌ | Search mode: "lexical" (default), "semantic", or "hybrid". See Search Modes. |
Search Modes¶
lexical (default)¶
FTS5 keyword search. Matches exact terms and phrases against the indexed content. This is the original search mode — fast, deterministic, and requires no embeddings.
semantic¶
Vector similarity search using cosine distance. The query text is embedded using the same all-MiniLM-L6-v2 model used at index time, then compared against all stored document embeddings. Returns the 20 nearest neighbours ranked by similarity.
Requires that the index operation was run with the embeddings model available (it is bundled with @xenova/transformers — no separate install needed). If no vector index exists in the database, returns a clear error asking you to re-index.
hybrid¶
Combines both strategies: runs the FTS5 keyword search first, then appends semantic results for documents not already found by FTS5. This gives you both exact-match precision and meaning-based recall.
Graceful fallback: if the embeddings model is unavailable or the database has no vector index (e.g. it was created by an older version), hybrid mode returns the lexical results with a warning field instead of failing. The FTS5 path always works.
Usage Examples¶
1. Indexing a directory¶
To build the SQLite database, specify the "index" operation. This creates both the FTS5 keyword index and the vector embeddings table in a single pass:
Output:
This creates .context.db and .context.db-journal in the target directory (which should be added to your .gitignore).
If @xenova/transformers is unavailable at index time, the index operation still succeeds — it builds the FTS5 index without embeddings and logs a warning. You can re-run index later once the model is available to add embeddings.
2. Lexical query (default)¶
Search for exact keyword matches. This is the same behavior as v2.1.0:
Output:
{
"message": "Found 3 files matching 'JWT authentication' in '/path/to/project'",
"matches": [
{
"path": "/path/to/project/src/auth.ts",
"snippet": "verify(token, secret); // <b>JWT authentication</b> middleware..."
}
],
"status": "success"
}
3. Semantic query¶
Find files by meaning, even when they don't contain the exact search terms:
{
"directory": "/path/to/project",
"operation": "query",
"query": "how does the app verify user identity",
"mode": "semantic"
}
Output:
{
"message": "Found 3 files matching 'how does the app verify user identity' in '/path/to/project'",
"matches": [
{
"path": "/path/to/project/src/auth.ts",
"snippet": "export function authenticate(user: string, password: string): boolean {\n const hash = bcrypt.has...",
"distance": 0.42
}
],
"status": "success"
}
4. Hybrid query¶
Get both keyword-exact and meaning-based results in one call:
{
"directory": "/path/to/project",
"operation": "query",
"query": "database connection",
"mode": "hybrid"
}
If the vector index is missing (e.g. older database), you still get results:
{
"message": "Found 2 files matching 'database connection' in '/path/to/project'",
"matches": [ ... ],
"warning": "No vector index found; returning lexical results only. Re-run 'index' to enable semantic search.",
"status": "success"
}
Architecture¶
The context tool stores everything in a single .context.db SQLite file:
| Table | Engine | Purpose |
|---|---|---|
docs | FTS5 virtual table | Full-text keyword index (path + content) |
vec_docs | vec0 virtual table (sqlite-vec) | 384-dimensional float embeddings |
doc_vec_map | Regular table | Maps FTS5 doc rowids to vector rowids |
Dependencies:
better-sqlite3— SQLite driver (used since v2.1.0)sqlite-vec— SQLite extension for vector similarity search@xenova/transformers— local inference ofall-MiniLM-L6-v2embeddings (no cloud key needed) ```