Skip to main content
Glama

mcp-pandoc-md2pptx

by maekawataiki
server.py7.3 kB
import pypandoc from mcp.server.models import InitializationOptions import mcp.types as types from mcp.server import NotificationOptions, Server import mcp.server.stdio import os from pathlib import Path server = Server("mcp-pandoc-md2pptx") # Get the path to the diagram.lua filter DIAGRAM_FILTER_PATH = Path(__file__).parent / "diagram.lua" @server.list_tools() async def handle_list_tools() -> list[types.Tool]: """ List available tools. Each tool specifies its arguments using JSON Schema validation. """ return [ types.Tool( name="convert-contents", description=( "Converts Markdown content to PowerPoint (PPTX) format.\n\n" "🚨 REQUIREMENTS:\n" "1. Input: Only Markdown format is supported\n" "2. Output: Only PPTX format is supported\n" "3. File Path: Complete output path with filename and .pptx extension is required\n\n" "✅ Usage Example:\n" "'Convert this markdown to PowerPoint and save as /presentations/demo.pptx'\n\n" "🎨 PPTX STYLING:\n" "* Use template parameter to apply custom PowerPoint templates\n" "* Create templates with your branding, fonts, and slide layouts\n" "* Example: 'Convert markdown to PPTX using /templates/theme.pptx as template and save as /presentations/pitch.pptx'\n\n" "➡️ Diagram Support:\n" "* Diagram using mermaid, plantuml, graphviz is supported by default. Referencing external resource in plantuml is also supported.\n" """* Example: \n```plantuml @startuml Two Modes - Technical View ' Uncomment the line below for "dark mode" styling '!$AWS_DARK = true !define AWSPuml https://raw.githubusercontent.com/awslabs/aws-icons-for-plantuml/v20.0/dist !include AWSPuml/AWSCommon.puml !include AWSPuml/AWSSimplified.puml !include AWSPuml/General/Users.puml !include AWSPuml/NetworkingContentDelivery/APIGateway.puml !include AWSPuml/SecurityIdentityCompliance/Cognito.puml !include AWSPuml/Compute/Lambda.puml !include AWSPuml/Database/DynamoDB.puml left to right direction Users(sources, "Events", "millions of users") APIGateway(votingAPI, "Voting API", "user votes") Cognito(userAuth, "User Authentication", "jwt to submit votes") Lambda(generateToken, "User Credentials", "return jwt") Lambda(recordVote, "Record Vote", "enter or update vote per user") DynamoDB(voteDb, "Vote Database", "one entry per user") sources --> userAuth sources --> votingAPI userAuth <--> generateToken votingAPI --> recordVote recordVote --> voteDb @enduml ```\n\n""" "📋 Creating Reference Documents:\n" "* Generate PPTX template: pandoc -o template.pptx --print-default-data-file reference.pptx\n" "* Customize in PowerPoint: fonts, colors, slide layouts\n" ), inputSchema={ "type": "object", "properties": { "contents": { "type": "string", "description": "Markdown content to be converted (required if input_file not provided)" }, "input_file": { "type": "string", "description": "Complete path to Markdown input file (e.g., '/path/to/input.md')" }, "output_file": { "type": "string", "description": "Complete path where to save the PPTX output including filename and .pptx extension (required)" }, "template": { "type": "string", "description": "Path to a template PPTX document to use for styling" } }, "oneOf": [ {"required": ["contents", "output_file"]}, {"required": ["input_file", "output_file"]} ] }, ) ] @server.call_tool() async def handle_call_tool( name: str, arguments: dict | None ) -> list[types.TextContent | types.ImageContent | types.EmbeddedResource]: """ Handle tool execution requests. Tools can modify server state and notify clients of changes. """ if name not in ["convert-contents"]: raise ValueError(f"Unknown tool: {name}") if not arguments: raise ValueError("Missing arguments") # Extract arguments contents = arguments.get("contents") input_file = arguments.get("input_file") output_file = arguments.get("output_file") template = arguments.get("template") # Validate input parameters if not contents and not input_file: raise ValueError("Either 'contents' or 'input_file' must be provided") if not output_file: raise ValueError("output_file path is required") # Validate template if provided if template and not os.path.exists(template): raise ValueError(f"Template document not found: {template}") try: # Create output directory if it doesn't exist output_path = Path(output_file) output_path.parent.mkdir(parents=True, exist_ok=True) # Prepare conversion arguments extra_args = [] # Add diagram filter by default if DIAGRAM_FILTER_PATH.exists(): extra_args.extend(["--lua-filter", str(DIAGRAM_FILTER_PATH)]) # Handle template for pptx format if template: extra_args.extend(["--reference-doc", template]) # Convert content using pypandoc if input_file: if not os.path.exists(input_file): raise ValueError(f"Input file not found: {input_file}") pypandoc.convert_file( input_file, "pptx", outputfile=output_file, extra_args=extra_args ) else: pypandoc.convert_text( contents, "pptx", format="markdown", outputfile=output_file, extra_args=extra_args ) result_message = f"Markdown successfully converted to PPTX and saved to: {output_file}" return [ types.TextContent( type="text", text=result_message ) ] except Exception as e: error_msg = f"Error converting markdown to PPTX: {str(e)}" raise ValueError(error_msg) async def main(): # Run the server using stdin/stdout streams async with mcp.server.stdio.stdio_server() as (read_stream, write_stream): await server.run( read_stream, write_stream, InitializationOptions( server_name="mcp-pandoc-md2pptx", server_version="0.7.0", # Updated version with defaults file support capabilities=server.get_capabilities( notification_options=NotificationOptions(), experimental_capabilities={}, ), ), )

MCP directory API

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

curl -X GET 'https://glama.ai/api/mcp/v1/servers/maekawataiki/mcp-pandoc-md2pptx'

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