@echoes-io/mcp-server 4.1.0 → 6.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/README.md +120 -185
  2. package/cli/index.d.ts +3 -0
  3. package/cli/index.d.ts.map +1 -0
  4. package/cli/index.js +4 -0
  5. package/cli/index.js.map +1 -0
  6. package/cli/program.d.ts +3 -0
  7. package/cli/program.d.ts.map +1 -0
  8. package/cli/program.js +150 -0
  9. package/cli/program.js.map +1 -0
  10. package/lib/constants.d.ts +8 -0
  11. package/lib/constants.d.ts.map +1 -0
  12. package/lib/constants.js +12 -0
  13. package/lib/constants.js.map +1 -0
  14. package/lib/database/index.d.ts +34 -0
  15. package/lib/database/index.d.ts.map +1 -0
  16. package/lib/database/index.js +266 -0
  17. package/lib/database/index.js.map +1 -0
  18. package/lib/database/schemas.d.ts +55 -0
  19. package/lib/database/schemas.d.ts.map +1 -0
  20. package/lib/database/schemas.js +70 -0
  21. package/lib/database/schemas.js.map +1 -0
  22. package/lib/indexer/embeddings.d.ts +6 -0
  23. package/lib/indexer/embeddings.d.ts.map +1 -0
  24. package/lib/indexer/embeddings.js +51 -0
  25. package/lib/indexer/embeddings.js.map +1 -0
  26. package/lib/indexer/extractor.d.ts +81 -0
  27. package/lib/indexer/extractor.d.ts.map +1 -0
  28. package/lib/indexer/extractor.js +68 -0
  29. package/lib/indexer/extractor.js.map +1 -0
  30. package/lib/indexer/scanner.d.ts +8 -0
  31. package/lib/indexer/scanner.d.ts.map +1 -0
  32. package/lib/indexer/scanner.js +73 -0
  33. package/lib/indexer/scanner.js.map +1 -0
  34. package/lib/prompts/index.d.ts +13 -0
  35. package/lib/prompts/index.d.ts.map +1 -0
  36. package/lib/prompts/index.js +153 -0
  37. package/lib/prompts/index.js.map +1 -0
  38. package/lib/server.d.ts +13 -0
  39. package/lib/server.d.ts.map +1 -0
  40. package/lib/server.js +90 -0
  41. package/lib/server.js.map +1 -0
  42. package/lib/tools/index.d.ts +19 -0
  43. package/lib/tools/index.d.ts.map +1 -0
  44. package/lib/tools/index.js +128 -0
  45. package/lib/tools/index.js.map +1 -0
  46. package/lib/tools/search.d.ts +86 -0
  47. package/lib/tools/search.d.ts.map +1 -0
  48. package/lib/tools/search.js +95 -0
  49. package/lib/tools/search.js.map +1 -0
  50. package/lib/tools/stats.d.ts +18 -0
  51. package/lib/tools/stats.d.ts.map +1 -0
  52. package/lib/tools/stats.js +62 -0
  53. package/lib/tools/stats.js.map +1 -0
  54. package/lib/tools/words-count.d.ts +18 -0
  55. package/lib/tools/words-count.d.ts.map +1 -0
  56. package/lib/tools/words-count.js +31 -0
  57. package/lib/tools/words-count.js.map +1 -0
  58. package/lib/types.d.ts +29 -0
  59. package/lib/types.d.ts.map +1 -0
  60. package/lib/types.js +2 -0
  61. package/lib/types.js.map +1 -0
  62. package/lib/utils.d.ts +19 -0
  63. package/lib/utils.d.ts.map +1 -0
  64. package/lib/utils.js +40 -0
  65. package/lib/utils.js.map +1 -0
  66. package/package.json +59 -61
package/README.md CHANGED
@@ -1,245 +1,180 @@
1
- # mcp-server
1
+ # Echoes MCP Server
2
2
 
3
- Model Context Protocol server for AI integration with Echoes storytelling platform
3
+ [![CI](https://github.com/echoes-io/mcp-server/actions/workflows/ci.yml/badge.svg)](https://github.com/echoes-io/mcp-server/actions/workflows/ci.yml)
4
+ [![npm](https://img.shields.io/npm/v/@echoes-io/mcp-server)](https://www.npmjs.com/package/@echoes-io/mcp-server)
5
+ [![Node](https://img.shields.io/node/v/@echoes-io/mcp-server)](https://www.npmjs.com/package/@echoes-io/mcp-server)
6
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
+ ![Coverage Badge](https://img.shields.io/badge/coverage-100%25-brightgreen?style=flat)
4
8
 
5
- ## Installation
9
+ Model Context Protocol server for AI integration with Echoes storytelling platform.
6
10
 
7
- The server is distributed as an npm package and can be used without cloning the repository.
11
+ ## Features
8
12
 
9
- ### Using with MCP Clients
13
+ - **Narrative Knowledge Graph**: Automatically extracts characters, locations, events, and their relationships using Gemini AI
14
+ - **Semantic Search**: Find relevant chapters using natural language queries
15
+ - **Entity Search**: Search for characters, locations, and events
16
+ - **Relation Search**: Explore relationships between entities
17
+ - **Arc Isolation**: Each arc is a separate narrative universe - no cross-arc contamination
18
+ - **Statistics**: Aggregate word counts, POV distribution, and more
19
+ - **Dynamic Prompts**: Reusable prompt templates with placeholder substitution
10
20
 
11
- The server can run in three modes depending on the working directory:
21
+ ## Installation
12
22
 
13
- 1. **Single Timeline Mode**: Run from a `timeline-*` directory to work with that specific timeline
14
- 2. **Multi-Timeline Mode**: Run from `.github` directory to access all timelines
15
- 3. **Test Mode**: Run from `mcp-server` directory for development
23
+ ```bash
24
+ npm install -g @echoes-io/mcp-server
25
+ ```
16
26
 
17
- #### Single Timeline Configuration (Recommended for Kiro CLI)
27
+ Or run directly with npx:
18
28
 
19
- ```json
20
- {
21
- "mcpServers": {
22
- "echoes": {
23
- "command": "npx",
24
- "args": ["-y", "@echoes-io/mcp-server"],
25
- "cwd": "/path/to/timeline-pulse"
26
- }
27
- }
28
- }
29
+ ```bash
30
+ npx @echoes-io/mcp-server --help
29
31
  ```
30
32
 
31
- #### Multi-Timeline Configuration (Legacy/CAO)
33
+ ## Requirements
32
34
 
33
- ```json
34
- {
35
- "mcpServers": {
36
- "echoes": {
37
- "command": "npx",
38
- "args": ["-y", "@echoes-io/mcp-server"],
39
- "cwd": "/path/to/echoes-io/.github"
40
- }
41
- }
42
- }
43
- ```
35
+ - Node.js 20+
36
+ - Gemini API key (for entity extraction)
37
+
38
+ ## Usage
44
39
 
45
- Or install globally:
40
+ ### CLI
46
41
 
47
42
  ```bash
48
- npm install -g @echoes-io/mcp-server
43
+ # Count words in a markdown file
44
+ echoes words-count ./content/arc1/ep01/ch001.md
45
+
46
+ # Index timeline content
47
+ echoes index ./content
48
+
49
+ # Index only a specific arc
50
+ echoes index ./content --arc bloom
51
+
52
+ # Get statistics
53
+ echoes stats
54
+ echoes stats --arc arc1 --pov Alice
55
+
56
+ # Search (filters by arc to avoid cross-arc contamination)
57
+ echoes search "primo incontro" --arc bloom
58
+ echoes search "Alice" --type entities --arc bloom
49
59
  ```
50
60
 
51
- Then configure:
61
+ ### MCP Server
62
+
63
+ Configure in your MCP client (e.g., Claude Desktop, Kiro):
52
64
 
53
65
  ```json
54
66
  {
55
67
  "mcpServers": {
56
68
  "echoes": {
57
- "command": "echoes-mcp-server",
58
- "cwd": "/path/to/timeline-pulse",
69
+ "command": "npx",
70
+ "args": ["@echoes-io/mcp-server"],
71
+ "cwd": "/path/to/timeline",
59
72
  "env": {
60
- "ECHOES_RAG_PROVIDER": "qwen3"
73
+ "GEMINI_API_KEY": "your_api_key"
61
74
  }
62
75
  }
63
76
  }
64
77
  }
65
78
  ```
66
79
 
67
- **Optional RAG Configuration:**
68
- - `ECHOES_RAG_PROVIDER`: Embedding provider (`qwen3`, `nomic-embed`, `bge-base`, `e5-large`, `e5-small`, or `gemini`). Default: `qwen3`
69
- - `ECHOES_GEMINI_API_KEY`: Required if using `gemini` provider
80
+ ## Environment Variables
70
81
 
71
- ## Execution Modes
72
-
73
- ### Single Timeline Mode (Recommended)
74
- Run from a timeline directory to work with that specific timeline:
75
- ```bash
76
- cd timeline-pulse
77
- npx @echoes-io/mcp-server
78
- # [DEBUG] Mode: single-timeline "pulse"
79
- ```
82
+ | Variable | Required | Default | Description |
83
+ |----------|----------|---------|-------------|
84
+ | `GEMINI_API_KEY` | Yes | - | API key for Gemini entity extraction |
85
+ | `ECHOES_GEMINI_MODEL` | No | `gemini-2.5-flash` | Gemini model for extraction |
86
+ | `ECHOES_EMBEDDING_MODEL` | No | `Xenova/multilingual-e5-small` | HuggingFace embedding model |
87
+ | `HF_TOKEN` | No | - | HuggingFace token for gated models |
80
88
 
81
- **Benefits:**
82
- - Simpler configuration for single-timeline workflows
83
- - Direct access to timeline databases
84
- - Perfect for Kiro CLI integration
89
+ ## Available Tools
85
90
 
86
- ### Multi-Timeline Mode (Legacy)
87
- Run from `.github` directory to access all timelines:
88
- ```bash
89
- cd .github
90
- npx @echoes-io/mcp-server
91
- # [DEBUG] Mode: multi-timeline (scanning /path/to/echoes-io)
92
- ```
91
+ | Tool | Description |
92
+ |------|-------------|
93
+ | `words-count` | Count words and statistics in a markdown file |
94
+ | `index` | Index timeline content into LanceDB |
95
+ | `search` | Search chapters, entities, or relations |
96
+ | `stats` | Get aggregate statistics |
93
97
 
94
- **Benefits:**
95
- - Manage multiple timelines simultaneously
96
- - Backward compatible with CAO agents
97
- - Timeline repositories can be private
98
+ ## Available Prompts
98
99
 
99
- ### Test Mode
100
- Run from `mcp-server` directory for development:
101
- ```bash
102
- cd mcp-server
103
- npm run dev
104
- # [DEBUG] Mode: test from mcp-server (in-memory)
105
- ```
100
+ | Prompt | Arguments | Description |
101
+ |--------|-----------|-------------|
102
+ | `new-chapter` | arc, chapter | Create a new chapter |
103
+ | `revise-chapter` | arc, chapter | Revise an existing chapter |
104
+ | `expand-chapter` | arc, chapter, target | Expand chapter to target word count |
105
+ | `new-character` | name | Create a new character sheet |
106
+ | `new-episode` | arc, episode | Create a new episode outline |
107
+ | `new-arc` | name | Create a new story arc |
108
+ | `revise-arc` | arc | Review and fix an entire arc |
106
109
 
107
- ## Timeline Architecture
110
+ ## Architecture
108
111
 
109
- Each timeline has isolated databases in its own repository:
112
+ ### Content Hierarchy
110
113
 
111
114
  ```
112
- echoes-io/
113
- .github/ # Multi-timeline mode runs from here
114
- timeline-eros/ # Private timeline repo
115
- tracker.db # Timeline-specific database
116
- lancedb/ # Timeline-specific RAG vector database
117
- content/...
118
- timeline-other/ # Another private timeline
119
- tracker.db
120
- lancedb/
121
- content/...
115
+ Timeline (content directory)
116
+ └── Arc (story universe)
117
+ └── Episode (story event)
118
+ └── Chapter (individual .md file)
122
119
  ```
123
120
 
124
- **Benefits:**
125
- - Each timeline has isolated databases in its own repository
126
- - Timeline repositories can be private while `.github` is public
127
- - No need to specify `contentPath` - auto-discovered from directory structure
128
- - Easy to manage access: just share/don't share specific timeline repos
121
+ ### Arc Isolation
129
122
 
123
+ Each arc is treated as a separate narrative universe:
124
+ - Entities are scoped to arcs: `bloom:CHARACTER:Alice` ≠ `work:CHARACTER:Alice`
125
+ - Relations are internal to arcs
126
+ - Searches can be filtered by arc to avoid cross-arc contamination
130
127
 
131
- ## Available Tools
128
+ ### Data Flow
132
129
 
133
- All tools require a `timeline` parameter to specify which timeline to operate on.
134
-
135
- ### Content Operations
136
- - **`words-count`** - Count words and text statistics in markdown files
137
- - Input: `file` (path to markdown file)
138
-
139
- - **`chapter-info`** - Extract chapter metadata from database
140
- - Input: `arc`, `episode`, `chapter`
141
-
142
- - **`chapter-refresh`** - Refresh chapter metadata and word counts from file
143
- - Input: `file` (path to chapter file)
144
-
145
- - **`chapter-insert`** - Insert new chapter with automatic renumbering
146
- - Input: `arc`, `episode`, `after`, `pov`, `title`, optional: `summary`, `location`, `outfit`, `kink`, `file`
147
-
148
- - **`chapter-delete`** - Delete chapter from database and optionally from filesystem
149
- - Input: `arc`, `episode`, `chapter`, optional: `file` (to delete from filesystem)
150
-
151
- ### Episode Operations
152
- - **`episode-info`** - Get episode information and list of chapters
153
- - Input: `arc`, `episode`
154
-
155
- - **`episode-update`** - Update episode metadata (description, title, slug)
156
- - Input: `arc`, `episode`, optional: `description`, `title`, `slug`
157
-
158
- ### Timeline Operations
159
- - **`timeline-sync`** - Synchronize filesystem content with database
160
- - Input: `timeline` (timeline name)
161
- - Note: Content path is auto-discovered from timeline directory structure
162
-
163
- ### Statistics
164
- - **`stats`** - Get aggregate statistics with optional filters
165
- - Input: `timeline`, optional: `arc`, `episode`, `pov`
166
- - Output: Total words/chapters, POV distribution, arc/episode breakdown, longest/shortest chapters
167
- - Examples:
168
- - No filters: Overall timeline statistics
169
- - `arc: "arc1"`: Statistics for specific arc
170
- - `arc: "arc1", episode: 1`: Statistics for specific episode
171
- - `pov: "Alice"`: Statistics for specific POV across timeline
172
-
173
- ### RAG (Semantic Search)
174
- - **`rag-index`** - Index chapters into vector database for semantic search
175
- - Input: `timeline`, optional: `arc`, `episode` (to index specific content)
176
- - Output: Number of chapters indexed
177
- - Note: Content path is auto-discovered from timeline directory structure
178
- - Note: Automatically extracts character names using NER (Named Entity Recognition)
179
-
180
- - **`rag-search`** - Semantic search across timeline content
181
- - Input: `timeline`, `query`, optional: `arc`, `pov`, `maxResults`, `characters`, `allCharacters`
182
- - Output: Relevant chapters with similarity scores, previews, and character names
183
- - Character filtering:
184
- - `characters`: Array of character names to filter by
185
- - `allCharacters`: If true, all characters must be present (AND). If false, at least one (OR). Default: false
186
- - Examples:
187
- - `characters: ["Alice", "Bob"], allCharacters: true` - Find chapters where both Alice AND Bob appear
188
- - `characters: ["Alice", "Bob"]` - Find chapters where Alice OR Bob appear
189
-
190
- - **`rag-context`** - Retrieve relevant context for AI interactions
191
- - Input: `timeline`, `query`, optional: `arc`, `pov`, `maxChapters`, `characters`
192
- - Output: Full chapter content for AI context with character names
193
- - Supports character filtering like `rag-search`
194
-
195
- - **`rag-characters`** - Get all characters that appear in chapters with a specific character
196
- - Input: `timeline`, `character` (character name)
197
- - Output: List of co-occurring characters sorted alphabetically
198
- - Use case: "Who does character X interact with?"
199
-
200
- ### Book Generation
201
- - **`book-generate`** - Generate PDF book from timeline content using LaTeX
202
- - Input: `timeline`, `outputPath`, optional: `episodes`, `format`
203
- - Output: PDF book with Victoria Regia template
204
- - Formats: `a4` (default), `a5`
205
- - Requirements: pandoc, LaTeX distribution (pdflatex/xelatex/lualatex)
206
- - Note: Content path is auto-discovered from timeline directory structure
130
+ ```
131
+ ┌─────────────────────────────────────────────────────────────┐
132
+ │ INDEXING PHASE │
133
+ ├─────────────────────────────────────────────────────────────┤
134
+ 1. Scan content/*.md (filesystem scanner)
135
+ 2. Parse frontmatter + content (gray-matter) │
136
+ │ 3. For each chapter: │
137
+ │ a. Extract entities/relations with Gemini API │
138
+ │ b. Generate embeddings (Transformers.js ONNX) │
139
+ │ c. Calculate word count and statistics │
140
+ 4. Save everything to LanceDB │
141
+ └─────────────────────────────────────────────────────────────┘
142
+ ```
207
143
 
208
144
  ## Development
209
145
 
210
- ### Scripts
211
-
212
146
  ```bash
147
+ # Install dependencies
148
+ npm install
149
+
213
150
  # Run tests
214
151
  npm test
215
152
 
216
153
  # Run tests with coverage
217
154
  npm run test:coverage
218
155
 
219
- # Build
220
- npm run build
221
-
222
156
  # Lint
223
157
  npm run lint
224
158
 
225
- # Fix linting issues
226
- npm run lint:format
227
- ```
228
-
229
- ### Tech Stack
230
-
231
- - **Language**: TypeScript (strict mode)
232
- - **Testing**: Vitest (90.71% coverage, 82 tests)
233
- - **Linting**: Biome (0 warnings)
234
- - **Build**: TypeScript compiler
159
+ # Type check
160
+ npm run typecheck
235
161
 
236
- ### Architecture
162
+ # Build
163
+ npm run build
164
+ ```
237
165
 
238
- - **MCP Protocol**: Standard Model Context Protocol implementation
239
- - **Database**: SQLite via @echoes-io/tracker (singleton pattern)
240
- - **Validation**: Zod schemas for type-safe inputs
241
- - **Testing**: Comprehensive unit and integration tests
242
- - **Timeline Parameter**: All tools accept timeline as a required parameter
166
+ ## Tech Stack
167
+
168
+ | Purpose | Tool |
169
+ |---------|------|
170
+ | Runtime | Node.js 20+ |
171
+ | Language | TypeScript |
172
+ | Vector DB | LanceDB |
173
+ | Embeddings | @huggingface/transformers (ONNX) |
174
+ | Entity Extraction | Gemini AI |
175
+ | MCP SDK | @modelcontextprotocol/sdk |
176
+ | Testing | Vitest |
177
+ | Linting | Biome |
243
178
 
244
179
  ## License
245
180
 
package/cli/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ #!/usr/bin/env node
2
+ export {};
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":""}
package/cli/index.js ADDED
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env node
2
+ import { program } from './program.js';
3
+ program.parse();
4
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":";AAEA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAEvC,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { Command } from '@commander-js/extra-typings';
2
+ export declare const program: Command<[], {}, {}>;
3
+ //# sourceMappingURL=program.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.d.ts","sourceRoot":"","sources":["program.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,6BAA6B,CAAC;AAYtD,eAAO,MAAM,OAAO,qBAGa,CAAC"}
package/cli/program.js ADDED
@@ -0,0 +1,150 @@
1
+ import { Command } from '@commander-js/extra-typings';
2
+ import { DEFAULT_DB_PATH } from '../lib/constants.js';
3
+ import { startServer } from '../lib/server.js';
4
+ import { index, indexConfig } from '../lib/tools/index.js';
5
+ import { search, searchConfig } from '../lib/tools/search.js';
6
+ import { stats, statsConfig } from '../lib/tools/stats.js';
7
+ import { wordsCount, wordsCountConfig } from '../lib/tools/words-count.js';
8
+ import { getPackageConfig } from '../lib/utils.js';
9
+ const packageConfig = getPackageConfig();
10
+ export const program = new Command()
11
+ .name(packageConfig.name)
12
+ .description(packageConfig.description)
13
+ .version(packageConfig.version);
14
+ program
15
+ .command(wordsCountConfig.name)
16
+ .description(wordsCountConfig.description)
17
+ .argument('<filePath...>', wordsCountConfig.arguments.filePath)
18
+ .option('-d, --detailed', wordsCountConfig.arguments.detailed)
19
+ .action(async (filePaths, { detailed }) => {
20
+ try {
21
+ filePaths.forEach((filePath, index) => {
22
+ const result = wordsCount({ filePath, detailed });
23
+ if (index > 0) {
24
+ console.log('');
25
+ }
26
+ console.log(`📄 ${filePath}\n`);
27
+ console.log(` 📝 Words: ${result.words.toLocaleString()}`);
28
+ console.log(` 🔤 Characters: ${result.characters.toLocaleString()}`);
29
+ console.log(` 🔡 Characters (no sp): ${result.charactersNoSpaces.toLocaleString()}`);
30
+ console.log(` ⏱️ Reading time: ${result.readingTimeMinutes} min`);
31
+ if (detailed) {
32
+ console.log(` 💬 Sentences: ${result.sentences?.toLocaleString()}`);
33
+ console.log(` 📃 Paragraphs: ${result.paragraphs?.toLocaleString()}`);
34
+ }
35
+ });
36
+ }
37
+ catch (error) {
38
+ console.error(`❌ Error: ${error.message}`);
39
+ process.exit(1);
40
+ }
41
+ });
42
+ program
43
+ .command(statsConfig.name)
44
+ .description(statsConfig.description)
45
+ .option('--db <path>', 'Database path', DEFAULT_DB_PATH)
46
+ .option('--arc <name>', statsConfig.arguments.arc)
47
+ .option('--pov <name>', statsConfig.arguments.pov)
48
+ .action(async ({ db, arc, pov }) => {
49
+ try {
50
+ const result = await stats({ arc, pov, dbPath: db });
51
+ console.log('📊 Timeline Statistics\n');
52
+ console.log(` 📚 Chapters: ${result.totalChapters.toLocaleString()}`);
53
+ console.log(` 📝 Total words: ${result.totalWords.toLocaleString()}`);
54
+ console.log(` 📈 Avg words/chapter: ${result.averageWordsPerChapter.toLocaleString()}`);
55
+ console.log(` 📁 Arcs: ${result.arcs.join(', ')}`);
56
+ console.log(' 👤 POVs:');
57
+ for (const [name, count] of Object.entries(result.povs).sort((a, b) => b[1] - a[1])) {
58
+ console.log(` - ${name}: ${count}`);
59
+ }
60
+ }
61
+ catch (error) {
62
+ console.error(`❌ Error: ${error.message}`);
63
+ process.exit(1);
64
+ }
65
+ });
66
+ program
67
+ .command(indexConfig.name)
68
+ .description(indexConfig.description)
69
+ .argument('<contentPath>', indexConfig.arguments.contentPath)
70
+ .option('--db <path>', 'Database path', DEFAULT_DB_PATH)
71
+ .option('--arc <name>', indexConfig.arguments.arc)
72
+ .option('--force', indexConfig.arguments.force)
73
+ .action(async (contentPath, { db, arc, force }) => {
74
+ try {
75
+ console.log('🔍 Indexing timeline...\n');
76
+ const result = await index({ contentPath, arc, force, dbPath: db });
77
+ console.log('✅ Indexing complete\n');
78
+ console.log(` 📖 Indexed: ${result.indexed}`);
79
+ console.log(` ⏭️ Skipped: ${result.skipped}`);
80
+ console.log(` 🗑️ Deleted: ${result.deleted}`);
81
+ console.log(` 👤 Entities: ${result.entities}`);
82
+ console.log(` 🔗 Relations: ${result.relations}`);
83
+ }
84
+ catch (error) {
85
+ console.error(`❌ Error: ${error.message}`);
86
+ process.exit(1);
87
+ }
88
+ });
89
+ program
90
+ .command(searchConfig.name)
91
+ .description(searchConfig.description)
92
+ .argument('<query>', searchConfig.arguments.query)
93
+ .option('--db <path>', 'Database path', DEFAULT_DB_PATH)
94
+ .option('--type <type>', searchConfig.arguments.type, 'chapters')
95
+ .option('--arc <name>', searchConfig.arguments.arc)
96
+ .option('--entity-type <type>', searchConfig.arguments.entityType)
97
+ .option('--relation-type <type>', searchConfig.arguments.relationType)
98
+ .option('--limit <n>', searchConfig.arguments.limit, '10')
99
+ .action(async (query, { db, type, arc, entityType, relationType, limit }) => {
100
+ try {
101
+ const result = await search({
102
+ query,
103
+ type: type,
104
+ arc,
105
+ entityType,
106
+ relationType,
107
+ limit: Number.parseInt(limit, 10),
108
+ dbPath: db,
109
+ });
110
+ if (result.type === 'chapters') {
111
+ console.log(`🔍 Found ${result.results.length} chapters\n`);
112
+ for (const ch of result.results) {
113
+ console.log(`📖 ${ch.id} - ${ch.title} (${ch.pov})`);
114
+ console.log(` Score: ${ch.score.toFixed(3)} | Words: ${ch.word_count}`);
115
+ console.log(` ${ch.content.slice(0, 100)}...`);
116
+ console.log('');
117
+ }
118
+ }
119
+ else if (result.type === 'entities') {
120
+ console.log(`🔍 Found ${result.results.length} entities\n`);
121
+ for (const e of result.results) {
122
+ console.log(`👤 ${e.name} (${e.type})`);
123
+ console.log(` ${e.description}`);
124
+ console.log(` Chapters: ${e.chapter_count} | Score: ${e.score.toFixed(3)}`);
125
+ console.log('');
126
+ }
127
+ }
128
+ else {
129
+ console.log(`🔍 Found ${result.results.length} relations\n`);
130
+ for (const r of result.results) {
131
+ console.log(`🔗 ${r.source_entity} → ${r.type} → ${r.target_entity}`);
132
+ console.log(` ${r.description}`);
133
+ console.log('');
134
+ }
135
+ }
136
+ }
137
+ catch (error) {
138
+ console.error(`❌ Error: ${error.message}`);
139
+ process.exit(1);
140
+ }
141
+ });
142
+ /* c8 ignore start */
143
+ program
144
+ .command('serve')
145
+ .description('Start MCP server (for AI assistant integration)')
146
+ .action(async () => {
147
+ await startServer();
148
+ });
149
+ /* c8 ignore stop */
150
+ //# sourceMappingURL=program.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"program.js","sourceRoot":"","sources":["program.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Application constants
3
+ */
4
+ export declare const DEFAULT_EMBEDDING_MODEL = "Xenova/e5-small-v2";
5
+ export declare const TEST_EMBEDDING_MODEL = "Xenova/e5-small-v2";
6
+ export declare const DEFAULT_GEMINI_MODEL = "gemini-2.5-flash";
7
+ export declare const DEFAULT_DB_PATH = "db";
8
+ //# sourceMappingURL=constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,eAAO,MAAM,uBAAuB,uBAAuB,CAAC;AAG5D,eAAO,MAAM,oBAAoB,uBAAuB,CAAC;AAGzD,eAAO,MAAM,oBAAoB,qBAAqB,CAAC;AAGvD,eAAO,MAAM,eAAe,OAAO,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Application constants
3
+ */
4
+ // Default embedding model for production
5
+ export const DEFAULT_EMBEDDING_MODEL = 'Xenova/e5-small-v2';
6
+ // Test embedding model (same as default for consistency)
7
+ export const TEST_EMBEDDING_MODEL = 'Xenova/e5-small-v2';
8
+ // Default Gemini model
9
+ export const DEFAULT_GEMINI_MODEL = 'gemini-2.5-flash';
10
+ // Default database path
11
+ export const DEFAULT_DB_PATH = 'db';
12
+ //# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.js","sourceRoot":"","sources":["constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,yCAAyC;AACzC,MAAM,CAAC,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AAE5D,yDAAyD;AACzD,MAAM,CAAC,MAAM,oBAAoB,GAAG,oBAAoB,CAAC;AAEzD,uBAAuB;AACvB,MAAM,CAAC,MAAM,oBAAoB,GAAG,kBAAkB,CAAC;AAEvD,wBAAwB;AACxB,MAAM,CAAC,MAAM,eAAe,GAAG,IAAI,CAAC"}
@@ -0,0 +1,34 @@
1
+ import { type Connection } from '@lancedb/lancedb';
2
+ import { type ChapterRecord, type EntityRecord, type RelationRecord } from './schemas.js';
3
+ export declare class Database {
4
+ readonly dbPath: string;
5
+ private db;
6
+ private tables;
7
+ private migrationChecked;
8
+ private metadata;
9
+ private tableConfigs;
10
+ private get metadataPath();
11
+ constructor(dbPath: string);
12
+ private getMetadata;
13
+ private getTableConfigs;
14
+ get embeddingModel(): string;
15
+ get embeddingDim(): number;
16
+ private getConnection;
17
+ private checkMigration;
18
+ private saveMetadata;
19
+ connect(): Promise<Connection>;
20
+ private getTable;
21
+ private upsert;
22
+ upsertChapters(records: ChapterRecord[]): Promise<number>;
23
+ upsertEntities(records: EntityRecord[]): Promise<number>;
24
+ upsertRelations(records: RelationRecord[]): Promise<number>;
25
+ getChapters(arc?: string): Promise<ChapterRecord[]>;
26
+ getChapterHashes(): Promise<Map<string, string>>;
27
+ deleteChaptersByPaths(paths: string[]): Promise<number>;
28
+ searchChapters(vector: number[], limit: number, arc?: string): Promise<ChapterRecord[]>;
29
+ searchEntities(vector: number[], limit: number, arc?: string, type?: string): Promise<EntityRecord[]>;
30
+ getEntities(arc?: string, type?: string): Promise<EntityRecord[]>;
31
+ getRelations(arc?: string, type?: string): Promise<RelationRecord[]>;
32
+ close(): void;
33
+ }
34
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,KAAK,UAAU,EAAuB,MAAM,kBAAkB,CAAC;AAMxE,OAAO,EACL,KAAK,aAAa,EAGlB,KAAK,YAAY,EACjB,KAAK,cAAc,EAEpB,MAAM,cAAc,CAAC;AActB,qBAAa,QAAQ;aAeS,MAAM,EAAE,MAAM;IAd1C,OAAO,CAAC,EAAE,CAA2B;IACrC,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,gBAAgB,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAyB;IACzC,OAAO,CAAC,YAAY,CAIJ;IAEhB,OAAO,KAAK,YAAY,GAEvB;gBAE2B,MAAM,EAAE,MAAM;YAE5B,WAAW;YAeX,eAAe;IAc7B,IAAI,cAAc,IAAI,MAAM,CAG3B;IAED,IAAI,YAAY,IAAI,MAAM,CAGzB;YAEa,aAAa;YAKb,cAAc;IAgD5B,OAAO,CAAC,YAAY;IAQd,OAAO,IAAI,OAAO,CAAC,UAAU,CAAC;YAKtB,QAAQ;YAeR,MAAM;IAWd,cAAc,CAAC,OAAO,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAKzD,cAAc,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAKxD,eAAe,CAAC,OAAO,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAK3D,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAgBnD,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAahD,qBAAqB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBvD,cAAc,CAAC,MAAM,EAAE,MAAM,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC;IAgBvF,cAAc,CAClB,MAAM,EAAE,MAAM,EAAE,EAChB,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,YAAY,EAAE,CAAC;IAmBpB,WAAW,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC;IAmBjE,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,EAAE,CAAC;IAmB1E,KAAK,IAAI,IAAI;CAId"}