@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
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.d.ts","sourceRoot":"","sources":["scanner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAG7D,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,cAAc,EAAE,CAAC;IAC3B,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAqBD,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,cAAc,CAyB9E;AAED,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,UAAU,CA4BhF"}
@@ -0,0 +1,73 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { readdirSync, readFileSync } from 'node:fs';
3
+ import { join, relative } from 'node:path';
4
+ import { parseChapter } from '../utils.js';
5
+ function computeHash(content) {
6
+ return createHash('sha256').update(content).digest('hex').slice(0, 16);
7
+ }
8
+ function scanDirectory(dir, pattern) {
9
+ const files = [];
10
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
11
+ const fullPath = join(dir, entry.name);
12
+ if (entry.isDirectory()) {
13
+ files.push(...scanDirectory(fullPath, pattern));
14
+ }
15
+ else if (entry.isFile() && pattern.test(entry.name)) {
16
+ files.push(fullPath);
17
+ }
18
+ }
19
+ return files;
20
+ }
21
+ export function scanChapter(filePath, basePath) {
22
+ const raw = readFileSync(filePath, 'utf-8');
23
+ const { metadata, content, stats } = parseChapter(raw);
24
+ if (!metadata.arc || !metadata.episode || !metadata.chapter || !metadata.pov || !metadata.title) {
25
+ throw new Error(`Missing required frontmatter in ${filePath}`);
26
+ }
27
+ return {
28
+ id: `${metadata.arc}:${metadata.episode}:${metadata.chapter}`,
29
+ file_path: relative(basePath, filePath),
30
+ file_hash: computeHash(raw),
31
+ arc: metadata.arc,
32
+ episode: metadata.episode,
33
+ chapter: metadata.chapter,
34
+ pov: metadata.pov,
35
+ title: metadata.title,
36
+ location: metadata.location ?? '',
37
+ date: metadata.date ?? '',
38
+ summary: metadata.summary ?? '',
39
+ content,
40
+ word_count: stats.wordCount,
41
+ char_count: stats.charCount,
42
+ paragraph_count: stats.paragraphCount,
43
+ };
44
+ }
45
+ export function scanTimeline(contentPath, arcFilter) {
46
+ const files = scanDirectory(contentPath, /\.md$/);
47
+ const chapters = [];
48
+ const arcsSet = new Set();
49
+ for (const file of files) {
50
+ try {
51
+ const chapter = scanChapter(file, contentPath);
52
+ if (arcFilter && chapter.arc !== arcFilter)
53
+ continue;
54
+ chapters.push(chapter);
55
+ arcsSet.add(chapter.arc);
56
+ }
57
+ catch {
58
+ // Skip files that fail to parse
59
+ }
60
+ }
61
+ chapters.sort((a, b) => {
62
+ if (a.arc !== b.arc)
63
+ return a.arc.localeCompare(b.arc);
64
+ if (a.episode !== b.episode)
65
+ return a.episode - b.episode;
66
+ return a.chapter - b.chapter;
67
+ });
68
+ return {
69
+ chapters,
70
+ arcs: [...arcsSet].sort(),
71
+ };
72
+ }
73
+ //# sourceMappingURL=scanner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scanner.js","sourceRoot":"","sources":["scanner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACpD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAG3C,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAO3C,SAAS,WAAW,CAAC,OAAe;IAClC,OAAO,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AACzE,CAAC;AAED,SAAS,aAAa,CAAC,GAAW,EAAE,OAAe;IACjD,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAC9D,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACvC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,GAAG,aAAa,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC;QAClD,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;YACtD,KAAK,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACvB,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,QAAgB,EAAE,QAAgB;IAC5D,MAAM,GAAG,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,KAAK,EAAE,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IAEvD,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAChG,MAAM,IAAI,KAAK,CAAC,mCAAmC,QAAQ,EAAE,CAAC,CAAC;IACjE,CAAC;IAED,OAAO;QACL,EAAE,EAAE,GAAG,QAAQ,CAAC,GAAG,IAAI,QAAQ,CAAC,OAAO,IAAI,QAAQ,CAAC,OAAO,EAAE;QAC7D,SAAS,EAAE,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;QACvC,SAAS,EAAE,WAAW,CAAC,GAAG,CAAC;QAC3B,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,OAAO,EAAE,QAAQ,CAAC,OAAO;QACzB,GAAG,EAAE,QAAQ,CAAC,GAAG;QACjB,KAAK,EAAE,QAAQ,CAAC,KAAK;QACrB,QAAQ,EAAE,QAAQ,CAAC,QAAQ,IAAI,EAAE;QACjC,IAAI,EAAE,QAAQ,CAAC,IAAI,IAAI,EAAE;QACzB,OAAO,EAAE,QAAQ,CAAC,OAAO,IAAI,EAAE;QAC/B,OAAO;QACP,UAAU,EAAE,KAAK,CAAC,SAAS;QAC3B,UAAU,EAAE,KAAK,CAAC,SAAS;QAC3B,eAAe,EAAE,KAAK,CAAC,cAAc;KACtC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,WAAmB,EAAE,SAAkB;IAClE,MAAM,KAAK,GAAG,aAAa,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAqB,EAAE,CAAC;IACtC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;YAE/C,IAAI,SAAS,IAAI,OAAO,CAAC,GAAG,KAAK,SAAS;gBAAE,SAAS;YAErD,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3B,CAAC;QAAC,MAAM,CAAC;YACP,gCAAgC;QAClC,CAAC;IACH,CAAC;IAED,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE;QACrB,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG;YAAE,OAAO,CAAC,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QACvD,IAAI,CAAC,CAAC,OAAO,KAAK,CAAC,CAAC,OAAO;YAAE,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;QAC1D,OAAO,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,OAAO,CAAC;IAC/B,CAAC,CAAC,CAAC;IAEH,OAAO;QACL,QAAQ;QACR,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,EAAE;KAC1B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,13 @@
1
+ import z from 'zod';
2
+ export interface PromptConfig {
3
+ name: string;
4
+ description: string;
5
+ args: z.ZodRawShape;
6
+ }
7
+ export declare const PROMPTS: PromptConfig[];
8
+ export interface GetPromptOptions {
9
+ timeline?: string;
10
+ contentPath?: string;
11
+ }
12
+ export declare function getPrompt(name: string, args: Record<string, string>, options?: GetPromptOptions): string;
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAGA,OAAO,CAAC,MAAM,KAAK,CAAC;AAEpB,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,CAAC,CAAC,WAAW,CAAC;CACrB;AAED,eAAO,MAAM,OAAO,EAAE,YAAY,EAuDjC,CAAC;AA6EF,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,wBAAgB,SAAS,CACvB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC5B,OAAO,GAAE,gBAAqB,GAC7B,MAAM,CAoCR"}
@@ -0,0 +1,153 @@
1
+ import { existsSync, readdirSync, readFileSync } from 'node:fs';
2
+ import { join } from 'node:path';
3
+ import z from 'zod';
4
+ export const PROMPTS = [
5
+ {
6
+ name: 'new-chapter',
7
+ description: 'Create a new chapter for a timeline arc',
8
+ args: {
9
+ arc: z.string().describe("Arc name (e.g., 'work', 'anima')"),
10
+ chapter: z.string().describe("Chapter number (e.g., '1', '12')"),
11
+ },
12
+ },
13
+ {
14
+ name: 'revise-chapter',
15
+ description: 'Revise an existing chapter with specific improvements',
16
+ args: {
17
+ arc: z.string().describe('Arc name'),
18
+ chapter: z.string().describe('Chapter number'),
19
+ },
20
+ },
21
+ {
22
+ name: 'expand-chapter',
23
+ description: 'Expand a chapter to reach target word count',
24
+ args: {
25
+ arc: z.string().describe('Arc name'),
26
+ chapter: z.string().describe('Chapter number'),
27
+ target: z.string().describe("Target word count (e.g., '4000')"),
28
+ },
29
+ },
30
+ {
31
+ name: 'new-character',
32
+ description: 'Create a new character sheet',
33
+ args: {
34
+ name: z.string().describe('Character name'),
35
+ },
36
+ },
37
+ {
38
+ name: 'new-episode',
39
+ description: 'Create a new episode outline',
40
+ args: {
41
+ arc: z.string().describe('Arc name'),
42
+ episode: z.string().describe('Episode number'),
43
+ },
44
+ },
45
+ {
46
+ name: 'new-arc',
47
+ description: 'Create a new story arc',
48
+ args: {
49
+ name: z.string().describe('Arc name (lowercase, no spaces)'),
50
+ },
51
+ },
52
+ {
53
+ name: 'revise-arc',
54
+ description: 'Review and fix an entire arc',
55
+ args: {
56
+ arc: z.string().describe('Arc name to revise'),
57
+ },
58
+ },
59
+ ];
60
+ function getGithubPromptsPath() {
61
+ const path = join(process.cwd(), '..', '.github', '.kiro', 'prompts');
62
+ return existsSync(path) ? path : null;
63
+ }
64
+ function getLocalPromptsPath() {
65
+ const path = join(process.cwd(), '.kiro', 'prompts');
66
+ return existsSync(path) ? path : null;
67
+ }
68
+ function getAvailableArcs(contentPath) {
69
+ if (!existsSync(contentPath))
70
+ return [];
71
+ return readdirSync(contentPath, { withFileTypes: true })
72
+ .filter((d) => d.isDirectory() && !d.name.startsWith('.'))
73
+ .map((d) => d.name)
74
+ .sort();
75
+ }
76
+ function validateArgs(promptName, args, contentPath) {
77
+ const arcs = getAvailableArcs(contentPath);
78
+ const requireArcExists = (arc) => {
79
+ if (!arcs.includes(arc)) {
80
+ throw new Error(`Arc "${arc}" not found. Available: ${arcs.join(', ') || 'none'}`);
81
+ }
82
+ };
83
+ const requireNumber = (value, name) => {
84
+ if (!/^\d+$/.test(value)) {
85
+ throw new Error(`${name} must be a number, got: "${value}"`);
86
+ }
87
+ };
88
+ switch (promptName) {
89
+ case 'new-chapter':
90
+ case 'revise-chapter':
91
+ case 'expand-chapter':
92
+ requireArcExists(args.arc);
93
+ requireNumber(args.chapter, 'Chapter');
94
+ if (promptName === 'expand-chapter') {
95
+ requireNumber(args.target, 'Target');
96
+ }
97
+ break;
98
+ case 'new-episode':
99
+ requireArcExists(args.arc);
100
+ requireNumber(args.episode, 'Episode');
101
+ break;
102
+ case 'new-arc':
103
+ if (arcs.includes(args.name)) {
104
+ throw new Error(`Arc "${args.name}" already exists.`);
105
+ }
106
+ break;
107
+ case 'revise-arc':
108
+ requireArcExists(args.arc);
109
+ break;
110
+ }
111
+ }
112
+ function substitutePlaceholders(template, args, timeline) {
113
+ const replacements = {
114
+ TIMELINE: timeline,
115
+ ...Object.fromEntries(Object.entries(args).map(([k, v]) => [k.toUpperCase(), v])),
116
+ };
117
+ let result = template;
118
+ for (const [key, value] of Object.entries(replacements)) {
119
+ result = result.replace(new RegExp(`\\{${key}\\}`, 'gi'), value);
120
+ }
121
+ return result;
122
+ }
123
+ export function getPrompt(name, args, options = {}) {
124
+ const timeline = options.timeline ?? 'timeline';
125
+ const contentPath = options.contentPath ?? 'content';
126
+ // Validate .github repo
127
+ const githubPath = getGithubPromptsPath();
128
+ if (!githubPath) {
129
+ throw new Error('.github repository not found.\n' +
130
+ 'Clone it as sibling: git clone https://github.com/echoes-io/.github ../.github');
131
+ }
132
+ // Read base template
133
+ const basePath = join(githubPath, `${name}.md`);
134
+ if (!existsSync(basePath)) {
135
+ throw new Error(`Prompt template not found: ${name}.md\nExpected: ${basePath}`);
136
+ }
137
+ const basePrompt = readFileSync(basePath, 'utf-8');
138
+ // Read optional local override
139
+ const localPath = getLocalPromptsPath();
140
+ let overridePrompt = '';
141
+ if (localPath) {
142
+ const overridePath = join(localPath, `${name}.md`);
143
+ if (existsSync(overridePath)) {
144
+ overridePrompt = readFileSync(overridePath, 'utf-8');
145
+ }
146
+ }
147
+ // Validate args
148
+ validateArgs(name, args, contentPath);
149
+ // Combine and substitute
150
+ const combined = overridePrompt ? `${basePrompt}\n\n---\n\n${overridePrompt}` : basePrompt;
151
+ return substitutePlaceholders(combined, args, timeline);
152
+ }
153
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ type ToolResult = {
3
+ content: Array<{
4
+ type: 'text';
5
+ text: string;
6
+ }>;
7
+ isError?: boolean;
8
+ };
9
+ export declare function formatError(err: unknown): ToolResult;
10
+ export declare function createServer(): McpServer;
11
+ export declare function startServer(): Promise<void>;
12
+ export {};
13
+ //# sourceMappingURL=server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAUpE,KAAK,UAAU,GAAG;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC;AAMxF,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,UAAU,CAGpD;AAED,wBAAgB,YAAY,IAAI,SAAS,CAoFxC;AAGD,wBAAsB,WAAW,IAAI,OAAO,CAAC,IAAI,CAAC,CAIjD"}
package/lib/server.js ADDED
@@ -0,0 +1,90 @@
1
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
3
+ import { getPrompt, PROMPTS } from './prompts/index.js';
4
+ import { index, indexConfig, indexSchema } from './tools/index.js';
5
+ import { search, searchConfig, searchSchema } from './tools/search.js';
6
+ import { stats, statsConfig, statsSchema } from './tools/stats.js';
7
+ import { wordsCount, wordsCountConfig, wordsCountSchema } from './tools/words-count.js';
8
+ import { getPackageConfig } from './utils.js';
9
+ function success(data) {
10
+ return { content: [{ type: 'text', text: JSON.stringify(data, null, 2) }] };
11
+ }
12
+ export function formatError(err) {
13
+ const message = err instanceof Error ? err.message : String(err);
14
+ return { content: [{ type: 'text', text: `Error: ${message}` }], isError: true };
15
+ }
16
+ export function createServer() {
17
+ const { description, name, version } = getPackageConfig();
18
+ const server = new McpServer({ name, description, version });
19
+ // Register tools
20
+ server.registerTool(wordsCountConfig.name, {
21
+ description: wordsCountConfig.description,
22
+ inputSchema: wordsCountSchema,
23
+ }, async (args) => {
24
+ try {
25
+ return success(wordsCount(args));
26
+ }
27
+ catch (err) {
28
+ return formatError(err);
29
+ }
30
+ });
31
+ server.registerTool(statsConfig.name, {
32
+ description: statsConfig.description,
33
+ inputSchema: statsSchema,
34
+ }, async (args) => {
35
+ try {
36
+ return success(await stats(args));
37
+ }
38
+ catch (err) {
39
+ return formatError(err);
40
+ }
41
+ });
42
+ server.registerTool(indexConfig.name, {
43
+ description: indexConfig.description,
44
+ inputSchema: indexSchema,
45
+ }, async (args) => {
46
+ try {
47
+ return success(await index(args));
48
+ }
49
+ catch (err) {
50
+ return formatError(err);
51
+ }
52
+ });
53
+ server.registerTool(searchConfig.name, {
54
+ description: searchConfig.description,
55
+ inputSchema: searchSchema,
56
+ /* v8 ignore start */
57
+ }, async (args) => {
58
+ try {
59
+ return success(await search(args));
60
+ }
61
+ catch (err) {
62
+ return formatError(err);
63
+ }
64
+ });
65
+ /* v8 ignore stop */
66
+ // Register prompts
67
+ for (const prompt of PROMPTS) {
68
+ server.prompt(prompt.name, prompt.description, prompt.args, (args) => {
69
+ try {
70
+ const text = getPrompt(prompt.name, args);
71
+ return { messages: [{ role: 'user', content: { type: 'text', text } }] };
72
+ }
73
+ catch (err) {
74
+ const message = err instanceof Error ? err.message : /* v8 ignore next */ String(err);
75
+ return {
76
+ messages: [{ role: 'user', content: { type: 'text', text: `Error: ${message}` } }],
77
+ };
78
+ }
79
+ });
80
+ }
81
+ return server;
82
+ }
83
+ /* v8 ignore start */
84
+ export async function startServer() {
85
+ const server = createServer();
86
+ const transport = new StdioServerTransport();
87
+ await server.connect(transport);
88
+ }
89
+ /* v8 ignore stop */
90
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import z from 'zod';
2
+ import type { ToolConfig } from '../types.js';
3
+ export declare const indexConfig: ToolConfig;
4
+ export declare const indexSchema: z.ZodObject<{
5
+ contentPath: z.ZodString;
6
+ arc: z.ZodOptional<z.ZodString>;
7
+ force: z.ZodOptional<z.ZodBoolean>;
8
+ dbPath: z.ZodDefault<z.ZodString>;
9
+ }, z.z.core.$strip>;
10
+ export type IndexInput = z.infer<typeof indexSchema>;
11
+ export interface IndexOutput {
12
+ indexed: number;
13
+ skipped: number;
14
+ deleted: number;
15
+ entities: number;
16
+ relations: number;
17
+ }
18
+ export declare function index(input: IndexInput): Promise<IndexOutput>;
19
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAQpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,WAAW,EAAE,UASzB,CAAC;AAEF,eAAO,MAAM,WAAW;;;;;mBAKtB,CAAC;AAEH,MAAM,MAAM,UAAU,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,CAAC;AAErD,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,wBAAsB,KAAK,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CA8HnE"}
@@ -0,0 +1,128 @@
1
+ import z from 'zod';
2
+ import { DEFAULT_DB_PATH } from '../constants.js';
3
+ import { Database } from '../database/index.js';
4
+ import { generateEmbedding } from '../indexer/embeddings.js';
5
+ import { extractEntities } from '../indexer/extractor.js';
6
+ import { scanTimeline } from '../indexer/scanner.js';
7
+ export const indexConfig = {
8
+ name: 'index',
9
+ description: 'Index timeline content into the database for semantic search.',
10
+ arguments: {
11
+ contentPath: 'Path to the content directory.',
12
+ arc: 'Filter by arc name (optional).',
13
+ force: 'Force re-indexing of all chapters.',
14
+ dbPath: `Database path (default: ${DEFAULT_DB_PATH}).`,
15
+ },
16
+ };
17
+ export const indexSchema = z.object({
18
+ contentPath: z.string().describe(indexConfig.arguments.contentPath),
19
+ arc: z.string().optional().describe(indexConfig.arguments.arc),
20
+ force: z.boolean().optional().describe(indexConfig.arguments.force),
21
+ dbPath: z.string().default(DEFAULT_DB_PATH).describe(indexConfig.arguments.dbPath),
22
+ });
23
+ export async function index(input) {
24
+ const { contentPath, arc, force = false, dbPath } = indexSchema.parse(input);
25
+ const db = new Database(dbPath);
26
+ await db.connect();
27
+ // 1. Scan filesystem
28
+ const { chapters: scanned } = scanTimeline(contentPath, arc);
29
+ // 2. Get existing hashes for incremental indexing
30
+ const existingHashes = await db.getChapterHashes();
31
+ // 3. Determine what needs indexing
32
+ const toIndex = scanned.filter((ch) => force || existingHashes.get(ch.file_path) !== ch.file_hash);
33
+ const skipped = scanned.length - toIndex.length;
34
+ // 4. Collect all entities and relations
35
+ const allEntities = new Map();
36
+ const allRelations = new Map();
37
+ // 5. Process chapters
38
+ for (const chapter of toIndex) {
39
+ // Generate embedding
40
+ const vector = await generateEmbedding(chapter.content, db.embeddingModel);
41
+ // Extract entities and relations
42
+ const { entities, relations } = await extractEntities(chapter.content);
43
+ // Build chapter record
44
+ const chapterRecord = {
45
+ ...chapter,
46
+ vector,
47
+ entities: entities.map((e) => `${chapter.arc}:${e.type}:${e.name}`),
48
+ indexed_at: Date.now(),
49
+ };
50
+ await db.upsertChapters([chapterRecord]);
51
+ // Aggregate entities
52
+ for (const entity of entities) {
53
+ const entityId = `${chapter.arc}:${entity.type}:${entity.name}`;
54
+ const existing = allEntities.get(entityId);
55
+ if (existing) {
56
+ existing.chapters.push(chapter.id);
57
+ existing.chapter_count++;
58
+ // Merge aliases
59
+ for (const alias of entity.aliases) {
60
+ if (!existing.aliases.includes(alias)) {
61
+ existing.aliases.push(alias);
62
+ }
63
+ }
64
+ }
65
+ else {
66
+ allEntities.set(entityId, {
67
+ id: entityId,
68
+ arc: chapter.arc,
69
+ name: entity.name,
70
+ type: entity.type,
71
+ description: entity.description,
72
+ aliases: entity.aliases,
73
+ vector: [], // Will be filled later
74
+ chapters: [chapter.id],
75
+ chapter_count: 1,
76
+ first_appearance: chapter.id,
77
+ indexed_at: Date.now(),
78
+ });
79
+ }
80
+ }
81
+ // Aggregate relations
82
+ for (const relation of relations) {
83
+ const relationId = `${chapter.arc}:${relation.source}:${relation.type}:${relation.target}`;
84
+ const existing = allRelations.get(relationId);
85
+ if (existing) {
86
+ if (!existing.chapters.includes(chapter.id)) {
87
+ existing.chapters.push(chapter.id);
88
+ }
89
+ }
90
+ else {
91
+ allRelations.set(relationId, {
92
+ id: relationId,
93
+ arc: chapter.arc,
94
+ source_entity: `${chapter.arc}:CHARACTER:${relation.source}`,
95
+ target_entity: `${chapter.arc}:CHARACTER:${relation.target}`,
96
+ type: relation.type,
97
+ description: relation.description,
98
+ weight: 0.5,
99
+ chapters: [chapter.id],
100
+ indexed_at: Date.now(),
101
+ });
102
+ }
103
+ }
104
+ }
105
+ // 6. Generate embeddings for entities and save
106
+ for (const entity of allEntities.values()) {
107
+ entity.vector = await generateEmbedding(`${entity.name}: ${entity.description}`, db.embeddingModel);
108
+ }
109
+ if (allEntities.size > 0) {
110
+ await db.upsertEntities([...allEntities.values()]);
111
+ }
112
+ if (allRelations.size > 0) {
113
+ await db.upsertRelations([...allRelations.values()]);
114
+ }
115
+ // 7. Delete removed chapters
116
+ const currentPaths = new Set(scanned.map((c) => c.file_path));
117
+ const toDelete = [...existingHashes.keys()].filter((p) => !currentPaths.has(p));
118
+ await db.deleteChaptersByPaths(toDelete);
119
+ db.close();
120
+ return {
121
+ indexed: toIndex.length,
122
+ skipped,
123
+ deleted: toDelete.length,
124
+ entities: allEntities.size,
125
+ relations: allRelations.size,
126
+ };
127
+ }
128
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,86 @@
1
+ import z from 'zod';
2
+ import type { ToolConfig } from '../types.js';
3
+ export declare const searchConfig: ToolConfig;
4
+ export declare const searchSchema: z.ZodObject<{
5
+ query: z.ZodString;
6
+ type: z.ZodDefault<z.ZodEnum<{
7
+ entities: "entities";
8
+ chapters: "chapters";
9
+ relations: "relations";
10
+ }>>;
11
+ arc: z.ZodOptional<z.ZodString>;
12
+ entityType: z.ZodOptional<z.ZodString>;
13
+ relationType: z.ZodOptional<z.ZodString>;
14
+ limit: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
15
+ dbPath: z.ZodDefault<z.ZodString>;
16
+ }, z.z.core.$strip>;
17
+ export type SearchInput = {
18
+ query: string;
19
+ type?: 'chapters' | 'entities' | 'relations';
20
+ arc?: string;
21
+ entityType?: string;
22
+ relationType?: string;
23
+ limit?: number;
24
+ dbPath?: string;
25
+ };
26
+ export interface ChapterResult {
27
+ id: string;
28
+ arc: string;
29
+ episode: number;
30
+ chapter: number;
31
+ pov: string;
32
+ title: string;
33
+ location: string;
34
+ content: string;
35
+ word_count: number;
36
+ score: number;
37
+ }
38
+ export interface EntityResult {
39
+ id: string;
40
+ arc: string;
41
+ name: string;
42
+ type: string;
43
+ description: string;
44
+ aliases: string[];
45
+ chapter_count: number;
46
+ score: number;
47
+ }
48
+ export interface RelationResult {
49
+ id: string;
50
+ arc: string;
51
+ source_entity: string;
52
+ target_entity: string;
53
+ type: string;
54
+ description: string;
55
+ chapters: string[];
56
+ }
57
+ export type SearchOutput = {
58
+ type: 'chapters';
59
+ results: ChapterResult[];
60
+ } | {
61
+ type: 'entities';
62
+ results: EntityResult[];
63
+ } | {
64
+ type: 'relations';
65
+ results: RelationResult[];
66
+ };
67
+ export declare function search(input: SearchInput & {
68
+ type: 'chapters';
69
+ }): Promise<{
70
+ type: 'chapters';
71
+ results: ChapterResult[];
72
+ }>;
73
+ export declare function search(input: SearchInput & {
74
+ type: 'entities';
75
+ }): Promise<{
76
+ type: 'entities';
77
+ results: EntityResult[];
78
+ }>;
79
+ export declare function search(input: SearchInput & {
80
+ type: 'relations';
81
+ }): Promise<{
82
+ type: 'relations';
83
+ results: RelationResult[];
84
+ }>;
85
+ export declare function search(input: SearchInput): Promise<SearchOutput>;
86
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["search.ts"],"names":[],"mappings":"AAAA,OAAO,CAAC,MAAM,KAAK,CAAC;AAMpB,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,eAAO,MAAM,YAAY,EAAE,UAY1B,CAAC;AAEF,eAAO,MAAM,YAAY;;;;;;;;;;;;mBAWvB,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED,MAAM,MAAM,YAAY,GACpB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,GAC7C;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC;AAGrD,wBAAsB,MAAM,CAC1B,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACxC,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,aAAa,EAAE,CAAA;CAAE,CAAC,CAAC;AAC3D,wBAAsB,MAAM,CAC1B,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACxC,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,OAAO,EAAE,YAAY,EAAE,CAAA;CAAE,CAAC,CAAC;AAC1D,wBAAsB,MAAM,CAC1B,KAAK,EAAE,WAAW,GAAG;IAAE,IAAI,EAAE,WAAW,CAAA;CAAE,GACzC,OAAO,CAAC;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC,CAAC;AAC7D,wBAAsB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC"}