directory-indexer 0.0.19 → 0.1.1

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
@@ -38,7 +38,7 @@ docker exec ollama ollama pull nomic-embed-text
38
38
  **3. Index your directories**
39
39
 
40
40
  ```bash
41
- npx directory-indexer index ~/Documents ~/Projects
41
+ npx directory-indexer@latest index ~/Documents ~/Projects
42
42
  ```
43
43
 
44
44
  **4. Configure AI assistant** _(Claude Desktop, Cursor, Cline, Roo Code, Zed etc.)_
@@ -50,7 +50,7 @@ Add to your MCP configuration:
50
50
  "mcpServers": {
51
51
  "directory-indexer": {
52
52
  "command": "npx",
53
- "args": ["directory-indexer", "serve"]
53
+ "args": ["directory-indexer@latest", "serve"]
54
54
  }
55
55
  }
56
56
  }
@@ -134,7 +134,7 @@ Configure with AI assistants (Claude Desktop, Cline, etc.) using npx:
134
134
  "mcpServers": {
135
135
  "directory-indexer": {
136
136
  "command": "npx",
137
- "args": ["directory-indexer", "serve"]
137
+ "args": ["directory-indexer@latest", "serve"]
138
138
  }
139
139
  }
140
140
  }
@@ -144,7 +144,7 @@ Index your directories:
144
144
 
145
145
  ```bash
146
146
  # Index your directories first
147
- npx directory-indexer index /home/user/projects/docs /home/user/work/reports
147
+ npx directory-indexer@latest index /home/user/projects/docs /home/user/work/reports
148
148
  ```
149
149
 
150
150
  **How it works:**
@@ -186,7 +186,7 @@ Configure with custom endpoints and data directory:
186
186
  "mcpServers": {
187
187
  "directory-indexer": {
188
188
  "command": "npx",
189
- "args": ["directory-indexer", "serve"],
189
+ "args": ["directory-indexer@latest", "serve"],
190
190
  "env": {
191
191
  "DIRECTORY_INDEXER_DATA_DIR": "/opt/ai-knowledge-base",
192
192
  "QDRANT_ENDPOINT": "http://localhost:6333",
package/dist/cli.js CHANGED
@@ -17,31 +17,31 @@ const VERSION$1 = packageJson$1.version;
17
17
  const MCP_TOOLS = [
18
18
  {
19
19
  name: "index",
20
- description: `Index directories for AI-powered semantic search. This tool processes files in specified directories, extracts text content, generates vector embeddings, and stores them for semantic search capabilities.
20
+ description: `Index directories to make their files searchable. Processes files to create vector embeddings for semantic search.
21
21
 
22
22
  When to use this tool:
23
- - Before performing any search operations on new directories
24
- - When you want to add new code repositories, documentation, or text files to the searchable knowledge base
25
- - To update the index when files have been modified (the tool automatically detects and reprocesses changed files)
26
- - When setting up semantic search for a project or workspace
23
+ - User specifically requests indexing a directory as a knowledge base
24
+ - Adding new documentation, code repositories, or file collections to search
25
+ - Updating index when many files have changed
27
26
 
28
- What this tool does:
29
- - Recursively scans directories for supported file types (code, markdown, text, config files)
30
- - Chunks large files into smaller segments for better search precision
31
- - Generates vector embeddings using the configured embedding model
32
- - Stores file metadata and embeddings in a local database
33
- - Skips unchanged files on re-indexing for efficiency
34
- - Supports overlapping directory paths (files are deduplicated automatically)
27
+ How it works:
28
+ - Recursively scans directories for supported file types
29
+ - Extracts text content and splits into chunks
30
+ - Generates vector embeddings for semantic similarity
31
+ - Stores in database for fast retrieval
35
32
 
36
- Supported file types: .md, .txt, .py, .js, .ts, .go, .rs, .java, .json, .yaml, .toml, .env, .conf, and many others
33
+ Examples:
34
+ - Index documentation: "/home/user/docs/project-wiki"
35
+ - Index codebase: "/home/user/projects/api-server"
36
+ - Index multiple directories: "/home/user/docs,/home/user/configs"
37
37
 
38
- Performance note: Initial indexing may take time for large directories, but subsequent re-indexing is much faster as only changed files are reprocessed.`,
38
+ Indexing can take several minutes for large directories. Most users will already have directories indexed and can directly use search tool. Use server_info to check current indexing status first.`,
39
39
  inputSchema: {
40
40
  type: "object",
41
41
  properties: {
42
42
  directory_path: {
43
43
  type: "string",
44
- description: 'Comma-separated list of absolute or relative directory paths to index. Examples: "/home/user/projects" or "./src,./docs,./tests"'
44
+ description: 'Comma-separated list of absolute directory paths to index. Must be absolute paths since MCP server runs independently. Examples: "/home/user/projects" (Unix) or "C:\\Users\\user\\projects" (Windows)'
45
45
  }
46
46
  },
47
47
  required: ["directory_path"]
@@ -49,19 +49,28 @@ Performance note: Initial indexing may take time for large directories, but subs
49
49
  },
50
50
  {
51
51
  name: "search",
52
- description: `Perform semantic search across indexed files using natural language queries. This tool uses vector similarity to find the most relevant content, going beyond simple keyword matching to understand intent and context.
52
+ description: `Search indexed files using natural language queries. Finds files containing content semantically similar to the query.
53
53
 
54
54
  When to use this tool:
55
- - Finding code examples, functions, or patterns ("error handling in Python", "JWT authentication implementation")
56
- - Locating documentation or explanations ("how to configure Redis", "API rate limiting guide")
57
- - Discovering similar functionality across files ("database connection patterns", "logging utilities")
58
- - Research and exploration of codebases ("machine learning models", "test utilities")
59
- - Finding files related to specific features or topics
55
+ - Find documentation, guides, or explanations about specific topics
56
+ - Locate code files implementing certain functionality or patterns
57
+ - Discover configuration files, scripts, or settings related to a topic
58
+ - Search for files covering specific concepts or technologies
60
59
 
61
- How semantic search works:
62
- - Searches by meaning and context, not just exact keywords
63
- - Finds conceptually related content even with different terminology
64
- - Returns files ranked by relevance with similarity scores
60
+ How it works:
61
+ - Converts query to vector embedding using semantic similarity
62
+ - Searches all indexed file chunks for relevant content
63
+ - Groups results by file and calculates average relevance scores
64
+ - Returns files ranked by relevance score
65
+
66
+ Examples:
67
+ - "database configuration" - finds config files, documentation about DB setup
68
+ - "error handling patterns" - finds code files with exception handling
69
+ - "authentication implementation" - finds auth-related code and docs
70
+ - "API documentation" - finds API guides, endpoint definitions
71
+ - "deployment scripts" - finds CI/CD configs, deployment automation
72
+
73
+ Returns files with similarity scores and chunk information. Use get_content to retrieve full file content or get_chunk to retrieve specific chunk content by chunk ID.
65
74
  - Groups results by file to avoid duplicates from multiple matching sections
66
75
 
67
76
  Response format:
@@ -92,30 +101,26 @@ Example queries:
92
101
  },
93
102
  {
94
103
  name: "similar_files",
95
- description: `Find files that are semantically similar to a given reference file. This tool analyzes the content and context of a file to discover other files with related functionality, similar patterns, or comparable content.
104
+ description: `Find files with content similar to a reference file. Uses semantic similarity to find related documents, code files, or any text content.
96
105
 
97
106
  When to use this tool:
98
- - Discovering related implementations across a codebase ("find files similar to this authentication module")
99
- - Locating alternative approaches or patterns ("find other components like this React component")
100
- - Finding documentation or examples related to a specific file
101
- - Identifying code duplication or similar functionality that could be refactored
102
- - Exploring unfamiliar codebases by finding files similar to known examples
103
- - Locating test files, configuration files, or documentation related to a source file
107
+ - Find documentation similar to a specific guide or README
108
+ - Locate related code files, configuration files, or scripts
109
+ - Discover alternative implementations or approaches
110
+ - Find files covering similar topics or concepts
104
111
 
105
- How similarity detection works:
112
+ How it works:
106
113
  - Analyzes the semantic content of the reference file
107
114
  - Compares against all indexed files using vector similarity
108
- - Considers code patterns, function signatures, imports, and documentation
109
- - Returns files ranked by content similarity, not just filename or location similarity
110
- - Works across different file types and programming languages
115
+ - Returns files ranked by content similarity score
111
116
 
112
- Use cases:
113
- - Code analysis: "Find files similar to this database model to understand the schema patterns"
114
- - Learning: "Show me other API controllers similar to this one"
115
- - Maintenance: "Find files with similar error handling patterns"
116
- - Architecture: "Locate other services that follow this microservice pattern"
117
+ Examples:
118
+ - Given "deployment-guide.md" - finds other deployment docs, CI/CD guides, infrastructure setup
119
+ - Given "troubleshooting.md" - finds other troubleshooting guides, FAQ files, error documentation
120
+ - Given "config.yaml" - finds other configuration files, settings, environment setups
121
+ - Given "auth.py" - finds other authentication modules, security code, middleware
117
122
 
118
- Note: The reference file must be indexed for this tool to work. If the file is not found in the index, an error will be returned.`,
123
+ Returns file paths with similarity scores. Use get_content to read full files or get_chunk for specific sections.`,
119
124
  inputSchema: {
120
125
  type: "object",
121
126
  properties: {
@@ -134,34 +139,26 @@ Note: The reference file must be indexed for this tool to work. If the file is n
134
139
  },
135
140
  {
136
141
  name: "get_content",
137
- description: `Retrieve the full content of a file or specific chunks within a file. This tool reads files directly from the filesystem and can optionally return only specific portions of indexed files.
142
+ description: `Retrieve the full content of a file or specific chunks. Reads files directly from the filesystem.
138
143
 
139
144
  When to use this tool:
140
- - After performing a search, to retrieve the actual content of relevant files
141
- - Reading complete files that were identified through semantic search
142
- - Extracting specific sections of large files using chunk ranges
143
- - Accessing source code, documentation, or configuration files for analysis
144
- - Following up on search results with detailed content examination
145
+ - Get complete file content after finding files through search
146
+ - Read documentation, code files, or configuration files for analysis
147
+ - Extract specific sections of large files using chunk ranges
148
+ - Access any text-based file content
145
149
 
146
- How chunk selection works:
147
- - If no chunks parameter is provided, returns the entire file content
148
- - Chunk ranges allow selective reading of large files (e.g., "2-5" returns chunks 2, 3, 4, and 5)
149
- - Single chunks can be specified (e.g., "3" returns only chunk 3)
150
- - Chunks are the same segments created during indexing for semantic search
151
- - Useful for large files where you only need specific sections identified by search
150
+ How it works:
151
+ - Reads files directly from filesystem (not from search index)
152
+ - Returns entire file by default
153
+ - Can return specific chunk ranges for indexed files
154
+ - Preserves original formatting and content
152
155
 
153
- File access:
154
- - Reads files directly from the filesystem (not from the search index)
155
- - Works with any readable file, whether indexed or not
156
- - Supports all text-based file formats
157
- - Preserves original formatting and content exactly as stored
156
+ Examples:
157
+ - Get full file: file_path="/home/user/docs/api.md"
158
+ - Get specific chunks: file_path="/home/user/code/main.py", chunks="2-5"
159
+ - Get single chunk: file_path="/home/user/config.json", chunks="1"
158
160
 
159
- Workflow integration:
160
- 1. Use 'search' to find relevant files and identify interesting chunk IDs
161
- 2. Use 'get_content' to retrieve full file content or specific chunks
162
- 3. Analyze the content to understand context and implementation details
163
-
164
- Performance note: For large files, using chunk ranges can be more efficient than reading entire files.`,
161
+ Returns file content as text. Use this after search or similar_files to read actual content.`,
165
162
  inputSchema: {
166
163
  type: "object",
167
164
  properties: {
@@ -179,34 +176,26 @@ Performance note: For large files, using chunk ranges can be more efficient than
179
176
  },
180
177
  {
181
178
  name: "get_chunk",
182
- description: `Retrieve the content of a specific chunk from an indexed file. This tool provides precise access to individual text segments that were identified during semantic search, allowing efficient retrieval of only the most relevant content.
179
+ description: `Retrieve content of a specific chunk from an indexed file. Gets exact text segments identified during search.
183
180
 
184
181
  When to use this tool:
185
- - After performing a 'search' operation, to fetch the actual content of specific chunks that matched your query
186
- - When you want to examine only the most relevant sections of a file rather than reading the entire file
187
- - For targeted content analysis where you need specific text segments identified by their chunk IDs
188
- - To build contextual responses using only the most semantically relevant portions of files
189
- - When working with large files and you only need particular sections
190
-
191
- How chunks work:
192
- - Files are divided into overlapping text segments during indexing for better search granularity
193
- - Each chunk represents a coherent section of text (typically 512 characters with overlap)
194
- - Chunk IDs are sequential strings ("0", "1", "2", etc.) within each file
195
- - Search results include chunk IDs for the most relevant sections
196
- - This tool retrieves the exact content that was semantically matched
182
+ - Get specific relevant sections after performing a search
183
+ - Access only the most pertinent parts of large files
184
+ - Retrieve content from high-scoring chunks identified in search results
185
+ - Avoid reading entire files when only specific sections are needed
197
186
 
198
- Typical workflow:
199
- 1. Use 'search' to find files and get chunk IDs with high relevance scores
200
- 2. Use 'get_chunk' to retrieve the specific content of the most relevant chunks
201
- 3. Analyze or process only the most pertinent text segments
187
+ How it works:
188
+ - Files are split into overlapping text chunks during indexing
189
+ - Each chunk has a sequential ID ("0", "1", "2", etc.)
190
+ - Search results include chunk IDs for relevant sections
191
+ - Returns the exact content that was semantically matched
202
192
 
203
- Efficiency benefits:
204
- - Avoids transferring unnecessary content from large files
205
- - Provides precise access to semantically relevant text
206
- - Reduces token usage by fetching only needed sections
207
- - Enables focused analysis on the most important content
193
+ Examples:
194
+ - After search returns chunk "3" from "api-docs.md" with high score
195
+ - Get chunk content: file_path="/docs/api-docs.md", chunk_id="3"
196
+ - Returns the specific text segment that matched your query
208
197
 
209
- Note: Both the file and the specific chunk must exist in the search index for this tool to work.`,
198
+ Returns chunk content as text. Use this with chunk IDs from search results to get precise content sections.`,
210
199
  inputSchema: {
211
200
  type: "object",
212
201
  properties: {
@@ -224,39 +213,26 @@ Note: Both the file and the specific chunk must exist in the search index for th
224
213
  },
225
214
  {
226
215
  name: "server_info",
227
- description: `Get comprehensive information about the directory indexer server status, configuration, and indexed content. This tool provides a complete overview of the current state of the semantic search system.
216
+ description: `Get information about server status and indexed content. Shows what directories and files are available for search.
228
217
 
229
218
  When to use this tool:
230
- - To check if the indexer is properly set up and operational
231
- - Before starting work to understand what content is already indexed
232
- - To verify indexing operations completed successfully
233
- - When debugging search issues or unexpected results
234
- - To get an overview of available content for semantic search
235
- - To check system health and identify any configuration problems
219
+ - Check what content is already indexed before performing searches
220
+ - Verify system is working properly
221
+ - See indexing statistics and status
222
+ - Understand scope of available searchable content
236
223
 
237
- Information provided:
238
- - Server version and operational status
239
- - Total count of indexed directories, files, and searchable chunks
240
- - Database size and storage information
241
- - Most recent indexing timestamp
242
- - List of all indexed directories with individual statistics
243
- - File counts and chunk counts per directory
244
- - Indexing status for each directory (completed, failed, in progress)
245
- - Error reports and processing issues
246
- - System consistency checks between database components
224
+ How it works:
225
+ - Reports total indexed directories, files, and chunks
226
+ - Shows database size and last indexing time
227
+ - Lists all indexed directories with file counts
228
+ - Reports any errors or issues
247
229
 
248
- Status indicators:
249
- - Operational status of vector database (Qdrant) connection
250
- - Embedding service availability
251
- - Data consistency between SQLite metadata and vector storage
252
- - Recent errors or warnings that may affect search quality
230
+ Examples:
231
+ - Check before searching: "What content is indexed?"
232
+ - Verify after indexing: "Did the indexing complete successfully?"
233
+ - Monitor system: "How many files are searchable?"
253
234
 
254
- Use this tool to:
255
- - Verify setup before performing search operations
256
- - Understand the scope of available content
257
- - Troubleshoot search or indexing issues
258
- - Plan additional indexing operations
259
- - Monitor system health and performance`,
235
+ Returns server version, indexing statistics, directory list, and any errors. Use this to understand what content is available for search and similar_files tools.`,
260
236
  inputSchema: {
261
237
  type: "object",
262
238
  properties: {},
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"cli.js","sources":["../src/mcp.ts","../src/cli.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { \n CallToolRequestSchema, \n ListToolsRequestSchema,\n Tool\n} from '@modelcontextprotocol/sdk/types.js';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { Config } from './config.js';\nimport { indexDirectories } from './indexing.js';\nimport { searchContent, findSimilarFiles, getFileContent, getChunkContent } from './search.js';\nimport { getIndexStatus } from './storage.js';\n\n// Read version from package.json\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst packageJsonPath = join(__dirname, '../package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\nconst VERSION = packageJson.version;\n\nconst MCP_TOOLS: Tool[] = [\n {\n name: 'index',\n description: `Index directories for AI-powered semantic search. This tool processes files in specified directories, extracts text content, generates vector embeddings, and stores them for semantic search capabilities.\n\nWhen to use this tool:\n- Before performing any search operations on new directories\n- When you want to add new code repositories, documentation, or text files to the searchable knowledge base\n- To update the index when files have been modified (the tool automatically detects and reprocesses changed files)\n- When setting up semantic search for a project or workspace\n\nWhat this tool does:\n- Recursively scans directories for supported file types (code, markdown, text, config files)\n- Chunks large files into smaller segments for better search precision\n- Generates vector embeddings using the configured embedding model\n- Stores file metadata and embeddings in a local database\n- Skips unchanged files on re-indexing for efficiency\n- Supports overlapping directory paths (files are deduplicated automatically)\n\nSupported file types: .md, .txt, .py, .js, .ts, .go, .rs, .java, .json, .yaml, .toml, .env, .conf, and many others\n\nPerformance note: Initial indexing may take time for large directories, but subsequent re-indexing is much faster as only changed files are reprocessed.`,\n inputSchema: {\n type: 'object',\n properties: {\n directory_path: {\n type: 'string',\n description: 'Comma-separated list of absolute or relative directory paths to index. Examples: \"/home/user/projects\" or \"./src,./docs,./tests\"'\n }\n },\n required: ['directory_path']\n }\n },\n {\n name: 'search',\n description: `Perform semantic search across indexed files using natural language queries. This tool uses vector similarity to find the most relevant content, going beyond simple keyword matching to understand intent and context.\n\nWhen to use this tool:\n- Finding code examples, functions, or patterns (\"error handling in Python\", \"JWT authentication implementation\")\n- Locating documentation or explanations (\"how to configure Redis\", \"API rate limiting guide\")\n- Discovering similar functionality across files (\"database connection patterns\", \"logging utilities\")\n- Research and exploration of codebases (\"machine learning models\", \"test utilities\")\n- Finding files related to specific features or topics\n\nHow semantic search works:\n- Searches by meaning and context, not just exact keywords\n- Finds conceptually related content even with different terminology\n- Returns files ranked by relevance with similarity scores\n- Groups results by file to avoid duplicates from multiple matching sections\n\nResponse format:\n- Returns lightweight metadata including file paths, relevance scores, and chunk IDs\n- Use 'get_chunk' or 'get_content' tools to fetch actual content from search results\n- Chunks are sorted by relevance score within each file\n- Average similarity score calculated across all matching chunks per file\n\nExample queries:\n- \"error handling patterns\" (finds try/catch, error classes, logging)\n- \"database migration scripts\" (finds SQL, schema changes, migration files)\n- \"authentication middleware\" (finds auth logic, JWT handling, middleware functions)`,\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language search query describing what you are looking for. Can be concepts, functionality, or specific technical terms.'\n },\n limit: {\n type: 'number',\n description: 'Maximum number of files to return (default: 10). Each file may contain multiple matching chunks.',\n default: 10\n }\n },\n required: ['query']\n }\n },\n {\n name: 'similar_files',\n description: `Find files that are semantically similar to a given reference file. This tool analyzes the content and context of a file to discover other files with related functionality, similar patterns, or comparable content.\n\nWhen to use this tool:\n- Discovering related implementations across a codebase (\"find files similar to this authentication module\")\n- Locating alternative approaches or patterns (\"find other components like this React component\")\n- Finding documentation or examples related to a specific file\n- Identifying code duplication or similar functionality that could be refactored\n- Exploring unfamiliar codebases by finding files similar to known examples\n- Locating test files, configuration files, or documentation related to a source file\n\nHow similarity detection works:\n- Analyzes the semantic content of the reference file\n- Compares against all indexed files using vector similarity\n- Considers code patterns, function signatures, imports, and documentation\n- Returns files ranked by content similarity, not just filename or location similarity\n- Works across different file types and programming languages\n\nUse cases:\n- Code analysis: \"Find files similar to this database model to understand the schema patterns\"\n- Learning: \"Show me other API controllers similar to this one\"\n- Maintenance: \"Find files with similar error handling patterns\"\n- Architecture: \"Locate other services that follow this microservice pattern\"\n\nNote: The reference file must be indexed for this tool to work. If the file is not found in the index, an error will be returned.`,\n inputSchema: {\n type: 'object',\n properties: {\n file_path: {\n type: 'string',\n description: 'Absolute or relative path to the reference file. This file must have been previously indexed.'\n },\n limit: {\n type: 'number',\n description: 'Maximum number of similar files to return (default: 10). Results are sorted by similarity score.',\n default: 10\n }\n },\n required: ['file_path']\n }\n },\n {\n name: 'get_content',\n description: `Retrieve the full content of a file or specific chunks within a file. This tool reads files directly from the filesystem and can optionally return only specific portions of indexed files.\n\nWhen to use this tool:\n- After performing a search, to retrieve the actual content of relevant files\n- Reading complete files that were identified through semantic search\n- Extracting specific sections of large files using chunk ranges\n- Accessing source code, documentation, or configuration files for analysis\n- Following up on search results with detailed content examination\n\nHow chunk selection works:\n- If no chunks parameter is provided, returns the entire file content\n- Chunk ranges allow selective reading of large files (e.g., \"2-5\" returns chunks 2, 3, 4, and 5)\n- Single chunks can be specified (e.g., \"3\" returns only chunk 3)\n- Chunks are the same segments created during indexing for semantic search\n- Useful for large files where you only need specific sections identified by search\n\nFile access:\n- Reads files directly from the filesystem (not from the search index)\n- Works with any readable file, whether indexed or not\n- Supports all text-based file formats\n- Preserves original formatting and content exactly as stored\n\nWorkflow integration:\n1. Use 'search' to find relevant files and identify interesting chunk IDs\n2. Use 'get_content' to retrieve full file content or specific chunks\n3. Analyze the content to understand context and implementation details\n\nPerformance note: For large files, using chunk ranges can be more efficient than reading entire files.`,\n inputSchema: {\n type: 'object',\n properties: {\n file_path: {\n type: 'string',\n description: 'Absolute or relative path to the file to retrieve. File must be readable and text-based.'\n },\n chunks: {\n type: 'string',\n description: 'Optional chunk range specification. Examples: \"3\" (single chunk), \"2-5\" (chunks 2 through 5), \"1-3\" (first three chunks). Only works for indexed files.'\n }\n },\n required: ['file_path']\n }\n },\n {\n name: 'get_chunk',\n description: `Retrieve the content of a specific chunk from an indexed file. This tool provides precise access to individual text segments that were identified during semantic search, allowing efficient retrieval of only the most relevant content.\n\nWhen to use this tool:\n- After performing a 'search' operation, to fetch the actual content of specific chunks that matched your query\n- When you want to examine only the most relevant sections of a file rather than reading the entire file\n- For targeted content analysis where you need specific text segments identified by their chunk IDs\n- To build contextual responses using only the most semantically relevant portions of files\n- When working with large files and you only need particular sections\n\nHow chunks work:\n- Files are divided into overlapping text segments during indexing for better search granularity\n- Each chunk represents a coherent section of text (typically 512 characters with overlap)\n- Chunk IDs are sequential strings (\"0\", \"1\", \"2\", etc.) within each file\n- Search results include chunk IDs for the most relevant sections\n- This tool retrieves the exact content that was semantically matched\n\nTypical workflow:\n1. Use 'search' to find files and get chunk IDs with high relevance scores\n2. Use 'get_chunk' to retrieve the specific content of the most relevant chunks\n3. Analyze or process only the most pertinent text segments\n\nEfficiency benefits:\n- Avoids transferring unnecessary content from large files\n- Provides precise access to semantically relevant text\n- Reduces token usage by fetching only needed sections\n- Enables focused analysis on the most important content\n\nNote: Both the file and the specific chunk must exist in the search index for this tool to work.`,\n inputSchema: {\n type: 'object',\n properties: {\n file_path: {\n type: 'string',\n description: 'Absolute or relative path to the indexed file containing the desired chunk.'\n },\n chunk_id: {\n type: 'string',\n description: 'ID of the specific chunk to retrieve. This is typically obtained from search results and is a sequential string like \"0\", \"1\", \"2\", etc.'\n }\n },\n required: ['file_path', 'chunk_id']\n }\n },\n {\n name: 'server_info',\n description: `Get comprehensive information about the directory indexer server status, configuration, and indexed content. This tool provides a complete overview of the current state of the semantic search system.\n\nWhen to use this tool:\n- To check if the indexer is properly set up and operational\n- Before starting work to understand what content is already indexed\n- To verify indexing operations completed successfully\n- When debugging search issues or unexpected results\n- To get an overview of available content for semantic search\n- To check system health and identify any configuration problems\n\nInformation provided:\n- Server version and operational status\n- Total count of indexed directories, files, and searchable chunks\n- Database size and storage information\n- Most recent indexing timestamp\n- List of all indexed directories with individual statistics\n- File counts and chunk counts per directory\n- Indexing status for each directory (completed, failed, in progress)\n- Error reports and processing issues\n- System consistency checks between database components\n\nStatus indicators:\n- Operational status of vector database (Qdrant) connection\n- Embedding service availability\n- Data consistency between SQLite metadata and vector storage\n- Recent errors or warnings that may affect search quality\n\nUse this tool to:\n- Verify setup before performing search operations\n- Understand the scope of available content\n- Troubleshoot search or indexing issues\n- Plan additional indexing operations\n- Monitor system health and performance`,\n inputSchema: {\n type: 'object',\n properties: {},\n additionalProperties: false\n }\n }\n];\n\nexport async function startMcpServer(config: Config): Promise<void> {\n const server = new Server(\n {\n name: 'directory-indexer',\n version: VERSION\n },\n {\n capabilities: {\n tools: {}\n }\n }\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: MCP_TOOLS\n };\n });\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n case 'index': {\n if (!args || typeof args.directory_path !== 'string') {\n throw new Error('directory_path is required');\n }\n const paths = args.directory_path.split(',').map((p: string) => p.trim());\n const result = await indexDirectories(paths, config);\n return {\n content: [\n {\n type: 'text',\n text: `Indexed ${result.indexed} files, skipped ${result.skipped} files, ${result.errors.length} errors`\n }\n ]\n };\n }\n\n case 'search': {\n if (!args || typeof args.query !== 'string') {\n throw new Error('query is required');\n }\n const results = await searchContent(args.query, { limit: (args.limit as number) || 10 });\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(results, null, 2)\n }\n ]\n };\n }\n\n case 'similar_files': {\n if (!args || typeof args.file_path !== 'string') {\n throw new Error('file_path is required');\n }\n const results = await findSimilarFiles(args.file_path, (args.limit as number) || 10);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(results, null, 2)\n }\n ]\n };\n }\n\n case 'get_content': {\n if (!args || typeof args.file_path !== 'string') {\n throw new Error('file_path is required');\n }\n const content = await getFileContent(args.file_path, args.chunks as string);\n return {\n content: [\n {\n type: 'text',\n text: content\n }\n ]\n };\n }\n\n case 'get_chunk': {\n if (!args || typeof args.file_path !== 'string' || typeof args.chunk_id !== 'string') {\n throw new Error('file_path and chunk_id are required');\n }\n const content = await getChunkContent(args.file_path, args.chunk_id);\n return {\n content: [\n {\n type: 'text',\n text: content\n }\n ]\n };\n }\n\n case 'server_info': {\n const status = await getIndexStatus();\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n name: 'directory-indexer',\n version: VERSION,\n status: status\n }, null, 2)\n }\n ]\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${errorMessage}`\n }\n ],\n isError: true\n };\n }\n });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n \n if (config.verbose) {\n console.error('MCP server started successfully');\n }\n}","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { fileURLToPath } from 'url';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { indexDirectories } from './indexing.js';\nimport { searchContent, findSimilarFiles, getFileContent } from './search.js';\nimport { loadConfig } from './config.js';\nimport { getIndexStatus } from './storage.js';\nimport { startMcpServer } from './mcp.js';\n\n// Read version from package.json\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst packageJsonPath = join(__dirname, '../package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\nconst VERSION = packageJson.version;\n\nexport async function main() {\n const program = new Command();\n \n program\n .name('directory-indexer')\n .description('AI-powered directory indexing with semantic search')\n .version(VERSION);\n\n program\n .command('index')\n .description('Index directories for semantic search')\n .argument('<paths...>', 'Directory paths to index')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (paths: string[], options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n console.log(`Indexing ${paths.length} ${paths.length === 1 ? 'directory' : 'directories'}: ${paths.join(', ')}`);\n const result = await indexDirectories(paths, config);\n console.log(`Indexed ${result.indexed} files, skipped ${result.skipped} files, ${result.errors.length} errors`);\n if (result.errors.length > 0 && config.verbose) {\n console.log('Errors:', result.errors);\n }\n } catch (error) {\n console.error('Error indexing directories:', error);\n process.exit(1);\n }\n });\n\n program\n .command('search')\n .description('Search indexed content semantically')\n .argument('<query>', 'Search query')\n .option('-l, --limit <number>', 'Maximum number of results', '10')\n .option('-c, --show-chunks', 'Show individual chunk scores and IDs')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (query: string, options) => {\n try {\n await loadConfig({ verbose: options.verbose });\n const results = await searchContent(query, { limit: parseInt(options.limit) });\n \n if (results.length === 0) {\n console.log('No results found');\n return;\n }\n\n console.log(`Found ${results.length} results:\\n`);\n results.forEach((result, index) => {\n console.log(`${index + 1}. ${result.filePath}`);\n console.log(` Score: ${result.score.toFixed(3)} (${result.matchingChunks} chunks)`);\n \n if (options.showChunks && result.chunks.length > 0) {\n console.log(` Chunks:`);\n result.chunks.forEach(chunk => {\n console.log(` - Chunk ${chunk.chunkId}: ${chunk.score.toFixed(3)}`);\n });\n }\n \n console.log();\n });\n } catch (error) {\n console.error('Error searching content:', error);\n process.exit(1);\n }\n });\n\n program\n .command('similar')\n .description('Find files similar to a given file')\n .argument('<file>', 'File path to find similar files for')\n .option('-l, --limit <number>', 'Maximum number of results', '10')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (filePath: string, options) => {\n try {\n await loadConfig({ verbose: options.verbose });\n const results = await findSimilarFiles(filePath, parseInt(options.limit));\n \n if (results.length === 0) {\n console.log('No similar files found');\n return;\n }\n\n console.log(`Found ${results.length} similar files:\\n`);\n results.forEach((result, index) => {\n console.log(`${index + 1}. ${result.filePath}`);\n console.log(` Similarity: ${result.score.toFixed(3)}`);\n console.log();\n });\n } catch (error) {\n console.error('Error finding similar files:', error);\n process.exit(1);\n }\n });\n\n program\n .command('get')\n .description('Get file content')\n .argument('<file>', 'File path to retrieve')\n .option('-c, --chunks <range>', 'Chunk range (e.g., \"2-5\")')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (filePath: string, options) => {\n try {\n await loadConfig({ verbose: options.verbose });\n const content = await getFileContent(filePath, options.chunks);\n console.log(content);\n } catch (error) {\n console.error('Error getting file content:', error);\n process.exit(1);\n }\n });\n\n program\n .command('serve')\n .description('Start MCP server')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n await startMcpServer(config);\n } catch (error) {\n console.error('Error starting MCP server:', error);\n process.exit(1);\n }\n });\n\n program\n .command('status')\n .description('Show indexing status')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n await loadConfig({ verbose: options.verbose });\n const status = await getIndexStatus();\n \n console.log('Directory Indexer Status Report');\n console.log('=====================================');\n console.log('');\n console.log('OVERVIEW:');\n console.log(` • ${status.directoriesIndexed} directories have been indexed`);\n console.log(` • ${status.filesIndexed} files processed for semantic search`);\n console.log(` • ${status.chunksIndexed} text chunks available for AI search`);\n console.log(` • Database storage: ${status.databaseSize}`);\n console.log(` • Most recent indexing: ${status.lastIndexed || 'No indexing performed yet'}`);\n \n if (status.errors.length > 0) {\n console.log(` • Processing errors encountered: ${status.errors.length}`);\n if (options.verbose) {\n console.log('');\n console.log('RECENT ERRORS:');\n status.errors.slice(0, 5).forEach(error => {\n console.log(` - ${error}`);\n });\n }\n }\n \n console.log('');\n console.log('INDEXED DIRECTORIES:');\n if (status.directories.length === 0) {\n console.log(' No directories have been indexed yet.');\n console.log(' Run \"directory-indexer index <path>\" to start indexing.');\n } else {\n status.directories.forEach(dir => {\n console.log('');\n console.log(` Directory: ${dir.path}`);\n console.log(` • Indexing status: ${dir.status}`);\n console.log(` • Files processed: ${dir.filesCount}`);\n console.log(` • Searchable chunks: ${dir.chunksCount}`);\n console.log(` • Last indexed: ${dir.lastIndexed || 'Never completed'}`);\n if (dir.errors.length > 0) {\n console.log(` • Files with errors: ${dir.errors.length}`);\n if (options.verbose) {\n console.log(' • Recent errors:');\n dir.errors.slice(0, 3).forEach(error => {\n console.log(` - ${error}`);\n });\n }\n }\n });\n }\n \n if (!status.qdrantConsistency.isConsistent) {\n console.log('');\n console.log('SYSTEM STATUS:');\n status.qdrantConsistency.issues.forEach(issue => {\n console.log(` • ${issue}`);\n });\n console.log('');\n console.log('ℹ️ Note: Status messages above may be normal during setup or active indexing.');\n } else {\n console.log('');\n console.log('SYSTEM STATUS:');\n console.log(' • All systems operational - ready for AI-powered search');\n }\n } catch (error) {\n console.error('Error getting status:', error);\n process.exit(1);\n }\n });\n\n await program.parseAsync();\n}\n\n// Main function is already exported above"],"names":["__dirname","packageJsonPath","packageJson","VERSION"],"mappings":"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"}
1
+ {"version":3,"file":"cli.js","sources":["../src/mcp.ts","../src/cli.ts"],"sourcesContent":["import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { \n CallToolRequestSchema, \n ListToolsRequestSchema,\n Tool\n} from '@modelcontextprotocol/sdk/types.js';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { fileURLToPath } from 'url';\nimport { Config } from './config.js';\nimport { indexDirectories } from './indexing.js';\nimport { searchContent, findSimilarFiles, getFileContent, getChunkContent } from './search.js';\nimport { getIndexStatus } from './storage.js';\n\n// Read version from package.json\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst packageJsonPath = join(__dirname, '../package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\nconst VERSION = packageJson.version;\n\nconst MCP_TOOLS: Tool[] = [\n {\n name: 'index',\n description: `Index directories to make their files searchable. Processes files to create vector embeddings for semantic search.\n\nWhen to use this tool:\n- User specifically requests indexing a directory as a knowledge base\n- Adding new documentation, code repositories, or file collections to search\n- Updating index when many files have changed\n\nHow it works:\n- Recursively scans directories for supported file types\n- Extracts text content and splits into chunks\n- Generates vector embeddings for semantic similarity\n- Stores in database for fast retrieval\n\nExamples:\n- Index documentation: \"/home/user/docs/project-wiki\"\n- Index codebase: \"/home/user/projects/api-server\"\n- Index multiple directories: \"/home/user/docs,/home/user/configs\"\n\nIndexing can take several minutes for large directories. Most users will already have directories indexed and can directly use search tool. Use server_info to check current indexing status first.`,\n inputSchema: {\n type: 'object',\n properties: {\n directory_path: {\n type: 'string',\n description: 'Comma-separated list of absolute directory paths to index. Must be absolute paths since MCP server runs independently. Examples: \"/home/user/projects\" (Unix) or \"C:\\\\Users\\\\user\\\\projects\" (Windows)'\n }\n },\n required: ['directory_path']\n }\n },\n {\n name: 'search',\n description: `Search indexed files using natural language queries. Finds files containing content semantically similar to the query.\n\nWhen to use this tool:\n- Find documentation, guides, or explanations about specific topics\n- Locate code files implementing certain functionality or patterns\n- Discover configuration files, scripts, or settings related to a topic\n- Search for files covering specific concepts or technologies\n\nHow it works:\n- Converts query to vector embedding using semantic similarity\n- Searches all indexed file chunks for relevant content\n- Groups results by file and calculates average relevance scores\n- Returns files ranked by relevance score\n\nExamples:\n- \"database configuration\" - finds config files, documentation about DB setup\n- \"error handling patterns\" - finds code files with exception handling\n- \"authentication implementation\" - finds auth-related code and docs\n- \"API documentation\" - finds API guides, endpoint definitions\n- \"deployment scripts\" - finds CI/CD configs, deployment automation\n\nReturns files with similarity scores and chunk information. Use get_content to retrieve full file content or get_chunk to retrieve specific chunk content by chunk ID.\n- Groups results by file to avoid duplicates from multiple matching sections\n\nResponse format:\n- Returns lightweight metadata including file paths, relevance scores, and chunk IDs\n- Use 'get_chunk' or 'get_content' tools to fetch actual content from search results\n- Chunks are sorted by relevance score within each file\n- Average similarity score calculated across all matching chunks per file\n\nExample queries:\n- \"error handling patterns\" (finds try/catch, error classes, logging)\n- \"database migration scripts\" (finds SQL, schema changes, migration files)\n- \"authentication middleware\" (finds auth logic, JWT handling, middleware functions)`,\n inputSchema: {\n type: 'object',\n properties: {\n query: {\n type: 'string',\n description: 'Natural language search query describing what you are looking for. Can be concepts, functionality, or specific technical terms.'\n },\n limit: {\n type: 'number',\n description: 'Maximum number of files to return (default: 10). Each file may contain multiple matching chunks.',\n default: 10\n }\n },\n required: ['query']\n }\n },\n {\n name: 'similar_files',\n description: `Find files with content similar to a reference file. Uses semantic similarity to find related documents, code files, or any text content.\n\nWhen to use this tool:\n- Find documentation similar to a specific guide or README\n- Locate related code files, configuration files, or scripts\n- Discover alternative implementations or approaches\n- Find files covering similar topics or concepts\n\nHow it works:\n- Analyzes the semantic content of the reference file\n- Compares against all indexed files using vector similarity\n- Returns files ranked by content similarity score\n\nExamples:\n- Given \"deployment-guide.md\" - finds other deployment docs, CI/CD guides, infrastructure setup\n- Given \"troubleshooting.md\" - finds other troubleshooting guides, FAQ files, error documentation\n- Given \"config.yaml\" - finds other configuration files, settings, environment setups\n- Given \"auth.py\" - finds other authentication modules, security code, middleware\n\nReturns file paths with similarity scores. Use get_content to read full files or get_chunk for specific sections.`,\n inputSchema: {\n type: 'object',\n properties: {\n file_path: {\n type: 'string',\n description: 'Absolute or relative path to the reference file. This file must have been previously indexed.'\n },\n limit: {\n type: 'number',\n description: 'Maximum number of similar files to return (default: 10). Results are sorted by similarity score.',\n default: 10\n }\n },\n required: ['file_path']\n }\n },\n {\n name: 'get_content',\n description: `Retrieve the full content of a file or specific chunks. Reads files directly from the filesystem.\n\nWhen to use this tool:\n- Get complete file content after finding files through search\n- Read documentation, code files, or configuration files for analysis\n- Extract specific sections of large files using chunk ranges\n- Access any text-based file content\n\nHow it works:\n- Reads files directly from filesystem (not from search index)\n- Returns entire file by default\n- Can return specific chunk ranges for indexed files\n- Preserves original formatting and content\n\nExamples:\n- Get full file: file_path=\"/home/user/docs/api.md\"\n- Get specific chunks: file_path=\"/home/user/code/main.py\", chunks=\"2-5\"\n- Get single chunk: file_path=\"/home/user/config.json\", chunks=\"1\"\n\nReturns file content as text. Use this after search or similar_files to read actual content.`,\n inputSchema: {\n type: 'object',\n properties: {\n file_path: {\n type: 'string',\n description: 'Absolute or relative path to the file to retrieve. File must be readable and text-based.'\n },\n chunks: {\n type: 'string',\n description: 'Optional chunk range specification. Examples: \"3\" (single chunk), \"2-5\" (chunks 2 through 5), \"1-3\" (first three chunks). Only works for indexed files.'\n }\n },\n required: ['file_path']\n }\n },\n {\n name: 'get_chunk',\n description: `Retrieve content of a specific chunk from an indexed file. Gets exact text segments identified during search.\n\nWhen to use this tool:\n- Get specific relevant sections after performing a search\n- Access only the most pertinent parts of large files\n- Retrieve content from high-scoring chunks identified in search results\n- Avoid reading entire files when only specific sections are needed\n\nHow it works:\n- Files are split into overlapping text chunks during indexing\n- Each chunk has a sequential ID (\"0\", \"1\", \"2\", etc.)\n- Search results include chunk IDs for relevant sections\n- Returns the exact content that was semantically matched\n\nExamples:\n- After search returns chunk \"3\" from \"api-docs.md\" with high score\n- Get chunk content: file_path=\"/docs/api-docs.md\", chunk_id=\"3\"\n- Returns the specific text segment that matched your query\n\nReturns chunk content as text. Use this with chunk IDs from search results to get precise content sections.`,\n inputSchema: {\n type: 'object',\n properties: {\n file_path: {\n type: 'string',\n description: 'Absolute or relative path to the indexed file containing the desired chunk.'\n },\n chunk_id: {\n type: 'string',\n description: 'ID of the specific chunk to retrieve. This is typically obtained from search results and is a sequential string like \"0\", \"1\", \"2\", etc.'\n }\n },\n required: ['file_path', 'chunk_id']\n }\n },\n {\n name: 'server_info',\n description: `Get information about server status and indexed content. Shows what directories and files are available for search.\n\nWhen to use this tool:\n- Check what content is already indexed before performing searches\n- Verify system is working properly\n- See indexing statistics and status\n- Understand scope of available searchable content\n\nHow it works:\n- Reports total indexed directories, files, and chunks\n- Shows database size and last indexing time\n- Lists all indexed directories with file counts\n- Reports any errors or issues\n\nExamples:\n- Check before searching: \"What content is indexed?\"\n- Verify after indexing: \"Did the indexing complete successfully?\"\n- Monitor system: \"How many files are searchable?\"\n\nReturns server version, indexing statistics, directory list, and any errors. Use this to understand what content is available for search and similar_files tools.`,\n inputSchema: {\n type: 'object',\n properties: {},\n additionalProperties: false\n }\n }\n];\n\nexport async function startMcpServer(config: Config): Promise<void> {\n const server = new Server(\n {\n name: 'directory-indexer',\n version: VERSION\n },\n {\n capabilities: {\n tools: {}\n }\n }\n );\n\n server.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: MCP_TOOLS\n };\n });\n\n server.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n switch (name) {\n case 'index': {\n if (!args || typeof args.directory_path !== 'string') {\n throw new Error('directory_path is required');\n }\n const paths = args.directory_path.split(',').map((p: string) => p.trim());\n const result = await indexDirectories(paths, config);\n return {\n content: [\n {\n type: 'text',\n text: `Indexed ${result.indexed} files, skipped ${result.skipped} files, ${result.errors.length} errors`\n }\n ]\n };\n }\n\n case 'search': {\n if (!args || typeof args.query !== 'string') {\n throw new Error('query is required');\n }\n const results = await searchContent(args.query, { limit: (args.limit as number) || 10 });\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(results, null, 2)\n }\n ]\n };\n }\n\n case 'similar_files': {\n if (!args || typeof args.file_path !== 'string') {\n throw new Error('file_path is required');\n }\n const results = await findSimilarFiles(args.file_path, (args.limit as number) || 10);\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify(results, null, 2)\n }\n ]\n };\n }\n\n case 'get_content': {\n if (!args || typeof args.file_path !== 'string') {\n throw new Error('file_path is required');\n }\n const content = await getFileContent(args.file_path, args.chunks as string);\n return {\n content: [\n {\n type: 'text',\n text: content\n }\n ]\n };\n }\n\n case 'get_chunk': {\n if (!args || typeof args.file_path !== 'string' || typeof args.chunk_id !== 'string') {\n throw new Error('file_path and chunk_id are required');\n }\n const content = await getChunkContent(args.file_path, args.chunk_id);\n return {\n content: [\n {\n type: 'text',\n text: content\n }\n ]\n };\n }\n\n case 'server_info': {\n const status = await getIndexStatus();\n return {\n content: [\n {\n type: 'text',\n text: JSON.stringify({\n name: 'directory-indexer',\n version: VERSION,\n status: status\n }, null, 2)\n }\n ]\n };\n }\n\n default:\n throw new Error(`Unknown tool: ${name}`);\n }\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : 'Unknown error';\n return {\n content: [\n {\n type: 'text',\n text: `Error: ${errorMessage}`\n }\n ],\n isError: true\n };\n }\n });\n\n const transport = new StdioServerTransport();\n await server.connect(transport);\n \n if (config.verbose) {\n console.error('MCP server started successfully');\n }\n}","#!/usr/bin/env node\n\nimport { Command } from 'commander';\nimport { fileURLToPath } from 'url';\nimport { readFileSync } from 'fs';\nimport { join, dirname } from 'path';\nimport { indexDirectories } from './indexing.js';\nimport { searchContent, findSimilarFiles, getFileContent } from './search.js';\nimport { loadConfig } from './config.js';\nimport { getIndexStatus } from './storage.js';\nimport { startMcpServer } from './mcp.js';\n\n// Read version from package.json\nconst __dirname = dirname(fileURLToPath(import.meta.url));\nconst packageJsonPath = join(__dirname, '../package.json');\nconst packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));\nconst VERSION = packageJson.version;\n\nexport async function main() {\n const program = new Command();\n \n program\n .name('directory-indexer')\n .description('AI-powered directory indexing with semantic search')\n .version(VERSION);\n\n program\n .command('index')\n .description('Index directories for semantic search')\n .argument('<paths...>', 'Directory paths to index')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (paths: string[], options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n console.log(`Indexing ${paths.length} ${paths.length === 1 ? 'directory' : 'directories'}: ${paths.join(', ')}`);\n const result = await indexDirectories(paths, config);\n console.log(`Indexed ${result.indexed} files, skipped ${result.skipped} files, ${result.errors.length} errors`);\n if (result.errors.length > 0 && config.verbose) {\n console.log('Errors:', result.errors);\n }\n } catch (error) {\n console.error('Error indexing directories:', error);\n process.exit(1);\n }\n });\n\n program\n .command('search')\n .description('Search indexed content semantically')\n .argument('<query>', 'Search query')\n .option('-l, --limit <number>', 'Maximum number of results', '10')\n .option('-c, --show-chunks', 'Show individual chunk scores and IDs')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (query: string, options) => {\n try {\n await loadConfig({ verbose: options.verbose });\n const results = await searchContent(query, { limit: parseInt(options.limit) });\n \n if (results.length === 0) {\n console.log('No results found');\n return;\n }\n\n console.log(`Found ${results.length} results:\\n`);\n results.forEach((result, index) => {\n console.log(`${index + 1}. ${result.filePath}`);\n console.log(` Score: ${result.score.toFixed(3)} (${result.matchingChunks} chunks)`);\n \n if (options.showChunks && result.chunks.length > 0) {\n console.log(` Chunks:`);\n result.chunks.forEach(chunk => {\n console.log(` - Chunk ${chunk.chunkId}: ${chunk.score.toFixed(3)}`);\n });\n }\n \n console.log();\n });\n } catch (error) {\n console.error('Error searching content:', error);\n process.exit(1);\n }\n });\n\n program\n .command('similar')\n .description('Find files similar to a given file')\n .argument('<file>', 'File path to find similar files for')\n .option('-l, --limit <number>', 'Maximum number of results', '10')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (filePath: string, options) => {\n try {\n await loadConfig({ verbose: options.verbose });\n const results = await findSimilarFiles(filePath, parseInt(options.limit));\n \n if (results.length === 0) {\n console.log('No similar files found');\n return;\n }\n\n console.log(`Found ${results.length} similar files:\\n`);\n results.forEach((result, index) => {\n console.log(`${index + 1}. ${result.filePath}`);\n console.log(` Similarity: ${result.score.toFixed(3)}`);\n console.log();\n });\n } catch (error) {\n console.error('Error finding similar files:', error);\n process.exit(1);\n }\n });\n\n program\n .command('get')\n .description('Get file content')\n .argument('<file>', 'File path to retrieve')\n .option('-c, --chunks <range>', 'Chunk range (e.g., \"2-5\")')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (filePath: string, options) => {\n try {\n await loadConfig({ verbose: options.verbose });\n const content = await getFileContent(filePath, options.chunks);\n console.log(content);\n } catch (error) {\n console.error('Error getting file content:', error);\n process.exit(1);\n }\n });\n\n program\n .command('serve')\n .description('Start MCP server')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n const config = await loadConfig({ verbose: options.verbose });\n await startMcpServer(config);\n } catch (error) {\n console.error('Error starting MCP server:', error);\n process.exit(1);\n }\n });\n\n program\n .command('status')\n .description('Show indexing status')\n .option('-v, --verbose', 'Enable verbose logging')\n .action(async (options) => {\n try {\n await loadConfig({ verbose: options.verbose });\n const status = await getIndexStatus();\n \n console.log('Directory Indexer Status Report');\n console.log('=====================================');\n console.log('');\n console.log('OVERVIEW:');\n console.log(` • ${status.directoriesIndexed} directories have been indexed`);\n console.log(` • ${status.filesIndexed} files processed for semantic search`);\n console.log(` • ${status.chunksIndexed} text chunks available for AI search`);\n console.log(` • Database storage: ${status.databaseSize}`);\n console.log(` • Most recent indexing: ${status.lastIndexed || 'No indexing performed yet'}`);\n \n if (status.errors.length > 0) {\n console.log(` • Processing errors encountered: ${status.errors.length}`);\n if (options.verbose) {\n console.log('');\n console.log('RECENT ERRORS:');\n status.errors.slice(0, 5).forEach(error => {\n console.log(` - ${error}`);\n });\n }\n }\n \n console.log('');\n console.log('INDEXED DIRECTORIES:');\n if (status.directories.length === 0) {\n console.log(' No directories have been indexed yet.');\n console.log(' Run \"directory-indexer index <path>\" to start indexing.');\n } else {\n status.directories.forEach(dir => {\n console.log('');\n console.log(` Directory: ${dir.path}`);\n console.log(` • Indexing status: ${dir.status}`);\n console.log(` • Files processed: ${dir.filesCount}`);\n console.log(` • Searchable chunks: ${dir.chunksCount}`);\n console.log(` • Last indexed: ${dir.lastIndexed || 'Never completed'}`);\n if (dir.errors.length > 0) {\n console.log(` • Files with errors: ${dir.errors.length}`);\n if (options.verbose) {\n console.log(' • Recent errors:');\n dir.errors.slice(0, 3).forEach(error => {\n console.log(` - ${error}`);\n });\n }\n }\n });\n }\n \n if (!status.qdrantConsistency.isConsistent) {\n console.log('');\n console.log('SYSTEM STATUS:');\n status.qdrantConsistency.issues.forEach(issue => {\n console.log(` • ${issue}`);\n });\n console.log('');\n console.log('ℹ️ Note: Status messages above may be normal during setup or active indexing.');\n } else {\n console.log('');\n console.log('SYSTEM STATUS:');\n console.log(' • All systems operational - ready for AI-powered search');\n }\n } catch (error) {\n console.error('Error getting status:', error);\n process.exit(1);\n }\n });\n\n await program.parseAsync();\n}\n\n// Main function is already exported above"],"names":["__dirname","packageJsonPath","packageJson","VERSION"],"mappings":"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"}
package/dist/embedding.js CHANGED
@@ -41,25 +41,41 @@ class OllamaEmbeddingProvider {
41
41
  dimensions = 768;
42
42
  async generateEmbedding(text) {
43
43
  try {
44
- const response = await fetch(`${this.config.endpoint}/api/embeddings`, {
44
+ const response = await fetch(`${this.config.endpoint}/api/embed`, {
45
45
  method: "POST",
46
46
  headers: { "Content-Type": "application/json" },
47
47
  body: JSON.stringify({
48
48
  model: this.config.model,
49
- prompt: text
49
+ input: text
50
50
  })
51
51
  });
52
52
  if (!response.ok) {
53
53
  throw new Error(`Ollama API error: ${response.statusText}`);
54
54
  }
55
55
  const data = await response.json();
56
- return data.embedding;
56
+ return data.embeddings[0];
57
57
  } catch (error) {
58
58
  throw new EmbeddingError(`Failed to generate Ollama embedding`, error);
59
59
  }
60
60
  }
61
61
  async generateEmbeddings(texts) {
62
- return Promise.all(texts.map((text) => this.generateEmbedding(text)));
62
+ try {
63
+ const response = await fetch(`${this.config.endpoint}/api/embed`, {
64
+ method: "POST",
65
+ headers: { "Content-Type": "application/json" },
66
+ body: JSON.stringify({
67
+ model: this.config.model,
68
+ input: texts
69
+ })
70
+ });
71
+ if (!response.ok) {
72
+ throw new Error(`Ollama API error: ${response.statusText}`);
73
+ }
74
+ const data = await response.json();
75
+ return data.embeddings;
76
+ } catch (error) {
77
+ throw new EmbeddingError(`Failed to generate Ollama embeddings`, error);
78
+ }
63
79
  }
64
80
  }
65
81
  class OpenAIEmbeddingProvider {
@@ -1 +1 @@
1
- {"version":3,"file":"embedding.js","sources":["../src/embedding.ts"],"sourcesContent":["import { Config } from './config.js';\n\nexport interface EmbeddingProvider {\n name: string;\n dimensions: number;\n generateEmbedding(text: string): Promise<number[]>;\n generateEmbeddings(texts: string[]): Promise<number[][]>;\n}\n\nexport interface EmbeddingConfig {\n model: string;\n endpoint: string;\n dimensions: number;\n}\n\nexport class EmbeddingError extends Error {\n constructor(message: string, public override cause?: Error) {\n super(message);\n this.name = 'EmbeddingError';\n }\n}\n\nclass MockEmbeddingProvider implements EmbeddingProvider {\n name = 'mock';\n \n constructor(private config: EmbeddingConfig) {}\n \n get dimensions(): number {\n return this.config.dimensions;\n }\n \n async generateEmbedding(text: string): Promise<number[]> {\n const hash = this.hashString(text);\n return Array.from({ length: this.dimensions }, (_, i) => \n Math.sin(hash + i) * 0.1\n );\n }\n \n async generateEmbeddings(texts: string[]): Promise<number[][]> {\n return Promise.all(texts.map(text => this.generateEmbedding(text)));\n }\n \n private hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash);\n }\n}\n\nclass OllamaEmbeddingProvider implements EmbeddingProvider {\n name = 'ollama';\n dimensions = 768;\n \n constructor(private config: EmbeddingConfig) {}\n \n async generateEmbedding(text: string): Promise<number[]> {\n try {\n const response = await fetch(`${this.config.endpoint}/api/embeddings`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model: this.config.model,\n prompt: text\n })\n });\n \n if (!response.ok) {\n throw new Error(`Ollama API error: ${response.statusText}`);\n }\n \n const data = await response.json();\n return data.embedding;\n } catch (error) {\n throw new EmbeddingError(`Failed to generate Ollama embedding`, error as Error);\n }\n }\n \n async generateEmbeddings(texts: string[]): Promise<number[][]> {\n return Promise.all(texts.map(text => this.generateEmbedding(text)));\n }\n}\n\nclass OpenAIEmbeddingProvider implements EmbeddingProvider {\n name = 'openai';\n dimensions = 1536;\n \n constructor(private config: EmbeddingConfig) {}\n \n async generateEmbedding(text: string): Promise<number[]> {\n try {\n const response = await fetch('https://api.openai.com/v1/embeddings', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`\n },\n body: JSON.stringify({\n model: this.config.model,\n input: text\n })\n });\n \n if (!response.ok) {\n throw new Error(`OpenAI API error: ${response.statusText}`);\n }\n \n const data = await response.json();\n return data.data[0].embedding;\n } catch (error) {\n throw new EmbeddingError(`Failed to generate OpenAI embedding`, error as Error);\n }\n }\n \n async generateEmbeddings(texts: string[]): Promise<number[][]> {\n try {\n const response = await fetch('https://api.openai.com/v1/embeddings', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`\n },\n body: JSON.stringify({\n model: this.config.model,\n input: texts\n })\n });\n \n if (!response.ok) {\n throw new Error(`OpenAI API error: ${response.statusText}`);\n }\n \n const data = await response.json();\n return data.data.map((item: { embedding: number[] }) => item.embedding);\n } catch (error) {\n throw new EmbeddingError(`Failed to generate OpenAI embeddings`, error as Error);\n }\n }\n}\n\nexport function createEmbeddingProvider(provider: string, config: EmbeddingConfig): EmbeddingProvider {\n switch (provider) {\n case 'mock':\n return new MockEmbeddingProvider(config);\n case 'ollama':\n return new OllamaEmbeddingProvider(config);\n case 'openai':\n return new OpenAIEmbeddingProvider(config);\n default:\n throw new EmbeddingError(`Unknown embedding provider: ${provider}`);\n }\n}\n\nexport async function generateEmbedding(text: string, config: Config): Promise<number[]> {\n const provider = createEmbeddingProvider(config.embedding.provider, {\n model: config.embedding.model,\n endpoint: config.embedding.endpoint,\n dimensions: config.embedding.provider === 'mock' ? 384 : (config.embedding.provider === 'ollama' ? 768 : 1536)\n });\n \n return provider.generateEmbedding(text);\n}"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"embedding.js","sources":["../src/embedding.ts"],"sourcesContent":["import { Config } from './config.js';\n\nexport interface EmbeddingProvider {\n name: string;\n dimensions: number;\n generateEmbedding(text: string): Promise<number[]>;\n generateEmbeddings(texts: string[]): Promise<number[][]>;\n}\n\nexport interface EmbeddingConfig {\n model: string;\n endpoint: string;\n dimensions: number;\n}\n\nexport class EmbeddingError extends Error {\n constructor(message: string, public override cause?: Error) {\n super(message);\n this.name = 'EmbeddingError';\n }\n}\n\nclass MockEmbeddingProvider implements EmbeddingProvider {\n name = 'mock';\n \n constructor(private config: EmbeddingConfig) {}\n \n get dimensions(): number {\n return this.config.dimensions;\n }\n \n async generateEmbedding(text: string): Promise<number[]> {\n const hash = this.hashString(text);\n return Array.from({ length: this.dimensions }, (_, i) => \n Math.sin(hash + i) * 0.1\n );\n }\n \n async generateEmbeddings(texts: string[]): Promise<number[][]> {\n return Promise.all(texts.map(text => this.generateEmbedding(text)));\n }\n \n private hashString(str: string): number {\n let hash = 0;\n for (let i = 0; i < str.length; i++) {\n const char = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + char;\n hash = hash & hash;\n }\n return Math.abs(hash);\n }\n}\n\nclass OllamaEmbeddingProvider implements EmbeddingProvider {\n name = 'ollama';\n dimensions = 768;\n \n constructor(private config: EmbeddingConfig) {}\n \n async generateEmbedding(text: string): Promise<number[]> {\n try {\n const response = await fetch(`${this.config.endpoint}/api/embed`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model: this.config.model,\n input: text\n })\n });\n \n if (!response.ok) {\n throw new Error(`Ollama API error: ${response.statusText}`);\n }\n \n const data = await response.json();\n return data.embeddings[0];\n } catch (error) {\n throw new EmbeddingError(`Failed to generate Ollama embedding`, error as Error);\n }\n }\n \n async generateEmbeddings(texts: string[]): Promise<number[][]> {\n try {\n const response = await fetch(`${this.config.endpoint}/api/embed`, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n model: this.config.model,\n input: texts\n })\n });\n \n if (!response.ok) {\n throw new Error(`Ollama API error: ${response.statusText}`);\n }\n \n const data = await response.json();\n return data.embeddings;\n } catch (error) {\n throw new EmbeddingError(`Failed to generate Ollama embeddings`, error as Error);\n }\n }\n}\n\nclass OpenAIEmbeddingProvider implements EmbeddingProvider {\n name = 'openai';\n dimensions = 1536;\n \n constructor(private config: EmbeddingConfig) {}\n \n async generateEmbedding(text: string): Promise<number[]> {\n try {\n const response = await fetch('https://api.openai.com/v1/embeddings', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`\n },\n body: JSON.stringify({\n model: this.config.model,\n input: text\n })\n });\n \n if (!response.ok) {\n throw new Error(`OpenAI API error: ${response.statusText}`);\n }\n \n const data = await response.json();\n return data.data[0].embedding;\n } catch (error) {\n throw new EmbeddingError(`Failed to generate OpenAI embedding`, error as Error);\n }\n }\n \n async generateEmbeddings(texts: string[]): Promise<number[][]> {\n try {\n const response = await fetch('https://api.openai.com/v1/embeddings', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`\n },\n body: JSON.stringify({\n model: this.config.model,\n input: texts\n })\n });\n \n if (!response.ok) {\n throw new Error(`OpenAI API error: ${response.statusText}`);\n }\n \n const data = await response.json();\n return data.data.map((item: { embedding: number[] }) => item.embedding);\n } catch (error) {\n throw new EmbeddingError(`Failed to generate OpenAI embeddings`, error as Error);\n }\n }\n}\n\nexport function createEmbeddingProvider(provider: string, config: EmbeddingConfig): EmbeddingProvider {\n switch (provider) {\n case 'mock':\n return new MockEmbeddingProvider(config);\n case 'ollama':\n return new OllamaEmbeddingProvider(config);\n case 'openai':\n return new OpenAIEmbeddingProvider(config);\n default:\n throw new EmbeddingError(`Unknown embedding provider: ${provider}`);\n }\n}\n\nexport async function generateEmbedding(text: string, config: Config): Promise<number[]> {\n const provider = createEmbeddingProvider(config.embedding.provider, {\n model: config.embedding.model,\n endpoint: config.embedding.endpoint,\n dimensions: config.embedding.provider === 'mock' ? 384 : (config.embedding.provider === 'ollama' ? 768 : 1536)\n });\n \n return provider.generateEmbedding(text);\n}"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "directory-indexer",
3
- "version": "0.0.19",
3
+ "version": "0.1.1",
4
4
  "description": "AI-powered directory indexing with semantic search for MCP servers",
5
5
  "main": "dist/cli.js",
6
6
  "bin": {