@esankhan3/code-search-mcp 0.0.1 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +203 -263
- package/dist/resources/resources.js +3 -3
- package/dist/server.js +2 -2
- package/dist/tools/graph.js +1 -1
- package/dist/tools/index-tools.js +1 -1
- package/dist/tools/profile.js +2 -2
- package/dist/tools/search.js +1 -1
- package/package.json +16 -9
- package/dist/core/ast-graph-builder.js +0 -800
- package/dist/core/chunker.js +0 -368
- package/dist/core/claude-runner.js +0 -173
- package/dist/core/config.js +0 -59
- package/dist/core/cross-repo-detector.js +0 -887
- package/dist/core/embedder.js +0 -334
- package/dist/core/file-walker.js +0 -186
- package/dist/core/git-diff.js +0 -160
- package/dist/core/graph-metrics.js +0 -233
- package/dist/core/indexer.js +0 -552
- package/dist/core/project-graph-builder.js +0 -202
- package/dist/core/query-classifier.js +0 -144
- package/dist/core/query-router.js +0 -210
- package/dist/core/rag-evaluator.js +0 -213
- package/dist/core/repo-profiler.js +0 -383
- package/dist/core/reranker.js +0 -218
- package/dist/core/retriever.js +0 -242
- package/dist/core/semantic-edge-detector.js +0 -147
- package/dist/core/service-mesh-inferrer.js +0 -241
- package/dist/core/structural-hasher.js +0 -316
- package/dist/core/tree-sitter-parser.js +0 -539
- package/dist/core/types.js +0 -0
- package/dist/core/vector-store.js +0 -259
- package/dist/core/workspace-detector.js +0 -481
package/README.md
CHANGED
|
@@ -1,333 +1,273 @@
|
|
|
1
|
-
|
|
1
|
+
# @esankhan3/code-search-mcp
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
**Your whole codebase, in any MCP client.**
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
[](https://modelcontextprotocol.io)
|
|
11
|
-
[]()
|
|
12
|
-
[]()
|
|
13
|
-
|
|
14
|
-
[Quick Start](#quick-start) · [Tools](#tools) · [Deploy](#deployment) · [Configuration](#configuration)
|
|
15
|
-
|
|
16
|
-
</div>
|
|
17
|
-
|
|
18
|
-
---
|
|
19
|
-
|
|
20
|
-
## What You Get
|
|
21
|
-
|
|
22
|
-
Ask questions in natural language. The server searches, traces, and analyzes across all your repos.
|
|
23
|
-
|
|
24
|
-
| Query | Tool | Result |
|
|
25
|
-
|:------|:-----|:-------|
|
|
26
|
-
| "How does authentication work across services?" | `search_code` | 8 results from 3 repos, ranked by relevance |
|
|
27
|
-
| "What calls handlePayment?" | `find_callers` | 12 call sites traced across api-gateway and billing-service |
|
|
28
|
-
| "If I change user.ts, what breaks?" | `impact_analysis` | 4 files in 2 repos identified as affected |
|
|
29
|
-
|
|
30
|
-
Works with Claude Code, Claude Desktop, Cursor, and any MCP client.
|
|
31
|
-
|
|
32
|
-
---
|
|
33
|
-
|
|
34
|
-
## Architecture
|
|
35
|
-
|
|
36
|
-
```mermaid
|
|
37
|
-
graph LR
|
|
38
|
-
A[Your AI Client] -- stdio / http --> B[Code Search MCP Server]
|
|
39
|
-
B --> C[LanceDB vectors]
|
|
40
|
-
B --> D[AST Graph]
|
|
41
|
-
B --> E[Git Repos]
|
|
42
|
-
```
|
|
5
|
+
A Model Context Protocol server that wraps `@anvil/knowledge-core`
|
|
6
|
+
behind an MCP-compliant tool surface. Point Claude Code, Claude
|
|
7
|
+
Desktop, or Cursor at it and your agent gains hybrid search,
|
|
8
|
+
caller tracing, and impact analysis across every repo you've
|
|
9
|
+
indexed — local or remote.
|
|
43
10
|
|
|
44
11
|
---
|
|
45
12
|
|
|
46
|
-
##
|
|
13
|
+
## Why "code search" needs more than grep
|
|
47
14
|
|
|
48
|
-
|
|
49
|
-
|
|
15
|
+
MCP gave us a clean way to expose tools to LLM agents. What's
|
|
16
|
+
missing is a *good* tool to expose. `grep` over your repo answers
|
|
17
|
+
"where is this string." Vector search over your repo answers
|
|
18
|
+
"what's semantically near this." Neither answers "who calls this
|
|
19
|
+
function and which other repos depend on it."
|
|
50
20
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
21
|
+
**code-search-mcp gives agents the answer.** Same hybrid retriever
|
|
22
|
+
that powers Anvil's pipelines, exposed through MCP. Agents get
|
|
23
|
+
AST-aware chunks, cross-repo graph traversal, and a whole-project
|
|
24
|
+
view — without you writing a single tool.
|
|
54
25
|
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
```bash
|
|
58
|
-
claude mcp add code-search -- npx @anvil-dev/code-search-mcp --local github:your-org --token ghp_xxx
|
|
59
|
-
```
|
|
60
|
-
|
|
61
|
-
</details>
|
|
62
|
-
|
|
63
|
-
<details>
|
|
64
|
-
<summary><strong>Connect to a team server</strong></summary>
|
|
65
|
-
|
|
66
|
-
**Claude Code:**
|
|
67
|
-
|
|
68
|
-
```bash
|
|
69
|
-
claude mcp add code-search \
|
|
70
|
-
-e CODE_SEARCH_SERVER=https://your-server:3100 \
|
|
71
|
-
-e CODE_SEARCH_API_KEY=your-api-key \
|
|
72
|
-
-- npx @anvil-dev/code-search-mcp
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
**Claude Desktop / Cursor (JSON config):**
|
|
76
|
-
|
|
77
|
-
```json
|
|
26
|
+
```jsonc
|
|
27
|
+
// claude_desktop_config.json
|
|
78
28
|
{
|
|
79
29
|
"mcpServers": {
|
|
80
30
|
"code-search": {
|
|
81
31
|
"command": "code-search-mcp",
|
|
82
|
-
"
|
|
83
|
-
"CODE_SEARCH_SERVER": "https://your-server:3100",
|
|
84
|
-
"CODE_SEARCH_API_KEY": "your-api-key"
|
|
85
|
-
}
|
|
32
|
+
"args": ["--local", "/path/to/your/projects"]
|
|
86
33
|
}
|
|
87
34
|
}
|
|
88
35
|
}
|
|
89
36
|
```
|
|
90
37
|
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
<details>
|
|
94
|
-
<summary><strong>Deploy the server</strong> (Docker)</summary>
|
|
38
|
+
That's the whole setup. Claude Desktop now knows your codebase.
|
|
95
39
|
|
|
96
|
-
|
|
97
|
-
cp .env.example .env
|
|
98
|
-
docker compose up
|
|
99
|
-
```
|
|
40
|
+
---
|
|
100
41
|
|
|
101
|
-
|
|
42
|
+
## Three modes, one binary
|
|
102
43
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
44
|
+
### Remote proxy (default)
|
|
45
|
+
```sh
|
|
46
|
+
code-search-mcp # default — proxies to remote
|
|
47
|
+
code-search-mcp --remote URL
|
|
107
48
|
```
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
49
|
+
Spawns a stdio MCP server that forwards to a remote HTTP server.
|
|
50
|
+
Zero local setup, zero local index — perfect for hosted
|
|
51
|
+
deployments where the index lives in the cloud and dev machines
|
|
52
|
+
stay light. Auth via `CODE_SEARCH_API_KEY`.
|
|
53
|
+
|
|
54
|
+
### Local
|
|
55
|
+
```sh
|
|
56
|
+
code-search-mcp --local /path/to/repos
|
|
57
|
+
code-search-mcp --local github:my-org/my-pattern
|
|
113
58
|
```
|
|
59
|
+
Discovers every repo under a path (or clones a GitHub org), builds
|
|
60
|
+
the knowledge base, and serves over stdio. Works fully offline if
|
|
61
|
+
your embedder + reranker are local (Ollama).
|
|
114
62
|
|
|
115
|
-
|
|
63
|
+
### Serve
|
|
64
|
+
```sh
|
|
65
|
+
code-search-mcp --serve --port 4000 --auth api-key
|
|
66
|
+
```
|
|
67
|
+
Boots an HTTP server (Streamable HTTP transport, SSE optional)
|
|
68
|
+
with `/mcp`, `/health`, `/status`, and an admin `POST /index`. Use
|
|
69
|
+
this to host one index for a whole team — every dev points their
|
|
70
|
+
client at the same URL.
|
|
116
71
|
|
|
117
72
|
---
|
|
118
73
|
|
|
119
|
-
##
|
|
74
|
+
## Tool surface
|
|
75
|
+
|
|
76
|
+
Eleven tools across four categories. Every one of them maps to a
|
|
77
|
+
function in `@anvil/knowledge-core` — you're getting the same
|
|
78
|
+
retrieval pipeline that powers the Anvil dashboard.
|
|
79
|
+
|
|
80
|
+
### Search
|
|
81
|
+
| Tool | What it does |
|
|
82
|
+
|---|---|
|
|
83
|
+
| `search_code` | Hybrid retrieval — vector + BM25 + graph + rerank |
|
|
84
|
+
| `search_semantic` | Vector-only (paraphrases, intent) |
|
|
85
|
+
| `search_exact` | BM25-only (identifiers, error codes) |
|
|
86
|
+
|
|
87
|
+
### Graph
|
|
88
|
+
| Tool | What it does |
|
|
89
|
+
|---|---|
|
|
90
|
+
| `get_repo_graph` | Single-repo AST graph |
|
|
91
|
+
| `get_cross_repo_edges` | Inter-repo edges (Kafka, HTTP, gRPC, shared types, …) |
|
|
92
|
+
| `find_callers` | Who calls this function |
|
|
93
|
+
| `find_dependencies` | What this function calls |
|
|
94
|
+
| `impact_analysis` | What breaks if this changes |
|
|
95
|
+
|
|
96
|
+
### Profiles
|
|
97
|
+
| Tool | What it does |
|
|
98
|
+
|---|---|
|
|
99
|
+
| `list_repos` | All indexed repos with profiles |
|
|
100
|
+
| `get_repo_profile` | Single repo's tech stack, structure, key entry points |
|
|
101
|
+
|
|
102
|
+
### Index
|
|
103
|
+
| Tool | What it does |
|
|
104
|
+
|---|---|
|
|
105
|
+
| `index_status` | Last indexed SHA, chunk count, embedding provider |
|
|
106
|
+
|
|
107
|
+
Plus four MCP resources via `code-search://`:
|
|
108
|
+
`repos`, `system-graph`, `repo/{name}/profile`, `repo/{name}/graph`.
|
|
120
109
|
|
|
121
|
-
|
|
122
|
-
Hybrid vector+BM25, semantic-only, and keyword search across all indexed repos.
|
|
123
|
-
|
|
124
|
-
**Graph** -- `get_repo_graph` · `find_callers` · `find_dependencies` · `impact_analysis` · `get_cross_repo_edges`
|
|
125
|
-
AST knowledge graph, caller tracing, dependency lookup, change impact, and cross-repo connections.
|
|
110
|
+
---
|
|
126
111
|
|
|
127
|
-
|
|
128
|
-
Indexed repo listing and LLM-generated repo profiles with role, stack, and endpoints.
|
|
112
|
+
## What makes the search good
|
|
129
113
|
|
|
130
|
-
|
|
131
|
-
Chunk count, embedding provider, repo list, and last-indexed timestamp.
|
|
114
|
+
This isn't a thin wrapper. The retrieval pipeline runs:
|
|
132
115
|
|
|
133
|
-
|
|
116
|
+
1. **Vector ⫽ BM25 in parallel** — semantic + lexical recall.
|
|
117
|
+
2. **Reciprocal Rank Fusion** — combine without one dominating.
|
|
118
|
+
3. **AST tripartite expansion** — pull in callers, callees, type
|
|
119
|
+
refs via the project graph.
|
|
120
|
+
4. **Cross-encoder rerank** — Qwen3-Reranker by default; Cohere /
|
|
121
|
+
Voyage / OpenAI-compatible swappable.
|
|
134
122
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
| `GET /health` | Server status, active sessions, index readiness |
|
|
139
|
-
| `GET /status` | Live indexing progress, phase, percent, history |
|
|
123
|
+
A query classifier picks adaptive weights — identifier queries
|
|
124
|
+
lean BM25, natural-language leans vector, error codes lean both.
|
|
125
|
+
You don't tune anything; the retriever does it per query.
|
|
140
126
|
|
|
141
127
|
---
|
|
142
128
|
|
|
143
|
-
##
|
|
144
|
-
|
|
145
|
-
<details>
|
|
146
|
-
<summary>Incremental Indexing -- 4-layer cost optimization</summary>
|
|
147
|
-
|
|
148
|
-
| Layer | Scope | What it does |
|
|
149
|
-
|:------|:------|:-------------|
|
|
150
|
-
| 1. Git SHA skip | Repo | Compares HEAD against last indexed SHA; skips unchanged repos |
|
|
151
|
-
| 2. Git diff via Merkle DAG | File | Only processes added/modified/deleted files from `git diff` |
|
|
152
|
-
| 3. Content hash SHA-256 | File | Fallback dedup when git diff is unavailable |
|
|
153
|
-
| 4. Embedding diff against LanceDB | Chunk | Only new/changed chunks sent to the embedding provider |
|
|
129
|
+
## Multi-repo by design
|
|
154
130
|
|
|
155
|
-
|
|
156
|
-
|
|
131
|
+
Unlike single-repo code-search MCPs, this one is built for the
|
|
132
|
+
real world: a team has *many* repos, and the interesting
|
|
133
|
+
questions cross them. Where does this Kafka topic get consumed?
|
|
134
|
+
Which services depend on this proto? What service-mesh edges
|
|
135
|
+
exist between web and api?
|
|
157
136
|
|
|
158
|
-
|
|
137
|
+
Fourteen cross-repo edge strategies cover shared types, Kafka,
|
|
138
|
+
HTTP, gRPC, databases, env vars, npm/workspace deps, k8s,
|
|
139
|
+
docker-compose, proto, Redis, S3, and shared constants. Plus an
|
|
140
|
+
LLM-inferred semantic edge layer. `find_callers` works *across
|
|
141
|
+
repos*. So does `impact_analysis`.
|
|
159
142
|
|
|
160
|
-
|
|
143
|
+
---
|
|
161
144
|
|
|
162
|
-
|
|
163
|
-
<summary>Embedding Providers</summary>
|
|
145
|
+
## Server features
|
|
164
146
|
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
| Voyage AI | `VOYAGE_API_KEY` | `voyage-code-3` |
|
|
171
|
-
| Gemini | OAuth via `~/.gemini/` | `text-embedding-004` |
|
|
172
|
-
| Any OpenAI-compatible | `CODE_SEARCH_EMBEDDING_BASE_URL` | Custom |
|
|
147
|
+
### Auth, three flavors
|
|
148
|
+
`none` (local-only, default 127.0.0.1 binding), `api-key`
|
|
149
|
+
(`Authorization: Bearer ...`, timing-safe compare), `jwt` (HS256,
|
|
150
|
+
signature + `exp` + `iss` validated). Public binding without auth
|
|
151
|
+
logs a warning, because that's what should happen.
|
|
173
152
|
|
|
174
|
-
|
|
153
|
+
### Rate limiting
|
|
154
|
+
In-memory sliding 1-minute window keyed by identity subject. Tune
|
|
155
|
+
per-deployment.
|
|
175
156
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
```
|
|
157
|
+
### Auto-reindex
|
|
158
|
+
`CODE_SEARCH_REINDEX_INTERVAL=30m` (or `1h`, `6h`, `0` to disable)
|
|
159
|
+
runs an incremental re-index in the background. Skips itself if a
|
|
160
|
+
manual index is already running. The timer is `unref`'d so it
|
|
161
|
+
doesn't keep the process alive.
|
|
182
162
|
|
|
183
|
-
|
|
163
|
+
### Status tracking
|
|
164
|
+
Every index call lands in a 50-entry FIFO history with start
|
|
165
|
+
timestamp, success / error, last duration. Available at
|
|
166
|
+
`GET /status`.
|
|
184
167
|
|
|
185
|
-
|
|
186
|
-
|
|
168
|
+
### Streamable HTTP sessions
|
|
169
|
+
Per-session `StreamableHTTPServerTransport`, max 100 concurrent
|
|
170
|
+
sessions, 30 min TTL. The remote proxy captures `mcp-session-id`
|
|
171
|
+
for continuity. SSE transport available as a fallback.
|
|
187
172
|
|
|
188
|
-
|
|
173
|
+
### Admin index endpoint
|
|
174
|
+
`POST /index` with `{ project, dirPath?, opts? }` triggers a
|
|
175
|
+
fresh index. Gated against concurrent runs. Auth-required when
|
|
176
|
+
auth is on.
|
|
189
177
|
|
|
190
|
-
|
|
191
|
-
- Claude CLI available -- `cli` mode
|
|
192
|
-
- Neither -- `none` (LLM features disabled)
|
|
178
|
+
---
|
|
193
179
|
|
|
194
|
-
|
|
180
|
+
## How it fits with the rest of Anvil
|
|
195
181
|
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
182
|
+
```
|
|
183
|
+
┌─────────────────────────┐
|
|
184
|
+
│ MCP client │
|
|
185
|
+
│ (Claude Code, │
|
|
186
|
+
│ Claude Desktop, │
|
|
187
|
+
│ Cursor, …) │
|
|
188
|
+
└────────────┬────────────┘
|
|
189
|
+
│ stdio / HTTP
|
|
190
|
+
▼
|
|
191
|
+
┌─────────────────────────┐
|
|
192
|
+
│ code-search-mcp │
|
|
193
|
+
│ (this package) │
|
|
194
|
+
│ tools + resources │
|
|
195
|
+
└────────────┬────────────┘
|
|
196
|
+
│ wraps
|
|
197
|
+
▼
|
|
198
|
+
┌─────────────────────────┐
|
|
199
|
+
│ @anvil/knowledge-core │
|
|
200
|
+
│ AST chunks + │
|
|
201
|
+
│ project graph + │
|
|
202
|
+
│ hybrid retriever │
|
|
203
|
+
└────────────┬────────────┘
|
|
204
|
+
│ on disk
|
|
205
|
+
▼
|
|
206
|
+
~/.anvil/knowledge-base/<project>/
|
|
200
207
|
```
|
|
201
208
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
<details>
|
|
205
|
-
<summary>Cross-Repo Detection -- 14 automatic strategies</summary>
|
|
206
|
-
|
|
207
|
-
npm dependencies, TypeScript shared types, HTTP route matching, Kafka topics, gRPC services, database tables, environment variables, Docker Compose links, Redis keys, S3 buckets, protobuf imports, shared constants, API schemas (OpenAPI/Swagger), and Kubernetes service references.
|
|
208
|
-
|
|
209
|
-
</details>
|
|
210
|
-
|
|
211
|
-
<details>
|
|
212
|
-
<summary>Supported Languages</summary>
|
|
213
|
-
|
|
214
|
-
**Tree-sitter AST parsing:** TypeScript, JavaScript, Go, Python, Rust, Java, PHP, C/C++
|
|
215
|
-
|
|
216
|
-
All other text files are indexed with BM25 keyword search.
|
|
217
|
-
|
|
218
|
-
</details>
|
|
219
|
-
|
|
220
|
-
<details>
|
|
221
|
-
<summary>Monitoring -- GET /status</summary>
|
|
209
|
+
Three different fronts, one knowledge stack:
|
|
222
210
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
"percent": 85,
|
|
230
|
-
"elapsedMs": 4200,
|
|
231
|
-
"lastSuccess": "2026-04-18T14:30:00Z",
|
|
232
|
-
"lastDurationMs": 8500,
|
|
233
|
-
"history": [
|
|
234
|
-
{"type": "start", "message": "auto-reindex: started..."},
|
|
235
|
-
{"type": "complete", "message": "Completed: 1200 chunks, 4 repos in 8s"}
|
|
236
|
-
]
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
```
|
|
211
|
+
- **The CLI** indexes via `anvil index` and retrieves during
|
|
212
|
+
pipelines.
|
|
213
|
+
- **The dashboard** browses the project graph and surfaces
|
|
214
|
+
retrieval results in pipeline UI.
|
|
215
|
+
- **code-search-mcp** exposes the same retriever to any MCP
|
|
216
|
+
client.
|
|
240
217
|
|
|
241
|
-
|
|
218
|
+
If you've already indexed a project with `anvil index`, this
|
|
219
|
+
server picks it up — same `~/.anvil/knowledge-base/` path, same
|
|
220
|
+
LanceDB store, same graph files.
|
|
242
221
|
|
|
243
222
|
---
|
|
244
223
|
|
|
245
224
|
## Configuration
|
|
246
225
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
| Variable | Role | Description |
|
|
250
|
-
|:---------|:-----|:------------|
|
|
251
|
-
| `CODE_SEARCH_SERVER` | Client | Remote server URL |
|
|
252
|
-
| `CODE_SEARCH_API_KEY` | Client | API key for remote server |
|
|
253
|
-
| `CODE_SEARCH_EMBEDDING_PROVIDER` | Server | `auto` \| `codestral` \| `openai` \| `voyage` \| `ollama` \| `custom` |
|
|
254
|
-
| `CODE_SEARCH_LLM_API_KEY` | Server | API key for LLM provider (repo profiling, service mesh) |
|
|
255
|
-
| `CODE_SEARCH_AUTH_MODE` | Server | `none` \| `api-key` \| `jwt` |
|
|
226
|
+
Everything is `CODE_SEARCH_*` env vars, single source of truth in
|
|
227
|
+
`src/core/env-config.ts`:
|
|
256
228
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
code-search-mcp --local [source] [options]
|
|
269
|
-
--project <name> Project name (default: derived from source)
|
|
270
|
-
--token <token> GitHub token (or GITHUB_TOKEN env)
|
|
271
|
-
--force Force full re-index
|
|
272
|
-
```
|
|
273
|
-
|
|
274
|
-
**All environment variables:**
|
|
275
|
-
|
|
276
|
-
| Variable | Description | Default |
|
|
277
|
-
|:---------|:------------|:--------|
|
|
278
|
-
| `CODE_SEARCH_TRANSPORT` | Transport mode | `streamable-http` |
|
|
279
|
-
| `CODE_SEARCH_PORT` | HTTP port | `3100` |
|
|
280
|
-
| `CODE_SEARCH_HOST` | Bind address | `0.0.0.0` |
|
|
281
|
-
| `CODE_SEARCH_AUTH_MODE` | Auth mode | `none` |
|
|
282
|
-
| `CODE_SEARCH_AUTH_API_KEYS` | Comma-separated API keys | -- |
|
|
283
|
-
| `CODE_SEARCH_AUTH_JWT_SECRET` | JWT signing secret | -- |
|
|
284
|
-
| `CODE_SEARCH_EMBEDDING_PROVIDER` | Embedding provider | `auto` |
|
|
285
|
-
| `CODE_SEARCH_EMBEDDING_API_KEY` | Unified embedding API key | -- |
|
|
286
|
-
| `CODE_SEARCH_EMBEDDING_BASE_URL` | Custom embedding endpoint | -- |
|
|
287
|
-
| `CODE_SEARCH_EMBEDDING_MODEL` | Custom embedding model | -- |
|
|
288
|
-
| `CODE_SEARCH_RERANKER_PROVIDER` | `ollama` \| `cohere` \| `voyage` \| `custom` \| `none` | `ollama` |
|
|
289
|
-
| `CODE_SEARCH_RERANKER_BASE_URL` | Custom reranker endpoint | -- |
|
|
290
|
-
| `CODE_SEARCH_RERANKER_MODEL` | Custom reranker model | -- |
|
|
291
|
-
| `CODE_SEARCH_DATA_DIR` | Data directory override | -- |
|
|
292
|
-
| `CODE_SEARCH_REINDEX_INTERVAL` | Auto-reindex schedule (`30m`, `1h`, `6h`, `0`) | `0` |
|
|
293
|
-
| `CODE_SEARCH_RATE_LIMIT_PER_MINUTE` | Rate limit per identity | `100` |
|
|
294
|
-
| `CODE_SEARCH_LLM_MODE` | `cli` \| `api` \| `none` | `cli` |
|
|
295
|
-
| `CODE_SEARCH_LLM_PROVIDER` | `anthropic` \| `openai` \| `ollama` \| `custom` | `anthropic` |
|
|
296
|
-
| `CODE_SEARCH_LLM_API_KEY` | API key for LLM provider | -- |
|
|
297
|
-
| `CODE_SEARCH_LLM_MODEL` | Model for profiling + service mesh | `claude-sonnet-4-6` |
|
|
298
|
-
| `CODE_SEARCH_LLM_BASE_URL` | Custom LLM endpoint | -- |
|
|
299
|
-
|
|
300
|
-
</details>
|
|
229
|
+
| Var | What it does |
|
|
230
|
+
|---|---|
|
|
231
|
+
| `CODE_SEARCH_SERVER` | Remote URL (proxy mode) |
|
|
232
|
+
| `CODE_SEARCH_API_KEY` | API key for proxy or serve modes |
|
|
233
|
+
| `CODE_SEARCH_DATA_DIR` | Override `~/.anvil/knowledge-base` |
|
|
234
|
+
| `CODE_SEARCH_REINDEX_INTERVAL` | `30m` / `1h` / `6h` / `0` |
|
|
235
|
+
| `EMBEDDING_PROVIDER` | `auto` / `voyage` / `openai` / `ollama` / … |
|
|
236
|
+
| `EMBEDDING_API_KEY` | Bridged to provider-specific var |
|
|
237
|
+
| `RERANKER_PROVIDER` | `ollama` / `cohere` / `voyage` / `none` |
|
|
238
|
+
| `OLLAMA_HOST` | Default `http://localhost:11434` |
|
|
301
239
|
|
|
302
240
|
---
|
|
303
241
|
|
|
304
|
-
##
|
|
242
|
+
## Philosophy
|
|
305
243
|
|
|
306
|
-
-
|
|
307
|
-
|
|
244
|
+
**Multi-repo or nothing.** Real codebases span repos. Code search
|
|
245
|
+
that doesn't is a toy.
|
|
308
246
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
```
|
|
247
|
+
**No vendor LLM SDK.** Anything LLM-driven (repo profiling,
|
|
248
|
+
semantic edges) routes through `@anvil/agent-core`'s single-shot —
|
|
249
|
+
the same router, retries, and cost ledger as the rest of Anvil.
|
|
313
250
|
|
|
314
|
-
|
|
251
|
+
**Three modes, one binary.** Remote proxy for hosted, local for
|
|
252
|
+
solo, serve for teams. The dispatcher is `src/index.ts:argv`.
|
|
315
253
|
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
| `api-key` | `Authorization: Bearer <key>` checked against allowlist |
|
|
320
|
-
| `jwt` | HS256 JWT verification with expiry and issuer validation |
|
|
254
|
+
**Stateless sessions.** HTTP sessions are in-memory by design.
|
|
255
|
+
Restart drops them; clients re-init on first request. No persistent
|
|
256
|
+
session store to maintain.
|
|
321
257
|
|
|
322
|
-
|
|
258
|
+
**Security defaults that don't bite.** Default bind is `127.0.0.1`
|
|
259
|
+
when auth is `none`. API keys compared timing-safe. JWT
|
|
260
|
+
signature + exp + iss validated. Public binding without auth
|
|
261
|
+
logs a warning instead of pretending it's fine.
|
|
323
262
|
|
|
324
|
-
|
|
263
|
+
---
|
|
325
264
|
|
|
326
|
-
|
|
265
|
+
## Status
|
|
327
266
|
|
|
328
|
-
|
|
329
|
-
|
|
267
|
+
Stable. The retrieval and graph layers move with
|
|
268
|
+
`@anvil/knowledge-core`; the MCP surface is locked. New tools
|
|
269
|
+
land additively.
|
|
330
270
|
|
|
331
|
-
|
|
271
|
+
---
|
|
332
272
|
|
|
333
|
-
|
|
273
|
+
## Part of [Anvil](../../) — the AI development pipeline.
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { getKnowledgeBasePath } from "
|
|
4
|
-
import { loadAllProfiles } from "
|
|
5
|
-
import { loadProfile } from "
|
|
3
|
+
import { getKnowledgeBasePath } from "@esankhan3/anvil-knowledge-core";
|
|
4
|
+
import { loadAllProfiles } from "@esankhan3/anvil-knowledge-core";
|
|
5
|
+
import { loadProfile } from "@esankhan3/anvil-knowledge-core";
|
|
6
6
|
function registerResources(ctx) {
|
|
7
7
|
return [
|
|
8
8
|
{
|
package/dist/server.js
CHANGED
|
@@ -13,8 +13,8 @@ import { registerGraphTools, handleGraphTool } from "./tools/graph.js";
|
|
|
13
13
|
import { registerProfileTools, handleProfileTool } from "./tools/profile.js";
|
|
14
14
|
import { registerIndexTools, handleIndexTool } from "./tools/index-tools.js";
|
|
15
15
|
import { registerResources, handleResource } from "./resources/resources.js";
|
|
16
|
-
import { getKnowledgeBasePath } from "
|
|
17
|
-
import { indexFromPath } from "
|
|
16
|
+
import { getKnowledgeBasePath } from "@esankhan3/anvil-knowledge-core";
|
|
17
|
+
import { indexFromPath } from "@esankhan3/anvil-knowledge-core";
|
|
18
18
|
import { loadServerConfig } from "./core/env-config.js";
|
|
19
19
|
import { startHttpTransport } from "./transports/http-transport.js";
|
|
20
20
|
function createMcpServerInstance(ctx) {
|
package/dist/tools/graph.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
2
2
|
import { join } from "node:path";
|
|
3
|
-
import { getKnowledgeBasePath } from "
|
|
3
|
+
import { getKnowledgeBasePath } from "@esankhan3/anvil-knowledge-core";
|
|
4
4
|
function registerGraphTools() {
|
|
5
5
|
return [
|
|
6
6
|
{
|
package/dist/tools/profile.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { loadAllProfiles, loadProfile } from "
|
|
2
|
-
import { discoverRepos } from "
|
|
1
|
+
import { loadAllProfiles, loadProfile } from "@esankhan3/anvil-knowledge-core";
|
|
2
|
+
import { discoverRepos } from "@esankhan3/anvil-knowledge-core";
|
|
3
3
|
function registerProfileTools() {
|
|
4
4
|
return [
|
|
5
5
|
{
|
package/dist/tools/search.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@esankhan3/code-search-mcp",
|
|
3
|
-
"version": "0.0
|
|
3
|
+
"version": "0.1.0",
|
|
4
4
|
"description": "MCP server for multi-repo code search — GitHub org or local path, zero config",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -18,16 +18,23 @@
|
|
|
18
18
|
"dev": "tsc -b --watch"
|
|
19
19
|
},
|
|
20
20
|
"dependencies": {
|
|
21
|
-
"@
|
|
22
|
-
"@
|
|
23
|
-
"
|
|
24
|
-
"graphology-communities-louvain": "2.0.2",
|
|
25
|
-
"graphology-metrics": "2.4.0",
|
|
26
|
-
"graphology-types": "0.24.8",
|
|
27
|
-
"tree-sitter-wasms": "0.1.13",
|
|
28
|
-
"web-tree-sitter": "0.26.8"
|
|
21
|
+
"@esankhan3/anvil-agent-core": "^0.1.0",
|
|
22
|
+
"@esankhan3/anvil-knowledge-core": "^0.1.0",
|
|
23
|
+
"@modelcontextprotocol/sdk": "^1.29.0"
|
|
29
24
|
},
|
|
30
25
|
"devDependencies": {
|
|
31
26
|
"@types/node": "^22.15.2"
|
|
27
|
+
},
|
|
28
|
+
"repository": {
|
|
29
|
+
"type": "git",
|
|
30
|
+
"url": "https://github.com/esanmohammad/Anvil.git",
|
|
31
|
+
"directory": "packages/code-search-mcp"
|
|
32
|
+
},
|
|
33
|
+
"homepage": "https://github.com/esanmohammad/Anvil/tree/main/packages/code-search-mcp#readme",
|
|
34
|
+
"bugs": {
|
|
35
|
+
"url": "https://github.com/esanmohammad/Anvil/issues"
|
|
36
|
+
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
32
39
|
}
|
|
33
40
|
}
|