extract_themes
Analyze manuscript content to identify and cluster main topics, helping writers organize and understand key themes in their writing projects.
Instructions
Cluster content into main themes/topics
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| project_path | No | Path to manuscript directory (defaults to current directory) | |
| scope | No | File scope pattern | |
| num_themes | No | Number of themes to extract |
Implementation Reference
- Defines the input schema and description for the extract_themes MCP tool.{ name: "extract_themes", description: "Cluster content into main themes/topics", inputSchema: { type: "object", properties: { project_path: { type: "string", description: "Path to manuscript directory (defaults to current directory)" }, scope: { type: "string", description: "File scope pattern" }, num_themes: { type: "number", description: "Number of themes to extract", default: 5 }, }, }, },
- src/tools/WriterToolHandlers.ts:123-128 (handler)The handler function that processes the tool call, parses arguments (scope, num_themes), and delegates to WritersAid.extractThemes.private async extractThemes(args: Record<string, unknown>) { const scope = args.scope as string | undefined; const numThemes = (args.num_themes as number) || 5; return this.writersAid.extractThemes({ scope, numThemes }); }
- src/tools/WriterToolHandlers.ts:18-19 (registration)Registers the extract_themes tool in the main handleTool switch statement, dispatching to the specific handler method.case "extract_themes": return this.extractThemes(args);
- src/search/ThemeExtractor.ts:15-39 (helper)Core implementation of theme extraction using simple word frequency counting from manuscript files.async extractThemes(options?: ThemeOptions) { const { numThemes = 5 } = options || {}; const files = await this.storage.getAllFiles(); const wordFreq = new Map<string, number>(); // Simple theme extraction based on word frequency for (const file of files) { const words = file.content.toLowerCase().match(/\b\w+\b/g) || []; for (const word of words) { if (word.length > 4) { // Skip short words wordFreq.set(word, (wordFreq.get(word) || 0) + 1); } } } // Get top themes const themes = Array.from(wordFreq.entries()) .sort((a, b) => b[1] - a[1]) .slice(0, numThemes) .map(([word, count]) => ({ theme: word, count })); return themes; }
- src/WritersAid.ts:191-193 (helper)Intermediate delegation layer in WritersAid class from tool handler to ThemeExtractor.async extractThemes(options?: { scope?: string; numThemes?: number }) { return this.themeExtractor.extractThemes(options); }