Skip to main content
Glama
mcp-server.js•161 kB
#!/usr/bin/env node /** * Office Whisperer - MCP Server v4.0 * 143 Professional Tools for Microsoft Office Suite Automation * Control Excel, Word, PowerPoint, and Outlook through natural language with Claude Desktop */ import { ExcelGenerator } from './generators/excel-generator.js'; import { WordGenerator } from './generators/word-generator.js'; import { PowerPointGenerator } from './generators/powerpoint-generator.js'; import { OutlookGenerator } from './generators/outlook-generator.js'; import * as fs from 'fs/promises'; import * as path from 'path'; class OfficeWhispererServer { excelGen = new ExcelGenerator(); wordGen = new WordGenerator(); pptGen = new PowerPointGenerator(); outlookGen = new OutlookGenerator(); tools = [ // ========== EXCEL TOOLS (21 tools) ========== { name: 'create_excel', description: 'šŸ“Š Create Excel workbook with sheets, data, formulas, and charts', inputSchema: { type: 'object', properties: { filename: { type: 'string', description: 'Output filename (e.g., "report.xlsx")' }, sheets: { type: 'array', description: 'Array of sheet configurations' }, outputPath: { type: 'string', description: 'Optional output directory' }, }, required: ['filename', 'sheets'], }, }, { name: 'excel_add_pivot_table', description: 'šŸ“ˆ Add pivot table with rows, columns, values, and filters', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, pivotTable: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'pivotTable'], }, }, { name: 'excel_add_chart', description: 'šŸ“‰ Add chart (line/bar/pie/scatter/area) with customization', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, chart: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'chart'], }, }, { name: 'excel_add_formula', description: 'šŸ”¢ Add formulas (VLOOKUP, SUMIF, INDEX/MATCH, IF, etc)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, formulas: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'formulas'], }, }, { name: 'excel_conditional_formatting', description: 'šŸŽØ Apply conditional formatting (color scales, data bars, icon sets)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, range: { type: 'string' }, rules: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'range', 'rules'], }, }, { name: 'excel_data_validation', description: 'āœ… Add dropdown lists and validation rules', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, range: { type: 'string' }, validation: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'range', 'validation'], }, }, { name: 'excel_freeze_panes', description: 'ā„ļø Freeze rows/columns for scrolling', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, row: { type: 'number' }, column: { type: 'number' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName'], }, }, { name: 'excel_filter_sort', description: 'šŸ” Apply AutoFilter and sorting', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, range: { type: 'string' }, sortBy: { type: 'array' }, autoFilter: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName'], }, }, { name: 'excel_format_cells', description: '✨ Format cells (fonts, colors, borders, alignment, number formats)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, range: { type: 'string' }, style: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'range', 'style'], }, }, { name: 'excel_named_range', description: 'šŸ·ļø Create and manage named ranges', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, name: { type: 'string' }, range: { type: 'string' }, sheetName: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'name', 'range'], }, }, { name: 'excel_protect_sheet', description: 'šŸ”’ Protect worksheets with passwords', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, password: { type: 'string' }, options: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName'], }, }, { name: 'excel_merge_workbooks', description: 'šŸ”— Merge multiple Excel files', inputSchema: { type: 'object', properties: { files: { type: 'array' }, outputFilename: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['files', 'outputFilename'], }, }, { name: 'excel_find_replace', description: 'šŸ”Ž Find and replace values/formulas', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, find: { type: 'string' }, replace: { type: 'string' }, matchCase: { type: 'boolean' }, matchEntireCell: { type: 'boolean' }, searchFormulas: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename', 'find', 'replace'], }, }, { name: 'excel_to_json', description: 'šŸ“‹ Export Excel to JSON format', inputSchema: { type: 'object', properties: { excelPath: { type: 'string' }, sheetName: { type: 'string' }, outputPath: { type: 'string' }, header: { type: 'boolean' }, }, required: ['excelPath'], }, }, { name: 'excel_to_csv', description: 'šŸ“„ Convert Excel to CSV format', inputSchema: { type: 'object', properties: { excelPath: { type: 'string' }, sheetName: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['excelPath'], }, }, { name: 'excel_add_sparklines', description: '✨ Add sparklines (mini charts in cells)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, dataRange: { type: 'string' }, location: { type: 'string' }, type: { type: 'string', enum: ['line', 'column', 'winLoss'] }, options: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'dataRange', 'location', 'type'], }, }, { name: 'excel_array_formulas', description: 'šŸ”¢ Add dynamic array formulas (UNIQUE, SORT, FILTER)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, formulas: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'formulas'], }, }, { name: 'excel_add_subtotals', description: 'šŸ“Š Add subtotals with grouping', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, range: { type: 'string' }, groupBy: { type: 'number' }, summaryFunction: { type: 'string', enum: ['SUM', 'COUNT', 'AVERAGE', 'MAX', 'MIN'] }, summaryColumns: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'range', 'groupBy', 'summaryFunction', 'summaryColumns'], }, }, { name: 'excel_add_hyperlinks', description: 'šŸ”— Add hyperlinks to cells (URLs or internal links)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, links: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'links'], }, }, { name: 'excel_advanced_charts', description: 'šŸ“ˆ Create advanced charts (waterfall, funnel, treemap, sunburst)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, chart: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'chart'], }, }, { name: 'excel_add_slicers', description: 'šŸŽ›ļø Add slicers for tables/pivot tables', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, tableName: { type: 'string' }, slicers: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'tableName', 'slicers'], }, }, { name: 'excel_power_query', description: 'šŸ“Š Power Query transformations (filter, sort, merge, pivot)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, queryName: { type: 'string' }, source: { type: 'object' }, transformations: { type: 'array' }, loadTo: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'queryName', 'source'], }, }, { name: 'excel_goal_seek', description: 'šŸŽÆ Goal Seek what-if analysis to find input value', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, setCell: { type: 'string' }, toValue: { type: 'number' }, byChangingCell: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'setCell', 'toValue', 'byChangingCell'], }, }, { name: 'excel_data_table', description: 'šŸ“Š Create one/two variable data tables for scenarios', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, type: { type: 'string', enum: ['oneVariable', 'twoVariable'] }, formulaCell: { type: 'string' }, rowInputCell: { type: 'string' }, columnInputCell: { type: 'string' }, outputRange: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'type', 'formulaCell', 'outputRange'], }, }, { name: 'excel_scenario_manager', description: 'šŸ“ˆ Scenario Manager with multiple what-if scenarios', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, scenarios: { type: 'array' }, resultCells: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'scenarios'], }, }, { name: 'excel_create_table', description: 'šŸ“Š Create Excel Tables with styles and features', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, tableName: { type: 'string' }, range: { type: 'string' }, hasHeaders: { type: 'boolean' }, style: { type: 'string' }, showTotalRow: { type: 'boolean' }, showFilterButton: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'tableName', 'range'], }, }, { name: 'excel_table_formula', description: 'šŸ“Š Add table structured reference formulas', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, tableName: { type: 'string' }, columnName: { type: 'string' }, formula: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'tableName', 'columnName', 'formula'], }, }, { name: 'excel_form_controls', description: 'šŸ“Š Add form controls (button, checkbox, dropdown, spinner)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, controls: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'controls'], }, }, { name: 'excel_insert_images', description: 'šŸ“Š Insert and position images in worksheets', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, images: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'images'], }, }, { name: 'excel_insert_shapes', description: 'šŸ“Š Insert shapes and connectors', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, shapes: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'shapes'], }, }, { name: 'excel_smart_art', description: 'šŸ“Š Insert SmartArt graphics (list, process, hierarchy)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, smartArt: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'smartArt'], }, }, { name: 'excel_page_setup', description: 'šŸ“Š Page setup (orientation, margins, print area)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, pageSetup: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'pageSetup'], }, }, { name: 'excel_header_footer', description: 'šŸ“Š Headers and footers with special codes', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, header: { type: 'object' }, footer: { type: 'object' }, differentFirstPage: { type: 'boolean' }, differentOddEven: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName'], }, }, { name: 'excel_page_breaks', description: 'šŸ“Š Configure page breaks for printing', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, horizontalBreaks: { type: 'array' }, verticalBreaks: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName'], }, }, { name: 'excel_track_changes', description: 'šŸ“Š Track changes and highlight modifications', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, enable: { type: 'boolean' }, highlightChanges: { type: 'boolean' }, listChangesOnNewSheet: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename', 'enable'], }, }, { name: 'excel_share_workbook', description: 'šŸ“Š Configure workbook sharing settings', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, share: { type: 'boolean' }, allowChanges: { type: 'boolean' }, protectSharing: { type: 'boolean' }, password: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'share'], }, }, { name: 'excel_compare_versions', description: 'šŸ“Š Compare two Excel files and highlight differences', inputSchema: { type: 'object', properties: { originalFile: { type: 'string' }, revisedFile: { type: 'string' }, outputPath: { type: 'string' }, highlightDifferences: { type: 'boolean' }, }, required: ['originalFile', 'revisedFile'], }, }, { name: 'excel_add_comments', description: 'šŸ“Š Add cell comments with author information', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sheetName: { type: 'string' }, comments: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sheetName', 'comments'], }, }, // ========== WORD TOOLS (16 tools) ========== { name: 'create_word', description: 'šŸ“ Create Word document with paragraphs, tables, images, and formatting', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, title: { type: 'string' }, sections: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sections'], }, }, { name: 'word_add_toc', description: 'šŸ“‘ Add table of contents', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, outputPath: { type: 'string' }, title: { type: 'string' }, hyperlinks: { type: 'boolean' }, levels: { type: 'number' }, }, required: ['filename'], }, }, { name: 'word_mail_merge', description: 'āœ‰ļø Mail merge with data source', inputSchema: { type: 'object', properties: { templatePath: { type: 'string' }, dataSource: { type: 'array' }, outputPath: { type: 'string' }, outputFilename: { type: 'string' }, }, required: ['templatePath', 'dataSource'], }, }, { name: 'word_find_replace', description: 'šŸ” Find and replace text with formatting', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, find: { type: 'string' }, replace: { type: 'string' }, matchCase: { type: 'boolean' }, matchWholeWord: { type: 'boolean' }, formatting: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'find', 'replace'], }, }, { name: 'word_add_comment', description: 'šŸ’¬ Add comments and track changes', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, text: { type: 'string' }, comment: { type: 'string' }, author: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'text', 'comment'], }, }, { name: 'word_format_styles', description: 'šŸŽØ Apply and customize styles/themes', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, styles: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'styles'], }, }, { name: 'word_insert_image', description: 'šŸ–¼ļø Insert and position images with wrapping', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, imagePath: { type: 'string' }, position: { type: 'object' }, size: { type: 'object' }, wrapping: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'imagePath'], }, }, { name: 'word_add_header_footer', description: 'šŸ“„ Customize headers/footers per section', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, type: { type: 'string', enum: ['header', 'footer'] }, content: { type: 'array' }, sectionType: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'type', 'content'], }, }, { name: 'word_compare_documents', description: 'šŸ”„ Compare two documents and show differences', inputSchema: { type: 'object', properties: { originalPath: { type: 'string' }, revisedPath: { type: 'string' }, outputPath: { type: 'string' }, author: { type: 'string' }, }, required: ['originalPath', 'revisedPath'], }, }, { name: 'word_to_pdf', description: 'šŸ“‘ Export Word document to PDF', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename'], }, }, { name: 'word_track_changes', description: 'āœļø Enable/disable track changes', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, enable: { type: 'boolean' }, author: { type: 'string' }, showMarkup: { type: 'boolean' }, trackFormatting: { type: 'boolean' }, trackMoves: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename', 'enable'], }, }, { name: 'word_add_footnotes', description: 'šŸ“Œ Add footnotes and endnotes', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, footnotes: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'footnotes'], }, }, { name: 'word_add_bookmarks', description: 'šŸ”– Add bookmarks to text', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, bookmarks: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'bookmarks'], }, }, { name: 'word_add_section_breaks', description: 'šŸ“„ Add section breaks (next page, continuous, even/odd page)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, breaks: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'breaks'], }, }, { name: 'word_add_text_boxes', description: 'šŸ“¦ Add text boxes with positioning', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, textBoxes: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'textBoxes'], }, }, { name: 'word_add_cross_references', description: 'šŸ”— Add cross-references to bookmarks', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, references: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'references'], }, }, { name: 'word_bibliography', description: 'šŸ“„ Create bibliography (APA, MLA, Chicago, Harvard, IEEE)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sources: { type: 'array' }, style: { type: 'string', enum: ['APA', 'MLA', 'Chicago', 'Harvard', 'IEEE'] }, insertAt: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'sources'], }, }, { name: 'word_citations', description: 'šŸ“„ Insert citations with page numbers', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, citations: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'citations'], }, }, { name: 'word_index', description: 'šŸ“„ Generate index with entries and subentries', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, entries: { type: 'array' }, title: { type: 'string' }, columns: { type: 'number' }, insertAt: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'entries'], }, }, { name: 'word_mark_index_entry', description: 'šŸ“„ Mark text for index inclusion', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, textToMark: { type: 'string' }, entryText: { type: 'string' }, crossReference: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'textToMark'], }, }, { name: 'word_form_fields', description: 'šŸ“„ Add form fields (text, checkbox, dropdown, date)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, fields: { type: 'array' }, protectForm: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename', 'fields'], }, }, { name: 'word_content_controls', description: 'šŸ“„ Add content controls (rich text, dropdown, date picker)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, controls: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'controls'], }, }, { name: 'word_smart_art', description: 'šŸ“„ Insert SmartArt (process, hierarchy, relationship)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, smartArt: { type: 'object' }, position: { type: 'number' }, outputPath: { type: 'string' }, }, required: ['filename', 'smartArt'], }, }, { name: 'word_equations', description: 'šŸ“„ Insert equations (LaTeX, MathML, linear format)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, equations: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'equations'], }, }, { name: 'word_symbols', description: 'šŸ“„ Insert special characters and symbols', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, symbols: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'symbols'], }, }, { name: 'word_accessibility_check', description: 'šŸ“„ Check document accessibility compliance', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, checks: { type: 'object' }, autoFix: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename', 'checks'], }, }, { name: 'word_alt_text', description: 'šŸ“„ Add alt text to images for accessibility', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, altTexts: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'altTexts'], }, }, { name: 'word_digital_signature', description: 'šŸ“„ Add or verify digital signatures', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, action: { type: 'string', enum: ['add', 'remove', 'verify'] }, certificatePath: { type: 'string' }, password: { type: 'string' }, reason: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'action'], }, }, { name: 'word_protect_document', description: 'šŸ“„ Protect document (read-only, forms, tracked changes)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, protection: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'protection'], }, }, { name: 'word_master_document', description: 'šŸ“„ Create master document with subdocuments', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, subdocuments: { type: 'array' }, generateTOC: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename', 'subdocuments'], }, }, { name: 'word_document_info', description: 'šŸ“„ Set document metadata (author, title, keywords)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, info: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'info'], }, }, { name: 'word_captions', description: 'šŸ“„ Add figure and table captions', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, captions: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'captions'], }, }, { name: 'word_advanced_hyperlinks', description: 'šŸ“„ Add advanced hyperlinks with tooltips', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, hyperlinks: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'hyperlinks'], }, }, { name: 'word_drop_cap', description: 'šŸ“„ Add drop cap formatting to paragraphs', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, paragraphIndex: { type: 'number' }, style: { type: 'string', enum: ['dropped', 'inMargin'] }, lines: { type: 'number' }, outputPath: { type: 'string' }, }, required: ['filename', 'paragraphIndex', 'style'], }, }, { name: 'word_watermark', description: 'šŸ“„ Add text or image watermark', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, watermark: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'watermark'], }, }, // ========== POWERPOINT TOOLS (13 tools) ========== { name: 'create_powerpoint', description: 'šŸŽ¬ Create PowerPoint presentation with slides, text, images, and charts', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, title: { type: 'string' }, theme: { type: 'string', enum: ['default', 'light', 'dark', 'colorful'] }, slides: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slides'], }, }, { name: 'ppt_add_transition', description: '✨ Add slide transitions (fade, push, wipe, etc)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, transition: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'transition'], }, }, { name: 'ppt_add_animation', description: 'šŸŽ­ Add animations to objects (entrance, emphasis, exit)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, objectId: { type: 'string' }, animation: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'animation'], }, }, { name: 'ppt_add_notes', description: 'šŸ“ Add/edit speaker notes', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, notes: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'notes'], }, }, { name: 'ppt_duplicate_slide', description: 'šŸ“‹ Duplicate slides', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, position: { type: 'number' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber'], }, }, { name: 'ppt_reorder_slides', description: 'šŸ”€ Reorder slide sequence', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideOrder: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideOrder'], }, }, { name: 'ppt_export_pdf', description: 'šŸ“‘ Export presentation to PDF', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['filename'], }, }, { name: 'ppt_add_media', description: 'šŸŽ„ Embed video/audio', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, mediaPath: { type: 'string' }, mediaType: { type: 'string', enum: ['video', 'audio'] }, position: { type: 'object' }, size: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'mediaPath', 'mediaType'], }, }, { name: 'ppt_define_master_slide', description: 'šŸŽØ Define custom master slide templates', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, masterSlide: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'masterSlide'], }, }, { name: 'ppt_add_hyperlinks', description: 'šŸ”— Add hyperlinks to text/objects (URLs or slide links)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, links: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'links'], }, }, { name: 'ppt_add_sections', description: 'šŸ“ Organize slides into sections', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, sections: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'sections'], }, }, { name: 'ppt_morph_transition', description: '✨ Add morph transition between slides', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, fromSlide: { type: 'number' }, toSlide: { type: 'number' }, duration: { type: 'number' }, outputPath: { type: 'string' }, }, required: ['filename', 'fromSlide', 'toSlide'], }, }, { name: 'ppt_add_action_buttons', description: 'šŸ”˜ Add interactive action buttons', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, buttons: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'buttons'], }, }, { name: 'ppt_smart_art', description: 'šŸŽÆ SmartArt graphics (list, process, hierarchy, cycle)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, smartArt: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'smartArt'], }, }, { name: 'ppt_insert_icons', description: 'šŸŽÆ Insert Microsoft SVG icons from library', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, icons: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'icons'], }, }, { name: 'ppt_3d_models', description: 'šŸŽÆ Insert 3D models (.glb, .fbx)', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, models: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'models'], }, }, { name: 'ppt_zoom', description: 'šŸŽÆ Summary/Slide/Section Zoom navigation', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, zooms: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'zooms'], }, }, { name: 'ppt_recording', description: 'šŸŽÆ Screen recording configuration', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, recording: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'recording'], }, }, { name: 'ppt_live_web', description: 'šŸŽÆ Embed live web page in slide', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, webPages: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'webPages'], }, }, { name: 'ppt_designer', description: 'šŸŽÆ PowerPoint Designer suggestions', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, preferences: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename'], }, }, { name: 'ppt_collaboration', description: 'šŸŽÆ Add comments and @mentions', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, comments: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'comments'], }, }, { name: 'ppt_presenter_coach', description: 'šŸŽÆ Presenter Coach rehearsal settings', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, settings: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'settings'], }, }, { name: 'ppt_subtitles', description: 'šŸŽÆ Live subtitles and captions configuration', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, subtitles: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'subtitles'], }, }, { name: 'ppt_ink_annotations', description: 'šŸŽÆ Digital ink drawings and annotations', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, annotations: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'annotations'], }, }, { name: 'ppt_grid_guides', description: 'šŸŽÆ Grids and guides for alignment', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, grid: { type: 'object' }, guides: { type: 'object' }, smartGuides: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['filename'], }, }, { name: 'ppt_custom_show', description: 'šŸŽÆ Create custom slide shows', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, shows: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'shows'], }, }, { name: 'ppt_animation_pane', description: 'šŸŽÆ Animation pane for timing and order', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, slideNumber: { type: 'number' }, animations: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['filename', 'slideNumber', 'animations'], }, }, { name: 'ppt_slide_master_advanced', description: 'šŸŽÆ Advanced slide master customization', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, master: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'master'], }, }, { name: 'ppt_theme', description: 'šŸŽÆ Apply and customize themes', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, theme: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'theme'], }, }, { name: 'ppt_template', description: 'šŸŽÆ Save as template with placeholders', inputSchema: { type: 'object', properties: { filename: { type: 'string' }, template: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['filename', 'template'], }, }, // ========== OUTLOOK TOOLS (13 tools) ========== { name: 'outlook_send_email', description: 'šŸ“§ Send emails with attachments', inputSchema: { type: 'object', properties: { to: { type: 'string' }, subject: { type: 'string' }, body: { type: 'string' }, cc: { type: 'string' }, bcc: { type: 'string' }, attachments: { type: 'array' }, html: { type: 'boolean' }, priority: { type: 'string', enum: ['high', 'normal', 'low'] }, smtpConfig: { type: 'object' }, }, required: ['to', 'subject', 'body'], }, }, { name: 'outlook_create_meeting', description: 'šŸ“… Create calendar events with attendees', inputSchema: { type: 'object', properties: { subject: { type: 'string' }, startTime: { type: 'string' }, endTime: { type: 'string' }, location: { type: 'string' }, attendees: { type: 'array' }, description: { type: 'string' }, reminder: { type: 'number' }, outputPath: { type: 'string' }, }, required: ['subject', 'startTime', 'endTime'], }, }, { name: 'outlook_add_contact', description: 'šŸ‘¤ Add contact to address book', inputSchema: { type: 'object', properties: { firstName: { type: 'string' }, lastName: { type: 'string' }, email: { type: 'string' }, phone: { type: 'string' }, company: { type: 'string' }, jobTitle: { type: 'string' }, address: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['firstName', 'lastName'], }, }, { name: 'outlook_create_task', description: 'āœ… Create Outlook task', inputSchema: { type: 'object', properties: { subject: { type: 'string' }, dueDate: { type: 'string' }, priority: { type: 'string', enum: ['high', 'normal', 'low'] }, status: { type: 'string' }, category: { type: 'string' }, reminder: { type: 'string' }, notes: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['subject'], }, }, { name: 'outlook_set_rule', description: 'āš™ļø Create inbox rule', inputSchema: { type: 'object', properties: { name: { type: 'string' }, conditions: { type: 'array' }, actions: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['name', 'conditions', 'actions'], }, }, { name: 'outlook_read_emails', description: 'šŸ“¬ Read emails from IMAP server', inputSchema: { type: 'object', properties: { folder: { type: 'string' }, limit: { type: 'number' }, unreadOnly: { type: 'boolean' }, since: { type: 'string' }, imapConfig: { type: 'object' }, }, }, }, { name: 'outlook_search_emails', description: 'šŸ” Search emails by query', inputSchema: { type: 'object', properties: { query: { type: 'string' }, searchIn: { type: 'array' }, folder: { type: 'string' }, limit: { type: 'number' }, since: { type: 'string' }, imapConfig: { type: 'object' }, }, required: ['query'], }, }, { name: 'outlook_recurring_meeting', description: 'šŸ”„ Create recurring calendar meetings', inputSchema: { type: 'object', properties: { subject: { type: 'string' }, startTime: { type: 'string' }, endTime: { type: 'string' }, recurrence: { type: 'object' }, location: { type: 'string' }, attendees: { type: 'array' }, description: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['subject', 'startTime', 'endTime', 'recurrence'], }, }, { name: 'outlook_save_template', description: 'šŸ“§ Save email template with placeholders', inputSchema: { type: 'object', properties: { name: { type: 'string' }, subject: { type: 'string' }, body: { type: 'string' }, html: { type: 'boolean' }, placeholders: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['name', 'subject', 'body'], }, }, { name: 'outlook_mark_read', description: 'āœ‰ļø Mark emails as read/unread', inputSchema: { type: 'object', properties: { messageIds: { type: 'array' }, markAsRead: { type: 'boolean' }, imapConfig: { type: 'object' }, }, required: ['messageIds', 'markAsRead'], }, }, { name: 'outlook_archive_email', description: 'šŸ“¦ Archive emails to folder', inputSchema: { type: 'object', properties: { messageIds: { type: 'array' }, archiveFolder: { type: 'string' }, imapConfig: { type: 'object' }, }, required: ['messageIds'], }, }, { name: 'outlook_calendar_view', description: 'šŸ“… Get calendar view for date range', inputSchema: { type: 'object', properties: { startDate: { type: 'string' }, endDate: { type: 'string' }, viewType: { type: 'string', enum: ['day', 'week', 'month', 'agenda'] }, outputFormat: { type: 'string', enum: ['ics', 'json'] }, outputPath: { type: 'string' }, }, required: ['startDate', 'endDate', 'viewType'], }, }, { name: 'outlook_search_contacts', description: 'šŸ‘„ Search contacts database', inputSchema: { type: 'object', properties: { query: { type: 'string' }, searchIn: { type: 'array' }, outputFormat: { type: 'string', enum: ['vcf', 'json'] }, outputPath: { type: 'string' }, }, required: ['query'], }, }, { name: 'outlook_read_full_email', description: 'šŸ“§ Full IMAP email read with attachments and headers', inputSchema: { type: 'object', properties: { messageIds: { type: 'array' }, folder: { type: 'string' }, includeAttachments: { type: 'boolean' }, includeHeaders: { type: 'boolean' }, markAsRead: { type: 'boolean' }, imapConfig: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['messageIds'], }, }, { name: 'outlook_delete_email', description: 'šŸ“§ Delete emails via IMAP', inputSchema: { type: 'object', properties: { messageIds: { type: 'array' }, folder: { type: 'string' }, permanent: { type: 'boolean' }, imapConfig: { type: 'object' }, }, required: ['messageIds'], }, }, { name: 'outlook_move_email', description: 'šŸ“§ Move emails between IMAP folders', inputSchema: { type: 'object', properties: { messageIds: { type: 'array' }, fromFolder: { type: 'string' }, toFolder: { type: 'string' }, createFolder: { type: 'boolean' }, imapConfig: { type: 'object' }, }, required: ['messageIds', 'toFolder'], }, }, { name: 'outlook_create_folder', description: 'šŸ“§ Create IMAP folder structure', inputSchema: { type: 'object', properties: { folderPath: { type: 'string' }, parent: { type: 'string' }, imapConfig: { type: 'object' }, }, required: ['folderPath'], }, }, { name: 'outlook_shared_mailbox', description: 'šŸ“§ Access shared mailboxes and delegate accounts', inputSchema: { type: 'object', properties: { sharedMailbox: { type: 'string' }, operation: { type: 'string', enum: ['list', 'send', 'read', 'move', 'delete'] }, folder: { type: 'string' }, messageIds: { type: 'array' }, emailData: { type: 'object' }, imapConfig: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['sharedMailbox', 'operation'], }, }, { name: 'outlook_delegate_access', description: 'šŸ“§ Grant delegate permissions to users', inputSchema: { type: 'object', properties: { delegateEmail: { type: 'string' }, permissions: { type: 'object' }, receiveNotifications: { type: 'boolean' }, privateItemsAccess: { type: 'boolean' }, outputPath: { type: 'string' }, }, required: ['delegateEmail', 'permissions'], }, }, { name: 'outlook_out_of_office', description: 'šŸ“§ Set automatic replies/out of office', inputSchema: { type: 'object', properties: { enable: { type: 'boolean' }, startTime: { type: 'string' }, endTime: { type: 'string' }, message: { type: 'object' }, externalAudience: { type: 'string' }, declineNewMeetings: { type: 'boolean' }, imapConfig: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['enable', 'message'], }, }, { name: 'outlook_notes', description: 'šŸ“§ Create Outlook notes', inputSchema: { type: 'object', properties: { notes: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['notes'], }, }, { name: 'outlook_journal', description: 'šŸ“§ Create journal entries for activity tracking', inputSchema: { type: 'object', properties: { entries: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['entries'], }, }, { name: 'outlook_rss_feed', description: 'šŸ“§ Subscribe to and manage RSS feeds', inputSchema: { type: 'object', properties: { operation: { type: 'string', enum: ['add', 'remove', 'list', 'update'] }, feeds: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['operation'], }, }, { name: 'outlook_data_file', description: 'šŸ“§ Manage PST/OST data files', inputSchema: { type: 'object', properties: { operation: { type: 'string', enum: ['create', 'open', 'close', 'compact', 'info'] }, filePath: { type: 'string' }, fileType: { type: 'string', enum: ['pst', 'ost'] }, password: { type: 'string' }, displayName: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['operation'], }, }, { name: 'outlook_quick_steps', description: 'šŸ“§ Create Quick Steps for email automation', inputSchema: { type: 'object', properties: { steps: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['steps'], }, }, { name: 'outlook_conversation_view', description: 'šŸ“§ Configure conversation view settings', inputSchema: { type: 'object', properties: { enable: { type: 'boolean' }, settings: { type: 'object' }, folders: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['enable'], }, }, { name: 'outlook_cleanup', description: 'šŸ“§ Clean up redundant messages in conversations', inputSchema: { type: 'object', properties: { folder: { type: 'string' }, scope: { type: 'string', enum: ['conversation', 'folderAndSubfolders', 'selectedMessages'] }, messageIds: { type: 'array' }, deleteRedundant: { type: 'boolean' }, imapConfig: { type: 'object' }, }, required: ['scope'], }, }, { name: 'outlook_ignore_conversation', description: 'šŸ“§ Ignore conversation threads', inputSchema: { type: 'object', properties: { conversationIds: { type: 'array' }, restore: { type: 'boolean' }, deleteExisting: { type: 'boolean' }, imapConfig: { type: 'object' }, }, required: ['conversationIds'], }, }, { name: 'outlook_flag_email', description: 'šŸ“§ Flag emails with colors and due dates', inputSchema: { type: 'object', properties: { messageIds: { type: 'array' }, flag: { type: 'object' }, imapConfig: { type: 'object' }, }, required: ['messageIds', 'flag'], }, }, { name: 'outlook_categories', description: 'šŸ“§ Create and apply color categories', inputSchema: { type: 'object', properties: { operation: { type: 'string', enum: ['create', 'apply', 'remove', 'list'] }, categories: { type: 'array' }, messageIds: { type: 'array' }, categoryNames: { type: 'array' }, imapConfig: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['operation'], }, }, { name: 'outlook_signature', description: 'šŸ“§ Create HTML email signatures', inputSchema: { type: 'object', properties: { signatures: { type: 'array' }, outputPath: { type: 'string' }, }, required: ['signatures'], }, }, { name: 'outlook_autocomplete', description: 'šŸ“§ Manage autocomplete nickname cache', inputSchema: { type: 'object', properties: { operation: { type: 'string', enum: ['list', 'add', 'remove', 'clear', 'export', 'import'] }, entries: { type: 'array' }, filePath: { type: 'string' }, outputPath: { type: 'string' }, }, required: ['operation'], }, }, { name: 'outlook_mail_merge_advanced', description: 'šŸ“§ Advanced mail merge with filters and conditional content', inputSchema: { type: 'object', properties: { templatePath: { type: 'string' }, template: { type: 'object' }, dataSource: { type: 'array' }, filters: { type: 'array' }, conditionalContent: { type: 'array' }, attachments: { type: 'array' }, sendOptions: { type: 'object' }, smtpConfig: { type: 'object' }, outputPath: { type: 'string' }, }, required: ['dataSource'], }, }, ]; async start() { process.stdin.setEncoding('utf-8'); let buffer = ''; process.stdin.on('data', async (chunk) => { buffer += chunk; const lines = buffer.split('\n'); buffer = lines.pop() || ''; for (const line of lines) { if (line.trim()) { try { const request = JSON.parse(line); const response = await this.handleRequest(request); if (response) { console.log(JSON.stringify(response)); } } catch (error) { console.error('Error processing request:', error); } } } }); process.stdin.on('end', () => { process.exit(0); }); } async handleRequest(request) { const { id, method, params } = request; if (id === undefined) { if (method === 'notifications/initialized') { return null; } return null; } try { switch (method) { case 'initialize': return this.initialize(id); case 'tools/list': return { jsonrpc: '2.0', id, result: { tools: this.tools }, }; case 'tools/call': return await this.callTool(id, params); default: return { jsonrpc: '2.0', id, error: { code: -32601, message: `Method not found: ${method}`, }, }; } } catch (error) { return { jsonrpc: '2.0', id, error: { code: -32603, message: error instanceof Error ? error.message : 'Internal error', }, }; } } initialize(id) { return { jsonrpc: '2.0', id, result: { protocolVersion: '2025-06-18', capabilities: { tools: {}, }, serverInfo: { name: 'office-whisperer', version: '3.0.0', }, }, }; } async callTool(id, params) { const { name, arguments: args } = params; let result; try { // Excel Tools if (name === 'create_excel') { result = await this.handleCreateExcel(args); } else if (name === 'excel_add_pivot_table') { result = await this.handleExcelAddPivotTable(args); } else if (name === 'excel_add_chart') { result = await this.handleExcelAddChart(args); } else if (name === 'excel_add_formula') { result = await this.handleExcelAddFormula(args); } else if (name === 'excel_conditional_formatting') { result = await this.handleExcelConditionalFormatting(args); } else if (name === 'excel_data_validation') { result = await this.handleExcelDataValidation(args); } else if (name === 'excel_freeze_panes') { result = await this.handleExcelFreezePanes(args); } else if (name === 'excel_filter_sort') { result = await this.handleExcelFilterSort(args); } else if (name === 'excel_format_cells') { result = await this.handleExcelFormatCells(args); } else if (name === 'excel_named_range') { result = await this.handleExcelNamedRange(args); } else if (name === 'excel_protect_sheet') { result = await this.handleExcelProtectSheet(args); } else if (name === 'excel_merge_workbooks') { result = await this.handleExcelMergeWorkbooks(args); } else if (name === 'excel_find_replace') { result = await this.handleExcelFindReplace(args); } else if (name === 'excel_to_json') { result = await this.handleExcelToJSON(args); } else if (name === 'excel_to_csv') { result = await this.handleExcelToCSV(args); } else if (name === 'excel_add_sparklines') { result = await this.handleExcelAddSparklines(args); } else if (name === 'excel_array_formulas') { result = await this.handleExcelArrayFormulas(args); } else if (name === 'excel_add_subtotals') { result = await this.handleExcelAddSubtotals(args); } else if (name === 'excel_add_hyperlinks') { result = await this.handleExcelAddHyperlinks(args); } else if (name === 'excel_advanced_charts') { result = await this.handleExcelAdvancedCharts(args); } else if (name === 'excel_add_slicers') { result = await this.handleExcelAddSlicers(args); } else if (name === 'excel_power_query') { result = await this.handleExcelPowerQuery(args); } else if (name === 'excel_goal_seek') { result = await this.handleExcelGoalSeek(args); } else if (name === 'excel_data_table') { result = await this.handleExcelDataTable(args); } else if (name === 'excel_scenario_manager') { result = await this.handleExcelScenarioManager(args); } else if (name === 'excel_create_table') { result = await this.handleExcelCreateTable(args); } else if (name === 'excel_table_formula') { result = await this.handleExcelTableFormula(args); } else if (name === 'excel_form_controls') { result = await this.handleExcelFormControls(args); } else if (name === 'excel_insert_images') { result = await this.handleExcelInsertImages(args); } else if (name === 'excel_insert_shapes') { result = await this.handleExcelInsertShapes(args); } else if (name === 'excel_smart_art') { result = await this.handleExcelSmartArt(args); } else if (name === 'excel_page_setup') { result = await this.handleExcelPageSetup(args); } else if (name === 'excel_header_footer') { result = await this.handleExcelHeaderFooter(args); } else if (name === 'excel_page_breaks') { result = await this.handleExcelPageBreaks(args); } else if (name === 'excel_track_changes') { result = await this.handleExcelTrackChanges(args); } else if (name === 'excel_share_workbook') { result = await this.handleExcelShareWorkbook(args); } else if (name === 'excel_compare_versions') { result = await this.handleExcelCompareVersions(args); } else if (name === 'excel_add_comments') { result = await this.handleExcelAddComments(args); } // Word Tools else if (name === 'create_word') { result = await this.handleCreateWord(args); } else if (name === 'word_add_toc') { result = await this.handleWordAddTOC(args); } else if (name === 'word_mail_merge') { result = await this.handleWordMailMerge(args); } else if (name === 'word_find_replace') { result = await this.handleWordFindReplace(args); } else if (name === 'word_add_comment') { result = await this.handleWordAddComment(args); } else if (name === 'word_format_styles') { result = await this.handleWordFormatStyles(args); } else if (name === 'word_insert_image') { result = await this.handleWordInsertImage(args); } else if (name === 'word_add_header_footer') { result = await this.handleWordAddHeaderFooter(args); } else if (name === 'word_compare_documents') { result = await this.handleWordCompareDocuments(args); } else if (name === 'word_to_pdf') { result = await this.handleWordToPDF(args); } else if (name === 'word_track_changes') { result = await this.handleWordTrackChanges(args); } else if (name === 'word_add_footnotes') { result = await this.handleWordAddFootnotes(args); } else if (name === 'word_add_bookmarks') { result = await this.handleWordAddBookmarks(args); } else if (name === 'word_add_section_breaks') { result = await this.handleWordAddSectionBreaks(args); } else if (name === 'word_add_text_boxes') { result = await this.handleWordAddTextBoxes(args); } else if (name === 'word_add_cross_references') { result = await this.handleWordAddCrossReferences(args); } else if (name === 'word_bibliography') { result = await this.handleWordBibliography(args); } else if (name === 'word_citations') { result = await this.handleWordCitations(args); } else if (name === 'word_index') { result = await this.handleWordIndex(args); } else if (name === 'word_mark_index_entry') { result = await this.handleWordMarkIndexEntry(args); } else if (name === 'word_form_fields') { result = await this.handleWordFormFields(args); } else if (name === 'word_content_controls') { result = await this.handleWordContentControls(args); } else if (name === 'word_smart_art') { result = await this.handleWordSmartArt(args); } else if (name === 'word_equations') { result = await this.handleWordEquations(args); } else if (name === 'word_symbols') { result = await this.handleWordSymbols(args); } else if (name === 'word_accessibility_check') { result = await this.handleWordAccessibilityCheck(args); } else if (name === 'word_alt_text') { result = await this.handleWordAltText(args); } else if (name === 'word_digital_signature') { result = await this.handleWordDigitalSignature(args); } else if (name === 'word_protect_document') { result = await this.handleWordProtectDocument(args); } else if (name === 'word_master_document') { result = await this.handleWordMasterDocument(args); } else if (name === 'word_document_info') { result = await this.handleWordDocumentInfo(args); } else if (name === 'word_captions') { result = await this.handleWordCaptions(args); } else if (name === 'word_advanced_hyperlinks') { result = await this.handleWordAdvancedHyperlinks(args); } else if (name === 'word_drop_cap') { result = await this.handleWordDropCap(args); } else if (name === 'word_watermark') { result = await this.handleWordWatermark(args); } // PowerPoint Tools else if (name === 'create_powerpoint') { result = await this.handleCreatePowerPoint(args); } else if (name === 'ppt_add_transition') { result = await this.handlePPTAddTransition(args); } else if (name === 'ppt_add_animation') { result = await this.handlePPTAddAnimation(args); } else if (name === 'ppt_add_notes') { result = await this.handlePPTAddNotes(args); } else if (name === 'ppt_duplicate_slide') { result = await this.handlePPTDuplicateSlide(args); } else if (name === 'ppt_reorder_slides') { result = await this.handlePPTReorderSlides(args); } else if (name === 'ppt_export_pdf') { result = await this.handlePPTExportPDF(args); } else if (name === 'ppt_add_media') { result = await this.handlePPTAddMedia(args); } else if (name === 'ppt_define_master_slide') { result = await this.handlePPTDefineMasterSlide(args); } else if (name === 'ppt_add_hyperlinks') { result = await this.handlePPTAddHyperlinks(args); } else if (name === 'ppt_add_sections') { result = await this.handlePPTAddSections(args); } else if (name === 'ppt_morph_transition') { result = await this.handlePPTMorphTransition(args); } else if (name === 'ppt_add_action_buttons') { result = await this.handlePPTAddActionButtons(args); } else if (name === 'ppt_smart_art') { result = await this.handlePPTSmartArt(args); } else if (name === 'ppt_insert_icons') { result = await this.handlePPTInsertIcons(args); } else if (name === 'ppt_3d_models') { result = await this.handlePPT3DModels(args); } else if (name === 'ppt_zoom') { result = await this.handlePPTZoom(args); } else if (name === 'ppt_recording') { result = await this.handlePPTRecording(args); } else if (name === 'ppt_live_web') { result = await this.handlePPTLiveWeb(args); } else if (name === 'ppt_designer') { result = await this.handlePPTDesigner(args); } else if (name === 'ppt_collaboration') { result = await this.handlePPTCollaboration(args); } else if (name === 'ppt_presenter_coach') { result = await this.handlePPTPresenterCoach(args); } else if (name === 'ppt_subtitles') { result = await this.handlePPTSubtitles(args); } else if (name === 'ppt_ink_annotations') { result = await this.handlePPTInkAnnotations(args); } else if (name === 'ppt_grid_guides') { result = await this.handlePPTGridGuides(args); } else if (name === 'ppt_custom_show') { result = await this.handlePPTCustomShow(args); } else if (name === 'ppt_animation_pane') { result = await this.handlePPTAnimationPane(args); } else if (name === 'ppt_slide_master_advanced') { result = await this.handlePPTSlideMasterAdvanced(args); } else if (name === 'ppt_theme') { result = await this.handlePPTTheme(args); } else if (name === 'ppt_template') { result = await this.handlePPTTemplate(args); } // Outlook Tools else if (name === 'outlook_send_email') { result = await this.handleOutlookSendEmail(args); } else if (name === 'outlook_create_meeting') { result = await this.handleOutlookCreateMeeting(args); } else if (name === 'outlook_add_contact') { result = await this.handleOutlookAddContact(args); } else if (name === 'outlook_create_task') { result = await this.handleOutlookCreateTask(args); } else if (name === 'outlook_set_rule') { result = await this.handleOutlookSetRule(args); } else if (name === 'outlook_read_emails') { result = await this.handleOutlookReadEmails(args); } else if (name === 'outlook_search_emails') { result = await this.handleOutlookSearchEmails(args); } else if (name === 'outlook_recurring_meeting') { result = await this.handleOutlookRecurringMeeting(args); } else if (name === 'outlook_save_template') { result = await this.handleOutlookSaveTemplate(args); } else if (name === 'outlook_mark_read') { result = await this.handleOutlookMarkRead(args); } else if (name === 'outlook_archive_email') { result = await this.handleOutlookArchiveEmail(args); } else if (name === 'outlook_calendar_view') { result = await this.handleOutlookCalendarView(args); } else if (name === 'outlook_search_contacts') { result = await this.handleOutlookSearchContacts(args); } else if (name === 'outlook_read_full_email') { result = await this.handleOutlookReadFullEmail(args); } else if (name === 'outlook_delete_email') { result = await this.handleOutlookDeleteEmail(args); } else if (name === 'outlook_move_email') { result = await this.handleOutlookMoveEmail(args); } else if (name === 'outlook_create_folder') { result = await this.handleOutlookCreateFolder(args); } else if (name === 'outlook_shared_mailbox') { result = await this.handleOutlookSharedMailbox(args); } else if (name === 'outlook_delegate_access') { result = await this.handleOutlookDelegateAccess(args); } else if (name === 'outlook_out_of_office') { result = await this.handleOutlookOutOfOffice(args); } else if (name === 'outlook_notes') { result = await this.handleOutlookNotes(args); } else if (name === 'outlook_journal') { result = await this.handleOutlookJournal(args); } else if (name === 'outlook_rss_feed') { result = await this.handleOutlookRSSFeed(args); } else if (name === 'outlook_data_file') { result = await this.handleOutlookDataFile(args); } else if (name === 'outlook_quick_steps') { result = await this.handleOutlookQuickSteps(args); } else if (name === 'outlook_conversation_view') { result = await this.handleOutlookConversationView(args); } else if (name === 'outlook_cleanup') { result = await this.handleOutlookCleanup(args); } else if (name === 'outlook_ignore_conversation') { result = await this.handleOutlookIgnoreConversation(args); } else if (name === 'outlook_flag_email') { result = await this.handleOutlookFlagEmail(args); } else if (name === 'outlook_categories') { result = await this.handleOutlookCategories(args); } else if (name === 'outlook_signature') { result = await this.handleOutlookSignature(args); } else if (name === 'outlook_autocomplete') { result = await this.handleOutlookAutocomplete(args); } else if (name === 'outlook_mail_merge_advanced') { result = await this.handleOutlookMailMergeAdvanced(args); } else { throw new Error(`Unknown tool: ${name}`); } } catch (error) { throw error; } return { jsonrpc: '2.0', id, result: { content: [ { type: 'text', text: result, }, ], }, }; } // ========== EXCEL HANDLERS ========== async handleCreateExcel(args) { const buffer = await this.excelGen.createWorkbook({ filename: args.filename, sheets: args.sheets, }); const outputPath = args.outputPath || process.cwd(); const fullPath = path.join(outputPath, args.filename); await fs.writeFile(fullPath, buffer); return `āœ… **Excel workbook created!**\n\nšŸ“Š **File:** ${fullPath}\nšŸ“ **Sheets:** ${args.sheets.length}\nšŸ’¾ **Size:** ${(buffer.length / 1024).toFixed(2)} KB`; } async handleExcelAddPivotTable(args) { const buffer = await this.excelGen.addPivotTable(args.filename, args.sheetName, args.pivotTable); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Pivot table added!**\n\nšŸ“ˆ **Name:** ${args.pivotTable.name}\nšŸ“Š **File:** ${fullPath}`; } async handleExcelAddChart(args) { const buffer = await this.excelGen.addChart(args.filename, args.sheetName, args.chart); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Chart added!**\n\nšŸ“‰ **Type:** ${args.chart.type}\nšŸ“Š **Title:** ${args.chart.title}\nšŸ“ **File:** ${fullPath}`; } async handleExcelAddFormula(args) { const buffer = await this.excelGen.addFormulas(args.filename, args.sheetName, args.formulas); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Formulas added!**\n\nšŸ”¢ **Count:** ${args.formulas.length}\nšŸ“ **File:** ${fullPath}`; } async handleExcelConditionalFormatting(args) { const buffer = await this.excelGen.addConditionalFormatting(args.filename, args.sheetName, args.range, args.rules); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Conditional formatting applied!**\n\nšŸŽØ **Range:** ${args.range}\nšŸ“Š **Rules:** ${args.rules.length}\nšŸ“ **File:** ${fullPath}`; } async handleExcelDataValidation(args) { const buffer = await this.excelGen.addDataValidation(args.filename, args.sheetName, args.range, args.validation); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Data validation added!**\n\nāœ… **Type:** ${args.validation.type}\nšŸ“ **Range:** ${args.range}\nšŸ“ **File:** ${fullPath}`; } async handleExcelFreezePanes(args) { const buffer = await this.excelGen.freezePanes(args.filename, args.sheetName, args.row, args.column); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Panes frozen!**\n\nā„ļø **Row:** ${args.row || 0}\nā„ļø **Column:** ${args.column || 0}\nšŸ“ **File:** ${fullPath}`; } async handleExcelFilterSort(args) { const buffer = await this.excelGen.filterSort(args.filename, args.sheetName, args.range, args.sortBy, args.autoFilter); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Filter/Sort applied!**\n\nšŸ” **AutoFilter:** ${args.autoFilter ? 'Yes' : 'No'}\nšŸ“ **File:** ${fullPath}`; } async handleExcelFormatCells(args) { const buffer = await this.excelGen.formatCells(args.filename, args.sheetName, args.range, args.style); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Cells formatted!**\n\n✨ **Range:** ${args.range}\nšŸ“ **File:** ${fullPath}`; } async handleExcelNamedRange(args) { const buffer = await this.excelGen.addNamedRange(args.filename, args.name, args.range, args.sheetName); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Named range created!**\n\nšŸ·ļø **Name:** ${args.name}\nšŸ“ **Range:** ${args.range}\nšŸ“ **File:** ${fullPath}`; } async handleExcelProtectSheet(args) { const buffer = await this.excelGen.protectSheet(args.filename, args.sheetName, args.password, args.options); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Sheet protected!**\n\nšŸ”’ **Sheet:** ${args.sheetName}\n${args.password ? 'šŸ”‘ **Password:** Set' : 'šŸ”“ **Password:** None'}\nšŸ“ **File:** ${fullPath}`; } async handleExcelMergeWorkbooks(args) { const buffer = await this.excelGen.mergeWorkbooks(args.files, args.outputFilename); const outputPath = args.outputPath || process.cwd(); const fullPath = path.join(outputPath, args.outputFilename); await fs.writeFile(fullPath, buffer); return `āœ… **Workbooks merged!**\n\nšŸ”— **Source files:** ${args.files.length}\nšŸ“ **Output:** ${fullPath}`; } async handleExcelFindReplace(args) { const buffer = await this.excelGen.findReplace(args.filename, args.find, args.replace, args.sheetName, args.matchCase, args.matchEntireCell, args.searchFormulas); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Find & Replace complete!**\n\nšŸ”Ž **Find:** "${args.find}"\nšŸ”„ **Replace:** "${args.replace}"\nšŸ“ **File:** ${fullPath}`; } async handleExcelToJSON(args) { const json = await this.excelGen.convertToJSON(args.excelPath, args.sheetName, args.header); const outputPath = args.outputPath || args.excelPath.replace(/\.xlsx?$/i, '.json'); await fs.writeFile(outputPath, json, 'utf-8'); return `āœ… **Converted to JSON!**\n\nšŸ“Š **Source:** ${args.excelPath}\nšŸ“‹ **Output:** ${outputPath}\nšŸ’¾ **Size:** ${(json.length / 1024).toFixed(2)} KB`; } async handleExcelToCSV(args) { const csv = await this.excelGen.convertToCSV(args.excelPath, args.sheetName); const outputPath = args.outputPath || args.excelPath.replace(/\.xlsx?$/i, '.csv'); await fs.writeFile(outputPath, csv, 'utf-8'); return `āœ… **Converted to CSV!**\n\nšŸ“Š **Source:** ${args.excelPath}\nšŸ“ **Output:** ${outputPath}\nšŸ’¾ **Size:** ${(csv.length / 1024).toFixed(2)} KB`; } // ========== WORD HANDLERS ========== async handleCreateWord(args) { const buffer = await this.wordGen.createDocument({ filename: args.filename, sections: args.sections, }); const outputPath = args.outputPath || process.cwd(); const fullPath = path.join(outputPath, args.filename); await fs.writeFile(fullPath, buffer); return `āœ… **Word document created!**\n\nšŸ“„ **File:** ${fullPath}\nšŸ“‘ **Sections:** ${args.sections.length}\nšŸ’¾ **Size:** ${(buffer.length / 1024).toFixed(2)} KB`; } async handleWordAddTOC(args) { const buffer = await this.wordGen.addTableOfContents(args.filename, args.title, args.hyperlinks, args.levels); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Table of Contents added!**\n\nšŸ“‘ **Title:** ${args.title || 'Table of Contents'}\nšŸ“ **File:** ${fullPath}`; } async handleWordMailMerge(args) { const buffers = await this.wordGen.mailMerge(args.templatePath, args.dataSource, args.outputFilename); const outputPath = args.outputPath || process.cwd(); let savedFiles = 0; for (let i = 0; i < buffers.length; i++) { const filename = args.outputFilename ? `${args.outputFilename}_${i + 1}.docx` : `merged_${i + 1}.docx`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, buffers[i]); savedFiles++; } return `āœ… **Mail merge complete!**\n\nāœ‰ļø **Documents created:** ${savedFiles}\nšŸ“ **Output:** ${outputPath}`; } async handleWordFindReplace(args) { const buffer = await this.wordGen.findReplace(args.filename, args.find, args.replace, args.matchCase, args.matchWholeWord, args.formatting); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Find & Replace complete!**\n\nšŸ” **Find:** "${args.find}"\nšŸ”„ **Replace:** "${args.replace}"\nšŸ“ **File:** ${fullPath}`; } async handleWordAddComment(args) { const buffer = await this.wordGen.addComment(args.filename, args.text, args.comment, args.author); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Comment added!**\n\nšŸ’¬ **Author:** ${args.author || 'Office Whisperer'}\nšŸ“ **File:** ${fullPath}`; } async handleWordFormatStyles(args) { const buffer = await this.wordGen.formatStyles(args.filename, args.styles); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Styles applied!**\n\nšŸŽØ **Custom styles added**\nšŸ“ **File:** ${fullPath}`; } async handleWordInsertImage(args) { const buffer = await this.wordGen.insertImage(args.filename, args.imagePath, args.position, args.size, args.wrapping); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Image inserted!**\n\nšŸ–¼ļø **Source:** ${args.imagePath}\nšŸ“ **File:** ${fullPath}`; } async handleWordAddHeaderFooter(args) { const buffer = await this.wordGen.addHeaderFooter(args.filename, args.type, args.content, args.sectionType); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **${args.type.charAt(0).toUpperCase() + args.type.slice(1)} added!**\n\nšŸ“„ **Type:** ${args.type}\nšŸ“ **File:** ${fullPath}`; } async handleWordCompareDocuments(args) { const buffer = await this.wordGen.compareDocuments(args.originalPath, args.revisedPath, args.author); const outputPath = args.outputPath || path.dirname(args.originalPath); const fullPath = path.join(outputPath, 'comparison.docx'); await fs.writeFile(fullPath, buffer); return `āœ… **Documents compared!**\n\nšŸ”„ **Original:** ${args.originalPath}\nšŸ”„ **Revised:** ${args.revisedPath}\nšŸ“ **Report:** ${fullPath}`; } async handleWordToPDF(args) { const buffer = await this.wordGen.convertToPDF(args.filename); const outputPath = args.outputPath || path.dirname(args.filename); const pdfPath = path.join(outputPath, path.basename(args.filename).replace(/\.docx?$/i, '.pdf')); await fs.writeFile(pdfPath, buffer); return `āœ… **PDF conversion info!**\n\nšŸ“‘ **Source:** ${args.filename}\nšŸ“„ **Output:** ${pdfPath}\n\nNote: Actual PDF conversion requires LibreOffice or similar tools.`; } // ========== POWERPOINT HANDLERS ========== async handleCreatePowerPoint(args) { const buffer = await this.pptGen.createPresentation({ filename: args.filename, title: args.title, theme: args.theme, slides: args.slides, }); const outputPath = args.outputPath || process.cwd(); const fullPath = path.join(outputPath, args.filename); await fs.writeFile(fullPath, buffer); return `āœ… **PowerPoint created!**\n\nšŸŽ¬ **File:** ${fullPath}\nšŸŽØ **Theme:** ${args.theme || 'default'}\nšŸ“Š **Slides:** ${args.slides.length}\nšŸ’¾ **Size:** ${(buffer.length / 1024).toFixed(2)} KB`; } async handlePPTAddTransition(args) { const buffer = await this.pptGen.addTransition(args.filename, args.transition, args.slideNumber); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Transition added!**\n\n✨ **Type:** ${args.transition.type}\nšŸ“ **File:** ${fullPath}`; } async handlePPTAddAnimation(args) { const buffer = await this.pptGen.addAnimation(args.filename, args.slideNumber, args.animation, args.objectId); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Animation added!**\n\nšŸŽ­ **Effect:** ${args.animation.effect}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPTAddNotes(args) { const buffer = await this.pptGen.addNotes(args.filename, args.slideNumber, args.notes); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Speaker notes added!**\n\nšŸ“ **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPTDuplicateSlide(args) { const buffer = await this.pptGen.duplicateSlide(args.filename, args.slideNumber, args.position); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Slide duplicated!**\n\nšŸ“‹ **Source:** Slide ${args.slideNumber}\nšŸ“ **Position:** ${args.position || 'end'}\nšŸ“ **File:** ${fullPath}`; } async handlePPTReorderSlides(args) { const buffer = await this.pptGen.reorderSlides(args.filename, args.slideOrder); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Slides reordered!**\n\nšŸ”€ **New order:** ${args.slideOrder.join(', ')}\nšŸ“ **File:** ${fullPath}`; } async handlePPTExportPDF(args) { const buffer = await this.pptGen.exportPDF(args.filename); const outputPath = args.outputPath || path.dirname(args.filename); const pdfPath = path.join(outputPath, path.basename(args.filename).replace(/\.pptx?$/i, '.pdf')); await fs.writeFile(pdfPath, buffer); return `āœ… **PDF export info!**\n\nšŸ“‘ **Source:** ${args.filename}\nšŸ“„ **Output:** ${pdfPath}\n\nNote: Actual PDF conversion requires LibreOffice or PowerPoint.`; } async handlePPTAddMedia(args) { const buffer = await this.pptGen.addMedia(args.filename, args.slideNumber, args.mediaPath, args.mediaType, args.position, args.size); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Media embedded!**\n\nšŸŽ„ **Type:** ${args.mediaType}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } // ========== OUTLOOK HANDLERS ========== async handleOutlookSendEmail(args) { const result = await this.outlookGen.sendEmail(args); return `āœ… **Email processed!**\n\n${result}`; } async handleOutlookCreateMeeting(args) { const ics = await this.outlookGen.createMeeting(args); const outputPath = args.outputPath || process.cwd(); const filename = `meeting_${Date.now()}.ics`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, ics, 'utf-8'); return `āœ… **Meeting created!**\n\nšŸ“… **Subject:** ${args.subject}\nā° **Start:** ${args.startTime}\nšŸ“ **ICS file:** ${fullPath}\n\nImport this file into Outlook/Google Calendar.`; } async handleOutlookAddContact(args) { const vcf = await this.outlookGen.addContact(args); const outputPath = args.outputPath || process.cwd(); const filename = `contact_${args.lastName}_${args.firstName}.vcf`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, vcf, 'utf-8'); return `āœ… **Contact created!**\n\nšŸ‘¤ **Name:** ${args.firstName} ${args.lastName}\n${args.email ? `šŸ“§ **Email:** ${args.email}\n` : ''}šŸ“ **VCF file:** ${fullPath}\n\nImport this file into Outlook/Contacts app.`; } async handleOutlookCreateTask(args) { const task = await this.outlookGen.createTask(args); const outputPath = args.outputPath || process.cwd(); const filename = `task_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, task, 'utf-8'); return `āœ… **Task created!**\n\nāœ… **Subject:** ${args.subject}\n${args.dueDate ? `šŸ“… **Due:** ${args.dueDate}\n` : ''}šŸ”¢ **Priority:** ${args.priority || 'normal'}\nšŸ“ **JSON file:** ${fullPath}`; } async handleOutlookSetRule(args) { const rule = await this.outlookGen.setRule(args); const outputPath = args.outputPath || process.cwd(); const filename = `rule_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, rule, 'utf-8'); return `āœ… **Inbox rule created!**\n\nāš™ļø **Name:** ${args.name}\nšŸ”§ **Conditions:** ${args.conditions.length}\nšŸŽÆ **Actions:** ${args.actions.length}\nšŸ“ **JSON file:** ${fullPath}`; } // ========== EXCEL v3.0 HANDLERS ========== async handleExcelAddSparklines(args) { const buffer = await this.excelGen.addSparklines(args.filename, args.sheetName, args.dataRange, args.location, args.type, args.options); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Sparklines added!**\n\n✨ **Type:** ${args.type}\nšŸ“ **Location:** ${args.location}\nšŸ“ **File:** ${fullPath}`; } async handleExcelArrayFormulas(args) { const buffer = await this.excelGen.addArrayFormulas(args.filename, args.sheetName, args.formulas); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Array formulas added!**\n\nšŸ”¢ **Count:** ${args.formulas.length}\nšŸ“ **File:** ${fullPath}`; } async handleExcelAddSubtotals(args) { const buffer = await this.excelGen.addSubtotals(args.filename, args.sheetName, args.range, args.groupBy, args.summaryFunction, args.summaryColumns); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Subtotals added!**\n\nšŸ“Š **Function:** ${args.summaryFunction}\nšŸ“ **Range:** ${args.range}\nšŸ“ **File:** ${fullPath}`; } async handleExcelAddHyperlinks(args) { const buffer = await this.excelGen.addHyperlinks(args.filename, args.sheetName, args.links); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Hyperlinks added!**\n\nšŸ”— **Count:** ${args.links.length}\nšŸ“ **File:** ${fullPath}`; } async handleExcelAdvancedCharts(args) { const buffer = await this.excelGen.addAdvancedChart(args.filename, args.sheetName, args.chart); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Advanced chart added!**\n\nšŸ“ˆ **Type:** ${args.chart.type}\nšŸ“Š **Title:** ${args.chart.title}\nšŸ“ **File:** ${fullPath}`; } async handleExcelAddSlicers(args) { const buffer = await this.excelGen.addSlicers(args.filename, args.sheetName, args.tableName, args.slicers); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Slicers added!**\n\nšŸŽ›ļø **Count:** ${args.slicers.length}\nšŸ“Š **Table:** ${args.tableName}\nšŸ“ **File:** ${fullPath}`; } // ========== WORD v3.0 HANDLERS ========== async handleWordTrackChanges(args) { const buffer = await this.wordGen.enableTrackChanges(args.filename, args.enable, args.author); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Track changes ${args.enable ? 'enabled' : 'disabled'}!**\n\nāœļø **Author:** ${args.author || 'Office Whisperer'}\nšŸ“ **File:** ${fullPath}`; } async handleWordAddFootnotes(args) { const buffer = await this.wordGen.addFootnotes(args.filename, args.footnotes); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Footnotes added!**\n\nšŸ“Œ **Count:** ${args.footnotes.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordAddBookmarks(args) { const buffer = await this.wordGen.addBookmarks(args.filename, args.bookmarks); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Bookmarks added!**\n\nšŸ”– **Count:** ${args.bookmarks.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordAddSectionBreaks(args) { const buffer = await this.wordGen.addSectionBreaks(args.filename, args.breaks); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Section breaks added!**\n\nšŸ“„ **Count:** ${args.breaks.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordAddTextBoxes(args) { const buffer = await this.wordGen.addTextBoxes(args.filename, args.textBoxes); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Text boxes added!**\n\nšŸ“¦ **Count:** ${args.textBoxes.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordAddCrossReferences(args) { const buffer = await this.wordGen.addCrossReferences(args.filename, args.references); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Cross-references added!**\n\nšŸ”— **Count:** ${args.references.length}\nšŸ“ **File:** ${fullPath}`; } // ========== POWERPOINT v3.0 HANDLERS ========== async handlePPTDefineMasterSlide(args) { const buffer = await this.pptGen.defineMasterSlide(args.filename, args.masterSlide); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Master slide defined!**\n\nšŸŽØ **Name:** ${args.masterSlide.name}\nšŸ“ **File:** ${fullPath}`; } async handlePPTAddHyperlinks(args) { const buffer = await this.pptGen.addHyperlinks(args.filename, args.slideNumber, args.links); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Hyperlinks added!**\n\nšŸ”— **Count:** ${args.links.length}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPTAddSections(args) { const buffer = await this.pptGen.addSections(args.filename, args.sections); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Sections added!**\n\nšŸ“ **Count:** ${args.sections.length}\nšŸ“ **File:** ${fullPath}`; } async handlePPTMorphTransition(args) { const buffer = await this.pptGen.addMorphTransition(args.filename, args.fromSlide, args.toSlide, args.duration); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Morph transition added!**\n\n✨ **From slide:** ${args.fromSlide}\n✨ **To slide:** ${args.toSlide}\nšŸ“ **File:** ${fullPath}`; } async handlePPTAddActionButtons(args) { const buffer = await this.pptGen.addActionButtons(args.filename, args.slideNumber, args.buttons); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Action buttons added!**\n\nšŸ”˜ **Count:** ${args.buttons.length}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } // ========== OUTLOOK v3.0 HANDLERS ========== async handleOutlookReadEmails(args) { const result = await this.outlookGen.readEmails(args); return `āœ… **Email reading processed!**\n\n${result}`; } async handleOutlookSearchEmails(args) { const result = await this.outlookGen.searchEmails(args); return `āœ… **Email search processed!**\n\n${result}`; } async handleOutlookRecurringMeeting(args) { const ics = await this.outlookGen.createRecurringMeeting(args); const outputPath = args.outputPath || process.cwd(); const filename = `recurring_meeting_${Date.now()}.ics`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, ics, 'utf-8'); return `āœ… **Recurring meeting created!**\n\nšŸ“… **Subject:** ${args.subject}\nšŸ”„ **Frequency:** ${args.recurrence.frequency}\nšŸ“ **ICS file:** ${fullPath}`; } async handleOutlookSaveTemplate(args) { const template = await this.outlookGen.saveEmailTemplate(args); const outputPath = args.outputPath || process.cwd(); const filename = `email_template_${args.name.replace(/\s+/g, '_')}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, template, 'utf-8'); return `āœ… **Email template saved!**\n\nšŸ“§ **Name:** ${args.name}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookMarkRead(args) { const result = await this.outlookGen.markAsRead(args); return `āœ… **Mark read/unread processed!**\n\n${result}`; } async handleOutlookArchiveEmail(args) { const result = await this.outlookGen.archiveEmail(args); return `āœ… **Archive processed!**\n\n${result}`; } async handleOutlookCalendarView(args) { const result = await this.outlookGen.getCalendarView(args); const outputPath = args.outputPath || process.cwd(); const ext = args.outputFormat === 'json' ? 'json' : 'ics'; const filename = `calendar_view_${Date.now()}.${ext}`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Calendar view created!**\n\nšŸ“… **View:** ${args.viewType}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookSearchContacts(args) { const result = await this.outlookGen.searchContacts(args); const outputPath = args.outputPath || process.cwd(); const ext = args.outputFormat === 'json' ? 'json' : 'vcf'; const filename = `contacts_search_${Date.now()}.${ext}`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Contact search completed!**\n\nšŸ” **Query:** ${args.query}\nšŸ“ **File:** ${fullPath}`; } // ========== EXCEL v4.0 HANDLERS ========== async handleExcelPowerQuery(args) { const buffer = await this.excelGen.addPowerQuery(args.filename, args.sheetName, args.queryName, args.source, args.transformations); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Power Query added!**\n\nšŸ“Š **Query:** ${args.queryName}\nšŸ“ **File:** ${fullPath}`; } async handleExcelGoalSeek(args) { const buffer = await this.excelGen.goalSeek(args.filename, args.sheetName, args.setCell, args.toValue, args.byChangingCell); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Goal Seek configured!**\n\nšŸŽÆ **Target:** ${args.toValue}\nšŸ“ **Cell:** ${args.setCell}\nšŸ“ **File:** ${fullPath}`; } async handleExcelDataTable(args) { const buffer = await this.excelGen.createDataTable(args.filename, args.sheetName, args.type, args.formulaCell, args.rowInputCell, args.columnInputCell); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Data table created!**\n\nšŸ“Š **Type:** ${args.type}\nšŸ“ **File:** ${fullPath}`; } async handleExcelScenarioManager(args) { const buffer = await this.excelGen.manageScenarios(args.filename, args.sheetName, args.scenarios, args.resultCells); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Scenarios created!**\n\nšŸ“ˆ **Count:** ${args.scenarios.length}\nšŸ“ **File:** ${fullPath}`; } async handleExcelCreateTable(args) { const buffer = await this.excelGen.createTable(args.filename, args.sheetName, args.tableName, args.range, args.hasHeaders, args.style, args.showTotalRow); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Table created!**\n\nšŸ“Š **Name:** ${args.tableName}\nšŸ“ **Range:** ${args.range}\nšŸ“ **File:** ${fullPath}`; } async handleExcelTableFormula(args) { const buffer = await this.excelGen.addTableFormula(args.filename, args.sheetName, args.tableName, args.columnName, args.formula); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Table formula added!**\n\nšŸ“Š **Table:** ${args.tableName}\nšŸ“ **Column:** ${args.columnName}\nšŸ“ **File:** ${fullPath}`; } async handleExcelFormControls(args) { const buffer = await this.excelGen.addFormControls(args.filename, args.sheetName, args.controls); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Form controls added!**\n\nšŸ“Š **Count:** ${args.controls.length}\nšŸ“ **File:** ${fullPath}`; } async handleExcelInsertImages(args) { const buffer = await this.excelGen.insertImages(args.filename, args.sheetName, args.images); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Images inserted!**\n\nšŸ“Š **Count:** ${args.images.length}\nšŸ“ **File:** ${fullPath}`; } async handleExcelInsertShapes(args) { const buffer = await this.excelGen.insertShapes(args.filename, args.sheetName, args.shapes); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Shapes inserted!**\n\nšŸ“Š **Count:** ${args.shapes.length}\nšŸ“ **File:** ${fullPath}`; } async handleExcelSmartArt(args) { const buffer = await this.excelGen.addSmartArt(args.filename, args.sheetName, args.smartArt); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **SmartArt added!**\n\nšŸ“Š **Type:** ${args.smartArt.type}\nšŸ“ **File:** ${fullPath}`; } async handleExcelPageSetup(args) { const buffer = await this.excelGen.configurePageSetup(args.filename, args.sheetName, args.pageSetup); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Page setup configured!**\n\nšŸ“Š **Sheet:** ${args.sheetName}\nšŸ“ **File:** ${fullPath}`; } async handleExcelHeaderFooter(args) { const buffer = await this.excelGen.setHeaderFooter(args.filename, args.sheetName, args.header, args.footer, args.differentFirstPage, args.differentOddEven); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Headers/footers configured!**\n\nšŸ“Š **Sheet:** ${args.sheetName}\nšŸ“ **File:** ${fullPath}`; } async handleExcelPageBreaks(args) { const buffer = await this.excelGen.addPageBreaks(args.filename, args.sheetName, args.horizontalBreaks, args.verticalBreaks); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Page breaks configured!**\n\nšŸ“Š **Horizontal:** ${args.horizontalBreaks?.length || 0}\nšŸ“Š **Vertical:** ${args.verticalBreaks?.length || 0}\nšŸ“ **File:** ${fullPath}`; } async handleExcelTrackChanges(args) { const buffer = await this.excelGen.enableTrackChanges(args.filename, args.enable, args.highlightChanges); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Track changes ${args.enable ? 'enabled' : 'disabled'}!**\n\nšŸ“Š **File:** ${fullPath}`; } async handleExcelShareWorkbook(args) { const buffer = await this.excelGen.shareWorkbook(args.filename, args.share, args.allowChanges, args.password); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Workbook sharing ${args.share ? 'enabled' : 'disabled'}!**\n\nšŸ“Š **File:** ${fullPath}`; } async handleExcelCompareVersions(args) { // TODO: compareVersions method not yet implemented in ExcelGenerator // const buffer = await this.excelGen.compareVersions(args.originalFile, args.revisedFile, args.highlightDifferences); // const outputPath = args.outputPath || path.dirname(args.originalFile); // const fullPath = path.join(outputPath, 'comparison.xlsx'); // await fs.writeFile(fullPath, buffer); return `āš ļø **Compare versions feature not yet implemented.**\n\nPlease check back in a future version of Office Whisperer.`; } async handleExcelAddComments(args) { const buffer = await this.excelGen.addComments(args.filename, args.sheetName, args.comments); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Comments added!**\n\nšŸ“Š **Count:** ${args.comments.length}\nšŸ“ **File:** ${fullPath}`; } // ========== WORD v4.0 HANDLERS ========== async handleWordBibliography(args) { const buffer = await this.wordGen.addBibliography(args.filename, args.sources, args.style, args.insertAt); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Bibliography created!**\n\nšŸ“„ **Style:** ${args.style || 'APA'}\nšŸ“„ **Sources:** ${args.sources.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordCitations(args) { const buffer = await this.wordGen.insertCitations(args.filename, args.citations); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Citations added!**\n\nšŸ“„ **Count:** ${args.citations.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordIndex(args) { const buffer = await this.wordGen.createIndex(args.filename, args.entries, args.title, args.columns, args.insertAt); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Index generated!**\n\nšŸ“„ **Entries:** ${args.entries.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordMarkIndexEntry(args) { const buffer = await this.wordGen.markIndexEntry(args.filename, args.textToMark, args.entryText, args.crossReference); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Index entry marked!**\n\nšŸ“„ **Text:** ${args.textToMark}\nšŸ“ **File:** ${fullPath}`; } async handleWordFormFields(args) { const buffer = await this.wordGen.addFormFields(args.filename, args.fields, args.protectForm); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Form fields added!**\n\nšŸ“„ **Count:** ${args.fields.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordContentControls(args) { const buffer = await this.wordGen.addContentControls(args.filename, args.controls); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Content controls added!**\n\nšŸ“„ **Count:** ${args.controls.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordSmartArt(args) { const buffer = await this.wordGen.insertSmartArt(args.filename, args.smartArt, args.position); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **SmartArt inserted!**\n\nšŸ“„ **Type:** ${args.smartArt.type}\nšŸ“ **File:** ${fullPath}`; } async handleWordEquations(args) { const buffer = await this.wordGen.addEquations(args.filename, args.equations); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Equations inserted!**\n\nšŸ“„ **Count:** ${args.equations.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordSymbols(args) { const buffer = await this.wordGen.insertSymbols(args.filename, args.symbols); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Symbols inserted!**\n\nšŸ“„ **Count:** ${args.symbols.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordAccessibilityCheck(args) { const buffer = await this.wordGen.checkAccessibility(args.filename, args.checks, args.autoFix); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Accessibility check complete!**\n\nšŸ“„ **Auto-fix:** ${args.autoFix ? 'Yes' : 'No'}\nšŸ“ **File:** ${fullPath}`; } async handleWordAltText(args) { const buffer = await this.wordGen.setAltText(args.filename, args.altTexts); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Alt text added!**\n\nšŸ“„ **Count:** ${args.altTexts.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordDigitalSignature(args) { const buffer = await this.wordGen.addDigitalSignature(args.filename, args.action, args.certificatePath, args.password, args.reason); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Digital signature ${args.action}!**\n\nšŸ“„ **Action:** ${args.action}\nšŸ“ **File:** ${fullPath}`; } async handleWordProtectDocument(args) { const buffer = await this.wordGen.protectDocument(args.filename, args.protection); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Document protected!**\n\nšŸ“„ **Type:** ${args.protection.type}\nšŸ“ **File:** ${fullPath}`; } async handleWordMasterDocument(args) { const buffer = await this.wordGen.createMasterDocument(args.filename, args.subdocuments, args.generateTOC); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Master document created!**\n\nšŸ“„ **Subdocuments:** ${args.subdocuments.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordDocumentInfo(args) { const buffer = await this.wordGen.setDocumentInfo(args.filename, args.info); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Document metadata updated!**\n\nšŸ“„ **File:** ${fullPath}`; } async handleWordCaptions(args) { const buffer = await this.wordGen.addCaptions(args.filename, args.captions); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Captions added!**\n\nšŸ“„ **Count:** ${args.captions.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordAdvancedHyperlinks(args) { const buffer = await this.wordGen.addAdvancedHyperlinks(args.filename, args.hyperlinks); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Hyperlinks added!**\n\nšŸ“„ **Count:** ${args.hyperlinks.length}\nšŸ“ **File:** ${fullPath}`; } async handleWordDropCap(args) { const buffer = await this.wordGen.addDropCap(args.filename, args.paragraphIndex, args.style, args.lines); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Drop cap added!**\n\nšŸ“„ **Style:** ${args.style}\nšŸ“ **File:** ${fullPath}`; } async handleWordWatermark(args) { const buffer = await this.wordGen.addWatermark(args.filename, args.watermark); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Watermark added!**\n\nšŸ“„ **Type:** ${args.watermark.type}\nšŸ“ **File:** ${fullPath}`; } // ========== POWERPOINT v4.0 HANDLERS ========== async handlePPTSmartArt(args) { const buffer = await this.pptGen.addSmartArt(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **SmartArt added!**\n\nšŸŽÆ **Type:** ${args.smartArt.type}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPTInsertIcons(args) { const buffer = await this.pptGen.insertIcons(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Icons inserted!**\n\nšŸŽÆ **Count:** ${args.icons.length}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPT3DModels(args) { const buffer = await this.pptGen.insert3DModels(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **3D models inserted!**\n\nšŸŽÆ **Count:** ${args.models.length}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPTZoom(args) { const buffer = await this.pptGen.addZoom(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Zoom added!**\n\nšŸŽÆ **Count:** ${args.zooms.length}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPTRecording(args) { const buffer = await this.pptGen.configureRecording(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Recording configured!**\n\nšŸŽÆ **Type:** ${args.recording.type}\nšŸ“ **File:** ${fullPath}`; } async handlePPTLiveWeb(args) { const buffer = await this.pptGen.embedLiveWeb(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Live web page embedded!**\n\nšŸŽÆ **Count:** ${args.webPages.length}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPTDesigner(args) { const buffer = await this.pptGen.applyDesigner(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Designer configured!**\n\nšŸŽÆ **File:** ${fullPath}`; } async handlePPTCollaboration(args) { const buffer = await this.pptGen.addCollaborationComments(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Comments added!**\n\nšŸŽÆ **Count:** ${args.comments.length}\nšŸ“ **File:** ${fullPath}`; } async handlePPTPresenterCoach(args) { const buffer = await this.pptGen.configurePresenterCoach(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Presenter Coach configured!**\n\nšŸŽÆ **File:** ${fullPath}`; } async handlePPTSubtitles(args) { const buffer = await this.pptGen.configureSubtitles(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Subtitles configured!**\n\nšŸŽÆ **Language:** ${args.subtitles.language || 'auto'}\nšŸ“ **File:** ${fullPath}`; } async handlePPTInkAnnotations(args) { const buffer = await this.pptGen.addInkAnnotations(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Ink annotations added!**\n\nšŸŽÆ **Count:** ${args.annotations.length}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPTGridGuides(args) { const buffer = await this.pptGen.configureGridGuides(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Grid/guides configured!**\n\nšŸŽÆ **File:** ${fullPath}`; } async handlePPTCustomShow(args) { const buffer = await this.pptGen.createCustomShow(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Custom shows created!**\n\nšŸŽÆ **Count:** ${args.shows.length}\nšŸ“ **File:** ${fullPath}`; } async handlePPTAnimationPane(args) { const buffer = await this.pptGen.manageAnimationPane(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Animations configured!**\n\nšŸŽÆ **Count:** ${args.animations.length}\nšŸ“Š **Slide:** ${args.slideNumber}\nšŸ“ **File:** ${fullPath}`; } async handlePPTSlideMasterAdvanced(args) { const buffer = await this.pptGen.customizeSlideMaster(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Slide master customized!**\n\nšŸŽÆ **File:** ${fullPath}`; } async handlePPTTheme(args) { const buffer = await this.pptGen.applyPresentationTheme(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename)); await fs.writeFile(fullPath, buffer); return `āœ… **Theme applied!**\n\nšŸŽÆ **Name:** ${args.theme.name || 'Custom'}\nšŸ“ **File:** ${fullPath}`; } async handlePPTTemplate(args) { const buffer = await this.pptGen.saveAsTemplate(args); const outputPath = args.outputPath || path.dirname(args.filename); const fullPath = path.join(outputPath, path.basename(args.filename).replace(/\.pptx$/i, '.potx')); await fs.writeFile(fullPath, buffer); return `āœ… **Template saved!**\n\nšŸŽÆ **Title:** ${args.template.title}\nšŸ“ **File:** ${fullPath}`; } // ========== OUTLOOK v4.0 HANDLERS ========== async handleOutlookReadFullEmail(args) { const result = await this.outlookGen.readFullEmail(args); const outputPath = args.outputPath || process.cwd(); const filename = `email_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Full email read!**\n\nšŸ“§ **Messages:** ${args.messageIds.length}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookDeleteEmail(args) { const result = await this.outlookGen.deleteEmail(args); return `āœ… **Emails deleted!**\n\nšŸ“§ ${result}`; } async handleOutlookMoveEmail(args) { const result = await this.outlookGen.moveEmail(args); return `āœ… **Emails moved!**\n\nšŸ“§ **To:** ${args.toFolder}\nšŸ“§ ${result}`; } async handleOutlookCreateFolder(args) { const result = await this.outlookGen.createFolder(args); return `āœ… **Folder created!**\n\nšŸ“§ **Path:** ${args.folderPath}\nšŸ“§ ${result}`; } async handleOutlookSharedMailbox(args) { const result = await this.outlookGen.accessSharedMailbox(args); const outputPath = args.outputPath || process.cwd(); if (args.outputPath && typeof result === 'string') { const filename = `shared_mailbox_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Shared mailbox operation complete!**\n\nšŸ“§ **Mailbox:** ${args.sharedMailbox}\nšŸ“§ **Operation:** ${args.operation}\nšŸ“ **File:** ${fullPath}`; } return `āœ… **Shared mailbox operation complete!**\n\nšŸ“§ **Mailbox:** ${args.sharedMailbox}\nšŸ“§ **Operation:** ${args.operation}`; } async handleOutlookDelegateAccess(args) { const result = await this.outlookGen.grantDelegateAccess(args); const outputPath = args.outputPath || process.cwd(); const filename = `delegate_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Delegate access granted!**\n\nšŸ“§ **Delegate:** ${args.delegateEmail}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookOutOfOffice(args) { const result = await this.outlookGen.setOutOfOffice(args); const outputPath = args.outputPath || process.cwd(); const filename = `out_of_office_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Out of office ${args.enable ? 'enabled' : 'disabled'}!**\n\nšŸ“§ **File:** ${fullPath}`; } async handleOutlookNotes(args) { const result = await this.outlookGen.createNotes(args); const outputPath = args.outputPath || process.cwd(); const filename = `notes_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Notes created!**\n\nšŸ“§ **Count:** ${args.notes.length}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookJournal(args) { const result = await this.outlookGen.createJournalEntry(args); const outputPath = args.outputPath || process.cwd(); const filename = `journal_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Journal entries created!**\n\nšŸ“§ **Count:** ${args.entries.length}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookRSSFeed(args) { const result = await this.outlookGen.manageRSSFeed(args); const outputPath = args.outputPath || process.cwd(); const filename = `rss_feeds_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **RSS feed operation complete!**\n\nšŸ“§ **Operation:** ${args.operation}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookDataFile(args) { const result = await this.outlookGen.manageDataFile(args); const outputPath = args.outputPath || process.cwd(); const filename = `data_file_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Data file operation complete!**\n\nšŸ“§ **Operation:** ${args.operation}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookQuickSteps(args) { const result = await this.outlookGen.createQuickStep(args); const outputPath = args.outputPath || process.cwd(); const filename = `quick_steps_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Quick Steps created!**\n\nšŸ“§ **Count:** ${args.steps.length}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookConversationView(args) { const result = await this.outlookGen.configureConversationView(args); const outputPath = args.outputPath || process.cwd(); const filename = `conversation_view_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Conversation view ${args.enable ? 'enabled' : 'disabled'}!**\n\nšŸ“§ **File:** ${fullPath}`; } async handleOutlookCleanup(args) { const result = await this.outlookGen.cleanupMessages(args); return `āœ… **Cleanup complete!**\n\nšŸ“§ **Scope:** ${args.scope}\nšŸ“§ ${result}`; } async handleOutlookIgnoreConversation(args) { const result = await this.outlookGen.ignoreConversation(args); return `āœ… **Conversation ${args.restore ? 'restored' : 'ignored'}!**\n\nšŸ“§ ${result}`; } async handleOutlookFlagEmail(args) { const result = await this.outlookGen.flagEmail(args); return `āœ… **Emails flagged!**\n\nšŸ“§ **Type:** ${args.flag.type}\nšŸ“§ ${result}`; } async handleOutlookCategories(args) { const result = await this.outlookGen.manageCategories(args); const outputPath = args.outputPath || process.cwd(); if (args.outputPath && typeof result === 'string') { const filename = `categories_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Category operation complete!**\n\nšŸ“§ **Operation:** ${args.operation}\nšŸ“ **File:** ${fullPath}`; } return `āœ… **Category operation complete!**\n\nšŸ“§ **Operation:** ${args.operation}`; } async handleOutlookSignature(args) { const result = await this.outlookGen.createSignature(args); const outputPath = args.outputPath || process.cwd(); const filename = `signatures_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Signatures created!**\n\nšŸ“§ **Count:** ${args.signatures.length}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookAutocomplete(args) { const result = await this.outlookGen.manageAutoComplete(args); const outputPath = args.outputPath || process.cwd(); const filename = `autocomplete_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Autocomplete operation complete!**\n\nšŸ“§ **Operation:** ${args.operation}\nšŸ“ **File:** ${fullPath}`; } async handleOutlookMailMergeAdvanced(args) { const result = await this.outlookGen.advancedMailMerge(args); const outputPath = args.outputPath || process.cwd(); const filename = `mail_merge_${Date.now()}.json`; const fullPath = path.join(outputPath, filename); await fs.writeFile(fullPath, result, 'utf-8'); return `āœ… **Mail merge complete!**\n\nšŸ“§ **Recipients:** ${args.dataSource.length}\nšŸ“ **File:** ${fullPath}`; } } // Start the server const server = new OfficeWhispererServer(); server.start().catch(console.error); //# sourceMappingURL=mcp-server.js.map

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/consigcody94/office-whisperer'

If you have feedback or need assistance with the MCP directory API, please join our Discord server