codeatlas-mcp-server 2.20.2

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.
Files changed (45) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +338 -0
  3. package/dist/index.js +261 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/src/analyzer/parser.js +1072 -0
  6. package/dist/src/analyzer/parser.js.map +1 -0
  7. package/dist/src/analyzer/parser.test.js +73 -0
  8. package/dist/src/analyzer/parser.test.js.map +1 -0
  9. package/dist/src/analyzer/phpParser.js +147 -0
  10. package/dist/src/analyzer/phpParser.js.map +1 -0
  11. package/dist/src/analyzer/pythonParser.js +185 -0
  12. package/dist/src/analyzer/pythonParser.js.map +1 -0
  13. package/dist/src/analyzer/types.js +2 -0
  14. package/dist/src/analyzer/types.js.map +1 -0
  15. package/dist/src/context.js +3 -0
  16. package/dist/src/context.js.map +1 -0
  17. package/dist/src/memoryGenerator.js +293 -0
  18. package/dist/src/memoryGenerator.js.map +1 -0
  19. package/dist/src/oracleDatabase.js +298 -0
  20. package/dist/src/oracleDatabase.js.map +1 -0
  21. package/dist/src/presentation/httpServer.js +306 -0
  22. package/dist/src/presentation/httpServer.js.map +1 -0
  23. package/dist/src/presentation/mcpServer.js +1487 -0
  24. package/dist/src/presentation/mcpServer.js.map +1 -0
  25. package/dist/src/repositories.js +144 -0
  26. package/dist/src/repositories.js.map +1 -0
  27. package/dist/src/securityScanner.js +69 -0
  28. package/dist/src/securityScanner.js.map +1 -0
  29. package/dist/src/services/authService.js +24 -0
  30. package/dist/src/services/authService.js.map +1 -0
  31. package/dist/src/services/dreamingService.js +119 -0
  32. package/dist/src/services/dreamingService.js.map +1 -0
  33. package/dist/src/services/dreamingService.test.js +179 -0
  34. package/dist/src/services/dreamingService.test.js.map +1 -0
  35. package/dist/src/services/projectService.js +1068 -0
  36. package/dist/src/services/projectService.js.map +1 -0
  37. package/dist/src/services/projectService.test.js +217 -0
  38. package/dist/src/services/projectService.test.js.map +1 -0
  39. package/dist/src/services/watcherService.js +164 -0
  40. package/dist/src/services/watcherService.js.map +1 -0
  41. package/dist/src/services/watcherService.test.js +65 -0
  42. package/dist/src/services/watcherService.test.js.map +1 -0
  43. package/dist/src/types.js +2 -0
  44. package/dist/src/types.js.map +1 -0
  45. package/package.json +61 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 giauphan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,338 @@
1
+ <div align="center">
2
+
3
+ # CodeAtlas MCP Enterprise
4
+
5
+ **Enterprise-Grade, Local-First MCP Server for AI-Powered Code Intelligence**
6
+
7
+ [![MIT License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
8
+ [![Node.js](https://img.shields.io/badge/node-%3E%3D18-brightgreen)](https://nodejs.org)
9
+ [![TypeScript](https://img.shields.io/badge/typescript-%5E5.4-blue)](https://www.typescriptlang.org/)
10
+ [![MCP](https://img.shields.io/badge/MCP-Model%20Context%20Protocol-purple)](https://modelcontextprotocol.io)
11
+ [![npm](https://img.shields.io/npm/v/codeatlas-enterprise)](https://www.npmjs.com/package/codeatlas-enterprise)
12
+ [![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)](https://github.com/giauphan/codeatlas-mcp-server/pulls)
13
+
14
+ **CodeAtlas MCP Enterprise** is an ultra-lightweight, local-first [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that securely indexes your codebase, performs deep AST-based analysis, and provides 20+ intelligent tools for AI code assistants. **Your source code never leaves your machine.**
15
+
16
+ </div>
17
+
18
+ ---
19
+
20
+ ## πŸ“‹ Table of Contents
21
+
22
+ - [Why CodeAtlas MCP?](#-why-codeatlas-mcp)
23
+ - [Features](#-features)
24
+ - [Architecture Overview](#-architecture-overview)
25
+ - [Quick Start](#-quick-start)
26
+ - [Authentication](#-authentication)
27
+ - [AI Editor Integration](#-ai-editor-integration)
28
+ - [Cursor](#cursor)
29
+ - [Claude Desktop](#claude-desktop)
30
+ - [VS Code / Windsurf / Copilot](#vs-code--windsurf--copilot)
31
+ - [MCP Tools Reference](#-mcp-tools-reference)
32
+ - [Analysis & Indexing](#analysis--indexing)
33
+ - [Code Exploration](#code-exploration)
34
+ - [Dependency & Impact Analysis](#dependency--impact-analysis)
35
+ - [Visualization & Diagrams](#visualization--diagrams)
36
+ - [Memory & Persistence](#memory--persistence)
37
+ - [Security & Architecture](#security--architecture)
38
+ - [Project Operations](#project-operations)
39
+ - [Security Model](#-security-model)
40
+ - [Multi-Tenant Mode](#-multi-tenant-mode)
41
+ - [Environment Configuration](#-environment-configuration)
42
+ - [How It Works](#-how-it-works)
43
+ - [License](#-license)
44
+
45
+ ---
46
+
47
+ ## 🎯 Why CodeAtlas MCP?
48
+
49
+ AI code assistants are powerful β€” but they work best with **context**. CodeAtlas gives them X-ray vision into your codebase by:
50
+
51
+ - πŸ” **Deep parsing** β€” Understands JavaScript, TypeScript, Python, and PHP at the AST level
52
+ - 🧠 **Persistent memory** β€” Retains insights across conversations via Dreaming Memory
53
+ - πŸ”’ **Zero data leakage** β€” All parsing happens locally, no source code ever transmitted
54
+ - ⚑ **Blazing fast** β€” Full codebase analysis in seconds, incremental re-indexing
55
+ - πŸ”Œ **Universal compatibility** β€” Works with any MCP-compatible editor (Cursor, Claude, VS Code, Windsurf, Copilot)
56
+
57
+ ---
58
+
59
+ ## ✨ Features
60
+
61
+ | Feature | Description |
62
+ |---------|-------------|
63
+ | πŸ”’ **Local-First Parsing** | AST analysis runs entirely on your machine β€” zero code uploaded |
64
+ | πŸ”Œ **MCP Protocol** | Works with all MCP-compatible AI editors |
65
+ | πŸ“ **Auto Workspace Discovery** | Automatically finds projects in your workspace |
66
+ | πŸ” **Multi-Language AST** | JavaScript, TypeScript, Python, PHP with deep dependency resolution |
67
+ | 🧠 **Dreaming Memory** | Persistent AI memory with vector search for cross-session context |
68
+ | 🏠 **Multi-Tenant Isolation** | Isolate projects by workspace with sandbox boundaries |
69
+ | πŸ” **API Key Auth** | Secure communication via cryptographic hash verification |
70
+ | ⚑ **Incremental Indexing** | Only re-parses changed files for near-instant updates |
71
+ | πŸ—οΈ **Knowledge Graph** | Visualize modules, classes, and functions as an interactive graph |
72
+ | 🌐 **Remote Sync** | Optionally sync metadata to CodeAtlas Enterprise via HTTPS |
73
+ | πŸ“Š **Code Metrics** | LOC, complexity scores, function counts per project |
74
+ | πŸ›‘οΈ **Security Scanner** | Detect hardcoded secrets, unsafe functions, SQL injection |
75
+ | πŸ”„ **Real-time Watching** | Auto re-index on file changes via chokidar |
76
+
77
+ ---
78
+
79
+ ## πŸ— Architecture Overview
80
+
81
+ ```
82
+ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
83
+ β”‚ Your Local Machine β”‚
84
+ β”‚ β”‚
85
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
86
+ β”‚ β”‚ Source │───▢│ AST │───▢│ MCP Server β”‚ β”‚
87
+ β”‚ β”‚ Code β”‚ β”‚ Parser β”‚ β”‚ (this tool) │───┼──▢ AI Editor
88
+ β”‚ β”‚ (JS/TS/ β”‚ β”‚ (local) β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
89
+ β”‚ β”‚ PY/PHP)β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
90
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚ β”‚
91
+ β”‚ β–Ό β”‚
92
+ β”‚ β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
93
+ β”‚ β”‚ Dreaming Memory β”‚ β”‚
94
+ β”‚ β”‚ (optional: sync) β”‚ β”‚
95
+ β”‚ β””β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
96
+ β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
97
+ β”‚ HTTPS (optional)
98
+ β–Ό
99
+ CodeAtlas Enterprise Server
100
+ ```
101
+
102
+ ---
103
+
104
+ ## πŸš€ Quick Start
105
+
106
+ ### Prerequisites
107
+
108
+ - **Node.js** v18.0.0 or higher (v20+ recommended)
109
+
110
+ ### Install Globally
111
+
112
+ ```bash
113
+ npm install -g codeatlas-enterprise
114
+ ```
115
+
116
+ ### Run
117
+
118
+ ```bash
119
+ # Scan current directory and start MCP server
120
+ codeatlas-mcp
121
+
122
+ # With API key for remote sync
123
+ codeatlas-mcp --apiKey="your_api_key_here"
124
+
125
+ # Point to a specific project directory
126
+ codeatlas-mcp --projectDir="/path/to/your/project"
127
+ ```
128
+
129
+ That's it! Your AI editor can now connect to the MCP server running on stdio.
130
+
131
+ ---
132
+
133
+ ## πŸ”‘ Authentication
134
+
135
+ Provide your API Key in one of these ways:
136
+
137
+ 1. **Environment Variable**:
138
+ ```bash
139
+ export CODEATLAS_API_KEY="your_api_key_here"
140
+ ```
141
+
142
+ 2. **CLI Argument**:
143
+ ```bash
144
+ codeatlas-mcp --apiKey="your_api_key_here"
145
+ ```
146
+
147
+ 3. **Local `.env` File** (in the directory where you run the command):
148
+ ```env
149
+ CODEATLAS_API_KEY=your_api_key_here
150
+ ```
151
+
152
+ ---
153
+
154
+ ## πŸ”Œ AI Editor Integration
155
+
156
+ ### Cursor
157
+
158
+ Add to `~/.cursor/mcp.json` or project-level `.cursor/mcp.json`:
159
+
160
+ ```json
161
+ {
162
+ "mcpServers": {
163
+ "codeatlas": {
164
+ "command": "codeatlas-mcp",
165
+ "args": ["--apiKey", "YOUR_API_KEY_HERE"]
166
+ }
167
+ }
168
+ }
169
+ ```
170
+
171
+ ### Claude Desktop
172
+
173
+ Add to `claude_desktop_config.json`:
174
+
175
+ ```json
176
+ {
177
+ "mcpServers": {
178
+ "codeatlas": {
179
+ "command": "codeatlas-mcp",
180
+ "args": ["--apiKey", "YOUR_API_KEY_HERE"]
181
+ }
182
+ }
183
+ }
184
+ ```
185
+
186
+ ### VS Code / Windsurf / Copilot
187
+
188
+ For any MCP-compatible editor, use the same JSON structure:
189
+
190
+ ```json
191
+ {
192
+ "mcpServers": {
193
+ "codeatlas": {
194
+ "command": "codeatlas-mcp",
195
+ "args": ["--apiKey", "YOUR_API_KEY_HERE"]
196
+ }
197
+ }
198
+ }
199
+ ```
200
+
201
+ > **Note:** If you're running without a remote server, omit the `--apiKey` argument. The local MCP tools (analysis, search, graph) work fully offline.
202
+
203
+ ---
204
+
205
+ ## πŸ›  MCP Tools Reference
206
+
207
+ CodeAtlas MCP exposes **20+ tools** organized into categories:
208
+
209
+ ### Analysis & Indexing
210
+ | Tool | Description |
211
+ |------|-------------|
212
+ | `analyze` | Trigger full AST analysis of the current project |
213
+ | `get_project_structure` | Get entities tree (modules, classes, functions, variables) |
214
+ | `get_file_entities` | List all entities defined in a specific file |
215
+
216
+ ### Code Exploration
217
+ | Tool | Description |
218
+ |------|-------------|
219
+ | `search_entities` | Search for functions, classes, modules by name (fuzzy) |
220
+ | `code_search` | Search source file contents for any text or regex |
221
+ | `get_file_content` | Read file contents with line numbers |
222
+
223
+ ### Dependency & Impact Analysis
224
+ | Tool | Description |
225
+ |------|-------------|
226
+ | `get_callers` | Find all functions/callers that reference a symbol |
227
+ | `get_callees` | Find everything a function/module imports or calls |
228
+ | `impact_analysis` | Full blast radius: callers + callees + test files |
229
+ | `get_dependencies` | Get import/call/containment/implements relationships |
230
+
231
+ ### Visualization & Diagrams
232
+ | Tool | Description |
233
+ |------|-------------|
234
+ | `generate_system_flow` | Mermaid flowchart of module architecture |
235
+ | `generate_feature_flow_diagram` | Mermaid sequence/flow diagram for a feature |
236
+ | `trace_feature_flow` | Ordered call chain from entry point to database |
237
+
238
+ ### Memory & Persistence
239
+ | Tool | Description |
240
+ |------|-------------|
241
+ | `query_dream_memories` | Semantic vector search across past AI memories |
242
+ | `save_dream_memory` | Persist an AI insight or observation for future sessions |
243
+ | `get_system_memory` | Retrieve business rules and change logs |
244
+ | `sync_system_memory` | Save business rules or change descriptions |
245
+
246
+ ### Security & Architecture
247
+ | Tool | Description |
248
+ |------|-------------|
249
+ | `scan_enterprise_vulnerabilities` | Scan all projects for hardcoded secrets, unsafe functions, SQL injection |
250
+ | `detect_architectural_smells` | Detect circular dependencies, God objects, dead code |
251
+
252
+ ### Project Operations
253
+ | Tool | Description |
254
+ |------|-------------|
255
+ | `list_projects` | List all discovered and indexed projects |
256
+ | `refresh_projects` | Re-scan directories for new or removed projects |
257
+ | `get_project_insights` | AI-generated refactoring and maintainability suggestions |
258
+
259
+ ---
260
+
261
+ ## πŸ”’ Security Model
262
+
263
+ ### πŸ” Local-First by Design
264
+
265
+ CodeAtlas MCP Enterprise follows a **zero-trust, local-first architecture**:
266
+
267
+ 1. **Parsing is local** β€” All source file reading, AST generation, and relationship mapping happens on your machine. No source code is ever uploaded.
268
+
269
+ 2. **No credentials embedded** β€” The package contains zero database passwords, Firebase configs, or private server keys. All remote communication uses standard HTTPS with Bearer token auth.
270
+
271
+ 3. **Encrypted sync** β€” If you enable remote sync, metadata is transmitted over HTTPS. The server authenticates via cryptographic hash of your API key.
272
+
273
+ ### πŸ”’ What Gets Sent (When Sync is Enabled)
274
+
275
+ Only **structural metadata** is transmitted:
276
+ - File paths and names (relative to project root)
277
+ - Function/class/module names and line numbers
278
+ - Import/export relationships
279
+ - Analysis statistics (file count, LOC, complexity)
280
+
281
+ **Raw source code, credentials, and proprietary logic are never transmitted.**
282
+
283
+ ### 🏠 Multi-Tenant Isolation
284
+
285
+ When multi-tenant mode is enabled:
286
+ - Each tenant's projects are isolated in separate sandbox directories
287
+ - Path traversal attacks are blocked by strict boundary validation
288
+ - Memory and analysis data are scoped per-tenant
289
+
290
+ ---
291
+
292
+ ## 🏠 Multi-Tenant Mode
293
+
294
+ Enable tenant isolation via environment variables:
295
+
296
+ ```env
297
+ CODEATLAS_MULTI_TENANT=true
298
+ CODEATLAS_PROJECTS_ROOT=./tenants
299
+ ```
300
+
301
+ Each tenant's projects live in `./tenants/{tenantId}/`, with strict path-boundary enforcement.
302
+
303
+ ---
304
+
305
+ ## 🌍 Environment Configuration
306
+
307
+ | Variable | Default | Description |
308
+ |----------|---------|-------------|
309
+ | `CODEATLAS_API_KEY` | β€” | API key for authenticating with remote server |
310
+ | `CODEATLAS_API_URL` | `https://your-server.com/api` | Remote CodeAtlas server URL |
311
+ | `CODEATLAS_MULTI_TENANT` | `false` | Enable multi-tenant isolation |
312
+ | `CODEATLAS_PROJECTS_ROOT` | `./tenants` | Root directory for tenant sandboxes |
313
+ | `CODEATLAS_PROJECT_DIR` | `process.cwd()` | Default project path |
314
+ | `NODE_ENV` | `production` | Environment mode |
315
+
316
+ ---
317
+
318
+ ## βš™οΈ How It Works
319
+
320
+ 1. **Start** β€” Run `codeatlas-mcp` in your project directory or point it with `--projectDir`
321
+ 2. **Auto-Discover** β€” The server scans for projects by detecting `package.json`, `pyproject.toml`, `composer.json`
322
+ 3. **AST Parse** β€” Each source file is parsed into an Abstract Syntax Tree
323
+ 4. **Build Graph** β€” Modules, classes, functions, and their relationships form a Knowledge Graph
324
+ 5. **Serve MCP** β€” AI editors query the graph through 20+ MCP tools
325
+ 6. **Dream** β€” Insights persist across sessions via Dreaming Memory (optional remote vector store)
326
+
327
+ ---
328
+
329
+ ## πŸ“„ License
330
+
331
+ [MIT](LICENSE) Β© 2026 Giau Phan
332
+
333
+ ---
334
+
335
+ ## πŸ”— Related Projects
336
+
337
+ - [CodeAtlas AI](https://github.com/giauphan/codeatlas-ai) β€” Full enterprise server with Oracle 26ai memory, dashboard, security scanner
338
+ - [npm package](https://www.npmjs.com/package/codeatlas-enterprise) β€” Install via npm
package/dist/index.js ADDED
@@ -0,0 +1,261 @@
1
+ #!/usr/bin/env node
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import * as dotenv from "dotenv";
4
+ import { fileURLToPath } from "url";
5
+ import { RootsListChangedNotificationSchema } from "@modelcontextprotocol/sdk/types.js";
6
+ import * as fs from "fs";
7
+ import * as path from "path";
8
+ import * as os from "os";
9
+ // Configure centralized log file in ~/.codeatlas/mcp.log
10
+ const homeDir = os.homedir();
11
+ const logDir = path.join(homeDir, ".codeatlas");
12
+ const logFilePath = path.join(logDir, "mcp.log");
13
+ const pidFilePath = path.join(logDir, "mcp.pid");
14
+ try {
15
+ if (!fs.existsSync(logDir)) {
16
+ fs.mkdirSync(logDir, { recursive: true });
17
+ }
18
+ }
19
+ catch (err) {
20
+ // Ignore directory creation errors
21
+ }
22
+ // ── Single-instance PID guard ──────────────────────────────────────────
23
+ // Prevents duplicate MCP server processes from consuming excessive memory.
24
+ // But allow --version and --help flags to pass through.
25
+ // Handle --version before PID guard
26
+ if (process.argv.includes('--version') || process.argv.includes('-v')) {
27
+ // Try both relative locations (source: index.ts, dist: dist/index.js)
28
+ let pkg;
29
+ for (const p of ['./package.json', '../package.json']) {
30
+ try {
31
+ pkg = JSON.parse(fs.readFileSync(new URL(p, import.meta.url), 'utf-8'));
32
+ break;
33
+ }
34
+ catch { }
35
+ }
36
+ if (pkg)
37
+ console.log(pkg.version);
38
+ process.exit(0);
39
+ }
40
+ if (!process.argv.includes('--help') && !process.argv.includes('-h')) {
41
+ try {
42
+ if (fs.existsSync(pidFilePath)) {
43
+ const existingPid = parseInt(fs.readFileSync(pidFilePath, "utf-8").trim(), 10);
44
+ if (!isNaN(existingPid) && existingPid > 0) {
45
+ try {
46
+ process.kill(existingPid, 0); // Check if alive
47
+ // Another instance is already running. Exit immediately to avoid duplicates.
48
+ // DO NOT kill the old instance β€” that would break the active MCP connection
49
+ // and cause Hermes to reconnect in an infinite kill-restart loop.
50
+ console.error(`[PID-Guard] πŸ”’ Instance already running (PID: ${existingPid}). New instance exiting.`);
51
+ process.exit(0);
52
+ }
53
+ catch (e) {
54
+ if (e?.code === 'ESRCH') {
55
+ console.error(`[PID-Guard] πŸ—‘οΈ Stale PID ${existingPid} β€” old instance is gone. Starting fresh.`);
56
+ }
57
+ else {
58
+ console.error(`[PID-Guard] ⚠️ Cannot verify PID ${existingPid}. Will overwrite.`);
59
+ }
60
+ }
61
+ }
62
+ }
63
+ fs.writeFileSync(pidFilePath, String(process.pid));
64
+ console.error(`[PID-Guard] πŸ”’ Lock acquired (PID: ${process.pid})`);
65
+ }
66
+ catch (err) {
67
+ console.error(`[PID-Guard] ⚠️ Could not write PID file β€” running without guard: ${err}`);
68
+ }
69
+ }
70
+ // ────────────────────────────────────────────────────────────────────────
71
+ // ⚠️ NOTE: API key must be set via CODEATLAS_API_KEY environment variable or .env file.
72
+ // Passing API keys via command-line arguments is NOT supported β€” they are visible
73
+ // to all users on the system via `ps aux`. Use environment variables instead.
74
+ // Parse command line arguments for projectDir (safe directory path, not a secret)
75
+ const projectDirArgIndex = process.argv.findIndex(arg => arg.startsWith('--projectDir'));
76
+ if (projectDirArgIndex !== -1) {
77
+ const arg = process.argv[projectDirArgIndex];
78
+ let val = '';
79
+ if (arg.includes('=')) {
80
+ val = arg.split('=')[1];
81
+ }
82
+ else if (projectDirArgIndex + 1 < process.argv.length) {
83
+ val = process.argv[projectDirArgIndex + 1];
84
+ }
85
+ if (val) {
86
+ process.env.CODEATLAS_PROJECT_DIR = val;
87
+ }
88
+ }
89
+ // Async logging queue to prevent blocking the Event Loop on console.error
90
+ const logQueue = [];
91
+ let isWritingLogs = false;
92
+ async function flushLogQueue() {
93
+ if (isWritingLogs || logQueue.length === 0)
94
+ return;
95
+ isWritingLogs = true;
96
+ while (logQueue.length > 0) {
97
+ const message = logQueue.shift();
98
+ if (message) {
99
+ try {
100
+ await fs.promises.appendFile(logFilePath, message);
101
+ }
102
+ catch (err) {
103
+ // Ignore write errors
104
+ }
105
+ }
106
+ }
107
+ isWritingLogs = false;
108
+ }
109
+ const originalConsoleError = console.error;
110
+ console.error = (...args) => {
111
+ originalConsoleError(...args);
112
+ try {
113
+ const message = args.map(arg => typeof arg === 'object' ? JSON.stringify(arg) : String(arg)).join(' ');
114
+ const timestamp = new Date().toISOString();
115
+ // Cap log queue at 1000 entries to prevent unbounded memory growth
116
+ if (logQueue.length >= 1000) {
117
+ logQueue.shift();
118
+ }
119
+ logQueue.push(`[${timestamp}] ${message}\n`);
120
+ flushLogQueue().catch(() => { });
121
+ }
122
+ catch (err) {
123
+ // Ignore queue errors
124
+ }
125
+ };
126
+ // Import Presentation Adapters
127
+ import { server } from "./src/presentation/mcpServer.js";
128
+ // Import Domain / Application Services
129
+ import { checkAuth } from "./src/services/authService.js";
130
+ import { getStats, discoverProjects, loadAnalysis, discoverProjectsAsync, loadAnalysisAsync, getWorkspaceFromAncestors, isSystemIdeDirectory, discoverGitSubProjects } from "./src/services/projectService.js";
131
+ import { startWatcher, stopWatcher, isIndexingEnabledForProject } from "./src/services/watcherService.js";
132
+ // Load environment variables
133
+ dotenv.config();
134
+ // Start server
135
+ async function main() {
136
+ startWatcher();
137
+ // Function to scan workspace roots from the client
138
+ async function scanRoots() {
139
+ let succeeded = false;
140
+ try {
141
+ const result = await server.server.listRoots();
142
+ if (result && result.roots && result.roots.length > 0) {
143
+ succeeded = true;
144
+ console.error(`[Auto-Scan] πŸ“‚ Discovered ${result.roots.length} workspace root(s) from client.`);
145
+ for (const root of result.roots) {
146
+ if (root.uri.startsWith("file://")) {
147
+ const workspacePath = fileURLToPath(root.uri).trim();
148
+ if (isSystemIdeDirectory(workspacePath)) {
149
+ console.error(`[Auto-Scan] πŸ›‘οΈ Ignored IDE system/extensions directory: ${workspacePath}`);
150
+ continue;
151
+ }
152
+ // Scan subdirectories for .git projects
153
+ const subProjects = await discoverGitSubProjects(workspacePath, true);
154
+ if (subProjects.length > 0) {
155
+ console.error(`[Auto-Scan] πŸ“¦ Found ${subProjects.length} project(s) with .git and open in IDE inside ${path.basename(workspacePath)}`);
156
+ for (const subDir of subProjects) {
157
+ const subName = path.basename(subDir);
158
+ isIndexingEnabledForProject(subName).then((enabled) => {
159
+ if (!enabled) {
160
+ console.error(`[Auto-Scan] ⏸️ Auto-indexing disabled for [${subName}]. Skipping.`);
161
+ return;
162
+ }
163
+ console.error(`[Auto-Scan] πŸ”„ Indexing sub-project: ${subDir}`);
164
+ loadAnalysisAsync(subDir, true).then((loaded) => {
165
+ if (loaded)
166
+ console.error(`[Auto-Scan] βœ… Indexed: ${subDir}`);
167
+ else
168
+ console.error(`[Auto-Scan] ⚠️ Skipped: ${subDir}`);
169
+ }).catch((err) => {
170
+ console.error(`[Auto-Scan] ❌ Failed: ${subDir}: ${err}`);
171
+ });
172
+ }).catch(() => { });
173
+ }
174
+ }
175
+ else {
176
+ console.error(`[Auto-Scan] ℹ️ No .git projects found under container root: ${workspacePath}`);
177
+ }
178
+ }
179
+ else {
180
+ console.error(`[Auto-Scan] ⚠️ Ignored non-file URI root: ${root.uri}`);
181
+ }
182
+ }
183
+ }
184
+ else {
185
+ console.error("[Auto-Scan] ℹ️ No workspace roots returned by client. Falling back to active workspace.");
186
+ }
187
+ }
188
+ catch (err) {
189
+ console.error(`[Auto-Scan] ⚠️ Failed to list workspace roots: ${err}. Falling back to active workspace.`);
190
+ }
191
+ if (!succeeded) {
192
+ const activeWorkspace = process.env.CODEATLAS_PROJECT_DIR || getWorkspaceFromAncestors() || process.env.GEMINI_CLI_IDE_WORKSPACE_PATH || process.cwd();
193
+ if (isSystemIdeDirectory(activeWorkspace)) {
194
+ console.error(`[Auto-Scan] πŸ›‘οΈ Ignored IDE system directory fallback: ${activeWorkspace}`);
195
+ return;
196
+ }
197
+ const subProjects = await discoverGitSubProjects(activeWorkspace, true);
198
+ if (subProjects.length > 0) {
199
+ console.error(`[Auto-Scan] πŸ“¦ Fallback: found ${subProjects.length} IDE-open .git project(s) in ${activeWorkspace}`);
200
+ for (const subDir of subProjects) {
201
+ const subName = path.basename(subDir);
202
+ isIndexingEnabledForProject(subName).then((enabled) => {
203
+ if (!enabled)
204
+ return;
205
+ loadAnalysisAsync(subDir, true).catch(() => { });
206
+ }).catch(() => { });
207
+ }
208
+ }
209
+ else {
210
+ console.error(`[Auto-Scan] ℹ️ No .git projects found in workspace fallback: ${activeWorkspace}`);
211
+ }
212
+ }
213
+ }
214
+ // Hook into client initialized event to fetch and index workspace roots
215
+ server.server.oninitialized = () => {
216
+ console.error("[Auto-Scan] πŸ”Œ MCP Client connection initialized. Checking workspace roots...");
217
+ scanRoots();
218
+ };
219
+ // Listen for changes to workspace roots
220
+ server.server.setNotificationHandler(RootsListChangedNotificationSchema, (notification) => {
221
+ console.error("[Auto-Scan] πŸ”” Received roots/list_changed notification from client. Re-scanning workspace roots...");
222
+ scanRoots();
223
+ });
224
+ // Stdio Mode - for local use (e.g. Claude Desktop, Cursor)
225
+ const transport = new StdioServerTransport();
226
+ await server.connect(transport);
227
+ console.error("CodeAtlas MCP server running on stdio");
228
+ }
229
+ main().catch(console.error);
230
+ // ── Graceful shutdown handlers ─────────────────────────────────────────
231
+ // Prevent zombie processes by cleaning up watchers, cache, and PID file.
232
+ function cleanup(signal) {
233
+ console.error(`[Cleanup] 🧹 Received ${signal}. Shutting down...`);
234
+ try {
235
+ stopWatcher();
236
+ }
237
+ catch (e) {
238
+ console.error(`[Cleanup] ⚠️ Watcher cleanup error: ${e}`);
239
+ }
240
+ try {
241
+ if (fs.existsSync(pidFilePath)) {
242
+ fs.unlinkSync(pidFilePath);
243
+ console.error(`[Cleanup] πŸ—‘οΈ PID file removed.`);
244
+ }
245
+ }
246
+ catch (e) {
247
+ console.error(`[Cleanup] ⚠️ PID file cleanup error: ${e}`);
248
+ }
249
+ process.exit(0);
250
+ }
251
+ process.on("SIGTERM", () => cleanup("SIGTERM"));
252
+ process.on("SIGINT", () => cleanup("SIGINT"));
253
+ process.on("SIGQUIT", () => cleanup("SIGQUIT"));
254
+ process.on("uncaughtException", (err) => {
255
+ console.error(`[Fatal] πŸ’₯ Uncaught exception: ${err}`);
256
+ cleanup("uncaughtException");
257
+ });
258
+ // ────────────────────────────────────────────────────────────────────────
259
+ // Re-export core modules/helpers to maintain compatibility with test suite
260
+ export { server, checkAuth, getStats, discoverProjects, loadAnalysis, discoverProjectsAsync, loadAnalysisAsync };
261
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"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"}