cqs 0.7.0

Semantic code search for Claude Code. Find functions by what they do, not their names. Local ML, GPU-accelerated.
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# cqs ("seeks")


Semantic code search with local ML embeddings. Find functions by concept, not name. GPU-accelerated. MCP server included.

**TL;DR:** Semantic code search for Claude Code. Instead of grep, it understands what code *does* - so Claude finds relevant functions without knowing exact names. Means Claude finds the right code faster and doesn't miss stuff buried in unfamiliar codebases.

[![Crates.io](https://img.shields.io/crates/v/cqs.svg)](https://crates.io/crates/cqs)
[![CI](https://github.com/jamie8johnson/cqs/actions/workflows/ci.yml/badge.svg)](https://github.com/jamie8johnson/cqs/actions/workflows/ci.yml)
[![CodeQL](https://github.com/jamie8johnson/cqs/actions/workflows/codeql.yml/badge.svg)](https://github.com/jamie8johnson/cqs/actions/workflows/codeql.yml)

---

> **`<claude>`**
>
> You're an AI assistant reading this. cqs gives you semantic code search via MCP.
>
> **Why you want this:** Find functions by what they do, not their names. When users ask about "retry logic" or "error handling", you find relevant code even in unfamiliar codebases - no need to know exact identifiers.
>
> **Setup:** `claude mcp add cqs -- cqs serve --project /path/to/project`
>
> **`</claude>`**

---

## Install


**Requires Rust 1.88+** (due to `ort` ONNX runtime dependency)

```bash
cargo install cqs
```

**Upgrading?** Schema changes require rebuilding the index:
```bash
cqs index --force  # Run after upgrading from older versions (current schema: v10)
```

## Quick Start


```bash
# Download model and initialize

cqs init

# Index your project

cd /path/to/project
cqs index

# Search

cqs "retry with exponential backoff"
cqs "validate email with regex"
cqs "database connection pool"
```

## Filters


```bash
# By language

cqs --lang rust "error handling"
cqs --lang python "parse json"

# By path pattern

cqs --path "src/*" "config"
cqs --path "tests/**" "mock"
cqs --path "**/*.go" "interface"

# Combined

cqs --lang typescript --path "src/api/*" "authentication"

# Hybrid search tuning

cqs --name-boost 0.2 "retry logic"   # Semantic-heavy (default)
cqs --name-boost 0.8 "serve_http"    # Name-heavy for known identifiers

# Show surrounding context

cqs -C 3 "error handling"       # 3 lines before/after each result

# Output options

cqs --json "query"           # JSON output
cqs --no-content "query"     # File:line only, no code
cqs -n 10 "query"            # Limit results
cqs -t 0.5 "query"           # Min similarity threshold
```

## Configuration


Set default options via config files. CLI flags override config file values.

**Config locations (later overrides earlier):**
1. `~/.config/cqs/config.toml` - user defaults
2. `.cqs.toml` in project root - project overrides

**Example `.cqs.toml`:**

```toml
# Default result limit

limit = 10

# Minimum similarity threshold (0.0 - 1.0)

threshold = 0.4

# Name boost for hybrid search (0.0 = pure semantic, 1.0 = pure name)

name_boost = 0.2

# Note weight in search results (0.0-1.0, lower = notes rank below code)

note_weight = 1.0

# Output modes

quiet = false
verbose = false
```

## Watch Mode


Keep your index up to date automatically:

```bash
cqs watch              # Watch for changes and reindex
cqs watch --debounce 1000  # Custom debounce (ms)
```

Watch mode respects `.gitignore` by default. Use `--no-ignore` to index ignored files.

## Call Graph


Find function call relationships:

```bash
cqs callers <name>   # Functions that call <name>
cqs callees <name>   # Functions called by <name>
cqs notes list       # List all project notes with sentiment
```

Use cases:
- **Impact analysis**: What calls this function I'm about to change?
- **Context expansion**: Show related functions
- **Entry point discovery**: Find functions with no callers

Call graph is indexed across all files - callers are found regardless of which file they're in.

## Discovery Tools


```bash
# Find functions similar to a given function (search by example)

cqs similar search_filtered                    # by name
cqs similar src/search.rs:search_filtered      # by file:name

# Function card: signature, callers, callees, similar functions

cqs explain search_filtered
cqs explain src/search.rs:search_filtered --json

# Semantic diff between indexed snapshots

cqs diff old-version                           # project vs reference
cqs diff old-version new-ref                   # two references
cqs diff old-version --threshold 0.90          # stricter "modified" cutoff
```

## Reference Indexes (Multi-Index Search)


Search across your project and external codebases simultaneously:

```bash
cqs ref add tokio /path/to/tokio          # Index an external codebase
cqs ref add stdlib /path/to/rust/library --weight 0.6  # Custom weight
cqs ref list                               # Show configured references
cqs ref update tokio                       # Re-index from source
cqs ref remove tokio                       # Remove reference and index files
```

Once added, all searches automatically include reference results:

```bash
cqs "spawn async task"    # Finds results in project AND tokio reference
```

Reference results are ranked with a weight multiplier (default 0.8) so project results naturally appear first at equal similarity.

**MCP integration**: The `cqs_search` tool gains a `sources` parameter to filter which indexes to search:
- Omit `sources` to search all indexes
- `sources: ["project"]` — search only the primary project
- `sources: ["tokio"]` — search only the tokio reference

References are configured in `.cqs.toml`:

```toml
[[reference]]
name = "tokio"
path = "/home/user/.local/share/cqs/refs/tokio"
source = "/home/user/code/tokio"
weight = 0.8
```

## Claude Code Integration


### Why use cqs?


Without cqs, Claude Code uses grep/glob to find code - which only works if you know the exact names. With cqs, Claude can:

- **Find code by behavior**: "function that retries with backoff" finds retry logic even if it's named `doWithAttempts`
- **Navigate unfamiliar codebases**: Claude finds relevant code without knowing the project structure
- **Catch related code**: Semantic search surfaces similar patterns across the codebase that text search misses

### Setup


**Step 1:** Add cqs as an MCP server:

```bash
claude mcp add cqs -- cqs serve --project /path/to/project
```

Or manually in `~/.claude.json`:

```json
{
  "projects": {
    "/path/to/project": {
      "mcpServers": {
        "cqs": {
          "command": "cqs",
          "args": ["serve", "--project", "/path/to/project"]
        }
      }
    }
  }
}
```

**Note:** The `--project` argument is required because MCP servers run from an unpredictable working directory.

**GPU acceleration:** Add `--gpu` for faster query embedding after warmup:
```bash
cqs serve --gpu --project /path/to/project
```
GPU: ~12ms warm queries. CPU (default): ~22ms. Server starts instantly with HNSW, upgrades to GPU in background.

**Step 2:** Add to your project's `CLAUDE.md` so Claude uses it automatically:

```markdown
## Code Search


Use `cqs_search` for semantic code search instead of grep/glob when looking for:
- Functions by behavior ("retry with backoff", "parse config")
- Implementation patterns ("error handling", "database connection")
- Code where you don't know the exact name

Available tools:
- `cqs_search` - semantic search with `language`, `path_pattern`, `threshold`, `limit`, `name_boost`, `note_weight`, `semantic_only`, `name_only`
  - Use `name_only=true` for "where is X defined?" queries (skips embedding, searches function names directly)
- `cqs_stats` - index stats, chunk counts, HNSW index status
- `cqs_callers` - find functions that call a given function
- `cqs_callees` - find functions called by a given function
- `cqs_read` - read file with context notes injected as comments
- `cqs_add_note` - add observation to project memory (indexed for future searches)
- `cqs_update_note` - update an existing note's text, sentiment, or mentions
- `cqs_remove_note` - remove a note from project memory
- `cqs_audit_mode` - toggle audit mode to exclude notes from search/read results
- `cqs_similar` - find functions similar to a given function (search by example)
- `cqs_explain` - function card: signature, callers, callees, similar functions
- `cqs_diff` - semantic diff between indexed snapshots

Keep index fresh: run `cqs watch` in a background terminal, or `cqs index` after significant changes.
```

### HTTP Transport


For web integrations, use the HTTP transport:

```bash
cqs serve --transport http --port 3000 --project /path/to/project
```

Endpoints:
- `POST /mcp` - JSON-RPC requests (MCP protocol messages)
- `GET /mcp` - SSE stream for server-to-client notifications
- `GET /health` - Health check (returns 200 OK when server is ready)

**Authentication:** For network-exposed servers, API key authentication is required:

```bash
# Via flag

cqs serve --transport http --api-key SECRET --project /path/to/project

# Via environment variable

export CQS_API_KEY=SECRET
cqs serve --transport http --project /path/to/project

# Via file (recommended - keeps secret out of process list)

echo "SECRET" > /path/to/keyfile
cqs serve --transport http --api-key-file /path/to/keyfile --project /path/to/project
```

Clients must include `Authorization: Bearer SECRET` header.

**Network binding:** By default, cqs binds to localhost only. To expose on a network:

```bash
# Requires both flags for safety

cqs serve --transport http --bind 0.0.0.0 --dangerously-allow-network-bind --api-key SECRET
```

Implements MCP Streamable HTTP spec 2025-11-25 with Origin validation and protocol version headers.

## Supported Languages


- Rust
- Python
- TypeScript
- JavaScript (JSDoc `@param`/`@returns` tags improve search quality)
- Go
- C
- Java

## Indexing


By default, `cqs index` respects `.gitignore` rules:

```bash
cqs index              # Respects .gitignore
cqs index --no-ignore  # Index everything
cqs index --force      # Re-index all files
cqs index --dry-run    # Show what would be indexed
```

## How It Works


1. Parses code with tree-sitter to extract:
   - Functions and methods
   - Classes and structs
   - Enums, traits, interfaces
   - Constants
2. Generates embeddings with E5-base-v2 (runs locally)
   - Includes doc comments for better semantic matching
3. Stores in SQLite with vector search + FTS5 keyword index
4. **Hybrid search (RRF)**: Combines semantic similarity with keyword matching
   - Semantic search finds conceptually related code
   - Keyword search catches exact identifier matches (e.g., `parseConfig`)
   - Reciprocal Rank Fusion merges both rankings for best results
5. Uses GPU if available, falls back to CPU

## HNSW Index Tuning


The HNSW (Hierarchical Navigable Small World) index provides fast approximate nearest neighbor search. Current parameters:

| Parameter | Value | Description |
|-----------|-------|-------------|
| M (connections) | 24 | Max edges per node. Higher = better recall, more memory |
| ef_construction | 200 | Search width during build. Higher = better index, slower build |
| max_layers | 16 | Graph layers. ~log(N) is typical |
| ef_search | 100 | Search width at query time. Higher = better recall, slower search |

**Trade-offs:**
- **Recall vs speed**: Higher ef_search improves recall but slows queries
- **Index size**: ~4KB per vector with current settings
- **Build time**: O(N * M * ef_construction) complexity

For most codebases (<100k chunks), defaults work well. Large repos may benefit from tuning ef_search higher (200+) if recall matters more than latency.

## Search Quality


Hybrid search (RRF) combines semantic understanding with keyword matching:

| Query | Top Match | Score |
|-------|-----------|-------|
| "cosine similarity" | `cosine_similarity` | 0.85 |
| "validate email regex" | `validateEmail` | 0.73 |
| "check if adult age 18" | `isAdult` | 0.71 |
| "pop from stack" | `Stack.Pop` | 0.70 |
| "generate random id" | `generateId` | 0.70 |

## GPU Acceleration (Optional)


cqs works on CPU (~20ms per embedding). GPU provides 3x+ speedup:

| Mode | Single Query | Batch (50 docs) |
|------|--------------|-----------------|
| CPU  | ~20ms        | ~15ms/doc       |
| CUDA | ~6ms         | ~0.3ms/doc      |

For GPU acceleration:

### Linux


```bash
# Add NVIDIA CUDA repo

wget https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2404/x86_64/cuda-keyring_1.1-1_all.deb
sudo dpkg -i cuda-keyring_1.1-1_all.deb
sudo apt update

# Install CUDA runtime and cuDNN 9

sudo apt install cuda-cudart-12-6 libcublas-12-6 libcudnn9-cuda-12
```

Set library path:
```bash
export LD_LIBRARY_PATH=/usr/local/cuda-12.6/lib64:/usr/lib/x86_64-linux-gnu:$LD_LIBRARY_PATH
```

### WSL2


Same as Linux, plus:
- Requires NVIDIA GPU driver on Windows host
- Add `/usr/lib/wsl/lib` to `LD_LIBRARY_PATH`
- Tested working with RTX A6000, CUDA 13.0 driver, cuDNN 9.18

### Verify


```bash
cqs doctor  # Shows execution provider (CUDA or CPU)
```

## Contributing


Issues and PRs welcome at [GitHub](https://github.com/jamie8johnson/cqs).

## License


MIT