clast-ai 0.2.5 → 0.3.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.
@@ -8,7 +8,7 @@
8
8
  {
9
9
  "name": "clast",
10
10
  "source": "./",
11
- "description": "Code index MCP server (symbol search, call graph, hierarchy, impact, dead code, counts) plus /clast:deadcode, /clast:impact, /clast:audit and /clast:status."
11
+ "description": "Code index MCP server (symbol search, call graph, hierarchy, impact, dead code, counts) plus /clast:use, /clast:deadcode, /clast:impact, /clast:audit and /clast:status. Off in a project until /clast:use."
12
12
  }
13
13
  ]
14
14
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clast",
3
- "version": "0.2.5",
3
+ "version": "0.3.0",
4
4
  "description": "Code index for coding agents: symbol search, exact symbol source, type-aware call graph, references, type hierarchy, change impact, dead code and exact counts for any repository. TypeScript, JavaScript, Python, Java, C#, Go, Rust, C, C++, Ruby, PHP, Swift and Dart.",
5
5
  "author": {
6
6
  "name": "Thomas"
package/CHANGELOG.md CHANGED
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.3.0
4
+
5
+ - Opt-in per project. The server process still starts in every project, but it indexes and offers
6
+ its tools only where a `.clast` folder exists in the project root. Elsewhere it is dormant: one
7
+ small tool (`clast_enable`), no index, no watcher, nothing written. `/clast:use` (or the tool, or
8
+ `mkdir .clast`) turns it on, also in a running session; deleting the folder turns it off.
9
+ Projects indexed before already have the folder and stay on. `CLAST_ALWAYS=1` restores the old
10
+ behaviour.
11
+ - Benchmark tables show tokens in and out instead of price.
12
+
3
13
  ## 0.2.5
4
14
 
5
15
  - Search: a common name plus context words ("write socket", "reset viterbi decoder") ranks the
package/README.md CHANGED
@@ -27,18 +27,24 @@ directly, with exact `file:line` locations. The index follows every edit, so ans
27
27
  /plugin install clast@clast
28
28
  ```
29
29
 
30
+ **Then turn it on in each project that wants it.** Type `/clast:use` once in the project. Clast does
31
+ nothing in a project until you do: no index, no tools in the prompt, so a notes folder or a project
32
+ where you do not want it costs nothing. `/clast:use` creates a `.clast` folder in the project root,
33
+ which holds the index and is the on switch. Delete the folder to turn clast off again.
34
+
30
35
  The plugin brings the index server, a short skill that teaches Claude which tool answers which
31
- question, and four slash commands:
36
+ question, and five slash commands:
32
37
 
33
38
  | Command | What it does |
34
39
  | --- | --- |
40
+ | `/clast:use` | Turns clast on for this project |
35
41
  | `/clast:deadcode [path]` | Finds unused functions, methods and types, verifies them, and removes the ones you confirm |
36
42
  | `/clast:impact <symbol>` | What must change with a symbol, every caller, and the tests to run |
37
43
  | `/clast:audit [path]` | Inventory for due diligence or onboarding: size, structure, endpoints, database access, dependencies, dead code |
38
44
  | `/clast:status` | State of the index |
39
45
 
40
- Requires **Node.js 22.22 or newer**. The first start indexes the project in the background (seconds;
41
- about half a minute for 15,000 files). Later starts are ready immediately.
46
+ Requires **Node.js 22.22 or newer**. Turning clast on indexes the project in the background (seconds;
47
+ about half a minute for 15,000 files). Later sessions are ready immediately.
42
48
 
43
49
  **Codex, Gemini CLI and other agents.** Clast is a standard MCP server, so any agent that speaks MCP
44
50
  can use it:
@@ -50,6 +56,10 @@ codex mcp add clast -- clast-ai # Codex
50
56
  gemini mcp add -s user clast clast-ai # Gemini CLI
51
57
  ```
52
58
 
59
+ Turn it on per project by creating the folder (`mkdir .clast`), or ask the agent to "use clast": a
60
+ dormant server offers one tool, `clast_enable`, that does it. `CLAST_ALWAYS=1` in the server's
61
+ environment turns it on everywhere.
62
+
53
63
  Then give the agent the usage guide the Claude plugin ships as a skill:
54
64
 
55
65
  ```sh
@@ -70,7 +80,8 @@ The first session after that cleans up in the background, once per plugin versio
70
80
  - entries the old VS Code extension wrote into `.claude/settings.local.json` are removed,
71
81
  - the v0.1 index file `.clast/clast.db` is deleted (the new index is rebuilt by itself).
72
82
 
73
- Restart Claude Code once more and `/mcp` shows a single `clast` server.
83
+ Restart Claude Code once more and `/mcp` shows a single `clast` server. Projects that were indexed
84
+ before already have a `.clast` folder and stay on; any other project is off until `/clast:use`.
74
85
 
75
86
  One case is left to you: a project whose `.mcp.json` lists clast. That file is shared with a team, so
76
87
  it is never changed, and in that project the server stays listed twice until the entry is removed
@@ -183,15 +194,16 @@ are found with it. Code used only by tests and names that still appear in a stri
183
194
  config file are listed separately, because those need a look before they go.
184
195
 
185
196
  ```
186
- > clast_unused path: app (a C++ application)
187
-
188
- unused code: 80 symbols, 415 lines in 51 files - the name is never referenced outside
189
- its own definition, or only from other unused code (10594 symbols judged under app)
190
- app/panels/agc_ui.cpp (6 symbols, 109 lines)
191
- function reasonText :12-23 (used only by unused agcGear)
192
- function ampNow :42-49 (used only by unused agcStep)
193
- function agcStep :79-111 exported
194
- function agcGear :126-169 exported
197
+ > clast_unused path: streams/.../state/internals (kafka)
198
+
199
+ unused code: 8 symbols, 197 lines in 1 file - the name is never referenced outside
200
+ its own definition, or only from other unused code (3818 symbols judged)
201
+ streams/.../state/internals/Murmur3.java (8 symbols, 197 lines)
202
+ method Murmur3.hash64 :201-203 exported
203
+ class Murmur3.IncrementalHash32 :453-543 exported
204
+ method Murmur3.orBytes :545-547 (used only by unused IncrementalHash32)
205
+ ...
206
+ used only by tests (6, 56 lines):
195
207
  ...
196
208
  ```
197
209
 
@@ -220,10 +232,10 @@ callers (2 resolved; depth 2):
220
232
  No name to search for? Describe the behaviour. Search covers names, signatures, doc comments and
221
233
  what function bodies mention, and copes with partial names, abbreviations and typos.
222
234
 
223
- A name that is everywhere is no problem either. One code base here has 1,157 methods called `reset`
224
- and grep returns them all. Ask for "reset viterbi decoder" and clast puts the right one first: it
225
- takes every definition with that name and lets the other words choose, by the class it sits in, its
226
- comment, and what its body calls.
235
+ A name that is everywhere is no problem either. A large code base can have a thousand methods called
236
+ `reset` or `write`, and grep returns them all. Ask for "write socket" and clast puts the right one
237
+ first: it takes every definition with that name and lets the other words choose, by the class it
238
+ sits in, its comment, and what its body calls.
227
239
 
228
240
  ```
229
241
  > clast_search "client ip from forwarded headers" (gin)
@@ -258,18 +270,22 @@ there is nothing to compile.
258
270
  ## Measured, not promised
259
271
 
260
272
  Every figure comes from real headless Claude Code sessions: the same question asked once with clast
261
- and once with only grep and file reads. The rows below are from OnAir (C++, 7.5k files, 1.6M lines);
262
- the vscode results (TypeScript, 15.7k files) are in the full tables.
263
-
264
- | Kind of work | Tool calls (clast / grep) | Time | Cost |
265
- | --- | ---: | ---: | ---: |
266
- | Find dead code in a directory | 2 / 16 | 20 s / 124 s | $0.15 / $1.89 |
267
- | Multi-hop questions (call chains, subclasses, impact) | 1.2 / 5.9 | 12.5 s / 25.8 s | $0.056 / $0.212 |
268
- | Code described by behaviour, in a repo the model has not seen | 1.8 / 4.2 | 12.0 s / 20.5 s | $0.068 / $0.197 |
269
- | One of many same-named methods ("which `reset` belongs to the Viterbi decoder") | 1.0 / 3.6 | 11.2 s / 17.4 s | $0.12 / $0.11 |
270
- | Counting ("how many receiver classes") | 1.0 / 3.3 | 11 s / 34 s | about $0.02 / $0.29 |
271
- | Simple lookups (where is X, who calls X) | 1.7 / 1.7 | 12.7 s / 14.3 s | $0.063 / $0.096 |
272
- | Cross-cutting refactors (rename a method, add a parameter everywhere) | 8.3 / 8.3 | 27 s / 26 s | $0.26 / $0.25 |
273
+ and once with only grep and file reads. The rows below are from a 1.6-million-line C++ application
274
+ that the model had never seen; results on vscode are in the full tables.
275
+
276
+ | Kind of work | Tool calls (clast / grep) | Time | Tokens in | Tokens out |
277
+ | --- | ---: | ---: | ---: | ---: |
278
+ | Find dead code in a directory | 2 / 16 | 20 s / 124 s | 82k / 928k | 0.6k / 9.5k |
279
+ | Multi-hop questions (call chains, subclasses, impact) | 1.2 / 5.9 | 12.5 s / 25.8 s | 50k / 118k | 0.5k / 1.2k |
280
+ | Code described by behaviour | 1.8 / 4.2 | 12.0 s / 20.5 s | 69k / 100k | 0.3k / 0.8k |
281
+ | One of many same-named methods ("which of a thousand `reset` methods is the decoder's") | 1.0 / 3.6 | 11.2 s / 17.4 s | 53k / 68k | 0.2k / 0.6k |
282
+ | Counting ("how many classes of this kind") | 1.0 / 3.3 | 11 s / 34 s | 52k / 91k | 0.3k / 2.5k |
283
+ | Simple lookups (where is X, who calls X) | 1.7 / 1.7 | 12.7 s / 14.3 s | 62k / 50k | 0.4k / 0.5k |
284
+ | Cross-cutting refactors (rename a method, add a parameter everywhere) | 8.3 / 8.3 | 27 s / 26 s | 104k / 81k | 1.7k / 1.7k |
285
+
286
+ "Tokens in" is everything sent to the model over the session. The fixed prompt goes out again on
287
+ every turn, and clast's tool definitions add about 5k to it, which is why clast reads more on the
288
+ two ties. Fewer turns is what brings the total down everywhere else.
273
289
 
274
290
  Both sides answered correctly almost everywhere; the difference is how much searching it took.
275
291
 
@@ -282,7 +298,7 @@ Full tables, method, answer-quality audits and index speed: [docs/benchmarks.md]
282
298
 
283
299
  ## Your first minute
284
300
 
285
- Open a project in Claude Code with the plugin installed, then try these:
301
+ Open a project in Claude Code with the plugin installed, type `/clast:use`, then try these:
286
302
 
287
303
  1. **Get the lie of the land:** "Give me an overview of this repository."
288
304
  2. **Trace something:** "Who ends up calling `saveOrder`, two levels up?"
@@ -290,7 +306,8 @@ Open a project in Claude Code with the plugin installed, then try these:
290
306
  4. **Clean up:** `/clast:deadcode src/billing`
291
307
  5. **Take stock:** `/clast:audit`
292
308
 
293
- **Not sure it is running?** `/clast:status` shows the index, and `/mcp` lists the server with 15 tools.
309
+ **Not sure it is running?** `/clast:status` shows the index, and `/mcp` lists the server with 15 tools
310
+ (one tool, `clast_enable`, while clast is off for the project).
294
311
 
295
312
  ## Reference
296
313
 
@@ -387,7 +404,7 @@ Optional. Create `clast.config.json` (or `.claude/clast.config.json`) in the pro
387
404
  | `watch.debounceMs` | `200` | Debounce for file change events |
388
405
  | `llm.*` | disabled | OpenAI-compatible endpoint for `clast_comment` (Ollama, LM Studio, vLLM, OpenAI, OpenRouter) |
389
406
 
390
- Environment: `CLAST_PROJECT_DIR` (project root), `CLAST_DB_PATH` (index location), `CLAST_GRAMMARS_DIR`
407
+ Environment: `CLAST_ALWAYS=1` (on in every project, no `.clast` folder needed), `CLAST_PROJECT_DIR` (project root), `CLAST_DB_PATH` (index location), `CLAST_GRAMMARS_DIR`
391
408
  (alternative grammar directory), `CLAST_NO_MIGRATE=1` (no automatic clean-up), `CLAST_DEBUG=1` (timings).
392
409
 
393
410
  | Language | id | Extensions |
@@ -456,7 +473,7 @@ under 50 ms.
456
473
  always the function.
457
474
  - **Not indexed**: Kotlin, Scala and other languages without a bundled grammar. `clast_grep` still
458
475
  searches those files as text.
459
- - **Prompt cost**: the tool definitions add about 5k tokens to every session.
476
+ - **Prompt size**: the tool definitions add about 5k tokens to every turn.
460
477
 
461
478
  More detail and examples: [docs/v0.2-summary.md](docs/v0.2-summary.md).
462
479
 
@@ -1,6 +1,7 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
- import { resolve } from 'node:path';
3
+ import { existsSync, mkdirSync } from 'node:fs';
4
+ import { join, resolve } from 'node:path';
4
5
  import { pathToFileURL } from 'node:url';
5
6
  import { z } from 'zod';
6
7
  import { Clast } from '../engine.js';
@@ -29,6 +30,7 @@ const INSTRUCTIONS = `Clast is a pre-built, always-fresh code index for this rep
29
30
  When adding something new (a subclass, a handler, a provider): find the siblings with clast_hierarchy or clast_search and read one with clast_get_context.
30
31
  When renaming a symbol or changing a signature: if the name is distinctive, do NOT use clast - one Grep for the name lists every site, then edit. Use clast_impact first only when the name is common (get, run, close) so that Grep would drown in unrelated hits, when overrides or interface implementations must change with it, or to choose the tests to run.
31
32
  Most tools take several names at once (arrays). Symbols: name, Container.name, or path/to/file.ext:name. "?" marks a name-based guess. The index follows file changes, including your own edits.`;
33
+ const DORMANT_INSTRUCTIONS = 'Clast (code index) is installed but off for this project: there is no .clast folder in the project root. Do not mention it. If the user asks to use clast, call clast_enable.';
32
34
  const text = (t) => ({ content: [{ type: 'text', text: t }] });
33
35
  const READ_ONLY = { readOnlyHint: true, idempotentHint: true, openWorldHint: false };
34
36
  // Claude Code defers MCP tools behind its tool search by default. Measured on vscode and OnAir
@@ -42,271 +44,336 @@ export async function startServer() {
42
44
  console.error(`[clast] ${msg}`);
43
45
  };
44
46
  log(`v${VERSION} project root: ${projectRoot}`);
45
- const clast = new Clast(projectRoot);
46
- const ctx = new ToolContext(clast);
47
- const watcher = new FileWatcher(clast.indexer, clast.config.watch.debounceMs);
48
- const commentGen = new CommentGenerator(clast.db, clast.config, ctx.lines);
49
- const server = new McpServer({ name: 'clast', version: VERSION }, { instructions: INSTRUCTIONS });
50
- const names = z.union([z.string(), z.array(z.string()).max(20)]);
51
- const guard = (fn, gated = true) => async (args) => {
52
- try {
53
- if (gated) {
54
- const building = await ctx.gate();
55
- if (building)
56
- return text(building);
47
+ // Opt-in per project. The client starts this process in every project, code or not. It indexes and
48
+ // offers its tools only where a `.clast` folder exists in the project root (`/clast:use` or the
49
+ // `clast_enable` tool creates it; the index lives there). Anywhere else it stays dormant: one small
50
+ // tool, no index, no watcher. CLAST_ALWAYS=1 or an explicit CLAST_DB_PATH switches it on regardless.
51
+ const marker = join(projectRoot, '.clast');
52
+ const wanted = () => process.env.CLAST_ALWAYS === '1' || !!process.env.CLAST_DB_PATH || existsSync(marker);
53
+ const startActive = wanted();
54
+ const server = new McpServer({ name: 'clast', version: VERSION }, { instructions: startActive ? INSTRUCTIONS : DORMANT_INSTRUCTIONS });
55
+ let active = null;
56
+ let connected = false;
57
+ let begin = null;
58
+ const activate = () => {
59
+ if (active)
60
+ return;
61
+ mkdirSync(marker, { recursive: true });
62
+ const clast = new Clast(projectRoot);
63
+ const ctx = new ToolContext(clast);
64
+ const watcher = new FileWatcher(clast.indexer, clast.config.watch.debounceMs);
65
+ const commentGen = new CommentGenerator(clast.db, clast.config, ctx.lines);
66
+ active = { clast, watcher };
67
+ const names = z.union([z.string(), z.array(z.string()).max(20)]);
68
+ const guard = (fn, gated = true) => async (args) => {
69
+ try {
70
+ if (gated) {
71
+ const building = await ctx.gate();
72
+ if (building)
73
+ return text(building);
74
+ }
75
+ return text(await fn(args));
57
76
  }
58
- return text(await fn(args));
59
- }
60
- catch (err) {
61
- log(`tool error: ${err instanceof Error ? err.stack ?? err.message : err}`);
62
- return { ...text(`error: ${err instanceof Error ? err.message : String(err)}`), isError: true };
63
- }
64
- };
65
- server.registerTool('clast_search', {
66
- title: 'Search symbols',
67
- description: 'Ranked symbol search. Query by exact, partial or abbreviated name ("parseConf", "pcfg"), typo, "Class.method", or plain words describing behaviour (matched against names, signatures, docs and the identifiers used in function bodies). Returns kind, qualified name, file:line, signature and doc summary. Prefer over grep for finding definitions. Array = several searches.',
68
- inputSchema: {
69
- query: names.describe('Name, partial name, Container.name, or descriptive words. Array = several searches.'),
70
- kind: z.enum(SYMBOL_KINDS).optional().describe('Only this kind of symbol'),
71
- path: z.string().optional().describe('Only symbols in files under / matching this path (e.g. "src/db" or "parser.ts")'),
72
- lang: z.string().optional().describe('Only this language id (typescript, python, go, ...)'),
73
- exported: z.boolean().optional().describe('Only exported / public symbols'),
74
- limit: z.number().int().min(1).max(100).default(10).describe('Max results per query'),
75
- },
76
- annotations: READ_ONLY,
77
- _meta: ALWAYS_LOAD,
78
- }, guard(args => search(ctx, args)));
79
- server.registerTool('clast_get_context', {
80
- title: 'Symbol source and context',
81
- description: 'One symbol in one call: its exact source with line numbers plus callers, callees, overloads, overrides and, for classes, members and sub/supertypes. Use INSTEAD of reading a whole file, and before editing a symbol. Address as "name", "Class.method", "path/file.ext:name" or "path/file.ext:<line>". Array = several symbols.',
82
- inputSchema: {
83
- name: names.describe('Symbol name, Container.name, or path:name. Array = several symbols.'),
84
- path: z.string().optional().describe('Disambiguate by file or directory path'),
85
- includeBody: z.boolean().default(true).describe('Include source code (false = signature + docs only)'),
86
- maxLines: z.number().int().min(5).max(2000).default(120).describe('Max source lines per symbol; large classes fall back to a member outline'),
87
- includeCalls: z.boolean().default(true).describe('Include callers and callees'),
88
- },
89
- annotations: READ_ONLY,
90
- _meta: ALWAYS_LOAD,
91
- }, guard(args => getContext(ctx, args)));
92
- server.registerTool('clast_call_graph', {
93
- title: 'Call graph',
94
- description: 'Callers and/or callees as a tree with file:line per edge; depth > 1 follows the chain. Use for the blast radius before a change (every caller to update) or to trace a path. Resolved by receiver type, imports and inheritance; "?" marks name-only matches. Test callers are summarised. Library names list their call sites.',
95
- inputSchema: {
96
- name: z.string().describe('Symbol name, Container.name, or path:name'),
97
- path: z.string().optional().describe('Disambiguate by file or directory path'),
98
- direction: z.enum(['callers', 'callees', 'both']).default('both'),
99
- depth: z.number().int().min(1).max(6).default(1).describe('Levels to traverse (1 = direct only; 2-3 to follow a chain)'),
100
- limit: z.number().int().min(1).max(2000).default(50).describe('Max nodes per direction'),
101
- includeTests: z.boolean().optional().describe('true = list test callers in full, false = drop them; default: one summary line naming the test files'),
102
- within: z.string().optional().describe('Only callers located under this path (e.g. "src/server")'),
103
- uncertain: z.boolean().default(false).describe('List every unconfirmed caller instead of a short summary'),
104
- },
105
- annotations: READ_ONLY,
106
- _meta: ALWAYS_LOAD,
107
- }, guard(args => callGraph(ctx, args)));
108
- server.registerTool('clast_hierarchy', {
109
- title: 'Type hierarchy',
110
- description: 'Supertypes and all direct and indirect subtypes of a class, interface, struct or trait as a tree (including Go interface satisfaction). For a method: the same method on related types (declaration, overrides, implementations). Use for "what implements X", "which classes override Y", "which base class do the others extend".',
111
- inputSchema: {
112
- name: z.string().describe('Type or method: name, Container.name, or path:name'),
113
- path: z.string().optional().describe('Disambiguate by file or directory path'),
114
- direction: z.enum(['supertypes', 'subtypes', 'both']).default('both'),
115
- depth: z.number().int().min(1).max(8).default(3).describe('Levels to expand'),
116
- limit: z.number().int().min(1).max(1000).default(80).describe('Max lines per direction'),
117
- within: z.string().optional().describe('Only subtypes / overrides located under this path'),
118
- },
119
- annotations: READ_ONLY,
120
- _meta: ALWAYS_LOAD,
121
- }, guard(args => hierarchy(ctx, args)));
122
- server.registerTool('clast_references', {
123
- title: 'Find references',
124
- description: 'Every use of an identifier (calls, type annotations, imports, assignments) grouped by file, each line with its enclosing function/class. Matches real identifiers only, not substrings, strings or comments. Use for variables, types, fields, constants and enum members, or when clast_call_graph is too narrow.',
125
- inputSchema: {
126
- name: z.string().describe('Identifier (or Container.name; matching is by the last name segment)'),
127
- path: z.string().optional().describe('Only references in files under / matching this path'),
128
- limit: z.number().int().min(1).max(500).default(40).describe('Max reference lines'),
129
- includeTests: z.boolean().default(true),
130
- },
131
- annotations: READ_ONLY,
132
- _meta: ALWAYS_LOAD,
133
- }, guard(args => references(ctx, args)));
134
- server.registerTool('clast_file_summary', {
135
- title: 'File or directory outline',
136
- description: 'Outline of a file: symbols as a tree of signatures with line ranges and doc summaries, plus its imports and importers. Use INSTEAD of reading a file to learn its structure. For a directory: its files with main symbols and sub-directories with sizes. Partial paths work ("db/queries").',
137
- inputSchema: {
138
- path: z.string().describe('File or directory path (relative; partial paths are matched)'),
139
- members: z
140
- .enum(['auto', 'all', 'callable'])
141
- .default('auto')
142
- .describe('Whether to list fields/properties/constants inside classes (auto hides them in very large files)'),
143
- limit: z.number().int().min(20).max(5000).default(300).describe('Max outline lines for a file'),
144
- },
145
- annotations: READ_ONLY,
146
- _meta: ALWAYS_LOAD,
147
- }, guard(args => fileSummary(ctx, args)));
148
- server.registerTool('clast_overview', {
149
- title: 'Repository map',
150
- description: 'Map of the repository or a sub-directory: languages, layout with sizes, most referenced classes/functions, hub files, entry points. Call first in an unfamiliar codebase.',
151
- inputSchema: {
152
- path: z.string().optional().describe('Sub-directory to map (default: whole repository)'),
153
- },
154
- annotations: READ_ONLY,
155
- _meta: ALWAYS_LOAD,
156
- }, guard(args => overview(ctx, args)));
157
- server.registerTool('clast_grep', {
158
- title: 'Text search with symbol context',
159
- description: 'Text search over all text files (literal or regex, smart-case); each hit is labelled with its enclosing function/class. Use for strings, comments, error messages and config keys; for identifiers prefer clast_search / clast_references.',
160
- inputSchema: {
161
- pattern: z.string().describe('Text to find (literal unless regex=true)'),
162
- regex: z.boolean().default(false).describe('Interpret pattern as a JavaScript regular expression'),
163
- path: z.string().optional().describe('Only files under / matching this path'),
164
- lang: z.string().optional().describe('Only this language id'),
165
- caseSensitive: z.boolean().optional().describe('Default: case-insensitive unless the pattern contains uppercase'),
166
- limit: z.number().int().min(1).max(500).default(50).describe('Max matching lines'),
167
- includeTests: z.boolean().default(true),
168
- },
169
- annotations: READ_ONLY,
170
- _meta: ALWAYS_LOAD,
171
- }, guard(args => grep(ctx, args)));
172
- server.registerTool('clast_stats', {
173
- title: 'Count and aggregate',
174
- description: 'Exact counts for "how many ..." questions, grouped by directory, file, kind or name; do not tally search results by hand. what = inventory (size, languages, production vs tests, symbols by kind, longest functions), symbols (name pattern "*Receiver|*Service" and/or kind), subtypes (direct and indirect subclasses / implementers), calls (call sites of "query|execute", optionally on a receiver), text (regex), imports (external dependencies), endpoints (route declarations of common web frameworks), database (SQL, schema, ORM models, query calls; heuristic).',
175
- inputSchema: {
176
- what: z.enum(['inventory', 'symbols', 'subtypes', 'calls', 'text', 'imports', 'endpoints', 'database']).optional()
177
- .describe('What to count (default inventory, or symbols when name is given)'),
178
- name: z.string().optional().describe('symbols: name pattern with * and | ; subtypes: base type; calls: called name(s); text: regular expression'),
179
- kind: z.string().optional().describe('symbols: only these kinds, comma separated (class, interface, function, method, ...)'),
180
- on: z.string().optional().describe('calls: only on receivers / receiver types matching this pattern'),
181
- path: z.string().optional().describe('Only files under / matching this path'),
182
- lang: z.string().optional().describe('Only this language id'),
183
- groupBy: z.enum(['dir', 'file', 'kind', 'lang', 'name', 'container', 'callee', 'caller', 'receiver', 'match']).optional()
184
- .describe('Grouping of the main table (default dir)'),
185
- depth: z.number().int().min(1).max(12).optional().describe('Directory depth for groupBy=dir (default 2)'),
186
- limit: z.number().int().min(1).max(500).optional().describe('Rows per table (default 25)'),
187
- includeTests: z.boolean().optional().describe('Include tests/examples in the tables (default: counted separately)'),
188
- },
189
- annotations: READ_ONLY,
190
- _meta: ALWAYS_LOAD,
191
- }, guard(args => stats(ctx, args)));
192
- server.registerTool('clast_impact', {
193
- title: 'Impact of changing a symbol',
194
- description: 'Before changing a signature, behaviour or deleting a symbol: one answer with the declarations / overrides / implementations that must change together, every direct caller by file and line, how far the change reaches through indirect callers, and the test files to run (those that call it directly or through its callers).',
195
- inputSchema: {
196
- name: z.string().describe('Symbol: name, Container.name, or path:name'),
197
- path: z.string().optional().describe('Disambiguate by file or directory path'),
198
- depth: z.number().int().min(1).max(6).optional().describe('Caller levels to follow (default 3)'),
199
- limit: z.number().int().min(1).max(500).optional().describe('Max lines per section (default 30)'),
200
- },
201
- annotations: READ_ONLY,
202
- _meta: ALWAYS_LOAD,
203
- }, guard(args => impact(ctx, args)));
204
- server.registerTool('clast_unused', {
205
- title: 'Unused code',
206
- description: 'Dead code: functions, methods and types that nothing references (or that only other unused code references), grouped by file with line ranges; plus code used only by tests, and names that only appear in strings or comments. Entry points, decorated / attribute-marked symbols and overrides of library types are left out. Use after a refactor or to clean up a directory.',
207
- inputSchema: {
208
- path: z.string().optional().describe('Only judge symbols under / matching this path'),
209
- lang: z.string().optional().describe('Only this language id'),
210
- kind: z.string().optional().describe('Kinds to judge, comma separated (default function, method, class, struct, interface, trait, enum, type)'),
211
- exported: z.boolean().optional().describe('false: leave out exported / public symbols'),
212
- limit: z.number().int().min(1).max(1000).optional().describe('Max symbols listed (default 60)'),
213
- },
214
- annotations: READ_ONLY,
215
- _meta: ALWAYS_LOAD,
216
- }, guard(args => unused(ctx, args)));
217
- server.registerTool('clast_changes', {
218
- title: 'Changed symbols and impact',
219
- description: 'Map the current git diff to code structure: which functions/classes were touched (uncommitted changes by default, or relative to a base ref such as "main"), which callers outside the change may be affected, and which test files exercise the changed symbols. Use when reviewing a change, before committing, or to decide which tests to run.',
220
- inputSchema: {
221
- base: z.string().optional().describe('Git ref to diff against (default HEAD = uncommitted changes; e.g. "main", "HEAD~3")'),
222
- },
223
- annotations: { readOnlyHint: true, openWorldHint: false },
224
- }, guard(args => changes(ctx, args)));
225
- server.registerTool('clast_status', {
226
- title: 'Index status',
227
- description: 'Index statistics and health: files, symbols, languages, whether indexing is in progress, watcher state.',
228
- inputSchema: {},
229
- annotations: READ_ONLY,
230
- }, guard(() => status(ctx, watcher), false));
231
- server.registerTool('clast_reindex', {
232
- title: 'Re-index',
233
- description: 'Re-scan the repository (incremental: only changed files are re-parsed) or force re-index one file. Rarely needed - the index follows file changes automatically and re-checks files when they are queried. Use force=true to rebuild from scratch.',
234
- inputSchema: {
235
- path: z.string().optional().describe('Single file to re-index (default: whole repository)'),
236
- force: z.boolean().default(false).describe('Re-parse every file even if unchanged'),
237
- },
238
- annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false },
239
- }, guard(args => reindex(ctx, args), false));
240
- server.registerTool('clast_comment', {
241
- title: 'Get or generate documentation',
242
- description: 'Return the documentation comment of a symbol. With generate=true and a local LLM configured (llm.model in clast.config.json), generates and stores a doc comment for undocumented symbols.',
243
- inputSchema: {
244
- name: z.string().describe('Symbol name, Container.name, or path:name'),
245
- generate: z.boolean().default(false).describe('Generate with the configured LLM if no comment exists'),
246
- },
247
- annotations: { readOnlyHint: false, openWorldHint: true },
248
- }, guard(async ({ name, generate }) => {
249
- await ctx.ready();
250
- const matches = findSymbols(ctx.db, name);
251
- if (matches.length === 0)
252
- return `"${name}": no symbol with this name.`;
253
- const out = [];
254
- for (const sym of matches.slice(0, 5)) {
255
- out.push(symLine(sym));
256
- const stored = commentGen.stored(sym);
257
- if (sym.doc)
258
- out.push(sym.doc);
259
- else if (stored)
260
- out.push(`[generated] ${stored}`);
261
- else if (generate) {
262
- if (!commentGen.isAvailable)
263
- out.push('(no comment; LLM not configured - set llm.model in clast.config.json)');
77
+ catch (err) {
78
+ log(`tool error: ${err instanceof Error ? err.stack ?? err.message : err}`);
79
+ return { ...text(`error: ${err instanceof Error ? err.message : String(err)}`), isError: true };
80
+ }
81
+ };
82
+ server.registerTool('clast_search', {
83
+ title: 'Search symbols',
84
+ description: 'Ranked symbol search. Query by exact, partial or abbreviated name ("parseConf", "pcfg"), typo, "Class.method", or plain words describing behaviour (matched against names, signatures, docs and the identifiers used in function bodies). Returns kind, qualified name, file:line, signature and doc summary. Prefer over grep for finding definitions. Array = several searches.',
85
+ inputSchema: {
86
+ query: names.describe('Name, partial name, Container.name, or descriptive words. Array = several searches.'),
87
+ kind: z.enum(SYMBOL_KINDS).optional().describe('Only this kind of symbol'),
88
+ path: z.string().optional().describe('Only symbols in files under / matching this path (e.g. "src/db" or "parser.ts")'),
89
+ lang: z.string().optional().describe('Only this language id (typescript, python, go, ...)'),
90
+ exported: z.boolean().optional().describe('Only exported / public symbols'),
91
+ limit: z.number().int().min(1).max(100).default(10).describe('Max results per query'),
92
+ },
93
+ annotations: READ_ONLY,
94
+ _meta: ALWAYS_LOAD,
95
+ }, guard(args => search(ctx, args)));
96
+ server.registerTool('clast_get_context', {
97
+ title: 'Symbol source and context',
98
+ description: 'One symbol in one call: its exact source with line numbers plus callers, callees, overloads, overrides and, for classes, members and sub/supertypes. Use INSTEAD of reading a whole file, and before editing a symbol. Address as "name", "Class.method", "path/file.ext:name" or "path/file.ext:<line>". Array = several symbols.',
99
+ inputSchema: {
100
+ name: names.describe('Symbol name, Container.name, or path:name. Array = several symbols.'),
101
+ path: z.string().optional().describe('Disambiguate by file or directory path'),
102
+ includeBody: z.boolean().default(true).describe('Include source code (false = signature + docs only)'),
103
+ maxLines: z.number().int().min(5).max(2000).default(120).describe('Max source lines per symbol; large classes fall back to a member outline'),
104
+ includeCalls: z.boolean().default(true).describe('Include callers and callees'),
105
+ },
106
+ annotations: READ_ONLY,
107
+ _meta: ALWAYS_LOAD,
108
+ }, guard(args => getContext(ctx, args)));
109
+ server.registerTool('clast_call_graph', {
110
+ title: 'Call graph',
111
+ description: 'Callers and/or callees as a tree with file:line per edge; depth > 1 follows the chain. Use for the blast radius before a change (every caller to update) or to trace a path. Resolved by receiver type, imports and inheritance; "?" marks name-only matches. Test callers are summarised. Library names list their call sites.',
112
+ inputSchema: {
113
+ name: z.string().describe('Symbol name, Container.name, or path:name'),
114
+ path: z.string().optional().describe('Disambiguate by file or directory path'),
115
+ direction: z.enum(['callers', 'callees', 'both']).default('both'),
116
+ depth: z.number().int().min(1).max(6).default(1).describe('Levels to traverse (1 = direct only; 2-3 to follow a chain)'),
117
+ limit: z.number().int().min(1).max(2000).default(50).describe('Max nodes per direction'),
118
+ includeTests: z.boolean().optional().describe('true = list test callers in full, false = drop them; default: one summary line naming the test files'),
119
+ within: z.string().optional().describe('Only callers located under this path (e.g. "src/server")'),
120
+ uncertain: z.boolean().default(false).describe('List every unconfirmed caller instead of a short summary'),
121
+ },
122
+ annotations: READ_ONLY,
123
+ _meta: ALWAYS_LOAD,
124
+ }, guard(args => callGraph(ctx, args)));
125
+ server.registerTool('clast_hierarchy', {
126
+ title: 'Type hierarchy',
127
+ description: 'Supertypes and all direct and indirect subtypes of a class, interface, struct or trait as a tree (including Go interface satisfaction). For a method: the same method on related types (declaration, overrides, implementations). Use for "what implements X", "which classes override Y", "which base class do the others extend".',
128
+ inputSchema: {
129
+ name: z.string().describe('Type or method: name, Container.name, or path:name'),
130
+ path: z.string().optional().describe('Disambiguate by file or directory path'),
131
+ direction: z.enum(['supertypes', 'subtypes', 'both']).default('both'),
132
+ depth: z.number().int().min(1).max(8).default(3).describe('Levels to expand'),
133
+ limit: z.number().int().min(1).max(1000).default(80).describe('Max lines per direction'),
134
+ within: z.string().optional().describe('Only subtypes / overrides located under this path'),
135
+ },
136
+ annotations: READ_ONLY,
137
+ _meta: ALWAYS_LOAD,
138
+ }, guard(args => hierarchy(ctx, args)));
139
+ server.registerTool('clast_references', {
140
+ title: 'Find references',
141
+ description: 'Every use of an identifier (calls, type annotations, imports, assignments) grouped by file, each line with its enclosing function/class. Matches real identifiers only, not substrings, strings or comments. Use for variables, types, fields, constants and enum members, or when clast_call_graph is too narrow.',
142
+ inputSchema: {
143
+ name: z.string().describe('Identifier (or Container.name; matching is by the last name segment)'),
144
+ path: z.string().optional().describe('Only references in files under / matching this path'),
145
+ limit: z.number().int().min(1).max(500).default(40).describe('Max reference lines'),
146
+ includeTests: z.boolean().default(true),
147
+ },
148
+ annotations: READ_ONLY,
149
+ _meta: ALWAYS_LOAD,
150
+ }, guard(args => references(ctx, args)));
151
+ server.registerTool('clast_file_summary', {
152
+ title: 'File or directory outline',
153
+ description: 'Outline of a file: symbols as a tree of signatures with line ranges and doc summaries, plus its imports and importers. Use INSTEAD of reading a file to learn its structure. For a directory: its files with main symbols and sub-directories with sizes. Partial paths work ("db/queries").',
154
+ inputSchema: {
155
+ path: z.string().describe('File or directory path (relative; partial paths are matched)'),
156
+ members: z
157
+ .enum(['auto', 'all', 'callable'])
158
+ .default('auto')
159
+ .describe('Whether to list fields/properties/constants inside classes (auto hides them in very large files)'),
160
+ limit: z.number().int().min(20).max(5000).default(300).describe('Max outline lines for a file'),
161
+ },
162
+ annotations: READ_ONLY,
163
+ _meta: ALWAYS_LOAD,
164
+ }, guard(args => fileSummary(ctx, args)));
165
+ server.registerTool('clast_overview', {
166
+ title: 'Repository map',
167
+ description: 'Map of the repository or a sub-directory: languages, layout with sizes, most referenced classes/functions, hub files, entry points. Call first in an unfamiliar codebase.',
168
+ inputSchema: {
169
+ path: z.string().optional().describe('Sub-directory to map (default: whole repository)'),
170
+ },
171
+ annotations: READ_ONLY,
172
+ _meta: ALWAYS_LOAD,
173
+ }, guard(args => overview(ctx, args)));
174
+ server.registerTool('clast_grep', {
175
+ title: 'Text search with symbol context',
176
+ description: 'Text search over all text files (literal or regex, smart-case); each hit is labelled with its enclosing function/class. Use for strings, comments, error messages and config keys; for identifiers prefer clast_search / clast_references.',
177
+ inputSchema: {
178
+ pattern: z.string().describe('Text to find (literal unless regex=true)'),
179
+ regex: z.boolean().default(false).describe('Interpret pattern as a JavaScript regular expression'),
180
+ path: z.string().optional().describe('Only files under / matching this path'),
181
+ lang: z.string().optional().describe('Only this language id'),
182
+ caseSensitive: z.boolean().optional().describe('Default: case-insensitive unless the pattern contains uppercase'),
183
+ limit: z.number().int().min(1).max(500).default(50).describe('Max matching lines'),
184
+ includeTests: z.boolean().default(true),
185
+ },
186
+ annotations: READ_ONLY,
187
+ _meta: ALWAYS_LOAD,
188
+ }, guard(args => grep(ctx, args)));
189
+ server.registerTool('clast_stats', {
190
+ title: 'Count and aggregate',
191
+ description: 'Exact counts for "how many ..." questions, grouped by directory, file, kind or name; do not tally search results by hand. what = inventory (size, languages, production vs tests, symbols by kind, longest functions), symbols (name pattern "*Receiver|*Service" and/or kind), subtypes (direct and indirect subclasses / implementers), calls (call sites of "query|execute", optionally on a receiver), text (regex), imports (external dependencies), endpoints (route declarations of common web frameworks), database (SQL, schema, ORM models, query calls; heuristic).',
192
+ inputSchema: {
193
+ what: z.enum(['inventory', 'symbols', 'subtypes', 'calls', 'text', 'imports', 'endpoints', 'database']).optional()
194
+ .describe('What to count (default inventory, or symbols when name is given)'),
195
+ name: z.string().optional().describe('symbols: name pattern with * and | ; subtypes: base type; calls: called name(s); text: regular expression'),
196
+ kind: z.string().optional().describe('symbols: only these kinds, comma separated (class, interface, function, method, ...)'),
197
+ on: z.string().optional().describe('calls: only on receivers / receiver types matching this pattern'),
198
+ path: z.string().optional().describe('Only files under / matching this path'),
199
+ lang: z.string().optional().describe('Only this language id'),
200
+ groupBy: z.enum(['dir', 'file', 'kind', 'lang', 'name', 'container', 'callee', 'caller', 'receiver', 'match']).optional()
201
+ .describe('Grouping of the main table (default dir)'),
202
+ depth: z.number().int().min(1).max(12).optional().describe('Directory depth for groupBy=dir (default 2)'),
203
+ limit: z.number().int().min(1).max(500).optional().describe('Rows per table (default 25)'),
204
+ includeTests: z.boolean().optional().describe('Include tests/examples in the tables (default: counted separately)'),
205
+ },
206
+ annotations: READ_ONLY,
207
+ _meta: ALWAYS_LOAD,
208
+ }, guard(args => stats(ctx, args)));
209
+ server.registerTool('clast_impact', {
210
+ title: 'Impact of changing a symbol',
211
+ description: 'Before changing a signature, behaviour or deleting a symbol: one answer with the declarations / overrides / implementations that must change together, every direct caller by file and line, how far the change reaches through indirect callers, and the test files to run (those that call it directly or through its callers).',
212
+ inputSchema: {
213
+ name: z.string().describe('Symbol: name, Container.name, or path:name'),
214
+ path: z.string().optional().describe('Disambiguate by file or directory path'),
215
+ depth: z.number().int().min(1).max(6).optional().describe('Caller levels to follow (default 3)'),
216
+ limit: z.number().int().min(1).max(500).optional().describe('Max lines per section (default 30)'),
217
+ },
218
+ annotations: READ_ONLY,
219
+ _meta: ALWAYS_LOAD,
220
+ }, guard(args => impact(ctx, args)));
221
+ server.registerTool('clast_unused', {
222
+ title: 'Unused code',
223
+ description: 'Dead code: functions, methods and types that nothing references (or that only other unused code references), grouped by file with line ranges; plus code used only by tests, and names that only appear in strings or comments. Entry points, decorated / attribute-marked symbols and overrides of library types are left out. Use after a refactor or to clean up a directory.',
224
+ inputSchema: {
225
+ path: z.string().optional().describe('Only judge symbols under / matching this path'),
226
+ lang: z.string().optional().describe('Only this language id'),
227
+ kind: z.string().optional().describe('Kinds to judge, comma separated (default function, method, class, struct, interface, trait, enum, type)'),
228
+ exported: z.boolean().optional().describe('false: leave out exported / public symbols'),
229
+ limit: z.number().int().min(1).max(1000).optional().describe('Max symbols listed (default 60)'),
230
+ },
231
+ annotations: READ_ONLY,
232
+ _meta: ALWAYS_LOAD,
233
+ }, guard(args => unused(ctx, args)));
234
+ server.registerTool('clast_changes', {
235
+ title: 'Changed symbols and impact',
236
+ description: 'Map the current git diff to code structure: which functions/classes were touched (uncommitted changes by default, or relative to a base ref such as "main"), which callers outside the change may be affected, and which test files exercise the changed symbols. Use when reviewing a change, before committing, or to decide which tests to run.',
237
+ inputSchema: {
238
+ base: z.string().optional().describe('Git ref to diff against (default HEAD = uncommitted changes; e.g. "main", "HEAD~3")'),
239
+ },
240
+ annotations: { readOnlyHint: true, openWorldHint: false },
241
+ }, guard(args => changes(ctx, args)));
242
+ server.registerTool('clast_status', {
243
+ title: 'Index status',
244
+ description: 'Index statistics and health: files, symbols, languages, whether indexing is in progress, watcher state.',
245
+ inputSchema: {},
246
+ annotations: READ_ONLY,
247
+ }, guard(() => status(ctx, watcher), false));
248
+ server.registerTool('clast_reindex', {
249
+ title: 'Re-index',
250
+ description: 'Re-scan the repository (incremental: only changed files are re-parsed) or force re-index one file. Rarely needed - the index follows file changes automatically and re-checks files when they are queried. Use force=true to rebuild from scratch.',
251
+ inputSchema: {
252
+ path: z.string().optional().describe('Single file to re-index (default: whole repository)'),
253
+ force: z.boolean().default(false).describe('Re-parse every file even if unchanged'),
254
+ },
255
+ annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false },
256
+ }, guard(args => reindex(ctx, args), false));
257
+ server.registerTool('clast_comment', {
258
+ title: 'Get or generate documentation',
259
+ description: 'Return the documentation comment of a symbol. With generate=true and a local LLM configured (llm.model in clast.config.json), generates and stores a doc comment for undocumented symbols.',
260
+ inputSchema: {
261
+ name: z.string().describe('Symbol name, Container.name, or path:name'),
262
+ generate: z.boolean().default(false).describe('Generate with the configured LLM if no comment exists'),
263
+ },
264
+ annotations: { readOnlyHint: false, openWorldHint: true },
265
+ }, guard(async ({ name, generate }) => {
266
+ await ctx.ready();
267
+ const matches = findSymbols(ctx.db, name);
268
+ if (matches.length === 0)
269
+ return `"${name}": no symbol with this name.`;
270
+ const out = [];
271
+ for (const sym of matches.slice(0, 5)) {
272
+ out.push(symLine(sym));
273
+ const stored = commentGen.stored(sym);
274
+ if (sym.doc)
275
+ out.push(sym.doc);
276
+ else if (stored)
277
+ out.push(`[generated] ${stored}`);
278
+ else if (generate) {
279
+ if (!commentGen.isAvailable)
280
+ out.push('(no comment; LLM not configured - set llm.model in clast.config.json)');
281
+ else
282
+ out.push((await commentGen.generate(sym)) ?? '(generation failed; see server log)');
283
+ }
264
284
  else
265
- out.push((await commentGen.generate(sym)) ?? '(generation failed; see server log)');
285
+ out.push('(no comment)');
266
286
  }
267
- else
268
- out.push('(no comment)');
269
- }
270
- return out.join('\n');
271
- }));
272
- // Connect first so the client never waits on indexing; the index builds
273
- // (or revalidates) in the background and tools report progress meanwhile.
274
- const transport = new StdioServerTransport();
275
- await server.connect(transport);
276
- log('MCP server running on stdio');
277
- clast.indexer
278
- .indexAll()
279
- .then(r => {
280
- const s = clast.db.stats();
281
- log(`index ready: scanned ${r.scanned}, parsed ${r.parsed}, removed ${r.removed} in ${r.durationMs}ms ` +
282
- `(${s.files} files, ${s.symbols} symbols)`);
283
- })
284
- .catch(err => log(`indexing failed: ${err instanceof Error ? err.stack : err}`))
285
- .finally(() => {
286
- if (clast.config.watch.enabled) {
287
+ return out.join('\n');
288
+ }));
289
+ // The index builds (or revalidates) in the background and tools report progress meanwhile.
290
+ begin = () => {
291
+ clast.indexer
292
+ .indexAll()
293
+ .then(r => {
294
+ const s = clast.db.stats();
295
+ log(`index ready: scanned ${r.scanned}, parsed ${r.parsed}, removed ${r.removed} in ${r.durationMs}ms ` +
296
+ `(${s.files} files, ${s.symbols} symbols)`);
297
+ })
298
+ .catch(err => log(`indexing failed: ${err instanceof Error ? err.stack : err}`))
299
+ .finally(() => {
300
+ if (clast.config.watch.enabled) {
301
+ try {
302
+ watcher.start();
303
+ log('file watcher active');
304
+ }
305
+ catch (err) {
306
+ log(`watcher failed to start: ${err instanceof Error ? err.message : err}`);
307
+ }
308
+ }
309
+ });
310
+ watcher.on('error', ({ filePath, error }) => {
311
+ log(`watch error ${filePath}: ${error.message}`);
312
+ });
313
+ };
314
+ if (connected)
315
+ begin();
316
+ }; // activate
317
+ if (startActive) {
318
+ activate();
319
+ }
320
+ else {
321
+ log('dormant: no .clast folder in the project root');
322
+ const enableTool = server.registerTool('clast_enable', {
323
+ title: 'Turn clast on for this project',
324
+ description: 'Clast (code index) is off for this project. Call this only when the user asks to use clast: it creates the .clast folder in the project root, builds the index and adds the clast tools.',
325
+ inputSchema: {},
326
+ annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false },
327
+ }, async () => {
287
328
  try {
288
- watcher.start();
289
- log('file watcher active');
329
+ activate();
330
+ enableTool.remove();
331
+ return text(`clast is on for ${projectRoot}. The index is building; the clast tools are available now ` +
332
+ `(reconnect the server or restart the session if they do not appear). ` +
333
+ `To turn it off again, delete the .clast folder.\n\n${INSTRUCTIONS}`);
290
334
  }
291
335
  catch (err) {
292
- log(`watcher failed to start: ${err instanceof Error ? err.message : err}`);
336
+ return { ...text(`error: ${err instanceof Error ? err.message : String(err)}`), isError: true };
293
337
  }
294
- }
295
- });
296
- watcher.on('error', ({ filePath, error }) => {
297
- log(`watch error ${filePath}: ${error.message}`);
298
- });
338
+ });
339
+ // The folder can also appear without the tool (a skill, the CLI, the user): pick that up.
340
+ const poll = setInterval(() => {
341
+ if (active)
342
+ return void clearInterval(poll);
343
+ if (!existsSync(marker))
344
+ return;
345
+ clearInterval(poll);
346
+ try {
347
+ activate();
348
+ enableTool.remove();
349
+ log('.clast folder found: active');
350
+ }
351
+ catch (err) {
352
+ log(`could not activate: ${err instanceof Error ? err.message : err}`);
353
+ }
354
+ }, 2000);
355
+ poll.unref();
356
+ }
357
+ // Connect first so the client never waits on indexing.
358
+ const transport = new StdioServerTransport();
359
+ await server.connect(transport);
360
+ connected = true;
361
+ log('MCP server running on stdio');
362
+ begin?.();
299
363
  let closing = false;
300
364
  const shutdown = () => {
301
365
  if (closing)
302
366
  return;
303
367
  closing = true;
304
- watcher
368
+ const live = active;
369
+ if (!live)
370
+ return void process.exit(0);
371
+ live.watcher
305
372
  .stop()
306
373
  .catch(() => undefined)
307
374
  .finally(() => {
308
375
  try {
309
- clast.close();
376
+ live.clast.close();
310
377
  }
311
378
  catch { /* already closed */ }
312
379
  process.exit(0);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"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"}
package/dist/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Package version (keep in sync with package.json; checked by a test). */
2
- export declare const VERSION = "0.2.5";
2
+ export declare const VERSION = "0.3.0";
package/dist/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  /** Package version (keep in sync with package.json; checked by a test). */
2
- export const VERSION = '0.2.5';
2
+ export const VERSION = '0.3.0';
3
3
  //# sourceMappingURL=version.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "clast-ai",
3
- "version": "0.2.5",
3
+ "version": "0.3.0",
4
4
  "description": "Code index MCP server for coding agents (Claude Code, Codex, Gemini CLI, any MCP client): symbol search, type-aware call graph, hierarchy, change impact, dead code and exact counts",
5
5
  "main": "dist/engine.js",
6
6
  "bin": {
@@ -3,10 +3,10 @@ name: audit
3
3
  description: Factual inventory of a code base for due diligence or onboarding - size, structure, endpoints, database access, dependencies, dead code.
4
4
  argument-hint: "[path]"
5
5
  disable-model-invocation: true
6
- allowed-tools: mcp__plugin_clast_clast__clast_stats, mcp__plugin_clast_clast__clast_overview, mcp__plugin_clast_clast__clast_unused, mcp__plugin_clast_clast__clast_file_summary, mcp__plugin_clast_clast__clast_grep, Grep, Read, Glob
6
+ allowed-tools: mcp__plugin_clast_clast__clast_enable, mcp__plugin_clast_clast__clast_stats, mcp__plugin_clast_clast__clast_overview, mcp__plugin_clast_clast__clast_unused, mcp__plugin_clast_clast__clast_file_summary, mcp__plugin_clast_clast__clast_grep, Grep, Read, Glob
7
7
  ---
8
8
 
9
- Scope: `$ARGUMENTS` (empty = whole project). Pass it as `path` to every call.
9
+ Scope: `$ARGUMENTS` (empty = whole project). Pass it as `path` to every call. If the clast tools are not available, call `clast_enable` first.
10
10
 
11
11
  Issue these calls together:
12
12
 
@@ -3,10 +3,10 @@ name: deadcode
3
3
  description: Find dead code in the project or under a path, verify it, remove what the user confirms.
4
4
  argument-hint: "[path]"
5
5
  disable-model-invocation: true
6
- allowed-tools: mcp__plugin_clast_clast__clast_unused, mcp__plugin_clast_clast__clast_call_graph, mcp__plugin_clast_clast__clast_references, mcp__plugin_clast_clast__clast_grep, Grep, Read
6
+ allowed-tools: mcp__plugin_clast_clast__clast_enable, mcp__plugin_clast_clast__clast_unused, mcp__plugin_clast_clast__clast_call_graph, mcp__plugin_clast_clast__clast_references, mcp__plugin_clast_clast__clast_grep, Grep, Read
7
7
  ---
8
8
 
9
- Scope: `$ARGUMENTS` (empty = whole project).
9
+ Scope: `$ARGUMENTS` (empty = whole project). If the clast tools are not available, call `clast_enable` first.
10
10
 
11
11
  1. Call `clast_unused` with `path` = scope.
12
12
  2. Treat each group:
@@ -3,12 +3,12 @@ name: impact
3
3
  description: Show what a change to one symbol affects - what changes with it, every caller, the tests to run.
4
4
  argument-hint: "<symbol>"
5
5
  disable-model-invocation: true
6
- allowed-tools: mcp__plugin_clast_clast__clast_impact, mcp__plugin_clast_clast__clast_search, mcp__plugin_clast_clast__clast_get_context, mcp__plugin_clast_clast__clast_call_graph, mcp__plugin_clast_clast__clast_hierarchy, Grep, Read
6
+ allowed-tools: mcp__plugin_clast_clast__clast_enable, mcp__plugin_clast_clast__clast_impact, mcp__plugin_clast_clast__clast_search, mcp__plugin_clast_clast__clast_get_context, mcp__plugin_clast_clast__clast_call_graph, mcp__plugin_clast_clast__clast_hierarchy, Grep, Read
7
7
  ---
8
8
 
9
9
  Symbol: `$ARGUMENTS`. If empty, ask. If ambiguous, pick the candidate the user means and address it as `Container.name` or `path/file.ext:name`.
10
10
 
11
- 1. Call `clast_impact`.
11
+ 1. If the clast tools are not available, call `clast_enable`. Call `clast_impact`.
12
12
  2. Report in this order:
13
13
  - Changes together: declarations, overrides, implementations, overloads.
14
14
  - Direct callers by file and line. Read each `?` caller and state if it is real.
@@ -2,7 +2,7 @@
2
2
  name: status
3
3
  description: Show the state of the clast index for this project.
4
4
  disable-model-invocation: true
5
- allowed-tools: mcp__plugin_clast_clast__clast_status, mcp__plugin_clast_clast__clast_reindex
5
+ allowed-tools: mcp__plugin_clast_clast__clast_enable, mcp__plugin_clast_clast__clast_status, mcp__plugin_clast_clast__clast_reindex
6
6
  ---
7
7
 
8
- Call `clast_status`. Report files, symbols, languages, up to date or building (with progress), database location. If it shows a problem, state it and offer `clast_reindex`. Do not reindex unasked.
8
+ If `clast_status` is not available, clast is off for this project: report that and name `/clast:use`. Otherwise call `clast_status`. Report files, symbols, languages, up to date or building (with progress), database location. If it shows a problem, state it and offer `clast_reindex`. Do not reindex unasked.
@@ -0,0 +1,13 @@
1
+ ---
2
+ name: use
3
+ description: Turn clast on for this project (creates the .clast folder and builds the index).
4
+ disable-model-invocation: true
5
+ allowed-tools: mcp__plugin_clast_clast__clast_enable
6
+ ---
7
+
8
+ 1. If `.clast` exists in the project root, clast is already on: report that and stop.
9
+ 2. Call the `clast_enable` tool. If it is deferred, load it with tool search first.
10
+ 3. If the tool is not available, create the folder `.clast` in the project root. The server finds it within seconds.
11
+ 4. Report: clast is on, the index builds in the background. If the clast tools do not appear, run `/mcp` and reconnect `clast`, or restart the session.
12
+
13
+ To turn clast off for the project, delete the `.clast` folder.
@@ -1,6 +1,7 @@
1
1
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
2
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
- import { resolve } from 'node:path';
3
+ import { existsSync, mkdirSync } from 'node:fs';
4
+ import { join, resolve } from 'node:path';
4
5
  import { pathToFileURL } from 'node:url';
5
6
  import { z } from 'zod';
6
7
 
@@ -32,6 +33,9 @@ When adding something new (a subclass, a handler, a provider): find the siblings
32
33
  When renaming a symbol or changing a signature: if the name is distinctive, do NOT use clast - one Grep for the name lists every site, then edit. Use clast_impact first only when the name is common (get, run, close) so that Grep would drown in unrelated hits, when overrides or interface implementations must change with it, or to choose the tests to run.
33
34
  Most tools take several names at once (arrays). Symbols: name, Container.name, or path/to/file.ext:name. "?" marks a name-based guess. The index follows file changes, including your own edits.`;
34
35
 
36
+ const DORMANT_INSTRUCTIONS =
37
+ 'Clast (code index) is installed but off for this project: there is no .clast folder in the project root. Do not mention it. If the user asks to use clast, call clast_enable.';
38
+
35
39
  const text = (t: string) => ({ content: [{ type: 'text' as const, text: t }] });
36
40
 
37
41
  const READ_ONLY = { readOnlyHint: true, idempotentHint: true, openWorldHint: false } as const;
@@ -51,12 +55,29 @@ export async function startServer(): Promise<void> {
51
55
  };
52
56
  log(`v${VERSION} project root: ${projectRoot}`);
53
57
 
58
+ // Opt-in per project. The client starts this process in every project, code or not. It indexes and
59
+ // offers its tools only where a `.clast` folder exists in the project root (`/clast:use` or the
60
+ // `clast_enable` tool creates it; the index lives there). Anywhere else it stays dormant: one small
61
+ // tool, no index, no watcher. CLAST_ALWAYS=1 or an explicit CLAST_DB_PATH switches it on regardless.
62
+ const marker = join(projectRoot, '.clast');
63
+ const wanted = (): boolean => process.env.CLAST_ALWAYS === '1' || !!process.env.CLAST_DB_PATH || existsSync(marker);
64
+ const startActive = wanted();
65
+ const server = new McpServer(
66
+ { name: 'clast', version: VERSION },
67
+ { instructions: startActive ? INSTRUCTIONS : DORMANT_INSTRUCTIONS }
68
+ );
69
+ let active: { clast: Clast; watcher: FileWatcher } | null = null;
70
+ let connected = false;
71
+ let begin: (() => void) | null = null;
72
+
73
+ const activate = (): void => {
74
+ if (active) return;
75
+ mkdirSync(marker, { recursive: true });
54
76
  const clast = new Clast(projectRoot);
55
77
  const ctx = new ToolContext(clast);
56
78
  const watcher = new FileWatcher(clast.indexer, clast.config.watch.debounceMs);
57
79
  const commentGen = new CommentGenerator(clast.db, clast.config, ctx.lines);
58
-
59
- const server = new McpServer({ name: 'clast', version: VERSION }, { instructions: INSTRUCTIONS });
80
+ active = { clast, watcher };
60
81
 
61
82
  const names = z.union([z.string(), z.array(z.string()).max(20)]);
62
83
  const guard = <A>(fn: (args: A) => Promise<string>, gated = true) => async (args: A) => {
@@ -361,12 +382,8 @@ export async function startServer(): Promise<void> {
361
382
  })
362
383
  );
363
384
 
364
- // Connect first so the client never waits on indexing; the index builds
365
- // (or revalidates) in the background and tools report progress meanwhile.
366
- const transport = new StdioServerTransport();
367
- await server.connect(transport);
368
- log('MCP server running on stdio');
369
-
385
+ // The index builds (or revalidates) in the background and tools report progress meanwhile.
386
+ begin = (): void => {
370
387
  clast.indexer
371
388
  .indexAll()
372
389
  .then(r => {
@@ -391,16 +408,71 @@ export async function startServer(): Promise<void> {
391
408
  watcher.on('error', ({ filePath, error }: { filePath: string; error: Error }) => {
392
409
  log(`watch error ${filePath}: ${error.message}`);
393
410
  });
411
+ };
412
+ if (connected) begin();
413
+ }; // activate
414
+
415
+ if (startActive) {
416
+ activate();
417
+ } else {
418
+ log('dormant: no .clast folder in the project root');
419
+ const enableTool = server.registerTool(
420
+ 'clast_enable',
421
+ {
422
+ title: 'Turn clast on for this project',
423
+ description:
424
+ 'Clast (code index) is off for this project. Call this only when the user asks to use clast: it creates the .clast folder in the project root, builds the index and adds the clast tools.',
425
+ inputSchema: {},
426
+ annotations: { readOnlyHint: false, idempotentHint: true, openWorldHint: false },
427
+ },
428
+ async () => {
429
+ try {
430
+ activate();
431
+ enableTool.remove();
432
+ return text(
433
+ `clast is on for ${projectRoot}. The index is building; the clast tools are available now ` +
434
+ `(reconnect the server or restart the session if they do not appear). ` +
435
+ `To turn it off again, delete the .clast folder.\n\n${INSTRUCTIONS}`
436
+ );
437
+ } catch (err) {
438
+ return { ...text(`error: ${err instanceof Error ? err.message : String(err)}`), isError: true };
439
+ }
440
+ }
441
+ );
442
+ // The folder can also appear without the tool (a skill, the CLI, the user): pick that up.
443
+ const poll = setInterval(() => {
444
+ if (active) return void clearInterval(poll);
445
+ if (!existsSync(marker)) return;
446
+ clearInterval(poll);
447
+ try {
448
+ activate();
449
+ enableTool.remove();
450
+ log('.clast folder found: active');
451
+ } catch (err) {
452
+ log(`could not activate: ${err instanceof Error ? err.message : err}`);
453
+ }
454
+ }, 2000);
455
+ poll.unref();
456
+ }
457
+
458
+ // Connect first so the client never waits on indexing.
459
+ const transport = new StdioServerTransport();
460
+ await server.connect(transport);
461
+ connected = true;
462
+ log('MCP server running on stdio');
463
+ (begin as (() => void) | null)?.();
394
464
 
395
465
  let closing = false;
396
466
  const shutdown = (): void => {
397
467
  if (closing) return;
398
468
  closing = true;
399
- watcher
469
+ const live = active;
470
+ if (!live) return void process.exit(0);
471
+ live.watcher
400
472
  .stop()
401
473
  .catch(() => undefined)
402
474
  .finally(() => {
403
- try { clast.close(); } catch { /* already closed */ }
475
+ try { live.clast.close(); } catch { /* already closed */ }
404
476
  process.exit(0);
405
477
  });
406
478
  };
package/src/version.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  /** Package version (keep in sync with package.json; checked by a test). */
2
- export const VERSION = '0.2.5';
2
+ export const VERSION = '0.3.0';