@echoes-io/mcp-server 1.2.0 → 1.3.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.
package/README.md CHANGED
@@ -40,7 +40,7 @@ Then configure:
40
40
  "env": {
41
41
  "ECHOES_TIMELINE": "your-timeline-name",
42
42
  "ECHOES_RAG_PROVIDER": "e5-small",
43
- "ECHOES_CHROMA_URL": "./rag_data"
43
+ "ECHOES_RAG_DB_PATH": "./rag_data.db"
44
44
  }
45
45
  }
46
46
  }
@@ -52,7 +52,7 @@ Then configure:
52
52
  **Optional RAG Configuration:**
53
53
  - `ECHOES_RAG_PROVIDER`: Embedding provider (`e5-small`, `e5-large`, or `gemini`). Default: `e5-small`
54
54
  - `ECHOES_GEMINI_API_KEY`: Required if using `gemini` provider
55
- - `ECHOES_CHROMA_URL`: ChromaDB storage path. Default: `./rag_data`
55
+ - `ECHOES_RAG_DB_PATH`: SQLite database path. Default: `./rag_data.db`
56
56
 
57
57
  ## Available Tools
58
58
 
@@ -108,6 +108,13 @@ All tools operate on the timeline specified by the `ECHOES_TIMELINE` environment
108
108
  - Input: `query`, optional: `arc`, `pov`, `maxChapters`
109
109
  - Output: Full chapter content for AI context
110
110
 
111
+ ### Book Generation
112
+ - **`book-generate`** - Generate PDF book from timeline content using LaTeX
113
+ - Input: `contentPath`, `outputPath`, optional: `episodes`, `format`
114
+ - Output: PDF book with Victoria Regia template
115
+ - Formats: `a4` (default), `a5`
116
+ - Requirements: pandoc, LaTeX distribution (pdflatex/xelatex/lualatex)
117
+
111
118
  ## Development
112
119
 
113
120
  ### Scripts
@@ -144,11 +151,6 @@ npm run lint:fix
144
151
  - **Testing**: Comprehensive unit and integration tests
145
152
  - **Environment**: Uses `ECHOES_TIMELINE` env var for timeline context
146
153
 
147
- ## Roadmap
148
-
149
- ### Planned Features
150
- - **Book generation** - LaTeX/PDF compilation tools for creating publishable books from timeline content
151
-
152
154
  ## License
153
155
 
154
156
  MIT
package/lib/server.js CHANGED
@@ -7,7 +7,7 @@ import { Server } from '@modelcontextprotocol/sdk/server/index.js';
7
7
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
8
8
  import { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';
9
9
  import { zodToJsonSchema } from 'zod-to-json-schema';
10
- import { chapterDelete, chapterDeleteSchema, chapterInfo, chapterInfoSchema, chapterInsert, chapterInsertSchema, chapterRefresh, chapterRefreshSchema, episodeInfo, episodeInfoSchema, episodeUpdate, episodeUpdateSchema, ragContext, ragContextSchema, ragIndex, ragIndexSchema, ragSearch, ragSearchSchema, stats, statsSchema, timelineSync, timelineSyncSchema, wordsCount, wordsCountSchema, } from './tools/index.js';
10
+ import { bookGenerate, bookGenerateSchema, chapterDelete, chapterDeleteSchema, chapterInfo, chapterInfoSchema, chapterInsert, chapterInsertSchema, chapterRefresh, chapterRefreshSchema, episodeInfo, episodeInfoSchema, episodeUpdate, episodeUpdateSchema, ragContext, ragContextSchema, ragIndex, ragIndexSchema, ragSearch, ragSearchSchema, stats, statsSchema, timelineSync, timelineSyncSchema, wordsCount, wordsCountSchema, } from './tools/index.js';
11
11
  const __dirname = dirname(fileURLToPath(import.meta.url));
12
12
  const pkg = JSON.parse(readFileSync(join(__dirname, '../package.json'), 'utf-8'));
13
13
  export function createServer(tracker, rag) {
@@ -82,6 +82,11 @@ export function createServer(tracker, rag) {
82
82
  description: 'Retrieve relevant context for AI interactions',
83
83
  inputSchema: zodToJsonSchema(ragContextSchema),
84
84
  },
85
+ {
86
+ name: 'book-generate',
87
+ description: 'Generate PDF book from timeline content using LaTeX',
88
+ inputSchema: zodToJsonSchema(bookGenerateSchema),
89
+ },
85
90
  ],
86
91
  };
87
92
  });
@@ -112,6 +117,8 @@ export function createServer(tracker, rag) {
112
117
  return await ragSearch(ragSearchSchema.parse(args), rag);
113
118
  case 'rag-context':
114
119
  return await ragContext(ragContextSchema.parse(args), rag);
120
+ case 'book-generate':
121
+ return await bookGenerate(bookGenerateSchema.parse(args));
115
122
  default:
116
123
  throw new Error(`Unknown tool: ${name}`);
117
124
  }
@@ -125,14 +132,15 @@ export async function runServer() {
125
132
  await tracker.init();
126
133
  console.error(`Tracker database initialized: ${dbPath}`);
127
134
  // Initialize RAG system
128
- const chromaUrl = process.env.ECHOES_CHROMA_URL || (process.env.NODE_ENV === 'test' ? ':memory:' : './rag_data');
135
+ const ragDbPath = process.env.ECHOES_RAG_DB_PATH ||
136
+ (process.env.NODE_ENV === 'test' ? ':memory:' : './rag_data.db');
129
137
  const provider = (process.env.ECHOES_RAG_PROVIDER || 'e5-small');
130
138
  const rag = new RAGSystem({
131
139
  provider,
132
- chromaUrl,
140
+ dbPath: ragDbPath,
133
141
  geminiApiKey: process.env.ECHOES_GEMINI_API_KEY,
134
142
  });
135
- console.error(`RAG system initialized: ${chromaUrl} (provider: ${provider})`);
143
+ console.error(`RAG system initialized: ${ragDbPath} (provider: ${provider})`);
136
144
  const server = createServer(tracker, rag);
137
145
  const transport = new StdioServerTransport();
138
146
  await server.connect(transport);
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ export declare const bookGenerateSchema: z.ZodObject<{
3
+ contentPath: z.ZodString;
4
+ outputPath: z.ZodString;
5
+ episodes: z.ZodOptional<z.ZodString>;
6
+ format: z.ZodOptional<z.ZodEnum<["a4", "a5"]>>;
7
+ }, "strip", z.ZodTypeAny, {
8
+ contentPath: string;
9
+ outputPath: string;
10
+ episodes?: string | undefined;
11
+ format?: "a4" | "a5" | undefined;
12
+ }, {
13
+ contentPath: string;
14
+ outputPath: string;
15
+ episodes?: string | undefined;
16
+ format?: "a4" | "a5" | undefined;
17
+ }>;
18
+ export declare function bookGenerate(args: z.infer<typeof bookGenerateSchema>): Promise<{
19
+ content: {
20
+ type: "text";
21
+ text: string;
22
+ }[];
23
+ }>;
@@ -0,0 +1,38 @@
1
+ import { generateBook } from '@echoes-io/books-generator';
2
+ import { z } from 'zod';
3
+ import { getTimeline } from '../utils.js';
4
+ export const bookGenerateSchema = z.object({
5
+ contentPath: z.string().describe('Path to timeline content folder'),
6
+ outputPath: z.string().describe('Output PDF file path'),
7
+ episodes: z.string().optional().describe('Comma-separated episode numbers (e.g., "1,2,3")'),
8
+ format: z.enum(['a4', 'a5']).optional().describe('Page format (default: a4)'),
9
+ });
10
+ export async function bookGenerate(args) {
11
+ try {
12
+ const timeline = getTimeline();
13
+ await generateBook({
14
+ contentPath: args.contentPath,
15
+ outputPath: args.outputPath,
16
+ timeline,
17
+ episodes: args.episodes,
18
+ format: args.format || 'a4',
19
+ });
20
+ return {
21
+ content: [
22
+ {
23
+ type: 'text',
24
+ text: JSON.stringify({
25
+ success: true,
26
+ timeline,
27
+ outputPath: args.outputPath,
28
+ episodes: args.episodes || 'all',
29
+ format: args.format || 'a4',
30
+ }, null, 2),
31
+ },
32
+ ],
33
+ };
34
+ }
35
+ catch (error) {
36
+ throw new Error(`Failed to generate book: ${error instanceof Error ? error.message : 'Unknown error'}`);
37
+ }
38
+ }
@@ -1,3 +1,4 @@
1
+ export { bookGenerate, bookGenerateSchema } from './book-generate.js';
1
2
  export { chapterDelete, chapterDeleteSchema } from './chapter-delete.js';
2
3
  export { chapterInfo, chapterInfoSchema } from './chapter-info.js';
3
4
  export { chapterInsert, chapterInsertSchema } from './chapter-insert.js';
@@ -1,3 +1,4 @@
1
+ export { bookGenerate, bookGenerateSchema } from './book-generate.js';
1
2
  export { chapterDelete, chapterDeleteSchema } from './chapter-delete.js';
2
3
  export { chapterInfo, chapterInfoSchema } from './chapter-info.js';
3
4
  export { chapterInsert, chapterInsertSchema } from './chapter-insert.js';
@@ -35,7 +35,7 @@ export async function ragSearch(args, rag) {
35
35
  title: r.metadata.title,
36
36
  },
37
37
  similarity: r.similarity,
38
- preview: r.content.substring(0, 200) + '...',
38
+ preview: `${r.content.substring(0, 200)}...`,
39
39
  })),
40
40
  }, null, 2),
41
41
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@echoes-io/mcp-server",
3
3
  "type": "module",
4
- "version": "1.2.0",
4
+ "version": "1.3.0",
5
5
  "description": "Model Context Protocol server for AI integration with Echoes storytelling platform",
6
6
  "scripts": {
7
7
  "dev": "tsx cli/index.ts",
@@ -81,8 +81,9 @@
81
81
  "vitest": "^3.2.4"
82
82
  },
83
83
  "dependencies": {
84
+ "@echoes-io/books-generator": "^1.0.0",
84
85
  "@echoes-io/models": "^1.0.0",
85
- "@echoes-io/rag": "^1.0.0",
86
+ "@echoes-io/rag": "^1.1.0",
86
87
  "@echoes-io/tracker": "^1.0.0",
87
88
  "@echoes-io/utils": "^1.1.1",
88
89
  "@modelcontextprotocol/sdk": "^1.0.0"