docsmith-mcp 0.0.1-beta.2 → 0.0.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -125,6 +125,7 @@ function detectFileType(filePath) {
125
125
  const ext = filePath.toLowerCase().split(".").pop();
126
126
  if (ext === "xlsx" || ext === "xls") return "excel";
127
127
  if (ext === "docx") return "word";
128
+ if (ext === "pptx" || ext === "ppt") return "pptx";
128
129
  if (ext === "pdf") return "pdf";
129
130
  if (ext === "txt" || ext === "csv" || ext === "md" || ext === "json" || ext === "yaml" || ext === "yml") return "text";
130
131
  return null;
@@ -136,6 +137,7 @@ function getPackages(fileType) {
136
137
  const packages = {
137
138
  excel: { openpyxl: "openpyxl" },
138
139
  word: { docx: "python-docx" },
140
+ pptx: { pptx: "python-pptx" },
139
141
  pdf: { PyPDF2: "PyPDF2" },
140
142
  text: {}
141
143
  };
@@ -156,6 +158,13 @@ function getConfig() {
156
158
  //#region src/index.ts
157
159
  const ReadDocumentSchema = zod.z.object({
158
160
  file_path: zod.z.string().describe("Absolute path to the document file"),
161
+ file_type: zod.z.enum([
162
+ "excel",
163
+ "word",
164
+ "pptx",
165
+ "pdf",
166
+ "text"
167
+ ]).optional().describe("Override file type detection. Use this to explicitly specify the format instead of relying on file extension"),
159
168
  mode: zod.z.enum(["raw", "paginated"]).optional().describe("Read mode: 'raw' for full content, 'paginated' for chunked reading"),
160
169
  page: zod.z.number().optional().describe("Page number for paginated mode (1-based)"),
161
170
  page_size: zod.z.number().optional().describe("Items per page for paginated mode"),
@@ -166,11 +175,21 @@ const WriteDocumentSchema = zod.z.object({
166
175
  format: zod.z.enum([
167
176
  "excel",
168
177
  "word",
178
+ "pptx",
169
179
  "text"
170
180
  ]).describe("Document format"),
171
181
  data: zod.z.any().describe("Document data structure")
172
182
  });
173
- const GetDocumentInfoSchema = zod.z.object({ file_path: zod.z.string().describe("Absolute path to the document file") });
183
+ const GetDocumentInfoSchema = zod.z.object({
184
+ file_path: zod.z.string().describe("Absolute path to the document file"),
185
+ file_type: zod.z.enum([
186
+ "excel",
187
+ "word",
188
+ "pptx",
189
+ "pdf",
190
+ "text"
191
+ ]).optional().describe("Override file type detection. Use this to explicitly specify the format instead of relying on file extension")
192
+ });
174
193
  const server = new __modelcontextprotocol_sdk_server_index_js.Server({
175
194
  name: "docsmith-mcp",
176
195
  version: "0.1.0"
@@ -271,28 +290,6 @@ const WordReadOutputSchema = {
271
290
  ...PaginationSchema
272
291
  }
273
292
  };
274
- const PDFReadOutputSchema = {
275
- type: "object",
276
- properties: {
277
- total_pages: {
278
- type: "number",
279
- description: "Total pages in PDF"
280
- },
281
- content: {
282
- type: "array",
283
- items: {
284
- type: "object",
285
- properties: {
286
- page_number: { type: "number" },
287
- text: { type: "string" }
288
- }
289
- },
290
- description: "Page content array"
291
- },
292
- current_page_group: { type: "number" },
293
- page_size: { type: "number" }
294
- }
295
- };
296
293
  const TextReadOutputSchema = {
297
294
  type: "object",
298
295
  properties: {
@@ -372,61 +369,6 @@ const WriteOutputSchema = {
372
369
  }
373
370
  }
374
371
  };
375
- const ExcelInfoOutputSchema = {
376
- type: "object",
377
- properties: {
378
- sheets: {
379
- type: "array",
380
- items: {
381
- type: "object",
382
- properties: {
383
- name: { type: "string" },
384
- rows: { type: "number" },
385
- cols: { type: "number" }
386
- }
387
- },
388
- description: "Sheet information"
389
- },
390
- file_size: {
391
- type: "number",
392
- description: "File size in bytes"
393
- }
394
- }
395
- };
396
- const WordInfoOutputSchema = {
397
- type: "object",
398
- properties: {
399
- paragraphs: {
400
- type: "number",
401
- description: "Paragraph count"
402
- },
403
- tables: {
404
- type: "number",
405
- description: "Table count"
406
- },
407
- file_size: {
408
- type: "number",
409
- description: "File size in bytes"
410
- }
411
- }
412
- };
413
- const PDFInfoOutputSchema = {
414
- type: "object",
415
- properties: {
416
- pages: {
417
- type: "number",
418
- description: "Page count"
419
- },
420
- file_size: {
421
- type: "number",
422
- description: "File size in bytes"
423
- },
424
- total_words: {
425
- type: "number",
426
- description: "Total word count"
427
- }
428
- }
429
- };
430
372
  const TextInfoOutputSchema = {
431
373
  type: "object",
432
374
  properties: {
@@ -461,7 +403,7 @@ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.ListToolsRequestSch
461
403
  return { tools: [
462
404
  {
463
405
  name: "read_document",
464
- description: "Read document content (Excel, Word, PDF, TXT, CSV, Markdown, JSON, YAML). Supports raw full read or paginated mode.",
406
+ description: "Read document content (Excel, Word, PowerPoint, PDF, TXT, CSV, Markdown, JSON, YAML). Supports raw full read or paginated mode.",
465
407
  inputSchema: {
466
408
  type: "object",
467
409
  properties: {
@@ -469,6 +411,17 @@ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.ListToolsRequestSch
469
411
  type: "string",
470
412
  description: "Absolute path to the document file"
471
413
  },
414
+ file_type: {
415
+ type: "string",
416
+ enum: [
417
+ "excel",
418
+ "word",
419
+ "pptx",
420
+ "pdf",
421
+ "text"
422
+ ],
423
+ description: "Override file type detection (optional). Specify format explicitly instead of relying on extension"
424
+ },
472
425
  mode: {
473
426
  type: "string",
474
427
  enum: ["raw", "paginated"],
@@ -491,20 +444,56 @@ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.ListToolsRequestSch
491
444
  },
492
445
  outputSchema: {
493
446
  type: "object",
494
- description: "Returns different structures based on file type: Excel (sheet data), Word (paragraphs/tables), PDF (page content), Text (plain text), CSV (structured rows), JSON (parsed object)",
495
- oneOf: [
496
- ExcelReadOutputSchema,
497
- WordReadOutputSchema,
498
- PDFReadOutputSchema,
499
- TextReadOutputSchema,
500
- CSVReadOutputSchema,
501
- JSONReadOutputSchema
502
- ]
447
+ description: "Document content with format-specific structure. Common fields: success (boolean), error (string, on failure).",
448
+ properties: {
449
+ success: { type: "boolean" },
450
+ error: { type: "string" },
451
+ encoding: { type: "string" },
452
+ sheet_name: { type: "string" },
453
+ sheets: {
454
+ type: "array",
455
+ items: { type: "string" }
456
+ },
457
+ total_rows: { type: "number" },
458
+ total_cols: { type: "number" },
459
+ current_page: { type: ["number", "null"] },
460
+ total_pages: { type: "number" },
461
+ paragraphs: { type: "array" },
462
+ tables: { type: "array" },
463
+ total_paragraphs: { type: "number" },
464
+ total_tables: { type: "number" },
465
+ total_slides: { type: "number" },
466
+ slides: {
467
+ type: "array",
468
+ items: {
469
+ type: "object",
470
+ properties: {
471
+ slide_number: { type: "number" },
472
+ title: { type: "string" },
473
+ content: { type: "array" },
474
+ notes: { type: "string" }
475
+ }
476
+ }
477
+ },
478
+ current_page_group: { type: ["number", "null"] },
479
+ total_page_groups: { type: "number" },
480
+ content: {},
481
+ total_lines: { type: "number" },
482
+ headers: {
483
+ type: "array",
484
+ items: { type: "string" }
485
+ },
486
+ data: {},
487
+ page: { type: "number" },
488
+ page_size: { type: ["number", "null"] },
489
+ has_more: { type: "boolean" }
490
+ },
491
+ additionalProperties: false
503
492
  }
504
493
  },
505
494
  {
506
495
  name: "write_document",
507
- description: "Write document content (Excel, Word, Text)",
496
+ description: "Write document content (Excel, Word, PowerPoint, Text)",
508
497
  inputSchema: {
509
498
  type: "object",
510
499
  properties: {
@@ -517,6 +506,7 @@ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.ListToolsRequestSch
517
506
  enum: [
518
507
  "excel",
519
508
  "word",
509
+ "pptx",
520
510
  "text"
521
511
  ],
522
512
  description: "Document format"
@@ -533,24 +523,65 @@ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.ListToolsRequestSch
533
523
  },
534
524
  {
535
525
  name: "get_document_info",
536
- description: "Get document metadata (page count, sheet count, file size, etc.)",
526
+ description: "Get document metadata (page count, sheet count, slide count, file size, etc.)",
537
527
  inputSchema: {
538
528
  type: "object",
539
- properties: { file_path: {
540
- type: "string",
541
- description: "Absolute path to the document file"
542
- } },
529
+ properties: {
530
+ file_path: {
531
+ type: "string",
532
+ description: "Absolute path to the document file"
533
+ },
534
+ file_type: {
535
+ type: "string",
536
+ enum: [
537
+ "excel",
538
+ "word",
539
+ "pptx",
540
+ "pdf",
541
+ "text"
542
+ ],
543
+ description: "Override file type detection (optional). Specify format explicitly instead of relying on extension"
544
+ }
545
+ },
543
546
  required: ["file_path"]
544
547
  },
545
548
  outputSchema: {
546
549
  type: "object",
547
- description: "Returns metadata based on file type",
548
- oneOf: [
549
- ExcelInfoOutputSchema,
550
- WordInfoOutputSchema,
551
- PDFInfoOutputSchema,
552
- TextInfoOutputSchema
553
- ]
550
+ description: "Document metadata with format-specific fields",
551
+ properties: {
552
+ success: { type: "boolean" },
553
+ error: { type: "string" },
554
+ file_size: { type: "number" },
555
+ sheets: {
556
+ type: "array",
557
+ items: {
558
+ type: "object",
559
+ properties: {
560
+ name: { type: "string" },
561
+ rows: { type: "number" },
562
+ cols: { type: "number" }
563
+ }
564
+ }
565
+ },
566
+ paragraphs: { type: "number" },
567
+ tables: { type: "number" },
568
+ slides: { type: "number" },
569
+ pages: { type: "number" },
570
+ total_words: { type: "number" },
571
+ metadata: { type: "object" },
572
+ line_count: { type: "number" },
573
+ encoding: { type: "string" },
574
+ file_type: { type: "string" },
575
+ headers: {
576
+ type: "array",
577
+ items: { type: "string" }
578
+ },
579
+ total_rows: { type: "number" },
580
+ total_cols: { type: "number" },
581
+ item_count: { type: "number" },
582
+ key_count: { type: "number" }
583
+ },
584
+ additionalProperties: false
554
585
  }
555
586
  }
556
587
  ] };
@@ -560,7 +591,7 @@ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.CallToolRequestSche
560
591
  try {
561
592
  if (name === "read_document") {
562
593
  const params = ReadDocumentSchema.parse(args);
563
- const fileType = detectFileType(params.file_path);
594
+ const fileType = params.file_type || detectFileType(params.file_path);
564
595
  if (!fileType) throw new Error(`Unsupported file type: ${params.file_path}`);
565
596
  const config = getConfig();
566
597
  const mode = params.mode || (config.rawFullRead ? "raw" : "paginated");
@@ -583,6 +614,13 @@ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.CallToolRequestSche
583
614
  scriptArgs.push(String(page));
584
615
  scriptArgs.push(String(pageSize));
585
616
  }
617
+ } else if (fileType === "pptx") {
618
+ scriptName = "pptx_handler.py";
619
+ scriptArgs = ["read", params.file_path];
620
+ if (page) {
621
+ scriptArgs.push(String(page));
622
+ scriptArgs.push(String(pageSize));
623
+ }
586
624
  } else if (fileType === "pdf") {
587
625
  scriptName = "pdf_handler.py";
588
626
  scriptArgs = ["read", params.file_path];
@@ -632,6 +670,14 @@ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.CallToolRequestSche
632
670
  JSON.stringify(paragraphs)
633
671
  ];
634
672
  if (tables) scriptArgs.push(JSON.stringify(tables));
673
+ } else if (params.format === "pptx") {
674
+ scriptName = "pptx_handler.py";
675
+ const slides = params.data.slides || params.data || [];
676
+ scriptArgs = [
677
+ "write",
678
+ params.file_path,
679
+ JSON.stringify(slides)
680
+ ];
635
681
  } else if (params.format === "text") {
636
682
  scriptName = "text_handler.py";
637
683
  const content = typeof params.data === "string" ? params.data : JSON.stringify(params.data);
@@ -656,12 +702,13 @@ server.setRequestHandler(__modelcontextprotocol_sdk_types_js.CallToolRequestSche
656
702
  }
657
703
  if (name === "get_document_info") {
658
704
  const params = GetDocumentInfoSchema.parse(args);
659
- const fileType = detectFileType(params.file_path);
705
+ const fileType = params.file_type || detectFileType(params.file_path);
660
706
  if (!fileType) throw new Error(`Unsupported file type: ${params.file_path}`);
661
707
  let scriptName;
662
708
  let scriptArgs = ["info", params.file_path];
663
709
  if (fileType === "excel") scriptName = "excel_handler.py";
664
710
  else if (fileType === "word") scriptName = "word_handler.py";
711
+ else if (fileType === "pptx") scriptName = "pptx_handler.py";
665
712
  else if (fileType === "pdf") scriptName = "pdf_handler.py";
666
713
  else scriptName = "text_handler.py";
667
714
  const result = await runPythonFile(scriptName, {
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["__filename","__dirname","filePath: string","scriptPath: string","options: RunPythonFileOptions","runPyOptions: RunPyOptions","filePath: string","fileType: string","packages: Record<string, Record<string, string>>","Server","ListToolsRequestSchema","CallToolRequestSchema","scriptName: string","scriptArgs: string[]","StdioServerTransport"],"sources":["../src/code-runner.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["/**\n * Code runner client - uses @mcpc-tech/code-runner-mcp npm package\n */\nimport { runPy, type RunPyOptions } from \"@mcpc-tech/code-runner-mcp\";\nimport { readFileSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join, resolve } from \"path\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Options for running Python script files\n */\nexport interface RunPythonFileOptions {\n /** Command line arguments to pass to the script */\n args?: string[];\n /** Package name mappings (import_name -> pypi_name) */\n packages?: Record<string, string>;\n /** Base directory for the script (default: \"python\") */\n baseDir?: string;\n /** User file paths that need to be accessible (for file system mounting) */\n filePaths?: string[];\n}\n\n/**\n * Convert absolute file path to Pyodide virtual path\n * Determines the mount root and converts the path accordingly\n *\n * @param filePath - Absolute path to the file\n * @returns Object with mountRoot (host path) and virtualPath (Pyodide path)\n */\nfunction getFileSystemMapping(\n filePath: string,\n): { mountRoot: string; virtualPath: string } {\n const absolutePath = resolve(filePath);\n\n // Mount the parent directory of the file\n // This allows Python to access the file and its siblings\n const mountRoot = dirname(absolutePath);\n const virtualPath = absolutePath;\n\n return { mountRoot, virtualPath };\n}\n\n/**\n * Run a Python script file using code-runner-mcp\n *\n * @param scriptPath - Path to the Python script (relative to baseDir)\n * @param options - Execution options\n * @returns The execution result\n */\nexport async function runPythonFile(\n scriptPath: string,\n options: RunPythonFileOptions = {},\n): Promise<any> {\n const {\n args = [],\n packages = {},\n baseDir = \"python\",\n filePaths = [],\n } = options;\n\n // Read the Python script\n // Python files are in the python/ directory at project root\n // From dist/index.js, go up one level to reach python/\n const fullPath = join(__dirname, \"..\", baseDir, scriptPath);\n const scriptContent = readFileSync(fullPath, \"utf-8\");\n\n // Build wrapper code that sets sys.argv and executes the script\n const wrapperCode = `\nimport sys\nimport json\n\n# Set command line arguments\nsys.argv = ['${scriptPath}'] + ${JSON.stringify(args)}\n\n# Execute the script\n${scriptContent}\n`;\n\n // Determine mount root from the first file path\n // Default: parent directory of dist/ (project root when running from dist/index.js)\n let mountRoot = join(__dirname, \"..\");\n if (filePaths.length > 0) {\n const mapping = getFileSystemMapping(filePaths[0]);\n mountRoot = mapping.mountRoot;\n }\n\n // Execute via runPy with options\n // Mount point is the same as the mount root (Pyodide will see host paths directly)\n const runPyOptions: RunPyOptions = {\n packages,\n nodeFSMountPoint: mountRoot,\n nodeFSRoot: mountRoot,\n };\n const stream = await runPy(wrapperCode, runPyOptions);\n\n // Read the stream output\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let stdout = \"\";\n let stderr = \"\";\n let error = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n if (chunk.startsWith(\"[stderr] \")) {\n stderr += chunk.slice(9);\n } else if (chunk.startsWith(\"[err]\")) {\n error += chunk;\n } else {\n stdout += chunk;\n }\n }\n } catch (streamError) {\n // Stream error means Python execution failed\n return { error: String(streamError) };\n }\n\n // Check for errors\n if (error) {\n return { error: error.replace(/\\[err\\]\\[py\\]\\s*/g, \"\").trim() };\n }\n\n // Parse the JSON output from the script (last line)\n const lines = stdout.trim().split(\"\\n\");\n const lastLine = lines[lines.length - 1];\n\n try {\n return JSON.parse(lastLine);\n } catch {\n return { stdout, stderr };\n }\n}\n","/**\n * Utility functions for document processing\n */\n\n/**\n * Detect file type from file extension\n */\nexport function detectFileType(\n filePath: string,\n): \"excel\" | \"word\" | \"pdf\" | \"text\" | null {\n const ext = filePath.toLowerCase().split(\".\").pop();\n if (ext === \"xlsx\" || ext === \"xls\") return \"excel\";\n if (ext === \"docx\") return \"word\";\n if (ext === \"pdf\") return \"pdf\";\n if (\n ext === \"txt\" || ext === \"csv\" || ext === \"md\" || ext === \"json\" ||\n ext === \"yaml\" || ext === \"yml\"\n ) return \"text\";\n return null;\n}\n\n/**\n * Get required packages for each file type\n */\nexport function getPackages(fileType: string): Record<string, string> {\n const packages: Record<string, Record<string, string>> = {\n excel: { openpyxl: \"openpyxl\" },\n word: { docx: \"python-docx\" }, // Map docx import to python-docx package\n pdf: { PyPDF2: \"PyPDF2\" },\n text: {}, // No external packages needed for text files\n };\n return packages[fileType] || {};\n}\n\n/**\n * Get environment configuration\n */\nexport function getConfig() {\n return {\n rawFullRead: process.env.DOC_RAW_FULL_READ === \"true\",\n pageSize: parseInt(process.env.DOC_PAGE_SIZE || \"100\", 10),\n maxFileSize: parseInt(process.env.DOC_MAX_FILE_SIZE || \"50\", 10) * 1024 *\n 1024,\n };\n}\n","#!/usr/bin/env node\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { runPythonFile } from \"./code-runner.js\";\nimport { detectFileType, getConfig, getPackages } from \"./utils.js\";\n\n// Tool schemas\nconst ReadDocumentSchema = z.object({\n file_path: z.string().describe(\"Absolute path to the document file\"),\n mode: z.enum([\"raw\", \"paginated\"]).optional().describe(\n \"Read mode: 'raw' for full content, 'paginated' for chunked reading\",\n ),\n page: z.number().optional().describe(\n \"Page number for paginated mode (1-based)\",\n ),\n page_size: z.number().optional().describe(\n \"Items per page for paginated mode\",\n ),\n sheet_name: z.string().optional().describe(\"Sheet name for Excel files\"),\n});\n\nconst WriteDocumentSchema = z.object({\n file_path: z.string().describe(\"Absolute path to save the document\"),\n format: z.enum([\"excel\", \"word\", \"text\"]).describe(\"Document format\"),\n data: z.any().describe(\"Document data structure\"),\n});\n\nconst GetDocumentInfoSchema = z.object({\n file_path: z.string().describe(\"Absolute path to the document file\"),\n});\n\n// Server setup\nconst server = new Server(\n {\n name: \"docsmith-mcp\",\n version: \"0.1.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n },\n);\n\n// Output schemas (reusable)\nconst BaseOutputSchema = {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Operation success status\" },\n error: { type: \"string\", description: \"Error message if failed\" },\n },\n} as const;\n\nconst PaginationSchema = {\n current_page: { type: \"number\", description: \"Current page number\" },\n page_size: { type: \"number\", description: \"Items per page\" },\n total_pages: { type: \"number\", description: \"Total number of pages\" },\n page: { type: \"number\", description: \"Current page number (alternative)\" },\n has_more: { type: \"boolean\", description: \"Whether more pages exist\" },\n} as const;\n\nconst ExcelReadOutputSchema = {\n type: \"object\",\n properties: {\n sheet_name: { type: \"string\", description: \"Active sheet name\" },\n sheets: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"All sheet names\",\n },\n total_rows: { type: \"number\", description: \"Total rows in sheet\" },\n total_cols: { type: \"number\", description: \"Total columns in sheet\" },\n data: {\n type: \"array\",\n items: { type: \"array\", items: {} },\n description: \"Sheet data as array of rows\",\n },\n ...PaginationSchema,\n },\n} as const;\n\nconst WordReadOutputSchema = {\n type: \"object\",\n properties: {\n paragraphs: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Document paragraphs\",\n },\n tables: {\n type: \"array\",\n items: {\n type: \"array\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n description: \"Tables data\",\n },\n total_paragraphs: { type: \"number\", description: \"Total paragraph count\" },\n total_tables: { type: \"number\", description: \"Total table count\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst PDFReadOutputSchema = {\n type: \"object\",\n properties: {\n total_pages: { type: \"number\", description: \"Total pages in PDF\" },\n content: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n page_number: { type: \"number\" },\n text: { type: \"string\" },\n },\n },\n description: \"Page content array\",\n },\n current_page_group: { type: \"number\" },\n page_size: { type: \"number\" },\n },\n} as const;\n\nconst TextReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n content: { type: \"string\", description: \"Text content\" },\n total_lines: { type: \"number\", description: \"Total line count\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst CSVReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n headers: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"CSV headers\",\n },\n data: {\n type: \"array\",\n items: { type: \"object\" },\n description: \"Structured data as array of objects\",\n },\n total_rows: { type: \"number\", description: \"Total data rows\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst JSONReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n data: { type: \"object\", description: \"Parsed JSON data\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n },\n} as const;\n\nconst WriteOutputSchema = {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Write operation success\" },\n file_path: { type: \"string\", description: \"Written file path\" },\n message: { type: \"string\", description: \"Success message\" },\n error: { type: \"string\", description: \"Error message if failed\" },\n },\n} as const;\n\nconst ExcelInfoOutputSchema = {\n type: \"object\",\n properties: {\n sheets: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n rows: { type: \"number\" },\n cols: { type: \"number\" },\n },\n },\n description: \"Sheet information\",\n },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n },\n} as const;\n\nconst WordInfoOutputSchema = {\n type: \"object\",\n properties: {\n paragraphs: { type: \"number\", description: \"Paragraph count\" },\n tables: { type: \"number\", description: \"Table count\" },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n },\n} as const;\n\nconst PDFInfoOutputSchema = {\n type: \"object\",\n properties: {\n pages: { type: \"number\", description: \"Page count\" },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n total_words: { type: \"number\", description: \"Total word count\" },\n },\n} as const;\n\nconst TextInfoOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n file_size: { type: \"number\", description: \"File size in bytes\" },\n line_count: { type: \"number\", description: \"Line count\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n file_type: { type: \"string\", description: \"File extension\" },\n // CSV specific\n headers: { type: \"array\", items: { type: \"string\" } },\n total_rows: { type: \"number\" },\n total_cols: { type: \"number\" },\n // JSON specific\n item_count: { type: \"number\" },\n key_count: { type: \"number\" },\n },\n} as const;\n\n// List available tools\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"read_document\",\n description:\n \"Read document content (Excel, Word, PDF, TXT, CSV, Markdown, JSON, YAML). Supports raw full read or paginated mode.\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to the document file\",\n },\n mode: {\n type: \"string\",\n enum: [\"raw\", \"paginated\"],\n description: \"Read mode\",\n },\n page: {\n type: \"number\",\n description: \"Page number for paginated mode\",\n },\n page_size: { type: \"number\", description: \"Items per page\" },\n sheet_name: {\n type: \"string\",\n description: \"Sheet name for Excel files\",\n },\n },\n required: [\"file_path\"],\n },\n outputSchema: {\n type: \"object\",\n description:\n \"Returns different structures based on file type: Excel (sheet data), Word (paragraphs/tables), PDF (page content), Text (plain text), CSV (structured rows), JSON (parsed object)\",\n oneOf: [\n ExcelReadOutputSchema,\n WordReadOutputSchema,\n PDFReadOutputSchema,\n TextReadOutputSchema,\n CSVReadOutputSchema,\n JSONReadOutputSchema,\n ],\n },\n },\n {\n name: \"write_document\",\n description: \"Write document content (Excel, Word, Text)\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to save the document\",\n },\n format: {\n type: \"string\",\n enum: [\"excel\", \"word\", \"text\"],\n description: \"Document format\",\n },\n data: {\n description:\n \"Document data structure. Excel: array of rows [[cell1, cell2], ...]. Word: {paragraphs: string[], tables?: [[[cell]]]}. Text/CSV/JSON: string or object\",\n },\n },\n required: [\"file_path\", \"format\", \"data\"],\n },\n outputSchema: WriteOutputSchema,\n },\n {\n name: \"get_document_info\",\n description:\n \"Get document metadata (page count, sheet count, file size, etc.)\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to the document file\",\n },\n },\n required: [\"file_path\"],\n },\n outputSchema: {\n type: \"object\",\n description: \"Returns metadata based on file type\",\n oneOf: [\n ExcelInfoOutputSchema,\n WordInfoOutputSchema,\n PDFInfoOutputSchema,\n TextInfoOutputSchema,\n ],\n },\n },\n ],\n };\n});\n\n// Handle tool calls\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n if (name === \"read_document\") {\n const params = ReadDocumentSchema.parse(args);\n const fileType = detectFileType(params.file_path);\n\n if (!fileType) {\n throw new Error(`Unsupported file type: ${params.file_path}`);\n }\n\n // Determine read mode\n const config = getConfig();\n const mode = params.mode || (config.rawFullRead ? \"raw\" : \"paginated\");\n const page = mode === \"paginated\" ? (params.page || 1) : undefined;\n const pageSize = params.page_size || config.pageSize;\n\n let scriptName: string;\n let scriptArgs: string[];\n\n if (fileType === \"excel\") {\n scriptName = \"excel_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (params.sheet_name) scriptArgs.push(params.sheet_name);\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"word\") {\n scriptName = \"word_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"pdf\") {\n scriptName = \"pdf_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(Math.min(pageSize, 10))); // PDF pages are larger\n }\n } else {\n // text files\n scriptName = \"text_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(fileType),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n if (name === \"write_document\") {\n const params = WriteDocumentSchema.parse(args);\n\n let scriptName: string;\n let scriptArgs: string[];\n\n if (params.format === \"excel\") {\n scriptName = \"excel_handler.py\";\n scriptArgs = [\"write\", params.file_path, JSON.stringify(params.data)];\n } else if (params.format === \"word\") {\n scriptName = \"word_handler.py\";\n const paragraphs = params.data.paragraphs || [];\n const tables = params.data.tables || null;\n scriptArgs = [\"write\", params.file_path, JSON.stringify(paragraphs)];\n if (tables) scriptArgs.push(JSON.stringify(tables));\n } else if (params.format === \"text\") {\n scriptName = \"text_handler.py\";\n const content = typeof params.data === \"string\"\n ? params.data\n : JSON.stringify(params.data);\n scriptArgs = [\"write\", params.file_path, content];\n } else {\n throw new Error(`Unsupported write format: ${params.format}`);\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(params.format),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n if (name === \"get_document_info\") {\n const params = GetDocumentInfoSchema.parse(args);\n const fileType = detectFileType(params.file_path);\n\n if (!fileType) {\n throw new Error(`Unsupported file type: ${params.file_path}`);\n }\n\n let scriptName: string;\n let scriptArgs = [\"info\", params.file_path];\n\n if (fileType === \"excel\") {\n scriptName = \"excel_handler.py\";\n } else if (fileType === \"word\") {\n scriptName = \"word_handler.py\";\n } else if (fileType === \"pdf\") {\n scriptName = \"pdf_handler.py\";\n } else {\n scriptName = \"text_handler.py\";\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(fileType),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n throw new Error(`Unknown tool: ${name}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: \"text\", text: `Error: ${errorMessage}` }],\n isError: true,\n };\n }\n});\n\n// Start server\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Docsmith MCP server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"Server error:\", error);\n process.exit(1);\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["__filename","__dirname","filePath: string","scriptPath: string","options: RunPythonFileOptions","runPyOptions: RunPyOptions","filePath: string","fileType: string","packages: Record<string, Record<string, string>>","Server","ListToolsRequestSchema","CallToolRequestSchema","scriptName: string","scriptArgs: string[]","StdioServerTransport"],"sources":["../src/code-runner.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["/**\n * Code runner client - uses @mcpc-tech/code-runner-mcp npm package\n */\nimport { runPy, type RunPyOptions } from \"@mcpc-tech/code-runner-mcp\";\nimport { readFileSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join, resolve } from \"path\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Options for running Python script files\n */\nexport interface RunPythonFileOptions {\n /** Command line arguments to pass to the script */\n args?: string[];\n /** Package name mappings (import_name -> pypi_name) */\n packages?: Record<string, string>;\n /** Base directory for the script (default: \"python\") */\n baseDir?: string;\n /** User file paths that need to be accessible (for file system mounting) */\n filePaths?: string[];\n}\n\n/**\n * Convert absolute file path to Pyodide virtual path\n * Determines the mount root and converts the path accordingly\n *\n * @param filePath - Absolute path to the file\n * @returns Object with mountRoot (host path) and virtualPath (Pyodide path)\n */\nfunction getFileSystemMapping(\n filePath: string,\n): { mountRoot: string; virtualPath: string } {\n const absolutePath = resolve(filePath);\n\n // Mount the parent directory of the file\n // This allows Python to access the file and its siblings\n const mountRoot = dirname(absolutePath);\n const virtualPath = absolutePath;\n\n return { mountRoot, virtualPath };\n}\n\n/**\n * Run a Python script file using code-runner-mcp\n *\n * @param scriptPath - Path to the Python script (relative to baseDir)\n * @param options - Execution options\n * @returns The execution result\n */\nexport async function runPythonFile(\n scriptPath: string,\n options: RunPythonFileOptions = {},\n): Promise<any> {\n const {\n args = [],\n packages = {},\n baseDir = \"python\",\n filePaths = [],\n } = options;\n\n // Read the Python script\n // Python files are in the python/ directory at project root\n // From dist/index.js, go up one level to reach python/\n const fullPath = join(__dirname, \"..\", baseDir, scriptPath);\n const scriptContent = readFileSync(fullPath, \"utf-8\");\n\n // Build wrapper code that sets sys.argv and executes the script\n const wrapperCode = `\nimport sys\nimport json\n\n# Set command line arguments\nsys.argv = ['${scriptPath}'] + ${JSON.stringify(args)}\n\n# Execute the script\n${scriptContent}\n`;\n\n // Determine mount root from the first file path\n // Default: parent directory of dist/ (project root when running from dist/index.js)\n let mountRoot = join(__dirname, \"..\");\n if (filePaths.length > 0) {\n const mapping = getFileSystemMapping(filePaths[0]);\n mountRoot = mapping.mountRoot;\n }\n\n // Execute via runPy with options\n // Mount point is the same as the mount root (Pyodide will see host paths directly)\n const runPyOptions: RunPyOptions = {\n packages,\n nodeFSMountPoint: mountRoot,\n nodeFSRoot: mountRoot,\n };\n const stream = await runPy(wrapperCode, runPyOptions);\n\n // Read the stream output\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let stdout = \"\";\n let stderr = \"\";\n let error = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n if (chunk.startsWith(\"[stderr] \")) {\n stderr += chunk.slice(9);\n } else if (chunk.startsWith(\"[err]\")) {\n error += chunk;\n } else {\n stdout += chunk;\n }\n }\n } catch (streamError) {\n // Stream error means Python execution failed\n return { error: String(streamError) };\n }\n\n // Check for errors\n if (error) {\n return { error: error.replace(/\\[err\\]\\[py\\]\\s*/g, \"\").trim() };\n }\n\n // Parse the JSON output from the script (last line)\n const lines = stdout.trim().split(\"\\n\");\n const lastLine = lines[lines.length - 1];\n\n try {\n return JSON.parse(lastLine);\n } catch {\n return { stdout, stderr };\n }\n}\n","/**\n * Utility functions for document processing\n */\n\n/**\n * Detect file type from file extension\n */\nexport function detectFileType(\n filePath: string,\n): \"excel\" | \"word\" | \"pdf\" | \"pptx\" | \"text\" | null {\n const ext = filePath.toLowerCase().split(\".\").pop();\n if (ext === \"xlsx\" || ext === \"xls\") return \"excel\";\n if (ext === \"docx\") return \"word\";\n if (ext === \"pptx\" || ext === \"ppt\") return \"pptx\";\n if (ext === \"pdf\") return \"pdf\";\n if (\n ext === \"txt\" || ext === \"csv\" || ext === \"md\" || ext === \"json\" ||\n ext === \"yaml\" || ext === \"yml\"\n ) return \"text\";\n return null;\n}\n\n/**\n * Get required packages for each file type\n */\nexport function getPackages(fileType: string): Record<string, string> {\n const packages: Record<string, Record<string, string>> = {\n excel: { openpyxl: \"openpyxl\" },\n word: { docx: \"python-docx\" }, // Map docx import to python-docx package\n pptx: { pptx: \"python-pptx\" }, // Map pptx import to python-pptx package\n pdf: { PyPDF2: \"PyPDF2\" },\n text: {}, // No external packages needed for text files\n };\n return packages[fileType] || {};\n}\n\n/**\n * Get environment configuration\n */\nexport function getConfig() {\n return {\n rawFullRead: process.env.DOC_RAW_FULL_READ === \"true\",\n pageSize: parseInt(process.env.DOC_PAGE_SIZE || \"100\", 10),\n maxFileSize: parseInt(process.env.DOC_MAX_FILE_SIZE || \"50\", 10) * 1024 *\n 1024,\n };\n}\n","#!/usr/bin/env node\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { runPythonFile } from \"./code-runner.js\";\nimport { detectFileType, getConfig, getPackages } from \"./utils.js\";\n\n// Tool schemas\nconst ReadDocumentSchema = z.object({\n file_path: z.string().describe(\"Absolute path to the document file\"),\n file_type: z.enum([\"excel\", \"word\", \"pptx\", \"pdf\", \"text\"]).optional()\n .describe(\n \"Override file type detection. Use this to explicitly specify the format instead of relying on file extension\",\n ),\n mode: z.enum([\"raw\", \"paginated\"]).optional().describe(\n \"Read mode: 'raw' for full content, 'paginated' for chunked reading\",\n ),\n page: z.number().optional().describe(\n \"Page number for paginated mode (1-based)\",\n ),\n page_size: z.number().optional().describe(\n \"Items per page for paginated mode\",\n ),\n sheet_name: z.string().optional().describe(\"Sheet name for Excel files\"),\n});\n\nconst WriteDocumentSchema = z.object({\n file_path: z.string().describe(\"Absolute path to save the document\"),\n format: z.enum([\"excel\", \"word\", \"pptx\", \"text\"]).describe(\n \"Document format\",\n ),\n data: z.any().describe(\"Document data structure\"),\n});\n\nconst GetDocumentInfoSchema = z.object({\n file_path: z.string().describe(\"Absolute path to the document file\"),\n file_type: z.enum([\"excel\", \"word\", \"pptx\", \"pdf\", \"text\"]).optional()\n .describe(\n \"Override file type detection. Use this to explicitly specify the format instead of relying on file extension\",\n ),\n});\n\n// Server setup\nconst server = new Server(\n {\n name: \"docsmith-mcp\",\n version: \"0.1.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n },\n);\n\n// Output schemas (reusable)\nconst BaseOutputSchema = {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Operation success status\" },\n error: { type: \"string\", description: \"Error message if failed\" },\n },\n} as const;\n\nconst PaginationSchema = {\n current_page: { type: \"number\", description: \"Current page number\" },\n page_size: { type: \"number\", description: \"Items per page\" },\n total_pages: { type: \"number\", description: \"Total number of pages\" },\n page: { type: \"number\", description: \"Current page number (alternative)\" },\n has_more: { type: \"boolean\", description: \"Whether more pages exist\" },\n} as const;\n\nconst ExcelReadOutputSchema = {\n type: \"object\",\n properties: {\n sheet_name: { type: \"string\", description: \"Active sheet name\" },\n sheets: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"All sheet names\",\n },\n total_rows: { type: \"number\", description: \"Total rows in sheet\" },\n total_cols: { type: \"number\", description: \"Total columns in sheet\" },\n data: {\n type: \"array\",\n items: { type: \"array\", items: {} },\n description: \"Sheet data as array of rows\",\n },\n ...PaginationSchema,\n },\n} as const;\n\nconst WordReadOutputSchema = {\n type: \"object\",\n properties: {\n paragraphs: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Document paragraphs\",\n },\n tables: {\n type: \"array\",\n items: {\n type: \"array\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n description: \"Tables data\",\n },\n total_paragraphs: { type: \"number\", description: \"Total paragraph count\" },\n total_tables: { type: \"number\", description: \"Total table count\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst PDFReadOutputSchema = {\n type: \"object\",\n properties: {\n total_pages: { type: \"number\", description: \"Total pages in PDF\" },\n content: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n page_number: { type: \"number\" },\n text: { type: \"string\" },\n },\n },\n description: \"Page content array\",\n },\n current_page_group: { type: \"number\" },\n page_size: { type: \"number\" },\n },\n} as const;\n\nconst TextReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n content: { type: \"string\", description: \"Text content\" },\n total_lines: { type: \"number\", description: \"Total line count\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst CSVReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n headers: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"CSV headers\",\n },\n data: {\n type: \"array\",\n items: { type: \"object\" },\n description: \"Structured data as array of objects\",\n },\n total_rows: { type: \"number\", description: \"Total data rows\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst JSONReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n data: { type: \"object\", description: \"Parsed JSON data\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n },\n} as const;\n\nconst WriteOutputSchema = {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Write operation success\" },\n file_path: { type: \"string\", description: \"Written file path\" },\n message: { type: \"string\", description: \"Success message\" },\n error: { type: \"string\", description: \"Error message if failed\" },\n },\n} as const;\n\nconst ExcelInfoOutputSchema = {\n type: \"object\",\n properties: {\n sheets: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n rows: { type: \"number\" },\n cols: { type: \"number\" },\n },\n },\n description: \"Sheet information\",\n },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n },\n} as const;\n\nconst WordInfoOutputSchema = {\n type: \"object\",\n properties: {\n paragraphs: { type: \"number\", description: \"Paragraph count\" },\n tables: { type: \"number\", description: \"Table count\" },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n },\n} as const;\n\nconst PDFInfoOutputSchema = {\n type: \"object\",\n properties: {\n pages: { type: \"number\", description: \"Page count\" },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n total_words: { type: \"number\", description: \"Total word count\" },\n },\n} as const;\n\nconst TextInfoOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n file_size: { type: \"number\", description: \"File size in bytes\" },\n line_count: { type: \"number\", description: \"Line count\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n file_type: { type: \"string\", description: \"File extension\" },\n // CSV specific\n headers: { type: \"array\", items: { type: \"string\" } },\n total_rows: { type: \"number\" },\n total_cols: { type: \"number\" },\n // JSON specific\n item_count: { type: \"number\" },\n key_count: { type: \"number\" },\n },\n} as const;\n\n// List available tools\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"read_document\",\n description:\n \"Read document content (Excel, Word, PowerPoint, PDF, TXT, CSV, Markdown, JSON, YAML). Supports raw full read or paginated mode.\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to the document file\",\n },\n file_type: {\n type: \"string\",\n enum: [\"excel\", \"word\", \"pptx\", \"pdf\", \"text\"],\n description:\n \"Override file type detection (optional). Specify format explicitly instead of relying on extension\",\n },\n mode: {\n type: \"string\",\n enum: [\"raw\", \"paginated\"],\n description: \"Read mode\",\n },\n page: {\n type: \"number\",\n description: \"Page number for paginated mode\",\n },\n page_size: { type: \"number\", description: \"Items per page\" },\n sheet_name: {\n type: \"string\",\n description: \"Sheet name for Excel files\",\n },\n },\n required: [\"file_path\"],\n },\n outputSchema: {\n type: \"object\",\n description:\n \"Document content with format-specific structure. Common fields: success (boolean), error (string, on failure).\",\n properties: {\n // Common fields\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n encoding: { type: \"string\" },\n\n // Excel-specific\n sheet_name: { type: \"string\" },\n sheets: { type: \"array\", items: { type: \"string\" } },\n total_rows: { type: \"number\" },\n total_cols: { type: \"number\" },\n current_page: { type: [\"number\", \"null\"] },\n total_pages: { type: \"number\" },\n\n // Word-specific\n paragraphs: { type: \"array\" },\n tables: { type: \"array\" },\n total_paragraphs: { type: \"number\" },\n total_tables: { type: \"number\" },\n\n // PowerPoint-specific\n total_slides: { type: \"number\" },\n slides: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n slide_number: { type: \"number\" },\n title: { type: \"string\" },\n content: { type: \"array\" },\n notes: { type: \"string\" },\n },\n },\n },\n\n // PDF-specific\n current_page_group: { type: [\"number\", \"null\"] },\n total_page_groups: { type: \"number\" },\n content: {}, // PDF: array of {page_number, text, words}, Text: string\n\n // Text/CSV-specific\n total_lines: { type: \"number\" },\n headers: { type: \"array\", items: { type: \"string\" } },\n\n // Data field (varies by format)\n data: {}, // Excel: array of arrays, CSV: array of objects, JSON: any\n\n // Pagination\n page: { type: \"number\" },\n page_size: { type: [\"number\", \"null\"] },\n has_more: { type: \"boolean\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"write_document\",\n description: \"Write document content (Excel, Word, PowerPoint, Text)\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to save the document\",\n },\n format: {\n type: \"string\",\n enum: [\"excel\", \"word\", \"pptx\", \"text\"],\n description: \"Document format\",\n },\n data: {\n description:\n \"Document data structure. Excel: array of rows [[cell1, cell2], ...]. Word: {paragraphs: string[], tables?: [[[cell]]]}. Text/CSV/JSON: string or object\",\n },\n },\n required: [\"file_path\", \"format\", \"data\"],\n },\n outputSchema: WriteOutputSchema,\n },\n {\n name: \"get_document_info\",\n description:\n \"Get document metadata (page count, sheet count, slide count, file size, etc.)\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to the document file\",\n },\n file_type: {\n type: \"string\",\n enum: [\"excel\", \"word\", \"pptx\", \"pdf\", \"text\"],\n description:\n \"Override file type detection (optional). Specify format explicitly instead of relying on extension\",\n },\n },\n required: [\"file_path\"],\n },\n outputSchema: {\n type: \"object\",\n description: \"Document metadata with format-specific fields\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n file_size: { type: \"number\" },\n\n // Excel-specific\n sheets: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n rows: { type: \"number\" },\n cols: { type: \"number\" },\n },\n },\n },\n\n // Word-specific\n paragraphs: { type: \"number\" },\n tables: { type: \"number\" },\n\n // PowerPoint-specific\n slides: { type: \"number\" },\n\n // PDF-specific\n pages: { type: \"number\" },\n total_words: { type: \"number\" },\n metadata: { type: \"object\" },\n\n // Text/CSV/JSON-specific\n line_count: { type: \"number\" },\n encoding: { type: \"string\" },\n file_type: { type: \"string\" },\n headers: { type: \"array\", items: { type: \"string\" } },\n total_rows: { type: \"number\" },\n total_cols: { type: \"number\" },\n item_count: { type: \"number\" },\n key_count: { type: \"number\" },\n },\n additionalProperties: false,\n },\n },\n ],\n };\n});\n\n// Handle tool calls\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n if (name === \"read_document\") {\n const params = ReadDocumentSchema.parse(args);\n // Use explicit file_type if provided, otherwise detect from extension\n const fileType = params.file_type || detectFileType(params.file_path);\n\n if (!fileType) {\n throw new Error(`Unsupported file type: ${params.file_path}`);\n }\n\n // Determine read mode\n const config = getConfig();\n const mode = params.mode || (config.rawFullRead ? \"raw\" : \"paginated\");\n const page = mode === \"paginated\" ? (params.page || 1) : undefined;\n const pageSize = params.page_size || config.pageSize;\n\n let scriptName: string;\n let scriptArgs: string[];\n\n if (fileType === \"excel\") {\n scriptName = \"excel_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (params.sheet_name) scriptArgs.push(params.sheet_name);\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"word\") {\n scriptName = \"word_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"pptx\") {\n scriptName = \"pptx_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"pdf\") {\n scriptName = \"pdf_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(Math.min(pageSize, 10))); // PDF pages are larger\n }\n } else {\n // text files\n scriptName = \"text_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(fileType),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n if (name === \"write_document\") {\n const params = WriteDocumentSchema.parse(args);\n\n let scriptName: string;\n let scriptArgs: string[];\n\n if (params.format === \"excel\") {\n scriptName = \"excel_handler.py\";\n scriptArgs = [\"write\", params.file_path, JSON.stringify(params.data)];\n } else if (params.format === \"word\") {\n scriptName = \"word_handler.py\";\n const paragraphs = params.data.paragraphs || [];\n const tables = params.data.tables || null;\n scriptArgs = [\"write\", params.file_path, JSON.stringify(paragraphs)];\n if (tables) scriptArgs.push(JSON.stringify(tables));\n } else if (params.format === \"pptx\") {\n scriptName = \"pptx_handler.py\";\n const slides = params.data.slides || params.data || [];\n scriptArgs = [\"write\", params.file_path, JSON.stringify(slides)];\n } else if (params.format === \"text\") {\n scriptName = \"text_handler.py\";\n const content = typeof params.data === \"string\"\n ? params.data\n : JSON.stringify(params.data);\n scriptArgs = [\"write\", params.file_path, content];\n } else {\n throw new Error(`Unsupported write format: ${params.format}`);\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(params.format),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n if (name === \"get_document_info\") {\n const params = GetDocumentInfoSchema.parse(args);\n // Use explicit file_type if provided, otherwise detect from extension\n const fileType = params.file_type || detectFileType(params.file_path);\n\n if (!fileType) {\n throw new Error(`Unsupported file type: ${params.file_path}`);\n }\n\n let scriptName: string;\n let scriptArgs = [\"info\", params.file_path];\n\n if (fileType === \"excel\") {\n scriptName = \"excel_handler.py\";\n } else if (fileType === \"word\") {\n scriptName = \"word_handler.py\";\n } else if (fileType === \"pptx\") {\n scriptName = \"pptx_handler.py\";\n } else if (fileType === \"pdf\") {\n scriptName = \"pdf_handler.py\";\n } else {\n scriptName = \"text_handler.py\";\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(fileType),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n throw new Error(`Unknown tool: ${name}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: \"text\", text: `Error: ${errorMessage}` }],\n isError: true,\n };\n }\n});\n\n// Start server\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Docsmith MCP server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"Server error:\", error);\n process.exit(1);\n});\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,MAAMA,eAAa,qEAA8B;AACjD,MAAMC,cAAY,kBAAQD,aAAW;;;;;;;;AAuBrC,SAAS,qBACPE,UAC4C;CAC5C,MAAM,eAAe,kBAAQ,SAAS;CAItC,MAAM,YAAY,kBAAQ,aAAa;CACvC,MAAM,cAAc;AAEpB,QAAO;EAAE;EAAW;CAAa;AAClC;;;;;;;;AASD,eAAsB,cACpBC,YACAC,UAAgC,CAAE,GACpB;CACd,MAAM,EACJ,OAAO,CAAE,GACT,WAAW,CAAE,GACb,UAAU,UACV,YAAY,CAAE,GACf,GAAG;CAKJ,MAAM,WAAW,eAAKH,aAAW,MAAM,SAAS,WAAW;CAC3D,MAAM,gBAAgB,qBAAa,UAAU,QAAQ;CAGrD,MAAM,eAAe;;;;;eAKR,WAAW,OAAO,KAAK,UAAU,KAAK,CAAC;;;EAGpD,cAAc;;CAKd,IAAI,YAAY,eAAKA,aAAW,KAAK;AACrC,KAAI,UAAU,SAAS,GAAG;EACxB,MAAM,UAAU,qBAAqB,UAAU,GAAG;AAClD,cAAY,QAAQ;CACrB;CAID,MAAMI,eAA6B;EACjC;EACA,kBAAkB;EAClB,YAAY;CACb;CACD,MAAM,SAAS,MAAM,uCAAM,aAAa,aAAa;CAGrD,MAAM,SAAS,OAAO,WAAW;CACjC,MAAM,UAAU,IAAI;CACpB,IAAI,SAAS;CACb,IAAI,SAAS;CACb,IAAI,QAAQ;AAEZ,KAAI;AACF,SAAO,MAAM;GACX,MAAM,EAAE,MAAM,OAAO,GAAG,MAAM,OAAO,MAAM;AAC3C,OAAI,KAAM;GAEV,MAAM,QAAQ,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAM,EAAC;AACrD,OAAI,MAAM,WAAW,YAAY,CAC/B,WAAU,MAAM,MAAM,EAAE;YACf,MAAM,WAAW,QAAQ,CAClC,UAAS;OAET,WAAU;EAEb;CACF,SAAQ,aAAa;AAEpB,SAAO,EAAE,OAAO,OAAO,YAAY,CAAE;CACtC;AAGD,KAAI,MACF,QAAO,EAAE,OAAO,MAAM,QAAQ,qBAAqB,GAAG,CAAC,MAAM,CAAE;CAIjE,MAAM,QAAQ,OAAO,MAAM,CAAC,MAAM,KAAK;CACvC,MAAM,WAAW,MAAM,MAAM,SAAS;AAEtC,KAAI;AACF,SAAO,KAAK,MAAM,SAAS;CAC5B,QAAO;AACN,SAAO;GAAE;GAAQ;EAAQ;CAC1B;AACF;;;;;;;;;;ACnID,SAAgB,eACdC,UACmD;CACnD,MAAM,MAAM,SAAS,aAAa,CAAC,MAAM,IAAI,CAAC,KAAK;AACnD,KAAI,QAAQ,UAAU,QAAQ,MAAO,QAAO;AAC5C,KAAI,QAAQ,OAAQ,QAAO;AAC3B,KAAI,QAAQ,UAAU,QAAQ,MAAO,QAAO;AAC5C,KAAI,QAAQ,MAAO,QAAO;AAC1B,KACE,QAAQ,SAAS,QAAQ,SAAS,QAAQ,QAAQ,QAAQ,UAC1D,QAAQ,UAAU,QAAQ,MAC1B,QAAO;AACT,QAAO;AACR;;;;AAKD,SAAgB,YAAYC,UAA0C;CACpE,MAAMC,WAAmD;EACvD,OAAO,EAAE,UAAU,WAAY;EAC/B,MAAM,EAAE,MAAM,cAAe;EAC7B,MAAM,EAAE,MAAM,cAAe;EAC7B,KAAK,EAAE,QAAQ,SAAU;EACzB,MAAM,CAAE;CACT;AACD,QAAO,SAAS,aAAa,CAAE;AAChC;;;;AAKD,SAAgB,YAAY;AAC1B,QAAO;EACL,aAAa,QAAQ,IAAI,sBAAsB;EAC/C,UAAU,SAAS,QAAQ,IAAI,iBAAiB,OAAO,GAAG;EAC1D,aAAa,SAAS,QAAQ,IAAI,qBAAqB,MAAM,GAAG,GAAG,OACjE;CACH;AACF;;;;ACjCD,MAAM,qBAAqB,MAAE,OAAO;CAClC,WAAW,MAAE,QAAQ,CAAC,SAAS,qCAAqC;CACpE,WAAW,MAAE,KAAK;EAAC;EAAS;EAAQ;EAAQ;EAAO;CAAO,EAAC,CAAC,UAAU,CACnE,SACC,+GACD;CACH,MAAM,MAAE,KAAK,CAAC,OAAO,WAAY,EAAC,CAAC,UAAU,CAAC,SAC5C,qEACD;CACD,MAAM,MAAE,QAAQ,CAAC,UAAU,CAAC,SAC1B,2CACD;CACD,WAAW,MAAE,QAAQ,CAAC,UAAU,CAAC,SAC/B,oCACD;CACD,YAAY,MAAE,QAAQ,CAAC,UAAU,CAAC,SAAS,6BAA6B;AACzE,EAAC;AAEF,MAAM,sBAAsB,MAAE,OAAO;CACnC,WAAW,MAAE,QAAQ,CAAC,SAAS,qCAAqC;CACpE,QAAQ,MAAE,KAAK;EAAC;EAAS;EAAQ;EAAQ;CAAO,EAAC,CAAC,SAChD,kBACD;CACD,MAAM,MAAE,KAAK,CAAC,SAAS,0BAA0B;AAClD,EAAC;AAEF,MAAM,wBAAwB,MAAE,OAAO;CACrC,WAAW,MAAE,QAAQ,CAAC,SAAS,qCAAqC;CACpE,WAAW,MAAE,KAAK;EAAC;EAAS;EAAQ;EAAQ;EAAO;CAAO,EAAC,CAAC,UAAU,CACnE,SACC,+GACD;AACJ,EAAC;AAGF,MAAM,SAAS,IAAIC,kDACjB;CACE,MAAM;CACN,SAAS;AACV,GACD,EACE,cAAc,EACZ,OAAO,CAAE,EACV,EACF;AAIH,MAAM,mBAAmB;CACvB,MAAM;CACN,YAAY;EACV,SAAS;GAAE,MAAM;GAAW,aAAa;EAA4B;EACrE,OAAO;GAAE,MAAM;GAAU,aAAa;EAA2B;CAClE;AACF;AAED,MAAM,mBAAmB;CACvB,cAAc;EAAE,MAAM;EAAU,aAAa;CAAuB;CACpE,WAAW;EAAE,MAAM;EAAU,aAAa;CAAkB;CAC5D,aAAa;EAAE,MAAM;EAAU,aAAa;CAAyB;CACrE,MAAM;EAAE,MAAM;EAAU,aAAa;CAAqC;CAC1E,UAAU;EAAE,MAAM;EAAW,aAAa;CAA4B;AACvE;AAED,MAAM,wBAAwB;CAC5B,MAAM;CACN,YAAY;EACV,YAAY;GAAE,MAAM;GAAU,aAAa;EAAqB;EAChE,QAAQ;GACN,MAAM;GACN,OAAO,EAAE,MAAM,SAAU;GACzB,aAAa;EACd;EACD,YAAY;GAAE,MAAM;GAAU,aAAa;EAAuB;EAClE,YAAY;GAAE,MAAM;GAAU,aAAa;EAA0B;EACrE,MAAM;GACJ,MAAM;GACN,OAAO;IAAE,MAAM;IAAS,OAAO,CAAE;GAAE;GACnC,aAAa;EACd;EACD,GAAG;CACJ;AACF;AAED,MAAM,uBAAuB;CAC3B,MAAM;CACN,YAAY;EACV,YAAY;GACV,MAAM;GACN,OAAO,EAAE,MAAM,SAAU;GACzB,aAAa;EACd;EACD,QAAQ;GACN,MAAM;GACN,OAAO;IACL,MAAM;IACN,OAAO;KAAE,MAAM;KAAS,OAAO,EAAE,MAAM,SAAU;IAAE;GACpD;GACD,aAAa;EACd;EACD,kBAAkB;GAAE,MAAM;GAAU,aAAa;EAAyB;EAC1E,cAAc;GAAE,MAAM;GAAU,aAAa;EAAqB;EAClE,GAAG;CACJ;AACF;AAsBD,MAAM,uBAAuB;CAC3B,MAAM;CACN,YAAY;EACV,GAAG,iBAAiB;EACpB,SAAS;GAAE,MAAM;GAAU,aAAa;EAAgB;EACxD,aAAa;GAAE,MAAM;GAAU,aAAa;EAAoB;EAChE,UAAU;GAAE,MAAM;GAAU,aAAa;EAAiB;EAC1D,GAAG;CACJ;AACF;AAED,MAAM,sBAAsB;CAC1B,MAAM;CACN,YAAY;EACV,GAAG,iBAAiB;EACpB,SAAS;GACP,MAAM;GACN,OAAO,EAAE,MAAM,SAAU;GACzB,aAAa;EACd;EACD,MAAM;GACJ,MAAM;GACN,OAAO,EAAE,MAAM,SAAU;GACzB,aAAa;EACd;EACD,YAAY;GAAE,MAAM;GAAU,aAAa;EAAmB;EAC9D,UAAU;GAAE,MAAM;GAAU,aAAa;EAAiB;EAC1D,GAAG;CACJ;AACF;AAED,MAAM,uBAAuB;CAC3B,MAAM;CACN,YAAY;EACV,GAAG,iBAAiB;EACpB,MAAM;GAAE,MAAM;GAAU,aAAa;EAAoB;EACzD,UAAU;GAAE,MAAM;GAAU,aAAa;EAAiB;CAC3D;AACF;AAED,MAAM,oBAAoB;CACxB,MAAM;CACN,YAAY;EACV,SAAS;GAAE,MAAM;GAAW,aAAa;EAA2B;EACpE,WAAW;GAAE,MAAM;GAAU,aAAa;EAAqB;EAC/D,SAAS;GAAE,MAAM;GAAU,aAAa;EAAmB;EAC3D,OAAO;GAAE,MAAM;GAAU,aAAa;EAA2B;CAClE;AACF;AAuCD,MAAM,uBAAuB;CAC3B,MAAM;CACN,YAAY;EACV,GAAG,iBAAiB;EACpB,WAAW;GAAE,MAAM;GAAU,aAAa;EAAsB;EAChE,YAAY;GAAE,MAAM;GAAU,aAAa;EAAc;EACzD,UAAU;GAAE,MAAM;GAAU,aAAa;EAAiB;EAC1D,WAAW;GAAE,MAAM;GAAU,aAAa;EAAkB;EAE5D,SAAS;GAAE,MAAM;GAAS,OAAO,EAAE,MAAM,SAAU;EAAE;EACrD,YAAY,EAAE,MAAM,SAAU;EAC9B,YAAY,EAAE,MAAM,SAAU;EAE9B,YAAY,EAAE,MAAM,SAAU;EAC9B,WAAW,EAAE,MAAM,SAAU;CAC9B;AACF;AAGD,OAAO,kBAAkBC,4DAAwB,YAAY;AAC3D,QAAO,EACL,OAAO;EACL;GACE,MAAM;GACN,aACE;GACF,aAAa;IACX,MAAM;IACN,YAAY;KACV,WAAW;MACT,MAAM;MACN,aAAa;KACd;KACD,WAAW;MACT,MAAM;MACN,MAAM;OAAC;OAAS;OAAQ;OAAQ;OAAO;MAAO;MAC9C,aACE;KACH;KACD,MAAM;MACJ,MAAM;MACN,MAAM,CAAC,OAAO,WAAY;MAC1B,aAAa;KACd;KACD,MAAM;MACJ,MAAM;MACN,aAAa;KACd;KACD,WAAW;MAAE,MAAM;MAAU,aAAa;KAAkB;KAC5D,YAAY;MACV,MAAM;MACN,aAAa;KACd;IACF;IACD,UAAU,CAAC,WAAY;GACxB;GACD,cAAc;IACZ,MAAM;IACN,aACE;IACF,YAAY;KAEV,SAAS,EAAE,MAAM,UAAW;KAC5B,OAAO,EAAE,MAAM,SAAU;KACzB,UAAU,EAAE,MAAM,SAAU;KAG5B,YAAY,EAAE,MAAM,SAAU;KAC9B,QAAQ;MAAE,MAAM;MAAS,OAAO,EAAE,MAAM,SAAU;KAAE;KACpD,YAAY,EAAE,MAAM,SAAU;KAC9B,YAAY,EAAE,MAAM,SAAU;KAC9B,cAAc,EAAE,MAAM,CAAC,UAAU,MAAO,EAAE;KAC1C,aAAa,EAAE,MAAM,SAAU;KAG/B,YAAY,EAAE,MAAM,QAAS;KAC7B,QAAQ,EAAE,MAAM,QAAS;KACzB,kBAAkB,EAAE,MAAM,SAAU;KACpC,cAAc,EAAE,MAAM,SAAU;KAGhC,cAAc,EAAE,MAAM,SAAU;KAChC,QAAQ;MACN,MAAM;MACN,OAAO;OACL,MAAM;OACN,YAAY;QACV,cAAc,EAAE,MAAM,SAAU;QAChC,OAAO,EAAE,MAAM,SAAU;QACzB,SAAS,EAAE,MAAM,QAAS;QAC1B,OAAO,EAAE,MAAM,SAAU;OAC1B;MACF;KACF;KAGD,oBAAoB,EAAE,MAAM,CAAC,UAAU,MAAO,EAAE;KAChD,mBAAmB,EAAE,MAAM,SAAU;KACrC,SAAS,CAAE;KAGX,aAAa,EAAE,MAAM,SAAU;KAC/B,SAAS;MAAE,MAAM;MAAS,OAAO,EAAE,MAAM,SAAU;KAAE;KAGrD,MAAM,CAAE;KAGR,MAAM,EAAE,MAAM,SAAU;KACxB,WAAW,EAAE,MAAM,CAAC,UAAU,MAAO,EAAE;KACvC,UAAU,EAAE,MAAM,UAAW;IAC9B;IACD,sBAAsB;GACvB;EACF;EACD;GACE,MAAM;GACN,aAAa;GACb,aAAa;IACX,MAAM;IACN,YAAY;KACV,WAAW;MACT,MAAM;MACN,aAAa;KACd;KACD,QAAQ;MACN,MAAM;MACN,MAAM;OAAC;OAAS;OAAQ;OAAQ;MAAO;MACvC,aAAa;KACd;KACD,MAAM,EACJ,aACE,0JACH;IACF;IACD,UAAU;KAAC;KAAa;KAAU;IAAO;GAC1C;GACD,cAAc;EACf;EACD;GACE,MAAM;GACN,aACE;GACF,aAAa;IACX,MAAM;IACN,YAAY;KACV,WAAW;MACT,MAAM;MACN,aAAa;KACd;KACD,WAAW;MACT,MAAM;MACN,MAAM;OAAC;OAAS;OAAQ;OAAQ;OAAO;MAAO;MAC9C,aACE;KACH;IACF;IACD,UAAU,CAAC,WAAY;GACxB;GACD,cAAc;IACZ,MAAM;IACN,aAAa;IACb,YAAY;KACV,SAAS,EAAE,MAAM,UAAW;KAC5B,OAAO,EAAE,MAAM,SAAU;KACzB,WAAW,EAAE,MAAM,SAAU;KAG7B,QAAQ;MACN,MAAM;MACN,OAAO;OACL,MAAM;OACN,YAAY;QACV,MAAM,EAAE,MAAM,SAAU;QACxB,MAAM,EAAE,MAAM,SAAU;QACxB,MAAM,EAAE,MAAM,SAAU;OACzB;MACF;KACF;KAGD,YAAY,EAAE,MAAM,SAAU;KAC9B,QAAQ,EAAE,MAAM,SAAU;KAG1B,QAAQ,EAAE,MAAM,SAAU;KAG1B,OAAO,EAAE,MAAM,SAAU;KACzB,aAAa,EAAE,MAAM,SAAU;KAC/B,UAAU,EAAE,MAAM,SAAU;KAG5B,YAAY,EAAE,MAAM,SAAU;KAC9B,UAAU,EAAE,MAAM,SAAU;KAC5B,WAAW,EAAE,MAAM,SAAU;KAC7B,SAAS;MAAE,MAAM;MAAS,OAAO,EAAE,MAAM,SAAU;KAAE;KACrD,YAAY,EAAE,MAAM,SAAU;KAC9B,YAAY,EAAE,MAAM,SAAU;KAC9B,YAAY,EAAE,MAAM,SAAU;KAC9B,WAAW,EAAE,MAAM,SAAU;IAC9B;IACD,sBAAsB;GACvB;EACF;CACF,EACF;AACF,EAAC;AAGF,OAAO,kBAAkBC,2DAAuB,OAAO,YAAY;CACjE,MAAM,EAAE,MAAM,WAAW,MAAM,GAAG,QAAQ;AAE1C,KAAI;AACF,MAAI,SAAS,iBAAiB;GAC5B,MAAM,SAAS,mBAAmB,MAAM,KAAK;GAE7C,MAAM,WAAW,OAAO,aAAa,eAAe,OAAO,UAAU;AAErE,QAAK,SACH,OAAM,IAAI,OAAO,yBAAyB,OAAO,UAAU;GAI7D,MAAM,SAAS,WAAW;GAC1B,MAAM,OAAO,OAAO,SAAS,OAAO,cAAc,QAAQ;GAC1D,MAAM,OAAO,SAAS,cAAe,OAAO,QAAQ;GACpD,MAAM,WAAW,OAAO,aAAa,OAAO;GAE5C,IAAIC;GACJ,IAAIC;AAEJ,OAAI,aAAa,SAAS;AACxB,iBAAa;AACb,iBAAa,CAAC,QAAQ,OAAO,SAAU;AACvC,QAAI,OAAO,WAAY,YAAW,KAAK,OAAO,WAAW;AACzD,QAAI,MAAM;AACR,gBAAW,KAAK,OAAO,KAAK,CAAC;AAC7B,gBAAW,KAAK,OAAO,SAAS,CAAC;IAClC;GACF,WAAU,aAAa,QAAQ;AAC9B,iBAAa;AACb,iBAAa,CAAC,QAAQ,OAAO,SAAU;AACvC,QAAI,MAAM;AACR,gBAAW,KAAK,OAAO,KAAK,CAAC;AAC7B,gBAAW,KAAK,OAAO,SAAS,CAAC;IAClC;GACF,WAAU,aAAa,QAAQ;AAC9B,iBAAa;AACb,iBAAa,CAAC,QAAQ,OAAO,SAAU;AACvC,QAAI,MAAM;AACR,gBAAW,KAAK,OAAO,KAAK,CAAC;AAC7B,gBAAW,KAAK,OAAO,SAAS,CAAC;IAClC;GACF,WAAU,aAAa,OAAO;AAC7B,iBAAa;AACb,iBAAa,CAAC,QAAQ,OAAO,SAAU;AACvC,QAAI,MAAM;AACR,gBAAW,KAAK,OAAO,KAAK,CAAC;AAC7B,gBAAW,KAAK,OAAO,KAAK,IAAI,UAAU,GAAG,CAAC,CAAC;IAChD;GACF,OAAM;AAEL,iBAAa;AACb,iBAAa,CAAC,QAAQ,OAAO,SAAU;AACvC,QAAI,MAAM;AACR,gBAAW,KAAK,OAAO,KAAK,CAAC;AAC7B,gBAAW,KAAK,OAAO,SAAS,CAAC;IAClC;GACF;GAED,MAAM,SAAS,MAAM,cAAc,YAAY;IAC7C,MAAM;IACN,UAAU,YAAY,SAAS;IAC/B,WAAW,CAAC,OAAO,SAAU;GAC9B,EAAC;AACF,UAAO;IACL,SAAS,CAAC;KACR,MAAM;KACN,MAAM,KAAK,UAAU,QAAQ,MAAM,EAAE;IACtC,CAAC;IACF,mBAAmB;GACpB;EACF;AAED,MAAI,SAAS,kBAAkB;GAC7B,MAAM,SAAS,oBAAoB,MAAM,KAAK;GAE9C,IAAID;GACJ,IAAIC;AAEJ,OAAI,OAAO,WAAW,SAAS;AAC7B,iBAAa;AACb,iBAAa;KAAC;KAAS,OAAO;KAAW,KAAK,UAAU,OAAO,KAAK;IAAC;GACtE,WAAU,OAAO,WAAW,QAAQ;AACnC,iBAAa;IACb,MAAM,aAAa,OAAO,KAAK,cAAc,CAAE;IAC/C,MAAM,SAAS,OAAO,KAAK,UAAU;AACrC,iBAAa;KAAC;KAAS,OAAO;KAAW,KAAK,UAAU,WAAW;IAAC;AACpE,QAAI,OAAQ,YAAW,KAAK,KAAK,UAAU,OAAO,CAAC;GACpD,WAAU,OAAO,WAAW,QAAQ;AACnC,iBAAa;IACb,MAAM,SAAS,OAAO,KAAK,UAAU,OAAO,QAAQ,CAAE;AACtD,iBAAa;KAAC;KAAS,OAAO;KAAW,KAAK,UAAU,OAAO;IAAC;GACjE,WAAU,OAAO,WAAW,QAAQ;AACnC,iBAAa;IACb,MAAM,iBAAiB,OAAO,SAAS,WACnC,OAAO,OACP,KAAK,UAAU,OAAO,KAAK;AAC/B,iBAAa;KAAC;KAAS,OAAO;KAAW;IAAQ;GAClD,MACC,OAAM,IAAI,OAAO,4BAA4B,OAAO,OAAO;GAG7D,MAAM,SAAS,MAAM,cAAc,YAAY;IAC7C,MAAM;IACN,UAAU,YAAY,OAAO,OAAO;IACpC,WAAW,CAAC,OAAO,SAAU;GAC9B,EAAC;AACF,UAAO;IACL,SAAS,CAAC;KACR,MAAM;KACN,MAAM,KAAK,UAAU,QAAQ,MAAM,EAAE;IACtC,CAAC;IACF,mBAAmB;GACpB;EACF;AAED,MAAI,SAAS,qBAAqB;GAChC,MAAM,SAAS,sBAAsB,MAAM,KAAK;GAEhD,MAAM,WAAW,OAAO,aAAa,eAAe,OAAO,UAAU;AAErE,QAAK,SACH,OAAM,IAAI,OAAO,yBAAyB,OAAO,UAAU;GAG7D,IAAID;GACJ,IAAI,aAAa,CAAC,QAAQ,OAAO,SAAU;AAE3C,OAAI,aAAa,QACf,cAAa;YACJ,aAAa,OACtB,cAAa;YACJ,aAAa,OACtB,cAAa;YACJ,aAAa,MACtB,cAAa;OAEb,cAAa;GAGf,MAAM,SAAS,MAAM,cAAc,YAAY;IAC7C,MAAM;IACN,UAAU,YAAY,SAAS;IAC/B,WAAW,CAAC,OAAO,SAAU;GAC9B,EAAC;AACF,UAAO;IACL,SAAS,CAAC;KACR,MAAM;KACN,MAAM,KAAK,UAAU,QAAQ,MAAM,EAAE;IACtC,CAAC;IACF,mBAAmB;GACpB;EACF;AAED,QAAM,IAAI,OAAO,gBAAgB,KAAK;CACvC,SAAQ,OAAO;EACd,MAAM,eAAe,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;AAC3E,SAAO;GACL,SAAS,CAAC;IAAE,MAAM;IAAQ,OAAO,SAAS,aAAa;GAAG,CAAC;GAC3D,SAAS;EACV;CACF;AACF,EAAC;AAGF,eAAe,OAAO;CACpB,MAAM,YAAY,IAAIE;AACtB,OAAM,OAAO,QAAQ,UAAU;AAC/B,SAAQ,MAAM,uCAAuC;AACtD;AAED,MAAM,CAAC,MAAM,CAAC,UAAU;AACtB,SAAQ,MAAM,iBAAiB,MAAM;AACrC,SAAQ,KAAK,EAAE;AAChB,EAAC"}
package/dist/index.js CHANGED
@@ -101,6 +101,7 @@ function detectFileType(filePath) {
101
101
  const ext = filePath.toLowerCase().split(".").pop();
102
102
  if (ext === "xlsx" || ext === "xls") return "excel";
103
103
  if (ext === "docx") return "word";
104
+ if (ext === "pptx" || ext === "ppt") return "pptx";
104
105
  if (ext === "pdf") return "pdf";
105
106
  if (ext === "txt" || ext === "csv" || ext === "md" || ext === "json" || ext === "yaml" || ext === "yml") return "text";
106
107
  return null;
@@ -112,6 +113,7 @@ function getPackages(fileType) {
112
113
  const packages = {
113
114
  excel: { openpyxl: "openpyxl" },
114
115
  word: { docx: "python-docx" },
116
+ pptx: { pptx: "python-pptx" },
115
117
  pdf: { PyPDF2: "PyPDF2" },
116
118
  text: {}
117
119
  };
@@ -132,6 +134,13 @@ function getConfig() {
132
134
  //#region src/index.ts
133
135
  const ReadDocumentSchema = z.object({
134
136
  file_path: z.string().describe("Absolute path to the document file"),
137
+ file_type: z.enum([
138
+ "excel",
139
+ "word",
140
+ "pptx",
141
+ "pdf",
142
+ "text"
143
+ ]).optional().describe("Override file type detection. Use this to explicitly specify the format instead of relying on file extension"),
135
144
  mode: z.enum(["raw", "paginated"]).optional().describe("Read mode: 'raw' for full content, 'paginated' for chunked reading"),
136
145
  page: z.number().optional().describe("Page number for paginated mode (1-based)"),
137
146
  page_size: z.number().optional().describe("Items per page for paginated mode"),
@@ -142,11 +151,21 @@ const WriteDocumentSchema = z.object({
142
151
  format: z.enum([
143
152
  "excel",
144
153
  "word",
154
+ "pptx",
145
155
  "text"
146
156
  ]).describe("Document format"),
147
157
  data: z.any().describe("Document data structure")
148
158
  });
149
- const GetDocumentInfoSchema = z.object({ file_path: z.string().describe("Absolute path to the document file") });
159
+ const GetDocumentInfoSchema = z.object({
160
+ file_path: z.string().describe("Absolute path to the document file"),
161
+ file_type: z.enum([
162
+ "excel",
163
+ "word",
164
+ "pptx",
165
+ "pdf",
166
+ "text"
167
+ ]).optional().describe("Override file type detection. Use this to explicitly specify the format instead of relying on file extension")
168
+ });
150
169
  const server = new Server({
151
170
  name: "docsmith-mcp",
152
171
  version: "0.1.0"
@@ -247,28 +266,6 @@ const WordReadOutputSchema = {
247
266
  ...PaginationSchema
248
267
  }
249
268
  };
250
- const PDFReadOutputSchema = {
251
- type: "object",
252
- properties: {
253
- total_pages: {
254
- type: "number",
255
- description: "Total pages in PDF"
256
- },
257
- content: {
258
- type: "array",
259
- items: {
260
- type: "object",
261
- properties: {
262
- page_number: { type: "number" },
263
- text: { type: "string" }
264
- }
265
- },
266
- description: "Page content array"
267
- },
268
- current_page_group: { type: "number" },
269
- page_size: { type: "number" }
270
- }
271
- };
272
269
  const TextReadOutputSchema = {
273
270
  type: "object",
274
271
  properties: {
@@ -348,61 +345,6 @@ const WriteOutputSchema = {
348
345
  }
349
346
  }
350
347
  };
351
- const ExcelInfoOutputSchema = {
352
- type: "object",
353
- properties: {
354
- sheets: {
355
- type: "array",
356
- items: {
357
- type: "object",
358
- properties: {
359
- name: { type: "string" },
360
- rows: { type: "number" },
361
- cols: { type: "number" }
362
- }
363
- },
364
- description: "Sheet information"
365
- },
366
- file_size: {
367
- type: "number",
368
- description: "File size in bytes"
369
- }
370
- }
371
- };
372
- const WordInfoOutputSchema = {
373
- type: "object",
374
- properties: {
375
- paragraphs: {
376
- type: "number",
377
- description: "Paragraph count"
378
- },
379
- tables: {
380
- type: "number",
381
- description: "Table count"
382
- },
383
- file_size: {
384
- type: "number",
385
- description: "File size in bytes"
386
- }
387
- }
388
- };
389
- const PDFInfoOutputSchema = {
390
- type: "object",
391
- properties: {
392
- pages: {
393
- type: "number",
394
- description: "Page count"
395
- },
396
- file_size: {
397
- type: "number",
398
- description: "File size in bytes"
399
- },
400
- total_words: {
401
- type: "number",
402
- description: "Total word count"
403
- }
404
- }
405
- };
406
348
  const TextInfoOutputSchema = {
407
349
  type: "object",
408
350
  properties: {
@@ -437,7 +379,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
437
379
  return { tools: [
438
380
  {
439
381
  name: "read_document",
440
- description: "Read document content (Excel, Word, PDF, TXT, CSV, Markdown, JSON, YAML). Supports raw full read or paginated mode.",
382
+ description: "Read document content (Excel, Word, PowerPoint, PDF, TXT, CSV, Markdown, JSON, YAML). Supports raw full read or paginated mode.",
441
383
  inputSchema: {
442
384
  type: "object",
443
385
  properties: {
@@ -445,6 +387,17 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
445
387
  type: "string",
446
388
  description: "Absolute path to the document file"
447
389
  },
390
+ file_type: {
391
+ type: "string",
392
+ enum: [
393
+ "excel",
394
+ "word",
395
+ "pptx",
396
+ "pdf",
397
+ "text"
398
+ ],
399
+ description: "Override file type detection (optional). Specify format explicitly instead of relying on extension"
400
+ },
448
401
  mode: {
449
402
  type: "string",
450
403
  enum: ["raw", "paginated"],
@@ -467,20 +420,56 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
467
420
  },
468
421
  outputSchema: {
469
422
  type: "object",
470
- description: "Returns different structures based on file type: Excel (sheet data), Word (paragraphs/tables), PDF (page content), Text (plain text), CSV (structured rows), JSON (parsed object)",
471
- oneOf: [
472
- ExcelReadOutputSchema,
473
- WordReadOutputSchema,
474
- PDFReadOutputSchema,
475
- TextReadOutputSchema,
476
- CSVReadOutputSchema,
477
- JSONReadOutputSchema
478
- ]
423
+ description: "Document content with format-specific structure. Common fields: success (boolean), error (string, on failure).",
424
+ properties: {
425
+ success: { type: "boolean" },
426
+ error: { type: "string" },
427
+ encoding: { type: "string" },
428
+ sheet_name: { type: "string" },
429
+ sheets: {
430
+ type: "array",
431
+ items: { type: "string" }
432
+ },
433
+ total_rows: { type: "number" },
434
+ total_cols: { type: "number" },
435
+ current_page: { type: ["number", "null"] },
436
+ total_pages: { type: "number" },
437
+ paragraphs: { type: "array" },
438
+ tables: { type: "array" },
439
+ total_paragraphs: { type: "number" },
440
+ total_tables: { type: "number" },
441
+ total_slides: { type: "number" },
442
+ slides: {
443
+ type: "array",
444
+ items: {
445
+ type: "object",
446
+ properties: {
447
+ slide_number: { type: "number" },
448
+ title: { type: "string" },
449
+ content: { type: "array" },
450
+ notes: { type: "string" }
451
+ }
452
+ }
453
+ },
454
+ current_page_group: { type: ["number", "null"] },
455
+ total_page_groups: { type: "number" },
456
+ content: {},
457
+ total_lines: { type: "number" },
458
+ headers: {
459
+ type: "array",
460
+ items: { type: "string" }
461
+ },
462
+ data: {},
463
+ page: { type: "number" },
464
+ page_size: { type: ["number", "null"] },
465
+ has_more: { type: "boolean" }
466
+ },
467
+ additionalProperties: false
479
468
  }
480
469
  },
481
470
  {
482
471
  name: "write_document",
483
- description: "Write document content (Excel, Word, Text)",
472
+ description: "Write document content (Excel, Word, PowerPoint, Text)",
484
473
  inputSchema: {
485
474
  type: "object",
486
475
  properties: {
@@ -493,6 +482,7 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
493
482
  enum: [
494
483
  "excel",
495
484
  "word",
485
+ "pptx",
496
486
  "text"
497
487
  ],
498
488
  description: "Document format"
@@ -509,24 +499,65 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
509
499
  },
510
500
  {
511
501
  name: "get_document_info",
512
- description: "Get document metadata (page count, sheet count, file size, etc.)",
502
+ description: "Get document metadata (page count, sheet count, slide count, file size, etc.)",
513
503
  inputSchema: {
514
504
  type: "object",
515
- properties: { file_path: {
516
- type: "string",
517
- description: "Absolute path to the document file"
518
- } },
505
+ properties: {
506
+ file_path: {
507
+ type: "string",
508
+ description: "Absolute path to the document file"
509
+ },
510
+ file_type: {
511
+ type: "string",
512
+ enum: [
513
+ "excel",
514
+ "word",
515
+ "pptx",
516
+ "pdf",
517
+ "text"
518
+ ],
519
+ description: "Override file type detection (optional). Specify format explicitly instead of relying on extension"
520
+ }
521
+ },
519
522
  required: ["file_path"]
520
523
  },
521
524
  outputSchema: {
522
525
  type: "object",
523
- description: "Returns metadata based on file type",
524
- oneOf: [
525
- ExcelInfoOutputSchema,
526
- WordInfoOutputSchema,
527
- PDFInfoOutputSchema,
528
- TextInfoOutputSchema
529
- ]
526
+ description: "Document metadata with format-specific fields",
527
+ properties: {
528
+ success: { type: "boolean" },
529
+ error: { type: "string" },
530
+ file_size: { type: "number" },
531
+ sheets: {
532
+ type: "array",
533
+ items: {
534
+ type: "object",
535
+ properties: {
536
+ name: { type: "string" },
537
+ rows: { type: "number" },
538
+ cols: { type: "number" }
539
+ }
540
+ }
541
+ },
542
+ paragraphs: { type: "number" },
543
+ tables: { type: "number" },
544
+ slides: { type: "number" },
545
+ pages: { type: "number" },
546
+ total_words: { type: "number" },
547
+ metadata: { type: "object" },
548
+ line_count: { type: "number" },
549
+ encoding: { type: "string" },
550
+ file_type: { type: "string" },
551
+ headers: {
552
+ type: "array",
553
+ items: { type: "string" }
554
+ },
555
+ total_rows: { type: "number" },
556
+ total_cols: { type: "number" },
557
+ item_count: { type: "number" },
558
+ key_count: { type: "number" }
559
+ },
560
+ additionalProperties: false
530
561
  }
531
562
  }
532
563
  ] };
@@ -536,7 +567,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
536
567
  try {
537
568
  if (name === "read_document") {
538
569
  const params = ReadDocumentSchema.parse(args);
539
- const fileType = detectFileType(params.file_path);
570
+ const fileType = params.file_type || detectFileType(params.file_path);
540
571
  if (!fileType) throw new Error(`Unsupported file type: ${params.file_path}`);
541
572
  const config = getConfig();
542
573
  const mode = params.mode || (config.rawFullRead ? "raw" : "paginated");
@@ -559,6 +590,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
559
590
  scriptArgs.push(String(page));
560
591
  scriptArgs.push(String(pageSize));
561
592
  }
593
+ } else if (fileType === "pptx") {
594
+ scriptName = "pptx_handler.py";
595
+ scriptArgs = ["read", params.file_path];
596
+ if (page) {
597
+ scriptArgs.push(String(page));
598
+ scriptArgs.push(String(pageSize));
599
+ }
562
600
  } else if (fileType === "pdf") {
563
601
  scriptName = "pdf_handler.py";
564
602
  scriptArgs = ["read", params.file_path];
@@ -608,6 +646,14 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
608
646
  JSON.stringify(paragraphs)
609
647
  ];
610
648
  if (tables) scriptArgs.push(JSON.stringify(tables));
649
+ } else if (params.format === "pptx") {
650
+ scriptName = "pptx_handler.py";
651
+ const slides = params.data.slides || params.data || [];
652
+ scriptArgs = [
653
+ "write",
654
+ params.file_path,
655
+ JSON.stringify(slides)
656
+ ];
611
657
  } else if (params.format === "text") {
612
658
  scriptName = "text_handler.py";
613
659
  const content = typeof params.data === "string" ? params.data : JSON.stringify(params.data);
@@ -632,12 +678,13 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
632
678
  }
633
679
  if (name === "get_document_info") {
634
680
  const params = GetDocumentInfoSchema.parse(args);
635
- const fileType = detectFileType(params.file_path);
681
+ const fileType = params.file_type || detectFileType(params.file_path);
636
682
  if (!fileType) throw new Error(`Unsupported file type: ${params.file_path}`);
637
683
  let scriptName;
638
684
  let scriptArgs = ["info", params.file_path];
639
685
  if (fileType === "excel") scriptName = "excel_handler.py";
640
686
  else if (fileType === "word") scriptName = "word_handler.py";
687
+ else if (fileType === "pptx") scriptName = "pptx_handler.py";
641
688
  else if (fileType === "pdf") scriptName = "pdf_handler.py";
642
689
  else scriptName = "text_handler.py";
643
690
  const result = await runPythonFile(scriptName, {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["filePath: string","scriptPath: string","options: RunPythonFileOptions","runPyOptions: RunPyOptions","filePath: string","fileType: string","packages: Record<string, Record<string, string>>","scriptName: string","scriptArgs: string[]"],"sources":["../src/code-runner.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["/**\n * Code runner client - uses @mcpc-tech/code-runner-mcp npm package\n */\nimport { runPy, type RunPyOptions } from \"@mcpc-tech/code-runner-mcp\";\nimport { readFileSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join, resolve } from \"path\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Options for running Python script files\n */\nexport interface RunPythonFileOptions {\n /** Command line arguments to pass to the script */\n args?: string[];\n /** Package name mappings (import_name -> pypi_name) */\n packages?: Record<string, string>;\n /** Base directory for the script (default: \"python\") */\n baseDir?: string;\n /** User file paths that need to be accessible (for file system mounting) */\n filePaths?: string[];\n}\n\n/**\n * Convert absolute file path to Pyodide virtual path\n * Determines the mount root and converts the path accordingly\n *\n * @param filePath - Absolute path to the file\n * @returns Object with mountRoot (host path) and virtualPath (Pyodide path)\n */\nfunction getFileSystemMapping(\n filePath: string,\n): { mountRoot: string; virtualPath: string } {\n const absolutePath = resolve(filePath);\n\n // Mount the parent directory of the file\n // This allows Python to access the file and its siblings\n const mountRoot = dirname(absolutePath);\n const virtualPath = absolutePath;\n\n return { mountRoot, virtualPath };\n}\n\n/**\n * Run a Python script file using code-runner-mcp\n *\n * @param scriptPath - Path to the Python script (relative to baseDir)\n * @param options - Execution options\n * @returns The execution result\n */\nexport async function runPythonFile(\n scriptPath: string,\n options: RunPythonFileOptions = {},\n): Promise<any> {\n const {\n args = [],\n packages = {},\n baseDir = \"python\",\n filePaths = [],\n } = options;\n\n // Read the Python script\n // Python files are in the python/ directory at project root\n // From dist/index.js, go up one level to reach python/\n const fullPath = join(__dirname, \"..\", baseDir, scriptPath);\n const scriptContent = readFileSync(fullPath, \"utf-8\");\n\n // Build wrapper code that sets sys.argv and executes the script\n const wrapperCode = `\nimport sys\nimport json\n\n# Set command line arguments\nsys.argv = ['${scriptPath}'] + ${JSON.stringify(args)}\n\n# Execute the script\n${scriptContent}\n`;\n\n // Determine mount root from the first file path\n // Default: parent directory of dist/ (project root when running from dist/index.js)\n let mountRoot = join(__dirname, \"..\");\n if (filePaths.length > 0) {\n const mapping = getFileSystemMapping(filePaths[0]);\n mountRoot = mapping.mountRoot;\n }\n\n // Execute via runPy with options\n // Mount point is the same as the mount root (Pyodide will see host paths directly)\n const runPyOptions: RunPyOptions = {\n packages,\n nodeFSMountPoint: mountRoot,\n nodeFSRoot: mountRoot,\n };\n const stream = await runPy(wrapperCode, runPyOptions);\n\n // Read the stream output\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let stdout = \"\";\n let stderr = \"\";\n let error = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n if (chunk.startsWith(\"[stderr] \")) {\n stderr += chunk.slice(9);\n } else if (chunk.startsWith(\"[err]\")) {\n error += chunk;\n } else {\n stdout += chunk;\n }\n }\n } catch (streamError) {\n // Stream error means Python execution failed\n return { error: String(streamError) };\n }\n\n // Check for errors\n if (error) {\n return { error: error.replace(/\\[err\\]\\[py\\]\\s*/g, \"\").trim() };\n }\n\n // Parse the JSON output from the script (last line)\n const lines = stdout.trim().split(\"\\n\");\n const lastLine = lines[lines.length - 1];\n\n try {\n return JSON.parse(lastLine);\n } catch {\n return { stdout, stderr };\n }\n}\n","/**\n * Utility functions for document processing\n */\n\n/**\n * Detect file type from file extension\n */\nexport function detectFileType(\n filePath: string,\n): \"excel\" | \"word\" | \"pdf\" | \"text\" | null {\n const ext = filePath.toLowerCase().split(\".\").pop();\n if (ext === \"xlsx\" || ext === \"xls\") return \"excel\";\n if (ext === \"docx\") return \"word\";\n if (ext === \"pdf\") return \"pdf\";\n if (\n ext === \"txt\" || ext === \"csv\" || ext === \"md\" || ext === \"json\" ||\n ext === \"yaml\" || ext === \"yml\"\n ) return \"text\";\n return null;\n}\n\n/**\n * Get required packages for each file type\n */\nexport function getPackages(fileType: string): Record<string, string> {\n const packages: Record<string, Record<string, string>> = {\n excel: { openpyxl: \"openpyxl\" },\n word: { docx: \"python-docx\" }, // Map docx import to python-docx package\n pdf: { PyPDF2: \"PyPDF2\" },\n text: {}, // No external packages needed for text files\n };\n return packages[fileType] || {};\n}\n\n/**\n * Get environment configuration\n */\nexport function getConfig() {\n return {\n rawFullRead: process.env.DOC_RAW_FULL_READ === \"true\",\n pageSize: parseInt(process.env.DOC_PAGE_SIZE || \"100\", 10),\n maxFileSize: parseInt(process.env.DOC_MAX_FILE_SIZE || \"50\", 10) * 1024 *\n 1024,\n };\n}\n","#!/usr/bin/env node\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { runPythonFile } from \"./code-runner.js\";\nimport { detectFileType, getConfig, getPackages } from \"./utils.js\";\n\n// Tool schemas\nconst ReadDocumentSchema = z.object({\n file_path: z.string().describe(\"Absolute path to the document file\"),\n mode: z.enum([\"raw\", \"paginated\"]).optional().describe(\n \"Read mode: 'raw' for full content, 'paginated' for chunked reading\",\n ),\n page: z.number().optional().describe(\n \"Page number for paginated mode (1-based)\",\n ),\n page_size: z.number().optional().describe(\n \"Items per page for paginated mode\",\n ),\n sheet_name: z.string().optional().describe(\"Sheet name for Excel files\"),\n});\n\nconst WriteDocumentSchema = z.object({\n file_path: z.string().describe(\"Absolute path to save the document\"),\n format: z.enum([\"excel\", \"word\", \"text\"]).describe(\"Document format\"),\n data: z.any().describe(\"Document data structure\"),\n});\n\nconst GetDocumentInfoSchema = z.object({\n file_path: z.string().describe(\"Absolute path to the document file\"),\n});\n\n// Server setup\nconst server = new Server(\n {\n name: \"docsmith-mcp\",\n version: \"0.1.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n },\n);\n\n// Output schemas (reusable)\nconst BaseOutputSchema = {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Operation success status\" },\n error: { type: \"string\", description: \"Error message if failed\" },\n },\n} as const;\n\nconst PaginationSchema = {\n current_page: { type: \"number\", description: \"Current page number\" },\n page_size: { type: \"number\", description: \"Items per page\" },\n total_pages: { type: \"number\", description: \"Total number of pages\" },\n page: { type: \"number\", description: \"Current page number (alternative)\" },\n has_more: { type: \"boolean\", description: \"Whether more pages exist\" },\n} as const;\n\nconst ExcelReadOutputSchema = {\n type: \"object\",\n properties: {\n sheet_name: { type: \"string\", description: \"Active sheet name\" },\n sheets: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"All sheet names\",\n },\n total_rows: { type: \"number\", description: \"Total rows in sheet\" },\n total_cols: { type: \"number\", description: \"Total columns in sheet\" },\n data: {\n type: \"array\",\n items: { type: \"array\", items: {} },\n description: \"Sheet data as array of rows\",\n },\n ...PaginationSchema,\n },\n} as const;\n\nconst WordReadOutputSchema = {\n type: \"object\",\n properties: {\n paragraphs: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Document paragraphs\",\n },\n tables: {\n type: \"array\",\n items: {\n type: \"array\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n description: \"Tables data\",\n },\n total_paragraphs: { type: \"number\", description: \"Total paragraph count\" },\n total_tables: { type: \"number\", description: \"Total table count\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst PDFReadOutputSchema = {\n type: \"object\",\n properties: {\n total_pages: { type: \"number\", description: \"Total pages in PDF\" },\n content: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n page_number: { type: \"number\" },\n text: { type: \"string\" },\n },\n },\n description: \"Page content array\",\n },\n current_page_group: { type: \"number\" },\n page_size: { type: \"number\" },\n },\n} as const;\n\nconst TextReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n content: { type: \"string\", description: \"Text content\" },\n total_lines: { type: \"number\", description: \"Total line count\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst CSVReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n headers: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"CSV headers\",\n },\n data: {\n type: \"array\",\n items: { type: \"object\" },\n description: \"Structured data as array of objects\",\n },\n total_rows: { type: \"number\", description: \"Total data rows\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst JSONReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n data: { type: \"object\", description: \"Parsed JSON data\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n },\n} as const;\n\nconst WriteOutputSchema = {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Write operation success\" },\n file_path: { type: \"string\", description: \"Written file path\" },\n message: { type: \"string\", description: \"Success message\" },\n error: { type: \"string\", description: \"Error message if failed\" },\n },\n} as const;\n\nconst ExcelInfoOutputSchema = {\n type: \"object\",\n properties: {\n sheets: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n rows: { type: \"number\" },\n cols: { type: \"number\" },\n },\n },\n description: \"Sheet information\",\n },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n },\n} as const;\n\nconst WordInfoOutputSchema = {\n type: \"object\",\n properties: {\n paragraphs: { type: \"number\", description: \"Paragraph count\" },\n tables: { type: \"number\", description: \"Table count\" },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n },\n} as const;\n\nconst PDFInfoOutputSchema = {\n type: \"object\",\n properties: {\n pages: { type: \"number\", description: \"Page count\" },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n total_words: { type: \"number\", description: \"Total word count\" },\n },\n} as const;\n\nconst TextInfoOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n file_size: { type: \"number\", description: \"File size in bytes\" },\n line_count: { type: \"number\", description: \"Line count\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n file_type: { type: \"string\", description: \"File extension\" },\n // CSV specific\n headers: { type: \"array\", items: { type: \"string\" } },\n total_rows: { type: \"number\" },\n total_cols: { type: \"number\" },\n // JSON specific\n item_count: { type: \"number\" },\n key_count: { type: \"number\" },\n },\n} as const;\n\n// List available tools\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"read_document\",\n description:\n \"Read document content (Excel, Word, PDF, TXT, CSV, Markdown, JSON, YAML). Supports raw full read or paginated mode.\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to the document file\",\n },\n mode: {\n type: \"string\",\n enum: [\"raw\", \"paginated\"],\n description: \"Read mode\",\n },\n page: {\n type: \"number\",\n description: \"Page number for paginated mode\",\n },\n page_size: { type: \"number\", description: \"Items per page\" },\n sheet_name: {\n type: \"string\",\n description: \"Sheet name for Excel files\",\n },\n },\n required: [\"file_path\"],\n },\n outputSchema: {\n type: \"object\",\n description:\n \"Returns different structures based on file type: Excel (sheet data), Word (paragraphs/tables), PDF (page content), Text (plain text), CSV (structured rows), JSON (parsed object)\",\n oneOf: [\n ExcelReadOutputSchema,\n WordReadOutputSchema,\n PDFReadOutputSchema,\n TextReadOutputSchema,\n CSVReadOutputSchema,\n JSONReadOutputSchema,\n ],\n },\n },\n {\n name: \"write_document\",\n description: \"Write document content (Excel, Word, Text)\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to save the document\",\n },\n format: {\n type: \"string\",\n enum: [\"excel\", \"word\", \"text\"],\n description: \"Document format\",\n },\n data: {\n description:\n \"Document data structure. Excel: array of rows [[cell1, cell2], ...]. Word: {paragraphs: string[], tables?: [[[cell]]]}. Text/CSV/JSON: string or object\",\n },\n },\n required: [\"file_path\", \"format\", \"data\"],\n },\n outputSchema: WriteOutputSchema,\n },\n {\n name: \"get_document_info\",\n description:\n \"Get document metadata (page count, sheet count, file size, etc.)\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to the document file\",\n },\n },\n required: [\"file_path\"],\n },\n outputSchema: {\n type: \"object\",\n description: \"Returns metadata based on file type\",\n oneOf: [\n ExcelInfoOutputSchema,\n WordInfoOutputSchema,\n PDFInfoOutputSchema,\n TextInfoOutputSchema,\n ],\n },\n },\n ],\n };\n});\n\n// Handle tool calls\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n if (name === \"read_document\") {\n const params = ReadDocumentSchema.parse(args);\n const fileType = detectFileType(params.file_path);\n\n if (!fileType) {\n throw new Error(`Unsupported file type: ${params.file_path}`);\n }\n\n // Determine read mode\n const config = getConfig();\n const mode = params.mode || (config.rawFullRead ? \"raw\" : \"paginated\");\n const page = mode === \"paginated\" ? (params.page || 1) : undefined;\n const pageSize = params.page_size || config.pageSize;\n\n let scriptName: string;\n let scriptArgs: string[];\n\n if (fileType === \"excel\") {\n scriptName = \"excel_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (params.sheet_name) scriptArgs.push(params.sheet_name);\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"word\") {\n scriptName = \"word_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"pdf\") {\n scriptName = \"pdf_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(Math.min(pageSize, 10))); // PDF pages are larger\n }\n } else {\n // text files\n scriptName = \"text_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(fileType),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n if (name === \"write_document\") {\n const params = WriteDocumentSchema.parse(args);\n\n let scriptName: string;\n let scriptArgs: string[];\n\n if (params.format === \"excel\") {\n scriptName = \"excel_handler.py\";\n scriptArgs = [\"write\", params.file_path, JSON.stringify(params.data)];\n } else if (params.format === \"word\") {\n scriptName = \"word_handler.py\";\n const paragraphs = params.data.paragraphs || [];\n const tables = params.data.tables || null;\n scriptArgs = [\"write\", params.file_path, JSON.stringify(paragraphs)];\n if (tables) scriptArgs.push(JSON.stringify(tables));\n } else if (params.format === \"text\") {\n scriptName = \"text_handler.py\";\n const content = typeof params.data === \"string\"\n ? params.data\n : JSON.stringify(params.data);\n scriptArgs = [\"write\", params.file_path, content];\n } else {\n throw new Error(`Unsupported write format: ${params.format}`);\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(params.format),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n if (name === \"get_document_info\") {\n const params = GetDocumentInfoSchema.parse(args);\n const fileType = detectFileType(params.file_path);\n\n if (!fileType) {\n throw new Error(`Unsupported file type: ${params.file_path}`);\n }\n\n let scriptName: string;\n let scriptArgs = [\"info\", params.file_path];\n\n if (fileType === \"excel\") {\n scriptName = \"excel_handler.py\";\n } else if (fileType === \"word\") {\n scriptName = \"word_handler.py\";\n } else if (fileType === \"pdf\") {\n scriptName = \"pdf_handler.py\";\n } else {\n scriptName = \"text_handler.py\";\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(fileType),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n throw new Error(`Unknown tool: ${name}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: \"text\", text: `Error: ${errorMessage}` }],\n isError: true,\n };\n }\n});\n\n// Start server\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Docsmith MCP server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"Server error:\", error);\n process.exit(1);\n});\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["filePath: string","scriptPath: string","options: RunPythonFileOptions","runPyOptions: RunPyOptions","filePath: string","fileType: string","packages: Record<string, Record<string, string>>","scriptName: string","scriptArgs: string[]"],"sources":["../src/code-runner.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["/**\n * Code runner client - uses @mcpc-tech/code-runner-mcp npm package\n */\nimport { runPy, type RunPyOptions } from \"@mcpc-tech/code-runner-mcp\";\nimport { readFileSync } from \"fs\";\nimport { fileURLToPath } from \"url\";\nimport { dirname, join, resolve } from \"path\";\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = dirname(__filename);\n\n/**\n * Options for running Python script files\n */\nexport interface RunPythonFileOptions {\n /** Command line arguments to pass to the script */\n args?: string[];\n /** Package name mappings (import_name -> pypi_name) */\n packages?: Record<string, string>;\n /** Base directory for the script (default: \"python\") */\n baseDir?: string;\n /** User file paths that need to be accessible (for file system mounting) */\n filePaths?: string[];\n}\n\n/**\n * Convert absolute file path to Pyodide virtual path\n * Determines the mount root and converts the path accordingly\n *\n * @param filePath - Absolute path to the file\n * @returns Object with mountRoot (host path) and virtualPath (Pyodide path)\n */\nfunction getFileSystemMapping(\n filePath: string,\n): { mountRoot: string; virtualPath: string } {\n const absolutePath = resolve(filePath);\n\n // Mount the parent directory of the file\n // This allows Python to access the file and its siblings\n const mountRoot = dirname(absolutePath);\n const virtualPath = absolutePath;\n\n return { mountRoot, virtualPath };\n}\n\n/**\n * Run a Python script file using code-runner-mcp\n *\n * @param scriptPath - Path to the Python script (relative to baseDir)\n * @param options - Execution options\n * @returns The execution result\n */\nexport async function runPythonFile(\n scriptPath: string,\n options: RunPythonFileOptions = {},\n): Promise<any> {\n const {\n args = [],\n packages = {},\n baseDir = \"python\",\n filePaths = [],\n } = options;\n\n // Read the Python script\n // Python files are in the python/ directory at project root\n // From dist/index.js, go up one level to reach python/\n const fullPath = join(__dirname, \"..\", baseDir, scriptPath);\n const scriptContent = readFileSync(fullPath, \"utf-8\");\n\n // Build wrapper code that sets sys.argv and executes the script\n const wrapperCode = `\nimport sys\nimport json\n\n# Set command line arguments\nsys.argv = ['${scriptPath}'] + ${JSON.stringify(args)}\n\n# Execute the script\n${scriptContent}\n`;\n\n // Determine mount root from the first file path\n // Default: parent directory of dist/ (project root when running from dist/index.js)\n let mountRoot = join(__dirname, \"..\");\n if (filePaths.length > 0) {\n const mapping = getFileSystemMapping(filePaths[0]);\n mountRoot = mapping.mountRoot;\n }\n\n // Execute via runPy with options\n // Mount point is the same as the mount root (Pyodide will see host paths directly)\n const runPyOptions: RunPyOptions = {\n packages,\n nodeFSMountPoint: mountRoot,\n nodeFSRoot: mountRoot,\n };\n const stream = await runPy(wrapperCode, runPyOptions);\n\n // Read the stream output\n const reader = stream.getReader();\n const decoder = new TextDecoder();\n let stdout = \"\";\n let stderr = \"\";\n let error = \"\";\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) break;\n\n const chunk = decoder.decode(value, { stream: true });\n if (chunk.startsWith(\"[stderr] \")) {\n stderr += chunk.slice(9);\n } else if (chunk.startsWith(\"[err]\")) {\n error += chunk;\n } else {\n stdout += chunk;\n }\n }\n } catch (streamError) {\n // Stream error means Python execution failed\n return { error: String(streamError) };\n }\n\n // Check for errors\n if (error) {\n return { error: error.replace(/\\[err\\]\\[py\\]\\s*/g, \"\").trim() };\n }\n\n // Parse the JSON output from the script (last line)\n const lines = stdout.trim().split(\"\\n\");\n const lastLine = lines[lines.length - 1];\n\n try {\n return JSON.parse(lastLine);\n } catch {\n return { stdout, stderr };\n }\n}\n","/**\n * Utility functions for document processing\n */\n\n/**\n * Detect file type from file extension\n */\nexport function detectFileType(\n filePath: string,\n): \"excel\" | \"word\" | \"pdf\" | \"pptx\" | \"text\" | null {\n const ext = filePath.toLowerCase().split(\".\").pop();\n if (ext === \"xlsx\" || ext === \"xls\") return \"excel\";\n if (ext === \"docx\") return \"word\";\n if (ext === \"pptx\" || ext === \"ppt\") return \"pptx\";\n if (ext === \"pdf\") return \"pdf\";\n if (\n ext === \"txt\" || ext === \"csv\" || ext === \"md\" || ext === \"json\" ||\n ext === \"yaml\" || ext === \"yml\"\n ) return \"text\";\n return null;\n}\n\n/**\n * Get required packages for each file type\n */\nexport function getPackages(fileType: string): Record<string, string> {\n const packages: Record<string, Record<string, string>> = {\n excel: { openpyxl: \"openpyxl\" },\n word: { docx: \"python-docx\" }, // Map docx import to python-docx package\n pptx: { pptx: \"python-pptx\" }, // Map pptx import to python-pptx package\n pdf: { PyPDF2: \"PyPDF2\" },\n text: {}, // No external packages needed for text files\n };\n return packages[fileType] || {};\n}\n\n/**\n * Get environment configuration\n */\nexport function getConfig() {\n return {\n rawFullRead: process.env.DOC_RAW_FULL_READ === \"true\",\n pageSize: parseInt(process.env.DOC_PAGE_SIZE || \"100\", 10),\n maxFileSize: parseInt(process.env.DOC_MAX_FILE_SIZE || \"50\", 10) * 1024 *\n 1024,\n };\n}\n","#!/usr/bin/env node\n\nimport { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport { StdioServerTransport } from \"@modelcontextprotocol/sdk/server/stdio.js\";\nimport {\n CallToolRequestSchema,\n ListToolsRequestSchema,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { z } from \"zod\";\nimport { runPythonFile } from \"./code-runner.js\";\nimport { detectFileType, getConfig, getPackages } from \"./utils.js\";\n\n// Tool schemas\nconst ReadDocumentSchema = z.object({\n file_path: z.string().describe(\"Absolute path to the document file\"),\n file_type: z.enum([\"excel\", \"word\", \"pptx\", \"pdf\", \"text\"]).optional()\n .describe(\n \"Override file type detection. Use this to explicitly specify the format instead of relying on file extension\",\n ),\n mode: z.enum([\"raw\", \"paginated\"]).optional().describe(\n \"Read mode: 'raw' for full content, 'paginated' for chunked reading\",\n ),\n page: z.number().optional().describe(\n \"Page number for paginated mode (1-based)\",\n ),\n page_size: z.number().optional().describe(\n \"Items per page for paginated mode\",\n ),\n sheet_name: z.string().optional().describe(\"Sheet name for Excel files\"),\n});\n\nconst WriteDocumentSchema = z.object({\n file_path: z.string().describe(\"Absolute path to save the document\"),\n format: z.enum([\"excel\", \"word\", \"pptx\", \"text\"]).describe(\n \"Document format\",\n ),\n data: z.any().describe(\"Document data structure\"),\n});\n\nconst GetDocumentInfoSchema = z.object({\n file_path: z.string().describe(\"Absolute path to the document file\"),\n file_type: z.enum([\"excel\", \"word\", \"pptx\", \"pdf\", \"text\"]).optional()\n .describe(\n \"Override file type detection. Use this to explicitly specify the format instead of relying on file extension\",\n ),\n});\n\n// Server setup\nconst server = new Server(\n {\n name: \"docsmith-mcp\",\n version: \"0.1.0\",\n },\n {\n capabilities: {\n tools: {},\n },\n },\n);\n\n// Output schemas (reusable)\nconst BaseOutputSchema = {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Operation success status\" },\n error: { type: \"string\", description: \"Error message if failed\" },\n },\n} as const;\n\nconst PaginationSchema = {\n current_page: { type: \"number\", description: \"Current page number\" },\n page_size: { type: \"number\", description: \"Items per page\" },\n total_pages: { type: \"number\", description: \"Total number of pages\" },\n page: { type: \"number\", description: \"Current page number (alternative)\" },\n has_more: { type: \"boolean\", description: \"Whether more pages exist\" },\n} as const;\n\nconst ExcelReadOutputSchema = {\n type: \"object\",\n properties: {\n sheet_name: { type: \"string\", description: \"Active sheet name\" },\n sheets: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"All sheet names\",\n },\n total_rows: { type: \"number\", description: \"Total rows in sheet\" },\n total_cols: { type: \"number\", description: \"Total columns in sheet\" },\n data: {\n type: \"array\",\n items: { type: \"array\", items: {} },\n description: \"Sheet data as array of rows\",\n },\n ...PaginationSchema,\n },\n} as const;\n\nconst WordReadOutputSchema = {\n type: \"object\",\n properties: {\n paragraphs: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"Document paragraphs\",\n },\n tables: {\n type: \"array\",\n items: {\n type: \"array\",\n items: { type: \"array\", items: { type: \"string\" } },\n },\n description: \"Tables data\",\n },\n total_paragraphs: { type: \"number\", description: \"Total paragraph count\" },\n total_tables: { type: \"number\", description: \"Total table count\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst PDFReadOutputSchema = {\n type: \"object\",\n properties: {\n total_pages: { type: \"number\", description: \"Total pages in PDF\" },\n content: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n page_number: { type: \"number\" },\n text: { type: \"string\" },\n },\n },\n description: \"Page content array\",\n },\n current_page_group: { type: \"number\" },\n page_size: { type: \"number\" },\n },\n} as const;\n\nconst TextReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n content: { type: \"string\", description: \"Text content\" },\n total_lines: { type: \"number\", description: \"Total line count\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst CSVReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n headers: {\n type: \"array\",\n items: { type: \"string\" },\n description: \"CSV headers\",\n },\n data: {\n type: \"array\",\n items: { type: \"object\" },\n description: \"Structured data as array of objects\",\n },\n total_rows: { type: \"number\", description: \"Total data rows\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n ...PaginationSchema,\n },\n} as const;\n\nconst JSONReadOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n data: { type: \"object\", description: \"Parsed JSON data\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n },\n} as const;\n\nconst WriteOutputSchema = {\n type: \"object\",\n properties: {\n success: { type: \"boolean\", description: \"Write operation success\" },\n file_path: { type: \"string\", description: \"Written file path\" },\n message: { type: \"string\", description: \"Success message\" },\n error: { type: \"string\", description: \"Error message if failed\" },\n },\n} as const;\n\nconst ExcelInfoOutputSchema = {\n type: \"object\",\n properties: {\n sheets: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n rows: { type: \"number\" },\n cols: { type: \"number\" },\n },\n },\n description: \"Sheet information\",\n },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n },\n} as const;\n\nconst WordInfoOutputSchema = {\n type: \"object\",\n properties: {\n paragraphs: { type: \"number\", description: \"Paragraph count\" },\n tables: { type: \"number\", description: \"Table count\" },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n },\n} as const;\n\nconst PDFInfoOutputSchema = {\n type: \"object\",\n properties: {\n pages: { type: \"number\", description: \"Page count\" },\n file_size: { type: \"number\", description: \"File size in bytes\" },\n total_words: { type: \"number\", description: \"Total word count\" },\n },\n} as const;\n\nconst TextInfoOutputSchema = {\n type: \"object\",\n properties: {\n ...BaseOutputSchema.properties,\n file_size: { type: \"number\", description: \"File size in bytes\" },\n line_count: { type: \"number\", description: \"Line count\" },\n encoding: { type: \"string\", description: \"File encoding\" },\n file_type: { type: \"string\", description: \"File extension\" },\n // CSV specific\n headers: { type: \"array\", items: { type: \"string\" } },\n total_rows: { type: \"number\" },\n total_cols: { type: \"number\" },\n // JSON specific\n item_count: { type: \"number\" },\n key_count: { type: \"number\" },\n },\n} as const;\n\n// List available tools\nserver.setRequestHandler(ListToolsRequestSchema, async () => {\n return {\n tools: [\n {\n name: \"read_document\",\n description:\n \"Read document content (Excel, Word, PowerPoint, PDF, TXT, CSV, Markdown, JSON, YAML). Supports raw full read or paginated mode.\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to the document file\",\n },\n file_type: {\n type: \"string\",\n enum: [\"excel\", \"word\", \"pptx\", \"pdf\", \"text\"],\n description:\n \"Override file type detection (optional). Specify format explicitly instead of relying on extension\",\n },\n mode: {\n type: \"string\",\n enum: [\"raw\", \"paginated\"],\n description: \"Read mode\",\n },\n page: {\n type: \"number\",\n description: \"Page number for paginated mode\",\n },\n page_size: { type: \"number\", description: \"Items per page\" },\n sheet_name: {\n type: \"string\",\n description: \"Sheet name for Excel files\",\n },\n },\n required: [\"file_path\"],\n },\n outputSchema: {\n type: \"object\",\n description:\n \"Document content with format-specific structure. Common fields: success (boolean), error (string, on failure).\",\n properties: {\n // Common fields\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n encoding: { type: \"string\" },\n\n // Excel-specific\n sheet_name: { type: \"string\" },\n sheets: { type: \"array\", items: { type: \"string\" } },\n total_rows: { type: \"number\" },\n total_cols: { type: \"number\" },\n current_page: { type: [\"number\", \"null\"] },\n total_pages: { type: \"number\" },\n\n // Word-specific\n paragraphs: { type: \"array\" },\n tables: { type: \"array\" },\n total_paragraphs: { type: \"number\" },\n total_tables: { type: \"number\" },\n\n // PowerPoint-specific\n total_slides: { type: \"number\" },\n slides: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n slide_number: { type: \"number\" },\n title: { type: \"string\" },\n content: { type: \"array\" },\n notes: { type: \"string\" },\n },\n },\n },\n\n // PDF-specific\n current_page_group: { type: [\"number\", \"null\"] },\n total_page_groups: { type: \"number\" },\n content: {}, // PDF: array of {page_number, text, words}, Text: string\n\n // Text/CSV-specific\n total_lines: { type: \"number\" },\n headers: { type: \"array\", items: { type: \"string\" } },\n\n // Data field (varies by format)\n data: {}, // Excel: array of arrays, CSV: array of objects, JSON: any\n\n // Pagination\n page: { type: \"number\" },\n page_size: { type: [\"number\", \"null\"] },\n has_more: { type: \"boolean\" },\n },\n additionalProperties: false,\n },\n },\n {\n name: \"write_document\",\n description: \"Write document content (Excel, Word, PowerPoint, Text)\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to save the document\",\n },\n format: {\n type: \"string\",\n enum: [\"excel\", \"word\", \"pptx\", \"text\"],\n description: \"Document format\",\n },\n data: {\n description:\n \"Document data structure. Excel: array of rows [[cell1, cell2], ...]. Word: {paragraphs: string[], tables?: [[[cell]]]}. Text/CSV/JSON: string or object\",\n },\n },\n required: [\"file_path\", \"format\", \"data\"],\n },\n outputSchema: WriteOutputSchema,\n },\n {\n name: \"get_document_info\",\n description:\n \"Get document metadata (page count, sheet count, slide count, file size, etc.)\",\n inputSchema: {\n type: \"object\",\n properties: {\n file_path: {\n type: \"string\",\n description: \"Absolute path to the document file\",\n },\n file_type: {\n type: \"string\",\n enum: [\"excel\", \"word\", \"pptx\", \"pdf\", \"text\"],\n description:\n \"Override file type detection (optional). Specify format explicitly instead of relying on extension\",\n },\n },\n required: [\"file_path\"],\n },\n outputSchema: {\n type: \"object\",\n description: \"Document metadata with format-specific fields\",\n properties: {\n success: { type: \"boolean\" },\n error: { type: \"string\" },\n file_size: { type: \"number\" },\n\n // Excel-specific\n sheets: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n name: { type: \"string\" },\n rows: { type: \"number\" },\n cols: { type: \"number\" },\n },\n },\n },\n\n // Word-specific\n paragraphs: { type: \"number\" },\n tables: { type: \"number\" },\n\n // PowerPoint-specific\n slides: { type: \"number\" },\n\n // PDF-specific\n pages: { type: \"number\" },\n total_words: { type: \"number\" },\n metadata: { type: \"object\" },\n\n // Text/CSV/JSON-specific\n line_count: { type: \"number\" },\n encoding: { type: \"string\" },\n file_type: { type: \"string\" },\n headers: { type: \"array\", items: { type: \"string\" } },\n total_rows: { type: \"number\" },\n total_cols: { type: \"number\" },\n item_count: { type: \"number\" },\n key_count: { type: \"number\" },\n },\n additionalProperties: false,\n },\n },\n ],\n };\n});\n\n// Handle tool calls\nserver.setRequestHandler(CallToolRequestSchema, async (request) => {\n const { name, arguments: args } = request.params;\n\n try {\n if (name === \"read_document\") {\n const params = ReadDocumentSchema.parse(args);\n // Use explicit file_type if provided, otherwise detect from extension\n const fileType = params.file_type || detectFileType(params.file_path);\n\n if (!fileType) {\n throw new Error(`Unsupported file type: ${params.file_path}`);\n }\n\n // Determine read mode\n const config = getConfig();\n const mode = params.mode || (config.rawFullRead ? \"raw\" : \"paginated\");\n const page = mode === \"paginated\" ? (params.page || 1) : undefined;\n const pageSize = params.page_size || config.pageSize;\n\n let scriptName: string;\n let scriptArgs: string[];\n\n if (fileType === \"excel\") {\n scriptName = \"excel_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (params.sheet_name) scriptArgs.push(params.sheet_name);\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"word\") {\n scriptName = \"word_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"pptx\") {\n scriptName = \"pptx_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n } else if (fileType === \"pdf\") {\n scriptName = \"pdf_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(Math.min(pageSize, 10))); // PDF pages are larger\n }\n } else {\n // text files\n scriptName = \"text_handler.py\";\n scriptArgs = [\"read\", params.file_path];\n if (page) {\n scriptArgs.push(String(page));\n scriptArgs.push(String(pageSize));\n }\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(fileType),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n if (name === \"write_document\") {\n const params = WriteDocumentSchema.parse(args);\n\n let scriptName: string;\n let scriptArgs: string[];\n\n if (params.format === \"excel\") {\n scriptName = \"excel_handler.py\";\n scriptArgs = [\"write\", params.file_path, JSON.stringify(params.data)];\n } else if (params.format === \"word\") {\n scriptName = \"word_handler.py\";\n const paragraphs = params.data.paragraphs || [];\n const tables = params.data.tables || null;\n scriptArgs = [\"write\", params.file_path, JSON.stringify(paragraphs)];\n if (tables) scriptArgs.push(JSON.stringify(tables));\n } else if (params.format === \"pptx\") {\n scriptName = \"pptx_handler.py\";\n const slides = params.data.slides || params.data || [];\n scriptArgs = [\"write\", params.file_path, JSON.stringify(slides)];\n } else if (params.format === \"text\") {\n scriptName = \"text_handler.py\";\n const content = typeof params.data === \"string\"\n ? params.data\n : JSON.stringify(params.data);\n scriptArgs = [\"write\", params.file_path, content];\n } else {\n throw new Error(`Unsupported write format: ${params.format}`);\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(params.format),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n if (name === \"get_document_info\") {\n const params = GetDocumentInfoSchema.parse(args);\n // Use explicit file_type if provided, otherwise detect from extension\n const fileType = params.file_type || detectFileType(params.file_path);\n\n if (!fileType) {\n throw new Error(`Unsupported file type: ${params.file_path}`);\n }\n\n let scriptName: string;\n let scriptArgs = [\"info\", params.file_path];\n\n if (fileType === \"excel\") {\n scriptName = \"excel_handler.py\";\n } else if (fileType === \"word\") {\n scriptName = \"word_handler.py\";\n } else if (fileType === \"pptx\") {\n scriptName = \"pptx_handler.py\";\n } else if (fileType === \"pdf\") {\n scriptName = \"pdf_handler.py\";\n } else {\n scriptName = \"text_handler.py\";\n }\n\n const result = await runPythonFile(scriptName, {\n args: scriptArgs,\n packages: getPackages(fileType),\n filePaths: [params.file_path],\n });\n return {\n content: [{\n type: \"text\",\n text: JSON.stringify(result, null, 2),\n }],\n structuredContent: result,\n };\n }\n\n throw new Error(`Unknown tool: ${name}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n return {\n content: [{ type: \"text\", text: `Error: ${errorMessage}` }],\n isError: true,\n };\n }\n});\n\n// Start server\nasync function main() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n console.error(\"Docsmith MCP server running on stdio\");\n}\n\nmain().catch((error) => {\n console.error(\"Server error:\", error);\n process.exit(1);\n});\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "docsmith-mcp",
3
- "version": "0.0.1-beta.2",
3
+ "version": "0.0.1-beta.3",
4
4
  "description": "Python-powered document processing MCP for Excel, Word, PDF",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -0,0 +1,169 @@
1
+ """
2
+ PowerPoint document handler - read/write PPTX files
3
+ """
4
+ import json
5
+ import sys
6
+ from pathlib import Path
7
+
8
+
9
+ def read_pptx(file_path: str, page: int = None, page_size: int = 100):
10
+ """Read PowerPoint presentation with optional pagination by slides"""
11
+ from pptx import Presentation
12
+
13
+ prs = Presentation(file_path)
14
+
15
+ # Extract all slides content
16
+ slides = []
17
+ for i, slide in enumerate(prs.slides):
18
+ slide_data = {
19
+ "slide_number": i + 1,
20
+ "title": "",
21
+ "content": [],
22
+ "notes": ""
23
+ }
24
+
25
+ # Extract text from shapes
26
+ for shape in slide.shapes:
27
+ if hasattr(shape, "text") and shape.text.strip():
28
+ # Try to detect if it's a title
29
+ if hasattr(shape, "is_placeholder") and shape.is_placeholder:
30
+ placeholder = shape.placeholder_format
31
+ if placeholder.type == 1: # Title placeholder
32
+ slide_data["title"] = shape.text
33
+ continue
34
+
35
+ slide_data["content"].append(shape.text)
36
+
37
+ # Extract table data
38
+ if hasattr(shape, "table"):
39
+ table_data = []
40
+ for row in shape.table.rows:
41
+ row_data = [cell.text for cell in row.cells]
42
+ table_data.append(row_data)
43
+ slide_data["content"].append({"table": table_data})
44
+
45
+ # Extract notes
46
+ if slide.has_notes_slide:
47
+ notes_frame = slide.notes_slide.notes_text_frame
48
+ if notes_frame:
49
+ slide_data["notes"] = notes_frame.text
50
+
51
+ slides.append(slide_data)
52
+
53
+ total_slides = len(slides)
54
+
55
+ # Handle pagination
56
+ if page is not None:
57
+ start = (page - 1) * page_size
58
+ end = start + page_size
59
+ slides = slides[start:end]
60
+ total_pages = (total_slides + page_size - 1) // page_size if total_slides else 1
61
+ else:
62
+ total_pages = 1
63
+
64
+ return {
65
+ "total_slides": total_slides,
66
+ "slides": slides,
67
+ "current_page": page,
68
+ "page_size": page_size if page else None,
69
+ "total_pages": total_pages
70
+ }
71
+
72
+
73
+ def get_pptx_info(file_path: str):
74
+ """Get PowerPoint metadata"""
75
+ from pptx import Presentation
76
+
77
+ prs = Presentation(file_path)
78
+
79
+ info = {
80
+ "slides": len(prs.slides),
81
+ "file_size": Path(file_path).stat().st_size
82
+ }
83
+
84
+ # Try to get presentation properties
85
+ if prs.core_properties:
86
+ props = prs.core_properties
87
+ metadata = {}
88
+ if props.title:
89
+ metadata["title"] = props.title
90
+ if props.author:
91
+ metadata["author"] = props.author
92
+ if props.subject:
93
+ metadata["subject"] = props.subject
94
+ if props.created:
95
+ metadata["created"] = str(props.created)
96
+ if props.modified:
97
+ metadata["modified"] = str(props.modified)
98
+
99
+ if metadata:
100
+ info["metadata"] = metadata
101
+
102
+ return info
103
+
104
+
105
+ def write_pptx(file_path: str, slides_data: list):
106
+ """Write data to PowerPoint presentation"""
107
+ from pptx import Presentation
108
+ from pptx.util import Inches, Pt
109
+
110
+ prs = Presentation()
111
+ prs.slide_width = Inches(10)
112
+ prs.slide_height = Inches(7.5)
113
+
114
+ for slide_info in slides_data:
115
+ # Add blank slide
116
+ blank_layout = prs.slide_layouts[6] # Blank layout
117
+ slide = prs.slides.add_slide(blank_layout)
118
+
119
+ # Add title if provided
120
+ title = slide_info.get("title", "")
121
+ if title:
122
+ left = Inches(0.5)
123
+ top = Inches(0.5)
124
+ width = Inches(9)
125
+ height = Inches(1)
126
+ title_box = slide.shapes.add_textbox(left, top, width, height)
127
+ title_frame = title_box.text_frame
128
+ title_frame.text = title
129
+ title_frame.paragraphs[0].font.size = Pt(32)
130
+ title_frame.paragraphs[0].font.bold = True
131
+
132
+ # Add content
133
+ content = slide_info.get("content", [])
134
+ if content:
135
+ left = Inches(0.5)
136
+ top = Inches(2)
137
+ width = Inches(9)
138
+ height = Inches(5)
139
+ content_box = slide.shapes.add_textbox(left, top, width, height)
140
+ text_frame = content_box.text_frame
141
+
142
+ for item in content:
143
+ if isinstance(item, str):
144
+ p = text_frame.add_paragraph()
145
+ p.text = item
146
+ p.level = 0
147
+
148
+ prs.save(file_path)
149
+ return {"success": True, "file_path": file_path}
150
+
151
+
152
+ if __name__ == "__main__":
153
+ command = sys.argv[1]
154
+ file_path = sys.argv[2]
155
+
156
+ if command == "read":
157
+ page = int(sys.argv[3]) if len(sys.argv) > 3 else None
158
+ page_size = int(sys.argv[4]) if len(sys.argv) > 4 else 100
159
+ result = read_pptx(file_path, page, page_size)
160
+ elif command == "info":
161
+ result = get_pptx_info(file_path)
162
+ elif command == "write":
163
+ # Data passed as JSON string
164
+ slides_data = json.loads(sys.argv[3])
165
+ result = write_pptx(file_path, slides_data)
166
+ else:
167
+ result = {"error": f"Unknown command: {command}"}
168
+
169
+ print(json.dumps(result, default=str))
@@ -10,6 +10,7 @@ import { runPy } from "@mcpc-tech/code-runner-mcp";
10
10
  const PACKAGES = [
11
11
  "openpyxl",
12
12
  "python-docx",
13
+ "python-pptx",
13
14
  "PyPDF2",
14
15
  ];
15
16
 
@@ -39,6 +40,7 @@ asyncio.run(main())
39
40
  packages: {
40
41
  openpyxl: "openpyxl",
41
42
  "python-docx": "python-docx",
43
+ "python-pptx": "python-pptx",
42
44
  PyPDF2: "PyPDF2",
43
45
  },
44
46
  });