ucn 3.4.4 → 3.4.5

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 CHANGED
@@ -134,6 +134,27 @@ EXTERNAL:
134
134
  fs, path, crypto
135
135
  ```
136
136
 
137
+ ## Workflows
138
+
139
+ **Investigating a bug:**
140
+ ```bash
141
+ ucn about problematic_function # Understand it fully
142
+ ucn trace problematic_function --depth=2 # See what it calls
143
+ ```
144
+
145
+ **Before modifying a function:**
146
+ ```bash
147
+ ucn impact the_function # Who will break?
148
+ ucn smart the_function # See it + its helpers
149
+ # ... make your changes ...
150
+ ucn verify the_function # Did all call sites survive?
151
+ ```
152
+
153
+ **Periodic cleanup:**
154
+ ```bash
155
+ ucn deadcode --exclude=test # What can be deleted?
156
+ ucn toc # Project overview
157
+ ```
137
158
  ## Supported Languages
138
159
 
139
160
  JavaScript, TypeScript, Python, Go, Rust, Java
@@ -144,9 +165,88 @@ JavaScript, TypeScript, Python, Go, Rust, Java
144
165
  npm install -g ucn
145
166
  ```
146
167
 
147
- ### Claude Code (optional)
168
+ ### MCP Server
169
+
170
+ UCN includes a built-in [MCP](https://modelcontextprotocol.io) server, so any MCP-compatible AI client can use it as a tool.
171
+
172
+ **Claude Code** (`~/.claude/mcp-config.json`):
173
+ ```json
174
+ {
175
+ "mcpServers": {
176
+ "ucn": {
177
+ "command": "npx",
178
+ "args": ["-y", "ucn", "--mcp"]
179
+ }
180
+ }
181
+ }
182
+ ```
183
+
184
+ **Claude Desktop** (macOS: `~/Library/Application Support/Claude/claude_desktop_config.json`):
185
+ ```json
186
+ {
187
+ "mcpServers": {
188
+ "ucn": {
189
+ "command": "npx",
190
+ "args": ["-y", "ucn", "--mcp"]
191
+ }
192
+ }
193
+ }
194
+ ```
195
+
196
+ **Cursor** (`~/.cursor/mcp.json` or `.cursor/mcp.json` in project):
197
+ ```json
198
+ {
199
+ "mcpServers": {
200
+ "ucn": {
201
+ "command": "npx",
202
+ "args": ["-y", "ucn", "--mcp"]
203
+ }
204
+ }
205
+ }
206
+ ```
207
+
208
+ **Windsurf** (`~/.codeium/windsurf/mcp_config.json`):
209
+ ```json
210
+ {
211
+ "mcpServers": {
212
+ "ucn": {
213
+ "command": "npx",
214
+ "args": ["-y", "ucn", "--mcp"]
215
+ }
216
+ }
217
+ }
218
+ ```
219
+
220
+ **VS Code Copilot** (`.vscode/mcp.json`):
221
+ ```json
222
+ {
223
+ "servers": {
224
+ "ucn": {
225
+ "type": "stdio",
226
+ "command": "npx",
227
+ "args": ["-y", "ucn", "--mcp"]
228
+ }
229
+ }
230
+ }
231
+ ```
232
+
233
+ **Zed** (Settings > `settings.json`):
234
+ ```json
235
+ {
236
+ "context_servers": {
237
+ "ucn": {
238
+ "command": "npx",
239
+ "args": ["-y", "ucn", "--mcp"]
240
+ }
241
+ }
242
+ }
243
+ ```
244
+
245
+ The MCP server exposes 27 tools: `ucn_about`, `ucn_context`, `ucn_impact`, `ucn_smart`, `ucn_trace`, `ucn_find`, `ucn_usages`, `ucn_toc`, `ucn_deadcode`, `ucn_fn`, `ucn_class`, `ucn_verify`, `ucn_imports`, `ucn_exporters`, `ucn_tests`, `ucn_related`, `ucn_graph`, `ucn_file_exports`, `ucn_search`, `ucn_plan`, `ucn_typedef`, `ucn_stacktrace`, `ucn_example`, `ucn_expand`, `ucn_lines`, `ucn_api`, `ucn_stats`.
148
246
 
149
- To use UCN as a skill in Claude Code:
247
+ ### Claude Code Skill (alternative)
248
+
249
+ To use UCN as a skill in Claude Code (alternative to MCP):
150
250
 
151
251
  ```bash
152
252
  mkdir -p ~/.claude/skills
@@ -257,6 +357,7 @@ Common Flags:
257
357
  --clear-cache Clear cache before running
258
358
  --no-follow-symlinks Don't follow symbolic links
259
359
  -i, --interactive Keep index in memory for multiple queries
360
+ --mcp Start as MCP server (stdio transport)
260
361
 
261
362
  Quick Start:
262
363
  ucn toc # See project structure (compact)
@@ -267,28 +368,6 @@ Quick Start:
267
368
  ucn --interactive # Multiple queries
268
369
  ```
269
370
 
270
- ## Workflows
271
-
272
- **Investigating a bug:**
273
- ```bash
274
- ucn about problematic_function # Understand it fully
275
- ucn trace problematic_function --depth=2 # See what it calls
276
- ```
277
-
278
- **Before modifying a function:**
279
- ```bash
280
- ucn impact the_function # Who will break?
281
- ucn smart the_function # See it + its helpers
282
- # ... make your changes ...
283
- ucn verify the_function # Did all call sites survive?
284
- ```
285
-
286
- **Periodic cleanup:**
287
- ```bash
288
- ucn deadcode --exclude=test # What can be deleted?
289
- ucn toc # Project overview
290
- ```
291
-
292
371
  ## License
293
372
 
294
373
  MIT
package/cli/index.js CHANGED
@@ -22,6 +22,10 @@ const output = require('../core/output');
22
22
 
23
23
  const rawArgs = process.argv.slice(2);
24
24
 
25
+ // MCP server mode — launch server and skip CLI
26
+ if (rawArgs.includes('--mcp')) {
27
+ require('../mcp/server.js');
28
+ } else {
25
29
  // Support -- to separate flags from positional arguments
26
30
  const doubleDashIdx = rawArgs.indexOf('--');
27
31
  const args = doubleDashIdx === -1 ? rawArgs : rawArgs.slice(0, doubleDashIdx);
@@ -78,7 +82,7 @@ if (fileArgIdx !== -1 && args[fileArgIdx + 1]) {
78
82
 
79
83
  // Known flags for validation
80
84
  const knownFlags = new Set([
81
- '--help', '-h',
85
+ '--help', '-h', '--mcp',
82
86
  '--json', '--verbose', '--no-quiet', '--quiet',
83
87
  '--code-only', '--with-types', '--top-level', '--exact',
84
88
  '--no-cache', '--clear-cache', '--include-tests',
@@ -2542,3 +2546,5 @@ if (flags.interactive) {
2542
2546
  } else {
2543
2547
  main();
2544
2548
  }
2549
+
2550
+ } // end of --mcp else block
package/core/discovery.js CHANGED
@@ -298,7 +298,8 @@ function shouldIgnore(name, ignores, parentDir) {
298
298
  }
299
299
 
300
300
  // Check conditional ignores (only if parentDir provided)
301
- if (parentDir && CONDITIONAL_IGNORES[name]) {
301
+ // Use Array.isArray to avoid matching Object.prototype properties (e.g. dir named "constructor")
302
+ if (parentDir && Array.isArray(CONDITIONAL_IGNORES[name])) {
302
303
  const markers = CONDITIONAL_IGNORES[name];
303
304
  for (const marker of markers) {
304
305
  if (fs.existsSync(path.join(parentDir, marker))) {